Skip to content

fix(agents): surface recovered subagent termination reasons#22325

Open
matei-anghel wants to merge 5 commits intogoogle-gemini:mainfrom
matei-anghel:fix/subagent-recovery-status
Open

fix(agents): surface recovered subagent termination reasons#22325
matei-anghel wants to merge 5 commits intogoogle-gemini:mainfrom
matei-anghel:fix/subagent-recovery-status

Conversation

@matei-anghel
Copy link
Copy Markdown

Summary

Surface recovered subagent termination reasons so recovered runs are not presented as plain clean GOAL successes.

Details

This change keeps the current recovery behavior for local subagents, but preserves the original recoverable stop reason when recovery succeeds.

When a subagent hits MAX_TURNS, TIMEOUT, or ERROR_NO_COMPLETE_TASK_CALL and the recovery turn succeeds, the final output now keeps:

  • terminate_reason=GOAL
  • recovered_from=<original reason>

This is surfaced in:

  • local subagent invocation output
  • browser agent invocation output
  • agent finish logs
  • metrics
  • Clearcut metadata

This keeps recovered runs usable by the parent agent while making the interruption visible to users and telemetry.

Related Issues

Fixes #22323

How to Validate

Run:

npm run build
cd packages/core
npx vitest run src/agents/local-executor.test.ts src/agents/local-invocation.test.ts src/agents/browser/browserAgentInvocation.test.ts src/telemetry/loggers.test.ts src/telemetry/metrics.test.ts src/telemetry/clearcut-logger/clearcut-logger.test.ts

Expected results:

  • build passes
  • all 6 test files pass
  • recovered subagent completions include Recovered From: <reason>
  • clean non-recovered GOAL completions do not include recovered_from

Pre-Merge Checklist

  • Updated relevant documentation and README (if needed)
  • Added/updated tests (if needed)
  • Noted breaking changes (if any)
  • Validated on required platforms/methods:
    • MacOS
      • npm run
      • npx
      • Docker
      • Podman
      • Seatbelt
    • Windows
      • npm run
      • npx
      • Docker
    • Linux
      • npm run
      • npx
      • Docker

@matei-anghel matei-anghel requested a review from a team as a code owner March 13, 2026 14:40
@gemini-code-assist
Copy link
Copy Markdown
Contributor

Summary of Changes

Hello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request improves the transparency of subagent recovery by ensuring that when a subagent successfully recovers from an initial termination condition, the system explicitly records and displays the original reason for the interruption. This change prevents recovered runs from appearing as simple successes, offering users and telemetry systems a clearer understanding of the agent's operational flow and any underlying issues it overcame. The modifications span across agent execution logic, output rendering, and various telemetry logging mechanisms.

Highlights

  • Enhanced Subagent Recovery Visibility: Subagent runs that successfully recover from an initial failure (e.g., MAX_TURNS, TIMEOUT, ERROR_NO_COMPLETE_TASK_CALL) now explicitly surface the original termination reason alongside the final 'GOAL' success.
  • Output and Display Updates: Both local and browser agent invocation outputs, as well as their display content, have been updated to clearly indicate when an agent finished after recovery and to show the specific reason it recovered from.
  • Telemetry and Metrics Integration: The recovered_from reason is now captured and logged in agent finish events, Clearcut metadata, and agent run metrics, providing better insights into agent behavior and recovery patterns.
  • Type Safety and Testing: A new RecoverableAgentTerminateMode type was introduced for clarity, and comprehensive test cases were added or updated across local executor, browser agent invocation, and telemetry modules to validate the new recovery behavior and logging.
Changelog
  • packages/core/src/agents/browser/browserAgentInvocation.test.ts
    • Added a test case to verify that recovered browser agent completions are rendered distinctly, including the 'recovered_from' reason.
  • packages/core/src/agents/browser/browserAgentInvocation.ts
    • Modified the output generation for browser agent invocations to include a 'recovered_from' line in both the LLM content and display output when applicable.
  • packages/core/src/agents/local-executor.test.ts
    • Added assertions to ensure the 'recovered_from' property is correctly set or absent in agent output for various recovery and non-recovery scenarios.
    • Updated tests for MAX_TURNS, ERROR_NO_COMPLETE_TASK_CALL, and TIMEOUT recovery to verify the presence and value of 'recovered_from'.
  • packages/core/src/agents/local-executor.ts
    • Imported the new RecoverableAgentTerminateMode type.
    • Introduced isRecoverableTerminateReason helper function to identify recoverable termination modes.
    • Added a recoveredFrom variable to track the original termination reason during agent execution.
    • Updated the recovery success logic to store the original terminateReason in recoveredFrom if it's a recoverable type.
    • Included the recoveredFrom property in the final output object returned by the executor.
    • Passed the recoveredFrom value to the agent finish event logging.
  • packages/core/src/agents/local-invocation.test.ts
    • Added a test case to verify that recovered local subagent completions are rendered distinctly, including the 'recovered_from' reason.
  • packages/core/src/agents/local-invocation.ts
    • Modified the output generation for local subagent invocations to include a 'recovered_from' line in both the LLM content and display output when applicable.
  • packages/core/src/agents/types.ts
    • Defined a new type RecoverableAgentTerminateMode to explicitly list termination modes from which an agent can recover.
    • Added an optional recovered_from property to the OutputObject interface to store the original termination reason.
  • packages/core/src/telemetry/clearcut-logger/clearcut-logger.test.ts
    • Added a test to confirm that the recovered_from reason is correctly logged as metadata in Clearcut events when present.
  • packages/core/src/telemetry/clearcut-logger/clearcut-logger.ts
    • Implemented logic to add GEMINI_CLI_AGENT_RECOVERED_FROM metadata to agent finish events if the recovered_from property is available.
  • packages/core/src/telemetry/clearcut-logger/event-metadata-key.ts
    • Added a new enum value GEMINI_CLI_AGENT_RECOVERED_FROM for Clearcut event metadata keys.
  • packages/core/src/telemetry/loggers.test.ts
    • Added a test to ensure that recovered_from is included in the log body and attributes of agent finish events when an agent recovers.
  • packages/core/src/telemetry/metrics.test.ts
    • Added a test to verify that recovered_from is correctly included in agent run metrics when an agent finishes after recovery.
  • packages/core/src/telemetry/metrics.ts
    • Updated the COUNTER_DEFINITIONS for agent run metrics to include recovered_from as an optional attribute.
    • Modified recordAgentRunMetrics to conditionally add the recovered_from attribute to the counter if it exists in the event.
  • packages/core/src/telemetry/types.ts
    • Imported RecoverableAgentTerminateMode for use in telemetry types.
    • Added an optional recovered_from property to the AgentFinishEvent class constructor and properties.
    • Updated toOpenTelemetryAttributes and toLogBody methods in AgentFinishEvent to include the recovered_from reason when available.
Activity
  • The author has implemented changes to surface recovered subagent termination reasons, ensuring that recovered runs are not misrepresented as plain successes.
  • New test cases have been added to browserAgentInvocation.test.ts, local-executor.test.ts, local-invocation.test.ts, clearcut-logger.test.ts, loggers.test.ts, and metrics.test.ts to validate the new recovered_from functionality across various components.
  • The author has validated the changes on Windows using npm run and npx, and marked the relevant checklist items as complete.
  • The pull request description includes detailed validation steps for reviewers, involving running specific vitest commands and checking for expected output formats.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for GitHub and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces a mechanism to surface the original termination reason for subagents that successfully recover from errors like timeouts or exceeding turn limits. The changes are well-implemented across the agent execution logic, telemetry, and metrics systems. A new recovered_from field is added to the agent output and telemetry events, providing better visibility into agent behavior without breaking the parent agent's workflow. The code is clean, type-safe, and includes comprehensive tests for the new functionality. I have no major concerns with this change.

Note: Security Review did not run due to the size of the PR.

@gemini-cli gemini-cli bot added the area/agent Issues related to Core Agent, Tools, Memory, Sub-Agents, Hooks, Agent Quality label Mar 13, 2026
@gemini-cli gemini-cli bot added priority/p1 Important and should be addressed in the near term. 🔒 maintainer only ⛔ Do not contribute. Internal roadmap item. labels Mar 13, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/agent Issues related to Core Agent, Tools, Memory, Sub-Agents, Hooks, Agent Quality 🔒 maintainer only ⛔ Do not contribute. Internal roadmap item. priority/p1 Important and should be addressed in the near term.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Subagent recovery after MAX_TURNS is reported as GOAL success, hiding interruption

1 participant