mirror of
https://github.com/google-gemini/gemini-cli.git
synced 2026-05-13 05:12:55 -07:00
fix(prompts): dynamically list active tools in Plan Mode system prompt
- Updates `PromptProvider` to retrieve and alphabetically sort the active tools from `ToolRegistry` for the Plan Mode prompt list. - Removes hardcoded descriptions for `write_file` and `replace` from `snippets.ts` and `snippets.legacy.ts` as they are now dynamically included. - Modifies verbiage in Plan Mode instructions to reflect that tools may not be exclusively "read-only" when workspace policies apply overrides. - Updates snapshot assertions and prompt test mocks to verify the correct dynamic and sorted injection of tool descriptions.
This commit is contained in:
@@ -42,11 +42,9 @@ For example:
|
|||||||
You are operating in **Plan Mode** - a structured planning workflow for designing implementation strategies before execution.
|
You are operating in **Plan Mode** - a structured planning workflow for designing implementation strategies before execution.
|
||||||
|
|
||||||
## Available Tools
|
## Available Tools
|
||||||
The following read-only tools are available in Plan Mode:
|
The following tools are available in Plan Mode:
|
||||||
<tool>\`glob\`</tool>
|
<tool>\`glob\`</tool>
|
||||||
<tool>\`grep_search\`</tool>
|
<tool>\`grep_search\`</tool>
|
||||||
- \`write_file\` - Save plans to the plans directory (see Plan Storage below)
|
|
||||||
- \`replace\` - Update plans in the plans directory
|
|
||||||
|
|
||||||
## Plan Storage
|
## Plan Storage
|
||||||
- Save your plans as Markdown (.md) files ONLY within: \`/tmp/plans/\`
|
- Save your plans as Markdown (.md) files ONLY within: \`/tmp/plans/\`
|
||||||
@@ -174,11 +172,9 @@ For example:
|
|||||||
You are operating in **Plan Mode** - a structured planning workflow for designing implementation strategies before execution.
|
You are operating in **Plan Mode** - a structured planning workflow for designing implementation strategies before execution.
|
||||||
|
|
||||||
## Available Tools
|
## Available Tools
|
||||||
The following read-only tools are available in Plan Mode:
|
The following tools are available in Plan Mode:
|
||||||
<tool>\`glob\`</tool>
|
<tool>\`glob\`</tool>
|
||||||
<tool>\`grep_search\`</tool>
|
<tool>\`grep_search\`</tool>
|
||||||
- \`write_file\` - Save plans to the plans directory (see Plan Storage below)
|
|
||||||
- \`replace\` - Update plans in the plans directory
|
|
||||||
|
|
||||||
## Plan Storage
|
## Plan Storage
|
||||||
- Save your plans as Markdown (.md) files ONLY within: \`/tmp/plans/\`
|
- Save your plans as Markdown (.md) files ONLY within: \`/tmp/plans/\`
|
||||||
@@ -424,11 +420,9 @@ For example:
|
|||||||
You are operating in **Plan Mode** - a structured planning workflow for designing implementation strategies before execution.
|
You are operating in **Plan Mode** - a structured planning workflow for designing implementation strategies before execution.
|
||||||
|
|
||||||
## Available Tools
|
## Available Tools
|
||||||
The following read-only tools are available in Plan Mode:
|
The following tools are available in Plan Mode:
|
||||||
<tool>\`glob\`</tool>
|
<tool>\`glob\`</tool>
|
||||||
<tool>\`grep_search\`</tool>
|
<tool>\`grep_search\`</tool>
|
||||||
- \`write_file\` - Save plans to the plans directory (see Plan Storage below)
|
|
||||||
- \`replace\` - Update plans in the plans directory
|
|
||||||
|
|
||||||
## Plan Storage
|
## Plan Storage
|
||||||
- Save your plans as Markdown (.md) files ONLY within: \`/tmp/project-temp/plans/\`
|
- Save your plans as Markdown (.md) files ONLY within: \`/tmp/project-temp/plans/\`
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ import {
|
|||||||
} from '../config/models.js';
|
} from '../config/models.js';
|
||||||
import { ApprovalMode } from '../policy/types.js';
|
import { ApprovalMode } from '../policy/types.js';
|
||||||
import { DiscoveredMCPTool } from '../tools/mcp-tool.js';
|
import { DiscoveredMCPTool } from '../tools/mcp-tool.js';
|
||||||
|
import type { AnyDeclarativeTool } from '../tools/tool-registry.js';
|
||||||
import type { CallableTool } from '@google/genai';
|
import type { CallableTool } from '@google/genai';
|
||||||
import type { MessageBus } from '../confirmation-bus/message-bus.js';
|
import type { MessageBus } from '../confirmation-bus/message-bus.js';
|
||||||
|
|
||||||
@@ -85,6 +86,12 @@ describe('Core System Prompt (prompts.ts)', () => {
|
|||||||
getToolRegistry: vi.fn().mockReturnValue({
|
getToolRegistry: vi.fn().mockReturnValue({
|
||||||
getAllToolNames: vi.fn().mockReturnValue(['grep_search', 'glob']),
|
getAllToolNames: vi.fn().mockReturnValue(['grep_search', 'glob']),
|
||||||
getAllTools: vi.fn().mockReturnValue([]),
|
getAllTools: vi.fn().mockReturnValue([]),
|
||||||
|
getActiveTools: vi
|
||||||
|
.fn()
|
||||||
|
.mockReturnValue([
|
||||||
|
{ name: 'grep_search' } as unknown as AnyDeclarativeTool,
|
||||||
|
{ name: 'glob' } as unknown as AnyDeclarativeTool,
|
||||||
|
]),
|
||||||
}),
|
}),
|
||||||
getEnableShellOutputEfficiency: vi.fn().mockReturnValue(true),
|
getEnableShellOutputEfficiency: vi.fn().mockReturnValue(true),
|
||||||
storage: {
|
storage: {
|
||||||
@@ -452,24 +459,11 @@ describe('Core System Prompt (prompts.ts)', () => {
|
|||||||
true, // isReadOnly
|
true, // isReadOnly
|
||||||
);
|
);
|
||||||
|
|
||||||
const nonReadOnlyMcpTool = new DiscoveredMCPTool(
|
// Note: non-read-only MCP tools are implicitly filtered out by the logic
|
||||||
{} as CallableTool,
|
// because they are not potentially allowed in Plan Mode by default.
|
||||||
'nonreadonly-server',
|
|
||||||
'non_read_static_value',
|
|
||||||
'A non-read-only tool',
|
|
||||||
{},
|
|
||||||
{} as MessageBus,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
);
|
|
||||||
|
|
||||||
vi.mocked(mockConfig.getToolRegistry().getAllTools).mockReturnValue([
|
vi.mocked(mockConfig.getToolRegistry().getActiveTools).mockReturnValue([
|
||||||
readOnlyMcpTool,
|
readOnlyMcpTool,
|
||||||
nonReadOnlyMcpTool,
|
|
||||||
]);
|
|
||||||
vi.mocked(mockConfig.getToolRegistry().getAllToolNames).mockReturnValue([
|
|
||||||
readOnlyMcpTool.name,
|
|
||||||
nonReadOnlyMcpTool.name,
|
|
||||||
]);
|
]);
|
||||||
|
|
||||||
const prompt = getCoreSystemPrompt(mockConfig);
|
const prompt = getCoreSystemPrompt(mockConfig);
|
||||||
@@ -483,10 +477,10 @@ describe('Core System Prompt (prompts.ts)', () => {
|
|||||||
it('should only list available tools in PLAN mode', () => {
|
it('should only list available tools in PLAN mode', () => {
|
||||||
vi.mocked(mockConfig.getApprovalMode).mockReturnValue(ApprovalMode.PLAN);
|
vi.mocked(mockConfig.getApprovalMode).mockReturnValue(ApprovalMode.PLAN);
|
||||||
// Only enable a subset of tools, including ask_user
|
// Only enable a subset of tools, including ask_user
|
||||||
vi.mocked(mockConfig.getToolRegistry().getAllToolNames).mockReturnValue([
|
vi.mocked(mockConfig.getToolRegistry().getActiveTools).mockReturnValue([
|
||||||
'glob',
|
{ name: 'glob' } as unknown as AnyDeclarativeTool,
|
||||||
'read_file',
|
{ name: 'read_file' } as unknown as AnyDeclarativeTool,
|
||||||
'ask_user',
|
{ name: 'ask_user' } as unknown as AnyDeclarativeTool,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
const prompt = getCoreSystemPrompt(mockConfig);
|
const prompt = getCoreSystemPrompt(mockConfig);
|
||||||
|
|||||||
@@ -22,7 +22,6 @@ import {
|
|||||||
import { CodebaseInvestigatorAgent } from '../agents/codebase-investigator.js';
|
import { CodebaseInvestigatorAgent } from '../agents/codebase-investigator.js';
|
||||||
import { isGitRepository } from '../utils/gitUtils.js';
|
import { isGitRepository } from '../utils/gitUtils.js';
|
||||||
import {
|
import {
|
||||||
PLAN_MODE_TOOLS,
|
|
||||||
WRITE_TODOS_TOOL_NAME,
|
WRITE_TODOS_TOOL_NAME,
|
||||||
READ_FILE_TOOL_NAME,
|
READ_FILE_TOOL_NAME,
|
||||||
ENTER_PLAN_MODE_TOOL_NAME,
|
ENTER_PLAN_MODE_TOOL_NAME,
|
||||||
@@ -67,25 +66,17 @@ export class PromptProvider {
|
|||||||
const contextFilenames = getAllGeminiMdFilenames();
|
const contextFilenames = getAllGeminiMdFilenames();
|
||||||
|
|
||||||
// --- Context Gathering ---
|
// --- Context Gathering ---
|
||||||
let planModeToolsList = PLAN_MODE_TOOLS.filter((t) =>
|
let planModeToolsList = '';
|
||||||
enabledToolNames.has(t),
|
|
||||||
)
|
|
||||||
.map((t) => ` <tool>\`${t}\`</tool>`)
|
|
||||||
.join('\n');
|
|
||||||
|
|
||||||
// Add read-only MCP tools to the list
|
|
||||||
if (isPlanMode) {
|
if (isPlanMode) {
|
||||||
const allTools = config.getToolRegistry().getAllTools();
|
const activeTools = config.getToolRegistry().getActiveTools();
|
||||||
const readOnlyMcpTools = allTools.filter(
|
activeTools.sort((a, b) => a.name.localeCompare(b.name));
|
||||||
(t): t is DiscoveredMCPTool =>
|
planModeToolsList = activeTools
|
||||||
t instanceof DiscoveredMCPTool && !!t.isReadOnly,
|
.map((t) => {
|
||||||
);
|
const serverSuffix =
|
||||||
if (readOnlyMcpTools.length > 0) {
|
t instanceof DiscoveredMCPTool ? ` (${t.serverName})` : '';
|
||||||
const mcpToolsList = readOnlyMcpTools
|
return ` <tool>\`${t.name}\`${serverSuffix}</tool>`;
|
||||||
.map((t) => ` <tool>\`${t.name}\` (${t.serverName})</tool>`)
|
})
|
||||||
.join('\n');
|
.join('\n');
|
||||||
planModeToolsList += `\n${mcpToolsList}`;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let basePrompt: string;
|
let basePrompt: string;
|
||||||
|
|||||||
@@ -398,10 +398,8 @@ export function renderPlanningWorkflow(
|
|||||||
You are operating in **Plan Mode** - a structured planning workflow for designing implementation strategies before execution.
|
You are operating in **Plan Mode** - a structured planning workflow for designing implementation strategies before execution.
|
||||||
|
|
||||||
## Available Tools
|
## Available Tools
|
||||||
The following read-only tools are available in Plan Mode:
|
The following tools are available in Plan Mode:
|
||||||
${options.planModeToolsList}
|
${options.planModeToolsList}
|
||||||
- \`${WRITE_FILE_TOOL_NAME}\` - Save plans to the plans directory (see Plan Storage below)
|
|
||||||
- \`${EDIT_TOOL_NAME}\` - Update plans in the plans directory
|
|
||||||
|
|
||||||
## Plan Storage
|
## Plan Storage
|
||||||
- Save your plans as Markdown (.md) files ONLY within: \`${options.plansDir}/\`
|
- Save your plans as Markdown (.md) files ONLY within: \`${options.plansDir}/\`
|
||||||
|
|||||||
@@ -452,11 +452,9 @@ export function renderPlanningWorkflow(
|
|||||||
You are operating in **Plan Mode**. Your goal is to produce a detailed implementation plan in \`${options.plansDir}/\` and get user approval before editing source code.
|
You are operating in **Plan Mode**. Your goal is to produce a detailed implementation plan in \`${options.plansDir}/\` and get user approval before editing source code.
|
||||||
|
|
||||||
## Available Tools
|
## Available Tools
|
||||||
The following read-only tools are available in Plan Mode:
|
The following tools are available in Plan Mode:
|
||||||
<available_tools>
|
<available_tools>
|
||||||
${options.planModeToolsList}
|
${options.planModeToolsList}
|
||||||
<tool>${formatToolName(WRITE_FILE_TOOL_NAME)} - Save plans to the plans directory</tool>
|
|
||||||
<tool>${formatToolName(EDIT_TOOL_NAME)} - Update plans in the plans directory</tool>
|
|
||||||
</available_tools>
|
</available_tools>
|
||||||
|
|
||||||
## Rules
|
## Rules
|
||||||
|
|||||||
Reference in New Issue
Block a user