diff --git a/internal/agent/agent.go b/internal/agent/agent.go index 3f21fa7f504ebb3fc6212354127fc5f0d15ae62a..66062270c669ffaba298980ff997c6e2c2e04c2e 100644 --- a/internal/agent/agent.go +++ b/internal/agent/agent.go @@ -581,16 +581,6 @@ func (a *sessionAgent) Run(ctx context.Context, call SessionAgentCall) (*fantasy return nil, err } - // Send notification that agent has finished its turn (skip for - // nested/non-interactive sessions). - if !call.NonInteractive && a.notify != nil { - a.notify.Publish(pubsub.CreatedEvent, notify.Notification{ - SessionID: call.SessionID, - SessionTitle: currentSession.Title, - Type: notify.TypeAgentFinished, - }) - } - if shouldSummarize { a.activeRequests.Del(call.SessionID) if summarizeErr := a.Summarize(genCtx, call.SessionID, call.ProviderOptions); summarizeErr != nil { @@ -608,10 +598,23 @@ func (a *sessionAgent) Run(ctx context.Context, call SessionAgentCall) (*fantasy } } - // Release active request before processing queued messages. + // Release active request before publishing the notification. + // TUI handlers poll IsSessionBusy() and only re-evaluate when a + // tea.Msg arrives, so the cleanup must precede the notify or + // subscribers see stale busy state at the moment of receipt. a.activeRequests.Del(call.SessionID) cancel() + // Send notification that agent has finished its turn (skip for + // nested/non-interactive sessions). + if !call.NonInteractive && a.notify != nil { + a.notify.Publish(pubsub.CreatedEvent, notify.Notification{ + SessionID: call.SessionID, + SessionTitle: currentSession.Title, + Type: notify.TypeAgentFinished, + }) + } + queuedMessages, ok := a.messageQueue.Get(call.SessionID) if !ok || len(queuedMessages) == 0 { return result, err