@@ -961,7 +961,38 @@ func (c *coordinator) Summarize(ctx context.Context, sessionID string) error {
961961 if !ok {
962962 return errModelProviderNotConfigured
963963 }
964− return c.currentAgent.Summarize(ctx, sessionID, getProviderOptions(c.currentAgent.Model(), providerCfg))
964+
965+ // Proactively refresh OAuth token if expired, same as Run().
966+ if providerCfg.OAuthToken != nil && providerCfg.OAuthToken.IsExpired() {
967+ slog.Debug("Token needs to be refreshed before summarize", "provider", providerCfg.ID)
968+ if err := c.refreshOAuth2Token(ctx, providerCfg); err != nil {
969+ slog.Error("Failed to refresh OAuth2 token before summarize. Proceeding with existing token.", "error", err)
970+ }
971+ }
972+
973+ summarize := func() error {
974+ return c.currentAgent.Summarize(ctx, sessionID, getProviderOptions(c.currentAgent.Model(), providerCfg))
975+ }
976+
977+ err := summarize()
978+ if err != nil && c.isUnauthorized(err) {
979+ switch {
980+ case providerCfg.OAuthToken != nil:
981+ slog.Debug("Received 401 during summarize. Refreshing token and retrying", "provider", providerCfg.ID)
982+ if refreshErr := c.refreshOAuth2Token(ctx, providerCfg); refreshErr != nil {
983+ return err
984+ }
985+ return summarize()
986+ case strings.Contains(providerCfg.APIKeyTemplate, "$"):
987+ slog.Debug("Received 401 during summarize. Refreshing API Key template and retrying", "provider", providerCfg.ID)
988+ if refreshErr := c.refreshApiKeyTemplate(ctx, providerCfg); refreshErr != nil {
989+ return err
990+ }
991+ return summarize()
992+ }
993+ }
994+
995+ return err
965996}
966997
967998func (c *coordinator) isUnauthorized(err error) bool {