Fix spinner clobbering user message text; add worker logging
ober
85af1a620b45c26ee9ae5f71b3fa6f8150e1fc0d
--- a/lib/jcode/ui/tui.sls +++ b/lib/jcode/ui/tui.sls @@ -88,8 +88,10 @@ (def (msg-area-height state) (- (app-state-height state) (app-state-input-height state) + 1 1)) - (def (input-y state) (msg-area-height state)) + (def (agent-status-y state) (msg-area-height state)) + (def (input-y state) (+ (msg-area-height state) 1)) (def (status-y state) (- (app-state-height state) 1)) (def (sidebar-x state) (- (app-state-width state) (app-state-sidebar-width state))) @@ -587,6 +589,7 @@ (and (config-get-provider-key p-name) #t)) (spawn (lambda () + (tui-log "worker: entered, main-thread=~a" (*main-thread*)) (try (parameterize ([current-provider-override p-override] [current-model-override m-override] [current-stream-cb @@ -595,18 +598,28 @@ (list 'stream-token token)))] [current-tool-cb (lambda (event name args) + (tui-log + "worker: tool-cb ~a ~a" + event + name) (send-agent-event! (list 'tool-event event name args)))] [current-usage-cb (lambda (usage) (send-agent-event! (list 'usage-update usage)))]) + (tui-log "worker: calling agent-run") (agent-run s-id text) - (send-agent-event! (list 'agent-done))) + (tui-log + "worker: agent-run returned, sending agent-done") + (send-agent-event! (list 'agent-done)) + (tui-log + "worker: agent-done sent, worker exiting normally")) (catch (e) - (send-agent-event! - (list 'agent-error (err->string e))))))))) + (let ([msg (err->string e)]) + (tui-log "worker: CAUGHT exception: ~a" msg) + (send-agent-event! (list 'agent-error msg))))))))) (def (tui-stream-token! state token) "Handle a streaming token from the LLM — called from agent thread." (let ([buf (app-state-stream-buf state)]) @@ -785,7 +798,7 @@ [frame (vector-ref *spinner-frames* frame-idx)] [fg (face-fg-attr 'spinner)] [bg (face-bg-attr 'default)] - [y (max 0 (- (input-y state) 1))] + [y (agent-status-y state)] [w (msg-area-width state)] [text (string-append " " frame " thinking...")]) (let clear ([col 0]) --- a/src/jcode/ui/tui.ss +++ b/src/jcode/ui/tui.ss @@ -153,9 +153,14 @@ (def (msg-area-height state) (- (app-state-height state) (app-state-input-height state) - 1)) ;; -1 for status bar - -(def (input-y state) (msg-area-height state)) + 1 ;; -1 for status bar + 1)) ;; -1 for dedicated agent-status row (spinner) + +;; The dedicated row for the thinking spinner. Lives BETWEEN the message +;; area and the input, so drawing the spinner never clobbers the last +;; rendered message line (which was the cause of missing user text). +(def (agent-status-y state) (msg-area-height state)) +(def (input-y state) (+ (msg-area-height state) 1)) (def (status-y state) (- (app-state-height state) 1)) (def (sidebar-x state) @@ -657,6 +662,7 @@ ;; Agent worker: sends events to main thread mailbox; never touches state. (spawn (lambda () + (tui-log "worker: entered, main-thread=~a" (*main-thread*)) (try (parameterize ((current-provider-override p-override) @@ -666,14 +672,20 @@ (send-agent-event! (list 'stream-token token)))) (current-tool-cb (lambda (event name args) + (tui-log "worker: tool-cb ~a ~a" event name) (send-agent-event! (list 'tool-event event name args)))) (current-usage-cb (lambda (usage) (send-agent-event! (list 'usage-update usage))))) + (tui-log "worker: calling agent-run") (agent-run s-id text) - (send-agent-event! (list 'agent-done))) + (tui-log "worker: agent-run returned, sending agent-done") + (send-agent-event! (list 'agent-done)) + (tui-log "worker: agent-done sent, worker exiting normally")) (catch (e) - (send-agent-event! (list 'agent-error (err->string e))))))))) + (let ((msg (err->string e))) + (tui-log "worker: CAUGHT exception: ~a" msg) + (send-agent-event! (list 'agent-error msg))))))))) (def (tui-stream-token! state token) "Handle a streaming token from the LLM — called from agent thread." @@ -870,10 +882,10 @@ (frame (vector-ref *spinner-frames* frame-idx)) (fg (face-fg-attr 'spinner)) (bg (face-bg-attr 'default)) - (y (max 0 (- (input-y state) 1))) + (y (agent-status-y state)) (w (msg-area-width state)) (text (string-append " " frame " thinking..."))) - ;; Clear entire row first so message content doesn't bleed through + ;; Dedicated status row, so clearing it never touches the message area. (let clear ((col 0)) (when (< col w) (tb-change-cell! col y (char->integer #\space) bg bg)