Skip to content

feat(core): resilient subagent tool rejection with contextual feedback#22951

Merged
abhipatel12 merged 2 commits into
mainfrom
abhi/subagent-reject-ux
Mar 19, 2026
Merged

feat(core): resilient subagent tool rejection with contextual feedback#22951
abhipatel12 merged 2 commits into
mainfrom
abhi/subagent-reject-ux

Conversation

@abhipatel12
Copy link
Copy Markdown
Contributor

Summary

This PR introduces a more resilient tool rejection mechanism for subagents, allowing them to rethink their strategy when a user denies a specific tool execution instead of immediately terminating the entire task.

Details

  • Soft Rejection vs. Hard Abort: Differentiates between a manual user "Reject" (via UI/Picker) and a process-level cancellation (via Ctrl+C).
  • Contextual Feedback: When a subagent tool is rejected, the subagent now stays alive and receives a direct instruction in its next turn: "User rejected this operation. Please acknowledge this, rethink your strategy, and try a different approach..."
  • System Instruction Anchor: Adds a foundational rule to every subagent's system prompt to handle rejections gracefully.
  • UI State Management: Updates LocalSubagentInvocation to correctly reflect individual tool rejections as cancelled in the progress bar without ending the subagent's overall execution state.
  • Fail-safe preserved: Hard aborts (Ctrl+C) still correctly stop the entire agent and bubble an AbortError to the parent.

Related Issues

N/A

How to Validate

  1. Run the CLI and trigger a subagent (e.g., @codebase_investigator).
  2. When the subagent requests a tool call (like run_shell_command), click Reject in the picker.
  3. Observe that the subagent remains active, acknowledges the rejection in its next thought, and attempts a different tool or approach.
  4. Verify that pressing Ctrl+C during a confirmation still terminates the subagent immediately.
  5. Run unit tests: npm test -w @google/gemini-cli-core -- src/agents/local-executor.test.ts src/agents/local-invocation.test.ts

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

@abhipatel12 abhipatel12 requested a review from a team as a code owner March 18, 2026 16:34
@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 significantly enhances the robustness and user experience of subagents by introducing a sophisticated tool rejection handling mechanism. Instead of immediately terminating when a user denies a tool execution, subagents now receive specific feedback and are prompted to rethink their strategy, allowing for more adaptive and continuous task completion. This change differentiates between user-initiated rejections and system-level aborts, ensuring that subagents can gracefully recover from user interventions while maintaining the ability for hard termination when necessary.

Highlights

  • Resilient Tool Rejection: Implemented a more resilient tool rejection mechanism for subagents, allowing them to rethink their strategy instead of immediately terminating when a user denies a specific tool execution.
  • Contextual Feedback: Subagents now receive direct, contextual instructions when a tool is rejected, prompting them to acknowledge the rejection, rethink their approach, and try a different method.
  • System Instruction Update: Added a foundational rule to every subagent's system prompt to ensure graceful handling of tool rejections.
  • UI State Management: Updated LocalSubagentInvocation to correctly reflect individual tool rejections as 'cancelled' in the progress bar without ending the subagent's overall execution state.
  • Soft vs. Hard Abort: Clearly differentiated between a manual user 'Reject' (soft rejection) and a process-level cancellation (hard abort), with hard aborts still terminating the entire agent.
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.

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.

@github-actions
Copy link
Copy Markdown

github-actions Bot commented Mar 18, 2026

Size Change: +3.24 kB (+0.01%)

Total Size: 26.2 MB

Filename Size Change
./bundle/chunk-6RBYLCXE.js 0 B -13.5 MB (removed) 🏆
./bundle/chunk-N5HU6JDH.js 0 B -3.63 MB (removed) 🏆
./bundle/core-473GCFLR.js 0 B -41.4 kB (removed) 🏆
./bundle/devtoolsService-LD6SLX6K.js 0 B -27.7 kB (removed) 🏆
./bundle/interactiveCli-KTBM4KO3.js 0 B -1.61 MB (removed) 🏆
./bundle/oauth2-provider-RRDB4BIX.js 0 B -9.19 kB (removed) 🏆
./bundle/chunk-3HEQAYYO.js 3.63 MB +3.63 MB (new file) 🆕
./bundle/chunk-RWRKC5LX.js 13.5 MB +13.5 MB (new file) 🆕
./bundle/core-GFJP726E.js 41.6 kB +41.6 kB (new file) 🆕
./bundle/devtoolsService-EUCR2CPX.js 27.7 kB +27.7 kB (new file) 🆕
./bundle/interactiveCli-BZG7WXA5.js 1.61 MB +1.61 MB (new file) 🆕
./bundle/oauth2-provider-XDZCMJYJ.js 9.19 kB +9.19 kB (new file) 🆕
ℹ️ View Unchanged
Filename Size
./bundle/chunk-34MYV7JD.js 2.45 kB
./bundle/chunk-37ZTTFQF.js 966 kB
./bundle/chunk-5AUYMPVF.js 858 B
./bundle/chunk-664ZODQF.js 124 kB
./bundle/chunk-DAHVX5MI.js 206 kB
./bundle/chunk-G4TMH6EN.js 1.95 MB
./bundle/chunk-IUUIT4SU.js 56.5 kB
./bundle/chunk-RJTRUG2J.js 39.8 kB
./bundle/devtools-36NN55EP.js 696 kB
./bundle/dist-T73EYRDX.js 356 B
./bundle/gemini.js 696 kB
./bundle/getMachineId-bsd-TXG52NKR.js 1.55 kB
./bundle/getMachineId-darwin-7OE4DDZ6.js 1.55 kB
./bundle/getMachineId-linux-SHIFKOOX.js 1.34 kB
./bundle/getMachineId-unsupported-5U5DOEYY.js 1.06 kB
./bundle/getMachineId-win-6KLLGOI4.js 1.72 kB
./bundle/memoryDiscovery-KKSSU3SI.js 922 B
./bundle/multipart-parser-KPBZEGQU.js 11.7 kB
./bundle/node_modules/@google/gemini-cli-devtools/dist/client/main.js 221 kB
./bundle/node_modules/@google/gemini-cli-devtools/dist/src/_client-assets.js 227 kB
./bundle/node_modules/@google/gemini-cli-devtools/dist/src/index.js 11.5 kB
./bundle/node_modules/@google/gemini-cli-devtools/dist/src/types.js 132 B
./bundle/sandbox-macos-permissive-open.sb 890 B
./bundle/sandbox-macos-permissive-proxied.sb 1.31 kB
./bundle/sandbox-macos-restrictive-open.sb 3.36 kB
./bundle/sandbox-macos-restrictive-proxied.sb 3.56 kB
./bundle/sandbox-macos-strict-open.sb 4.82 kB
./bundle/sandbox-macos-strict-proxied.sb 5.02 kB
./bundle/src-QVCVGIUX.js 47 kB
./bundle/tree-sitter-7U6MW5PS.js 274 kB
./bundle/tree-sitter-bash-34ZGLXVX.js 1.84 MB
./bundle/undici-4X2YZID5.js 360 B

compressed-size-action

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

The pull request introduces a robust mechanism for handling soft tool rejections by subagents, allowing them to adapt their strategy rather than immediately terminating. This is achieved through contextual feedback to the model and appropriate UI state management. The changes include updating system instructions for subagents, modifying activity stream handling, and adding comprehensive test cases to validate the new behavior. The implementation appears solid, effectively differentiating between soft rejections and hard aborts, and ensuring the agent can recover gracefully.

case 'ERROR': {
const error = String(activity.data['error']);
const isCancellation = error === 'Request cancelled.';
const isRejection = error.startsWith(
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

don't love this string matching on errors. Can we do this a bit more robustly or at least make these string constants. Same issue applies for existing "Request cancelled."

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Done

call.outcome === ToolConfirmationOutcome.Cancel;

if (isSoftRejection) {
const error = `User rejected this operation. Please acknowledge this, rethink your strategy, and try a different approach. If you cannot proceed without the rejected operation, summarize the issue and use \`${TASK_COMPLETE_TOOL_NAME}\` to report your findings and the blocker.`;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

would be great to have some behavioral tests to verify the agent actually behaves reasonably given these soft rejections rather than always looping attempting the request again.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Agreed. Going to file this as an issue to follow up with since the immediate concern is that we don't want to lose this context immediately. We may need some more tuning the exact tool response and SI

Copy link
Copy Markdown
Contributor

@jacob314 jacob314 left a comment

Choose a reason for hiding this comment

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

Approved from a core perspective.

@gemini-cli gemini-cli Bot added the status/need-issue Pull requests that need to have an associated issue. label Mar 18, 2026
Distinguishes between UI-based tool rejection (soft rejection) and process-level cancellation (hard abort) for subagents. Soft rejections now allow the subagent to rethink its strategy via a direct context injection, while Ctrl+C remains terminal.
@abhipatel12 abhipatel12 force-pushed the abhi/subagent-reject-ux branch from bbc7b1d to 9167cc2 Compare March 18, 2026 21:32
@abhipatel12 abhipatel12 added this pull request to the merge queue Mar 18, 2026
@github-merge-queue github-merge-queue Bot removed this pull request from the merge queue due to failed status checks Mar 18, 2026
@abhipatel12 abhipatel12 added this pull request to the merge queue Mar 19, 2026
Merged via the queue into main with commit 5fa14db Mar 19, 2026
27 checks passed
@abhipatel12 abhipatel12 deleted the abhi/subagent-reject-ux branch March 19, 2026 01:27
ProthamD pushed a commit to ProthamD/gemini-cli that referenced this pull request Mar 29, 2026
warrenzhu25 pushed a commit to warrenzhu25/gemini-cli that referenced this pull request Apr 9, 2026
@sripasg sripasg added the size/l A large sized PR label Jun 2, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size/l A large sized PR status/need-issue Pull requests that need to have an associated issue.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants