Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 3 additions & 7 deletions packages/core/src/core/coreToolScheduler.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6239,9 +6239,7 @@ describe('CoreToolScheduler plan mode with ask_user_question', () => {
expect(responseJson).toContain('"error"');
expect(responseJson).toContain('Tool blocked by plan mode');
expect(responseJson).toContain('write_file');
// Plan-required teammates get pivot-to-read-only then exit_plan_mode hint
expect(responseJson).toContain('Do NOT retry');
expect(responseJson).toContain('Pivot to read-only');
// Plan-required teammates get exit_plan_mode hint
expect(responseJson).toContain('exit_plan_mode');
expect(completedCalls[0].response.error).toBeInstanceOf(Error);
expect(completedCalls[0].response.errorType).toBe(
Expand Down Expand Up @@ -6314,14 +6312,12 @@ describe('CoreToolScheduler plan mode with ask_user_question', () => {
expect(completedCalls[0].status).toBe('error');
if (completedCalls[0].status === 'error') {
// SDK, subagent, and teammate paths all get the same error format
// but different guidance: SDK/subagents get "present your plan directly"
// but different guidance: SDK/subagents get "Present your plan directly"
const responseParts = completedCalls[0].response.responseParts;
const responseJson = JSON.stringify(responseParts);
expect(responseJson).toContain('"error"');
expect(responseJson).toContain('Tool blocked by plan mode');
expect(responseJson).toContain('Do NOT retry');
expect(responseJson).toContain('Pivot to read-only');
expect(responseJson).toContain('present your plan directly');
expect(responseJson).toContain('Present your plan directly');
expect(responseJson).not.toContain('exit_plan_mode');
expect(completedCalls[0].response.error).toBeInstanceOf(Error);
expect(completedCalls[0].response.errorType).toBe(
Expand Down
5 changes: 2 additions & 3 deletions packages/core/src/core/coreToolScheduler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2467,10 +2467,9 @@ export class CoreToolScheduler {
`Tool blocked by plan mode: "${reqInfo.name}" is not a read-only tool. ` +
`Only read-only tools (read_file, grep_search, glob, list_directory, ` +
`web_fetch, etc.) are allowed in plan mode.` +
` Do NOT retry this tool. ` +
(isPlanRequiredTeammate
? `Pivot to read-only alternatives to gather the information you need, then call exit_plan_mode with a plan that covers this tool's purpose.`
: `Pivot to read-only alternatives to gather equivalent information, then present your plan directly to the caller.`),
? ` Call exit_plan_mode to exit plan mode and execute this tool.`
: ` Present your plan directly to the caller instead of executing this tool.`),
);
this.setStatusInternal(reqInfo.callId, 'error', {
...createErrorResponse(
Expand Down
8 changes: 0 additions & 8 deletions packages/core/src/core/prompts.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -498,14 +498,6 @@ describe('getPlanModeSystemReminder', () => {
expect(result).toContain('exit_plan_mode tool');
});

it('should include guidance when a tool is blocked by plan mode', () => {
const result = getPlanModeSystemReminder();

expect(result).toContain('When a Tool is Blocked by Plan Mode');
expect(result).toContain('Do NOT retry');
expect(result).toContain('Pivot to read-only');
});

it('should be deterministic', () => {
const result1 = getPlanModeSystemReminder();
const result2 = getPlanModeSystemReminder();
Expand Down
8 changes: 0 additions & 8 deletions packages/core/src/core/prompts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -893,14 +893,6 @@ Start by quickly scanning a few key files to form an initial understanding of th
- Reference existing functions and utilities you found that should be reused, with their file paths.
- Include a verification section describing how to test the changes end-to-end.

### When a Tool is Blocked by Plan Mode

If a non-read-only tool is blocked:
- Do NOT retry the blocked tool or repeatedly attempt similar non-read-only tools
- Do NOT immediately call exit_plan_mode just to unblock it — continue gathering context with read-only tools first
- Pivot to read-only tools (read_file, grep_search, glob, list_directory, agents) to gather the information the blocked tool would have provided
- Once you have enough context to form a complete plan, call exit_plan_mode

### When to Converge

Your plan is ready when you have addressed all ambiguities and it covers: what to change, which files to modify, what existing code to reuse (with file paths), and how to verify the changes. Present your plan ${planOnly ? 'directly' : `by calling the ${ToolNames.EXIT_PLAN_MODE} tool, which will prompt the user to confirm the plan`}. Do NOT make any file changes or run any tools that modify the system state in any way until the user has confirmed the plan.
Expand Down
Loading