fix(agent): move reauth notification from agent to coordinator

Kieran Klukas created

The agent was publishing TypeReAuthenticate immediately on 401, before
the coordinator had a chance to retry with a refreshed token. This
caused premature reauth popups even when the retry would succeed.

Move the notification to the coordinator so it only fires after
retryAfterUnauthorized fails.

Change summary

internal/agent/agent.go       | 8 --------
internal/agent/coordinator.go | 6 ++++++
2 files changed, 6 insertions(+), 8 deletions(-)

Detailed changes

internal/agent/agent.go 🔗

@@ -641,14 +641,6 @@ func (a *sessionAgent) Run(ctx context.Context, call SessionAgentCall) (result *
 			currentAssistant.AddFinish(message.FinishReasonCanceled, "User canceled request", "")
 		} else if isHyper && errors.As(err, &providerErr) && providerErr.StatusCode == http.StatusUnauthorized {
 			currentAssistant.AddFinish(message.FinishReasonError, "Unauthorized", `Please re-authenticate with Hyper. You can also run "crush auth" to re-authenticate.`)
-			if a.notify != nil {
-				a.notify.Publish(pubsub.CreatedEvent, notify.Notification{
-					SessionID:    call.SessionID,
-					SessionTitle: currentSession.Title,
-					Type:         notify.TypeReAuthenticate,
-					ProviderID:   largeModel.ModelCfg.Provider,
-				})
-			}
 		} else if isHyper && errors.As(err, &providerErr) && providerErr.StatusCode == http.StatusPaymentRequired {
 			url := hyper.BaseURL()
 			link := linkStyle.Hyperlink(url, "id=hyper").Render(url)

internal/agent/coordinator.go 🔗

@@ -266,6 +266,12 @@ func (c *coordinator) Run(ctx context.Context, sessionID string, prompt string,
 		if err := c.retryAfterUnauthorized(ctx, providerCfg); err == nil {
 			result, originalErr = run()
 		}
+		if c.notify != nil && model.ModelCfg.Provider == hyper.Name {
+			c.notify.Publish(pubsub.CreatedEvent, notify.Notification{
+				Type:       notify.TypeReAuthenticate,
+				ProviderID: model.ModelCfg.Provider,
+			})
+		}
 	}
 
 	if hasLatest && c.runComplete != nil {