mirror of
https://github.com/google-gemini/gemini-cli.git
synced 2026-03-13 07:30:52 -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.
|
||||
|
||||
## Available Tools
|
||||
The following read-only tools are available in Plan Mode:
|
||||
The following tools are available in Plan Mode:
|
||||
<tool>\`glob\`</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
|
||||
- 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.
|
||||
|
||||
## Available Tools
|
||||
The following read-only tools are available in Plan Mode:
|
||||
The following tools are available in Plan Mode:
|
||||
<tool>\`glob\`</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
|
||||
- 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.
|
||||
|
||||
## Available Tools
|
||||
The following read-only tools are available in Plan Mode:
|
||||
The following tools are available in Plan Mode:
|
||||
<tool>\`glob\`</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
|
||||
- Save your plans as Markdown (.md) files ONLY within: \`/tmp/project-temp/plans/\`
|
||||
|
||||
@@ -25,6 +25,7 @@ import {
|
||||
} from '../config/models.js';
|
||||
import { ApprovalMode } from '../policy/types.js';
|
||||
import { DiscoveredMCPTool } from '../tools/mcp-tool.js';
|
||||
import type { AnyDeclarativeTool } from '../tools/tool-registry.js';
|
||||
import type { CallableTool } from '@google/genai';
|
||||
import type { MessageBus } from '../confirmation-bus/message-bus.js';
|
||||
|
||||
@@ -85,6 +86,12 @@ describe('Core System Prompt (prompts.ts)', () => {
|
||||
getToolRegistry: vi.fn().mockReturnValue({
|
||||
getAllToolNames: vi.fn().mockReturnValue(['grep_search', 'glob']),
|
||||
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),
|
||||
storage: {
|
||||
@@ -452,24 +459,11 @@ describe('Core System Prompt (prompts.ts)', () => {
|
||||
true, // isReadOnly
|
||||
);
|
||||
|
||||
const nonReadOnlyMcpTool = new DiscoveredMCPTool(
|
||||
{} as CallableTool,
|
||||
'nonreadonly-server',
|
||||
'non_read_static_value',
|
||||
'A non-read-only tool',
|
||||
{},
|
||||
{} as MessageBus,
|
||||
false,
|
||||
false,
|
||||
);
|
||||
// Note: non-read-only MCP tools are implicitly filtered out by the logic
|
||||
// because they are not potentially allowed in Plan Mode by default.
|
||||
|
||||
vi.mocked(mockConfig.getToolRegistry().getAllTools).mockReturnValue([
|
||||
vi.mocked(mockConfig.getToolRegistry().getActiveTools).mockReturnValue([
|
||||
readOnlyMcpTool,
|
||||
nonReadOnlyMcpTool,
|
||||
]);
|
||||
vi.mocked(mockConfig.getToolRegistry().getAllToolNames).mockReturnValue([
|
||||
readOnlyMcpTool.name,
|
||||
nonReadOnlyMcpTool.name,
|
||||
]);
|
||||
|
||||
const prompt = getCoreSystemPrompt(mockConfig);
|
||||
@@ -483,10 +477,10 @@ describe('Core System Prompt (prompts.ts)', () => {
|
||||
it('should only list available tools in PLAN mode', () => {
|
||||
vi.mocked(mockConfig.getApprovalMode).mockReturnValue(ApprovalMode.PLAN);
|
||||
// Only enable a subset of tools, including ask_user
|
||||
vi.mocked(mockConfig.getToolRegistry().getAllToolNames).mockReturnValue([
|
||||
'glob',
|
||||
'read_file',
|
||||
'ask_user',
|
||||
vi.mocked(mockConfig.getToolRegistry().getActiveTools).mockReturnValue([
|
||||
{ name: 'glob' } as unknown as AnyDeclarativeTool,
|
||||
{ name: 'read_file' } as unknown as AnyDeclarativeTool,
|
||||
{ name: 'ask_user' } as unknown as AnyDeclarativeTool,
|
||||
]);
|
||||
|
||||
const prompt = getCoreSystemPrompt(mockConfig);
|
||||
|
||||
@@ -22,7 +22,6 @@ import {
|
||||
import { CodebaseInvestigatorAgent } from '../agents/codebase-investigator.js';
|
||||
import { isGitRepository } from '../utils/gitUtils.js';
|
||||
import {
|
||||
PLAN_MODE_TOOLS,
|
||||
WRITE_TODOS_TOOL_NAME,
|
||||
READ_FILE_TOOL_NAME,
|
||||
ENTER_PLAN_MODE_TOOL_NAME,
|
||||
@@ -67,25 +66,17 @@ export class PromptProvider {
|
||||
const contextFilenames = getAllGeminiMdFilenames();
|
||||
|
||||
// --- Context Gathering ---
|
||||
let planModeToolsList = PLAN_MODE_TOOLS.filter((t) =>
|
||||
enabledToolNames.has(t),
|
||||
)
|
||||
.map((t) => ` <tool>\`${t}\`</tool>`)
|
||||
.join('\n');
|
||||
|
||||
// Add read-only MCP tools to the list
|
||||
let planModeToolsList = '';
|
||||
if (isPlanMode) {
|
||||
const allTools = config.getToolRegistry().getAllTools();
|
||||
const readOnlyMcpTools = allTools.filter(
|
||||
(t): t is DiscoveredMCPTool =>
|
||||
t instanceof DiscoveredMCPTool && !!t.isReadOnly,
|
||||
);
|
||||
if (readOnlyMcpTools.length > 0) {
|
||||
const mcpToolsList = readOnlyMcpTools
|
||||
.map((t) => ` <tool>\`${t.name}\` (${t.serverName})</tool>`)
|
||||
.join('\n');
|
||||
planModeToolsList += `\n${mcpToolsList}`;
|
||||
}
|
||||
const activeTools = config.getToolRegistry().getActiveTools();
|
||||
activeTools.sort((a, b) => a.name.localeCompare(b.name));
|
||||
planModeToolsList = activeTools
|
||||
.map((t) => {
|
||||
const serverSuffix =
|
||||
t instanceof DiscoveredMCPTool ? ` (${t.serverName})` : '';
|
||||
return ` <tool>\`${t.name}\`${serverSuffix}</tool>`;
|
||||
})
|
||||
.join('\n');
|
||||
}
|
||||
|
||||
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.
|
||||
|
||||
## Available Tools
|
||||
The following read-only tools are available in Plan Mode:
|
||||
The following tools are available in Plan Mode:
|
||||
${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
|
||||
- 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.
|
||||
|
||||
## Available Tools
|
||||
The following read-only tools are available in Plan Mode:
|
||||
The following tools are available in Plan Mode:
|
||||
<available_tools>
|
||||
${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>
|
||||
|
||||
## Rules
|
||||
|
||||
Reference in New Issue
Block a user