@@ -581,16 +581,6 @@ func (a *sessionAgent) Run(ctx context.Context, call SessionAgentCall) (*fantasy
581581 return nil, err
582582 }
583583
584โ // Send notification that agent has finished its turn (skip for
585โ // nested/non-interactive sessions).
586โ if !call.NonInteractive && a.notify != nil {
587โ a.notify.Publish(pubsub.CreatedEvent, notify.Notification{
588โ SessionID: call.SessionID,
589โ SessionTitle: currentSession.Title,
590โ Type: notify.TypeAgentFinished,
591โ })
592โ }
593โ
594584 if shouldSummarize {
595585 a.activeRequests.Del(call.SessionID)
596586 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
608598 }
609599 }
610600
611โ // Release active request before processing queued messages.
601+ // Release active request before publishing the notification.
602+ // TUI handlers poll IsSessionBusy() and only re-evaluate when a
603+ // tea.Msg arrives, so the cleanup must precede the notify or
604+ // subscribers see stale busy state at the moment of receipt.
612605 a.activeRequests.Del(call.SessionID)
613606 cancel()
614607
608+ // Send notification that agent has finished its turn (skip for
609+ // nested/non-interactive sessions).
610+ if !call.NonInteractive && a.notify != nil {
611+ a.notify.Publish(pubsub.CreatedEvent, notify.Notification{
612+ SessionID: call.SessionID,
613+ SessionTitle: currentSession.Title,
614+ Type: notify.TypeAgentFinished,
615+ })
616+ }
617+
615618 queuedMessages, ok := a.messageQueue.Get(call.SessionID)
616619 if !ok || len(queuedMessages) == 0 {
617620 return result, err