@@ -44,11 +44,13 @@ type Agent struct {
4444 hooks * latest.HooksConfig
4545 cache * cache.Cache
4646
47- // warningsMu guards pendingWarnings. addToolWarning and DrainWarnings
48- // may be called concurrently from the runtime loop, the MCP server,
49- // the TUI and session manager.
47+ // warningsMu guards pendingWarnings and pendingNotices. AddToolWarning,
48+ // AddToolNotice, DrainWarnings and DrainNotices may be called
49+ // concurrently from the runtime loop, the MCP server, the TUI and
50+ // session manager.
5051 warningsMu sync.Mutex
5152 pendingWarnings []string
53+ pendingNotices []string
5254}
5355
5456// New creates a new agent
@@ -288,7 +290,7 @@ func (a *Agent) collectTools(ctx context.Context) ([]tools.Tool, error) {
288290 if err != nil {
289291 desc := tools .DescribeToolSet (toolSet )
290292 slog .Warn ("Toolset listing failed; skipping" , "agent" , a .Name (), "toolset" , desc , "error" , err )
291- a .addToolWarning (fmt .Sprintf ("%s list failed: %v" , desc , err ))
293+ a .AddToolWarning (fmt .Sprintf ("%s list failed: %v" , desc , err ))
292294 continue
293295 }
294296 agentTools = append (agentTools , ta ... )
@@ -321,7 +323,7 @@ func (a *Agent) ensureToolSetsAreStarted(ctx context.Context) {
321323 if toolSet .ShouldReportFailure () {
322324 desc := tools .DescribeToolSet (toolSet )
323325 slog .Warn ("Toolset start failed; will retry on next turn" , "agent" , a .Name (), "toolset" , desc , "error" , err )
324- a .addToolWarning (fmt .Sprintf ("%s start failed: %v" , desc , err ))
326+ a .AddToolWarning (fmt .Sprintf ("%s start failed: %v" , desc , err ))
325327 } else {
326328 desc := tools .DescribeToolSet (toolSet )
327329 slog .Debug ("Toolset still unavailable; retrying next turn" , "agent" , a .Name (), "toolset" , desc , "error" , err )
@@ -332,13 +334,17 @@ func (a *Agent) ensureToolSetsAreStarted(ctx context.Context) {
332334 if toolSet .ConsumeRecovery () {
333335 desc := tools .DescribeToolSet (toolSet )
334336 slog .Info ("Toolset now available" , "agent" , a .Name (), "toolset" , desc )
335- a .addToolWarning (desc + " is now available" )
337+ a .AddToolNotice (desc + " is now available" )
336338 }
337339 }
338340}
339341
340- // addToolWarning records a warning generated while loading or starting toolsets.
341- func (a * Agent ) addToolWarning (msg string ) {
342+ // AddToolWarning records a warning generated while loading or starting toolsets.
343+ // Warnings represent real failures the user should know about (a remote MCP
344+ // server returning 4xx, an MCP binary missing, ...). For positive notices
345+ // (a previously-failed toolset becoming available again) use AddToolNotice
346+ // instead so the message isn't framed as a failure.
347+ func (a * Agent ) AddToolWarning (msg string ) {
342348 if msg == "" {
343349 return
344350 }
@@ -347,6 +353,19 @@ func (a *Agent) addToolWarning(msg string) {
347353 a .warningsMu .Unlock ()
348354}
349355
356+ // AddToolNotice records a positive, informational notice about a toolset
357+ // (typically: a previously-failed toolset is now available). Notices are
358+ // surfaced to the user separately from warnings so the framing doesn't
359+ // say "failed to initialize" for a recovery message.
360+ func (a * Agent ) AddToolNotice (msg string ) {
361+ if msg == "" {
362+ return
363+ }
364+ a .warningsMu .Lock ()
365+ a .pendingNotices = append (a .pendingNotices , msg )
366+ a .warningsMu .Unlock ()
367+ }
368+
350369// DrainWarnings returns pending warnings and clears them.
351370func (a * Agent ) DrainWarnings () []string {
352371 a .warningsMu .Lock ()
@@ -356,6 +375,15 @@ func (a *Agent) DrainWarnings() []string {
356375 return warnings
357376}
358377
378+ // DrainNotices returns pending notices and clears them.
379+ func (a * Agent ) DrainNotices () []string {
380+ a .warningsMu .Lock ()
381+ defer a .warningsMu .Unlock ()
382+ notices := a .pendingNotices
383+ a .pendingNotices = nil
384+ return notices
385+ }
386+
359387func (a * Agent ) StopToolSets (ctx context.Context ) error {
360388 for _ , toolSet := range a .toolsets {
361389 // Only stop toolsets that were successfully started
0 commit comments