Skip to content

fix(core): make subagents aware of active approval modes#23608

Open
akh64bit wants to merge 2 commits intomainfrom
fix-issue-23582-subagent-approval-modes
Open

fix(core): make subagents aware of active approval modes#23608
akh64bit wants to merge 2 commits intomainfrom
fix-issue-23582-subagent-approval-modes

Conversation

@akh64bit
Copy link
Copy Markdown
Contributor

Summary

Make subagents explicitly aware of global Approval Modes (Plan Mode, Auto-Edit Mode) to prevent them from attempting globally blocked actions. This fixes an issue where subagents would get stuck in failure loops in Plan Mode due to lack of context.

Details

  • Inject Plan Mode context into the LocalAgentExecutor system prompt when the global ApprovalMode is PLAN.
  • Dynamically adjust the Generalist Agent description in PLAN mode to avoid misleading routing for batch refactoring tasks.

Related Issues

Fixes #23582

How to Validate

  1. Run npm test -w @google/gemini-cli-core -- src/agents/generalist-agent.test.ts src/agents/local-executor.test.ts
  2. Enter Plan Mode (/plan), invoke a subagent, and verify it does not attempt unauthorized file edits and explicitly knows it is in plan mode.

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

@akh64bit akh64bit requested a review from a team as a code owner March 23, 2026 23:30
@github-actions
Copy link
Copy Markdown

github-actions bot commented Mar 23, 2026

🧠 Model Steering Guidance

This PR modifies files that affect the model's behavior (prompts, tools, or instructions).

  • ⚠️ Consider adding Evals: No behavioral evaluations (evals/*.eval.ts) were added or updated in this PR. Consider adding a test case to verify the new behavior and prevent regressions.
  • 🚀 Maintainer Reminder: Please ensure that these changes do not regress results on benchmark evals before merging.

This is an automated guidance message triggered by steering logic signatures.

@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 enhances the core agent system by making subagents context-aware of global approval modes, specifically Plan Mode. This prevents subagents from attempting unauthorized operations, such as direct file edits, when operating under restrictions. By injecting explicit constraints into the system prompt and dynamically adjusting agent descriptions, the change aims to improve agent reliability and prevent them from getting stuck in failure loops, leading to more predictable and controlled agent behavior.

Highlights

  • Subagent Awareness of Approval Modes: Subagents are now explicitly aware of global Approval Modes (e.g., Plan Mode), preventing them from attempting globally blocked actions and resolving issues where they would get stuck in failure loops.
  • Plan Mode Context Injection: The LocalAgentExecutor system prompt is now injected with specific Plan Mode context when the global ApprovalMode is PLAN, informing the agent about execution constraints.
  • Dynamic Agent Description: The Generalist Agent's description dynamically adjusts in PLAN mode to avoid misleading routing for batch refactoring tasks, instead guiding it towards large-scale investigation and planning.
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 23, 2026

Size Change: +679 B (0%)

Total Size: 26.5 MB

Filename Size Change
./bundle/chunk-DVPZ2ZXD.js 0 B -14.7 MB (removed) 🏆
./bundle/chunk-PYKNZK6Q.js 0 B -3.78 MB (removed) 🏆
./bundle/core-FG3CCXRJ.js 0 B -44.5 kB (removed) 🏆
./bundle/devtoolsService-PZADM62I.js 0 B -28.4 kB (removed) 🏆
./bundle/interactiveCli-SJ3YPM2E.js 0 B -1.63 MB (removed) 🏆
./bundle/oauth2-provider-HP3FVLBJ.js 0 B -9.16 kB (removed) 🏆
./bundle/chunk-AXPBUBNP.js 3.78 MB +3.78 MB (new file) 🆕
./bundle/chunk-KE2WOXQF.js 14.7 MB +14.7 MB (new file) 🆕
./bundle/core-HLQG5C2H.js 44.5 kB +44.5 kB (new file) 🆕
./bundle/devtoolsService-3N6TGYFE.js 28.4 kB +28.4 kB (new file) 🆕
./bundle/interactiveCli-5UDSQROR.js 1.63 MB +1.63 MB (new file) 🆕
./bundle/oauth2-provider-Z7DALP4U.js 9.16 kB +9.16 kB (new file) 🆕
ℹ️ View Unchanged
Filename Size
./bundle/chunk-34MYV7JD.js 2.45 kB
./bundle/chunk-5AUYMPVF.js 858 B
./bundle/chunk-664ZODQF.js 124 kB
./bundle/chunk-DAHVX5MI.js 206 kB
./bundle/chunk-IUUIT4SU.js 56.5 kB
./bundle/chunk-QGLNP2IW.js 1.96 MB
./bundle/chunk-RJTRUG2J.js 39.8 kB
./bundle/chunk-U4FACSVX.js 1.13 kB
./bundle/devtools-36NN55EP.js 696 kB
./bundle/dist-T73EYRDX.js 356 B
./bundle/events-CLX3JQHP.js 418 B
./bundle/gemini.js 532 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-XKQPPGVK.js 922 B
./bundle/multipart-parser-KPBZEGQU.js 11.7 kB
./bundle/node_modules/@google/gemini-cli-devtools/dist/client/main.js 222 kB
./bundle/node_modules/@google/gemini-cli-devtools/dist/src/_client-assets.js 229 kB
./bundle/node_modules/@google/gemini-cli-devtools/dist/src/index.js 13.4 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

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

This pull request effectively makes subagents aware of Plan Mode by injecting execution constraints into the system prompt and dynamically adjusting the Generalist Agent's description. This should resolve the issue of subagents getting stuck in failure loops. The accompanying tests are well-written and validate the new behavior. However, as noted in the specific comment, there's a potential omission regarding Auto-Edit Mode, which was mentioned in the PR description but doesn't appear to be handled in the implementation.

Comment on lines +1403 to +1406
if (approvalMode === ApprovalMode.PLAN) {
const plansDir = this.context.config.storage.getPlansDir();
finalPrompt += `\n\n# Execution Constraints\nYou are currently operating in Plan Mode. Your write tools are globally restricted to only modifying plan (.md) files in the plans directory: ${plansDir}/. Do not attempt to modify source code directly.`;
}
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.

high

The pull request description states that subagents should be made aware of both Plan Mode and Auto-Edit Mode. This implementation correctly injects constraints for Plan Mode, but Auto-Edit Mode is not handled. If Auto-Edit Mode imposes global restrictions that could cause subagents to fail (similar to the issue this PR fixes for Plan Mode), its constraints should also be injected into the system prompt here. Consider adding an else if (approvalMode === ApprovalMode.AUTO_EDIT) block to provide the necessary context for that mode.

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 effectively addresses the issue of subagents being unaware of global approval modes, particularly Plan Mode. The changes to inject context into the LocalAgentExecutor system prompt and dynamically adjust the Generalist Agent description are well-implemented and correctly tested. I have one suggestion to improve the maintainability of the generalist-agent.ts file by reducing code duplication.

Comment on lines +28 to +33
get description() {
if (context.config.getApprovalMode() === ApprovalMode.PLAN) {
return 'A general-purpose AI agent with access to all tools. Highly recommended for tasks that are turn-intensive or involve processing large amounts of data. Use this to keep the main session history lean and efficient. Excellent for: large-scale investigation and batch planning across multiple files.';
}
return 'A general-purpose AI agent with access to all tools. Highly recommended for tasks that are turn-intensive or involve processing large amounts of data. Use this to keep the main session history lean and efficient. Excellent for: batch refactoring/error fixing across multiple files, running commands with high-volume output, and speculative investigations.';
},
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.

high

To improve maintainability and reduce code duplication, you can refactor the description getter. The two long description strings are mostly identical except for the 'Excellent for:' part. By extracting the common base string, you can make the code more concise and easier to maintain, preventing the shared text from diverging in the future.

  get description() {
    const baseDescription =
      'A general-purpose AI agent with access to all tools. Highly recommended for tasks that are turn-intensive or involve processing large amounts of data. Use this to keep the main session history lean and efficient. Excellent for: ';
    if (context.config.getApprovalMode() === ApprovalMode.PLAN) {
      return `${baseDescription}large-scale investigation and batch planning across multiple files.`;
    }
    return `${baseDescription}batch refactoring/error fixing across multiple files, running commands with high-volume output, and speculative investigations.`;
  },

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.

+1

This helps make it more readable

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.

Refactored this to reduce duplication as suggested.

@gemini-cli gemini-cli bot added area/agent Issues related to Core Agent, Tools, Memory, Sub-Agents, Hooks, Agent Quality 🔒 maintainer only ⛔ Do not contribute. Internal roadmap item. labels Mar 23, 2026
'A general-purpose AI agent with access to all tools. Highly recommended for tasks that are turn-intensive or involve processing large amounts of data. Use this to keep the main session history lean and efficient. Excellent for: batch refactoring/error fixing across multiple files, running commands with high-volume output, and speculative investigations.',
get description() {
if (context.config.getApprovalMode() === ApprovalMode.PLAN) {
return 'A general-purpose AI agent with access to all tools. Highly recommended for tasks that are turn-intensive or involve processing large amounts of data. Use this to keep the main session history lean and efficient. Excellent for: large-scale investigation and batch planning across multiple files.';
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.

For this piece, what is the delta? the "excellent for ..." piece is the only difference I see.

Did you notice any change with this specific ablation for plan mode?

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.

The delta is indeed just the 'excellent for...' part. In testing, without this change, the main agent would often delegate 'fix these 5 files' tasks to the Generalist even in Plan Mode because the description still advertised it as being excellent for refactoring. By updating the description, we guide the main agent to only use the Generalist for investigative or planning tasks that are permissible in Plan Mode, rather than having it spawn a subagent that immediately hits execution constraints.

const approvalMode = this.context.config.getApprovalMode();
if (approvalMode === ApprovalMode.PLAN) {
const plansDir = this.context.config.storage.getPlansDir();
finalPrompt += `\n\n# Execution Constraints\nYou are currently operating in Plan Mode. Your write tools are globally restricted to only modifying plan (.md) files in the plans directory: ${plansDir}/. Do not attempt to modify source code directly.`;
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.

If we have this, why is the change in the generalist needed?

I can see that the two pieces of instructions are conflicting, but that is essentially what the generalist is made for. It is ideally an instance of gemini cli itself.

If a user doesn't want that in their plan mode, it seems better to discourage using / giving plan mode access to the generalist

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.

The change in the generalist is primarily for better routing at the main agent level. While local-executor provides the 'safety net' by enforcing constraints, the dynamic description helps the main agent (the 'orchestrator') make better decisions about when to invoke the Generalist. If the description remains 'Excellent for: batch refactoring', the main agent will continue to try and use it for that purpose, leading to wasted turns and confusing failure loops for the user.

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.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Subagents Awareness of Active Approval Modes

2 participants