mirror of
https://github.com/google-gemini/gemini-cli.git
synced 2026-03-13 07:30:52 -07:00
feat: refactor bulky tools to improve token efficiency
This commit is contained in:
@@ -2440,7 +2440,7 @@ export class Config {
|
||||
);
|
||||
if (this.getUseWriteTodos()) {
|
||||
maybeRegister(WriteTodosTool, () =>
|
||||
registry.registerTool(new WriteTodosTool(this.messageBus)),
|
||||
registry.registerTool(new WriteTodosTool(this, this.messageBus)),
|
||||
);
|
||||
}
|
||||
if (this.isPlanEnabled()) {
|
||||
|
||||
@@ -63,6 +63,16 @@ export class PromptProvider {
|
||||
const activeSnippets = isModernModel ? snippets : legacySnippets;
|
||||
const contextFilenames = getAllGeminiMdFilenames();
|
||||
|
||||
const registry =
|
||||
typeof config.getToolRegistry === 'function'
|
||||
? config.getToolRegistry()
|
||||
: undefined;
|
||||
const allTools =
|
||||
typeof registry?.getAllTools === 'function' ? registry.getAllTools() : [];
|
||||
const toolInstructions = allTools
|
||||
.map((t) => t.instructions)
|
||||
.filter((i): i is string => !!i);
|
||||
|
||||
// --- Context Gathering ---
|
||||
let planModeToolsList = PLAN_MODE_TOOLS.filter((t) =>
|
||||
enabledToolNames.has(t),
|
||||
@@ -201,6 +211,8 @@ export class PromptProvider {
|
||||
: this.withSection('finalReminder', () => ({
|
||||
readFileToolName: READ_FILE_TOOL_NAME,
|
||||
})),
|
||||
toolInstructions:
|
||||
toolInstructions.length > 0 ? toolInstructions : undefined,
|
||||
} as snippets.SystemPromptOptions;
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion
|
||||
|
||||
@@ -35,6 +35,7 @@ export interface SystemPromptOptions {
|
||||
interactiveYoloMode?: boolean;
|
||||
gitRepo?: GitRepoOptions;
|
||||
finalReminder?: FinalReminderOptions;
|
||||
toolInstructions?: string[];
|
||||
}
|
||||
|
||||
export interface PreambleOptions {
|
||||
@@ -113,6 +114,8 @@ ${
|
||||
: renderPrimaryWorkflows(options.primaryWorkflows)
|
||||
}
|
||||
|
||||
${renderToolInstructions(options.toolInstructions)}
|
||||
|
||||
${renderOperationalGuidelines(options.operationalGuidelines)}
|
||||
|
||||
${renderInteractiveYoloMode(options.interactiveYoloMode)}
|
||||
@@ -244,6 +247,15 @@ ${newApplicationSteps(options)}
|
||||
`.trim();
|
||||
}
|
||||
|
||||
export function renderToolInstructions(instructions?: string[]): string {
|
||||
if (!instructions || instructions.length === 0) return '';
|
||||
return `
|
||||
# Detailed Tool Reference
|
||||
|
||||
${instructions.join('\n\n')}
|
||||
`.trim();
|
||||
}
|
||||
|
||||
export function renderOperationalGuidelines(
|
||||
options?: OperationalGuidelinesOptions,
|
||||
): string {
|
||||
|
||||
@@ -35,6 +35,7 @@ export interface SystemPromptOptions {
|
||||
sandbox?: SandboxMode;
|
||||
interactiveYoloMode?: boolean;
|
||||
gitRepo?: GitRepoOptions;
|
||||
toolInstructions?: string[];
|
||||
}
|
||||
|
||||
export interface PreambleOptions {
|
||||
@@ -110,6 +111,8 @@ ${
|
||||
: renderPrimaryWorkflows(options.primaryWorkflows)
|
||||
}
|
||||
|
||||
${renderToolInstructions(options.toolInstructions)}
|
||||
|
||||
${renderOperationalGuidelines(options.operationalGuidelines)}
|
||||
|
||||
${renderInteractiveYoloMode(options.interactiveYoloMode)}
|
||||
@@ -268,6 +271,15 @@ ${newApplicationSteps(options)}
|
||||
`.trim();
|
||||
}
|
||||
|
||||
export function renderToolInstructions(instructions?: string[]): string {
|
||||
if (!instructions || instructions.length === 0) return '';
|
||||
return `
|
||||
# Detailed Tool Reference
|
||||
|
||||
${instructions.join('\n\n')}
|
||||
`.trim();
|
||||
}
|
||||
|
||||
export function renderOperationalGuidelines(
|
||||
options?: OperationalGuidelinesOptions,
|
||||
): string {
|
||||
|
||||
@@ -506,8 +506,8 @@ exports[`coreTools snapshots for specific models > Model: gemini-2.5-pro > snaps
|
||||
{
|
||||
"description": "Replaces text within a file. By default, replaces a single occurrence, but can replace multiple occurrences when \`expected_replacements\` is specified. This tool requires providing significant context around the change to ensure precise targeting. Always use the read_file tool to examine the file's current content before attempting a text replacement.
|
||||
|
||||
The user has the ability to modify the \`new_string\` content. If modified, this will be stated in the response.
|
||||
|
||||
The user has the ability to modify the \`new_string\` content. If modified, this will be stated in the response.",
|
||||
"instructions": "
|
||||
Expectation for required parameters:
|
||||
1. \`old_string\` MUST be the exact literal text to replace (including all whitespace, indentation, newlines, and surrounding code etc.).
|
||||
2. \`new_string\` MUST be the exact literal text to replace \`old_string\` with (also including all whitespace, indentation, newlines, and surrounding code etc.). Ensure the resulting code is correct and idiomatic and that \`old_string\` and \`new_string\` are different.
|
||||
@@ -684,8 +684,8 @@ exports[`coreTools snapshots for specific models > Model: gemini-2.5-pro > snaps
|
||||
|
||||
exports[`coreTools snapshots for specific models > Model: gemini-2.5-pro > snapshot for tool: write_todos 1`] = `
|
||||
{
|
||||
"description": "This tool can help you list out the current subtasks that are required to be completed for a given user request. The list of subtasks helps you keep track of the current task, organize complex queries and help ensure that you don't miss any steps. With this list, the user can also see the current progress you are making in executing a given task.
|
||||
|
||||
"description": "This tool can help you list out the current subtasks that are required to be completed for a given user request. The list of subtasks helps you keep track of the current task, organize complex queries and help ensure that you don't miss any steps. With this list, the user can also see the current progress you are making in executing a given task.",
|
||||
"instructions": "
|
||||
Depending on the task complexity, you should first divide a given task into subtasks and then use this tool to list out the subtasks that are required to be completed for a given user request.
|
||||
Each of the subtasks should be clear and distinct.
|
||||
|
||||
@@ -1295,8 +1295,8 @@ exports[`coreTools snapshots for specific models > Model: gemini-3-pro-preview >
|
||||
{
|
||||
"description": "Replaces text within a file. By default, replaces a single occurrence, but can replace multiple occurrences when \`expected_replacements\` is specified. This tool requires providing significant context around the change to ensure precise targeting. Always use the read_file tool to examine the file's current content before attempting a text replacement.
|
||||
|
||||
The user has the ability to modify the \`new_string\` content. If modified, this will be stated in the response.
|
||||
|
||||
The user has the ability to modify the \`new_string\` content. If modified, this will be stated in the response.",
|
||||
"instructions": "
|
||||
Expectation for required parameters:
|
||||
1. \`old_string\` MUST be the exact literal text to replace (including all whitespace, indentation, newlines, and surrounding code etc.).
|
||||
2. \`new_string\` MUST be the exact literal text to replace \`old_string\` with (also including all whitespace, indentation, newlines, and surrounding code etc.). Ensure the resulting code is correct and idiomatic and that \`old_string\` and \`new_string\` are different.
|
||||
@@ -1473,8 +1473,8 @@ exports[`coreTools snapshots for specific models > Model: gemini-3-pro-preview >
|
||||
|
||||
exports[`coreTools snapshots for specific models > Model: gemini-3-pro-preview > snapshot for tool: write_todos 1`] = `
|
||||
{
|
||||
"description": "This tool can help you list out the current subtasks that are required to be completed for a given user request. The list of subtasks helps you keep track of the current task, organize complex queries and help ensure that you don't miss any steps. With this list, the user can also see the current progress you are making in executing a given task.
|
||||
|
||||
"description": "This tool can help you list out the current subtasks that are required to be completed for a given user request. The list of subtasks helps you keep track of the current task, organize complex queries and help ensure that you don't miss any steps. With this list, the user can also see the current progress you are making in executing a given task.",
|
||||
"instructions": "
|
||||
Depending on the task complexity, you should first divide a given task into subtasks and then use this tool to list out the subtasks that are required to be completed for a given user request.
|
||||
Each of the subtasks should be clear and distinct.
|
||||
|
||||
|
||||
@@ -269,8 +269,8 @@ export const EDIT_DEFINITION: ToolDefinition = {
|
||||
name: EDIT_TOOL_NAME,
|
||||
description: `Replaces text within a file. By default, replaces a single occurrence, but can replace multiple occurrences when \`expected_replacements\` is specified. This tool requires providing significant context around the change to ensure precise targeting. Always use the ${READ_FILE_TOOL_NAME} tool to examine the file's current content before attempting a text replacement.
|
||||
|
||||
The user has the ability to modify the \`new_string\` content. If modified, this will be stated in the response.
|
||||
|
||||
The user has the ability to modify the \`new_string\` content. If modified, this will be stated in the response.`,
|
||||
instructions: `
|
||||
Expectation for required parameters:
|
||||
1. \`old_string\` MUST be the exact literal text to replace (including all whitespace, indentation, newlines, and surrounding code etc.).
|
||||
2. \`new_string\` MUST be the exact literal text to replace \`old_string\` with (also including all whitespace, indentation, newlines, and surrounding code etc.). Ensure the resulting code is correct and idiomatic and that \`old_string\` and \`new_string\` are different.
|
||||
@@ -646,8 +646,8 @@ NEVER save workspace-specific context, local paths, or commands (e.g. "The entry
|
||||
export const WRITE_TODOS_DEFINITION: ToolDefinition = {
|
||||
base: {
|
||||
name: WRITE_TODOS_TOOL_NAME,
|
||||
description: `This tool can help you list out the current subtasks that are required to be completed for a given user request. The list of subtasks helps you keep track of the current task, organize complex queries and help ensure that you don't miss any steps. With this list, the user can also see the current progress you are making in executing a given task.
|
||||
|
||||
description: `This tool can help you list out the current subtasks that are required to be completed for a given user request. The list of subtasks helps you keep track of the current task, organize complex queries and help ensure that you don't miss any steps. With this list, the user can also see the current progress you are making in executing a given task.`,
|
||||
instructions: `
|
||||
Depending on the task complexity, you should first divide a given task into subtasks and then use this tool to list out the subtasks that are required to be completed for a given user request.
|
||||
Each of the subtasks should be clear and distinct.
|
||||
|
||||
|
||||
@@ -17,7 +17,7 @@ import type { ToolDefinition } from './types.js';
|
||||
export function resolveToolDeclaration(
|
||||
definition: ToolDefinition,
|
||||
modelId?: string,
|
||||
): FunctionDeclaration {
|
||||
): FunctionDeclaration & { instructions?: string } {
|
||||
if (!modelId || !definition.overrides) {
|
||||
return definition.base;
|
||||
}
|
||||
|
||||
@@ -11,10 +11,12 @@ import { type FunctionDeclaration } from '@google/genai';
|
||||
*/
|
||||
export interface ToolDefinition {
|
||||
/** The base declaration for the tool. */
|
||||
base: FunctionDeclaration;
|
||||
base: FunctionDeclaration & { instructions?: string };
|
||||
|
||||
/**
|
||||
* Optional overrides for specific model families or versions.
|
||||
*/
|
||||
overrides?: (modelId: string) => Partial<FunctionDeclaration> | undefined;
|
||||
overrides?: (
|
||||
modelId: string,
|
||||
) => (Partial<FunctionDeclaration> & { instructions?: string }) | undefined;
|
||||
}
|
||||
|
||||
@@ -910,15 +910,23 @@ export class EditTool
|
||||
private readonly config: Config,
|
||||
messageBus: MessageBus,
|
||||
) {
|
||||
const modelId =
|
||||
typeof config.getActiveModel === 'function'
|
||||
? config.getActiveModel()
|
||||
: undefined;
|
||||
const resolved = resolveToolDeclaration(EDIT_DEFINITION, modelId);
|
||||
super(
|
||||
EditTool.Name,
|
||||
EDIT_DISPLAY_NAME,
|
||||
EDIT_DEFINITION.base.description!,
|
||||
resolved.description!,
|
||||
Kind.Edit,
|
||||
EDIT_DEFINITION.base.parametersJsonSchema,
|
||||
resolved.parametersJsonSchema,
|
||||
messageBus,
|
||||
true, // isOutputMarkdown
|
||||
false, // canUpdateOutput
|
||||
undefined, // extensionName
|
||||
undefined, // extensionId
|
||||
resolved.instructions,
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -361,6 +361,7 @@ export abstract class DeclarativeTool<
|
||||
readonly canUpdateOutput: boolean = false,
|
||||
readonly extensionName?: string,
|
||||
readonly extensionId?: string,
|
||||
readonly instructions?: string,
|
||||
) {}
|
||||
|
||||
getSchema(_modelId?: string): FunctionDeclaration {
|
||||
|
||||
@@ -12,6 +12,7 @@ import {
|
||||
type Todo,
|
||||
type ToolResult,
|
||||
} from './tools.js';
|
||||
import type { Config } from '../config/config.js';
|
||||
import type { MessageBus } from '../confirmation-bus/message-bus.js';
|
||||
import { WRITE_TODOS_TOOL_NAME } from './tool-names.js';
|
||||
import { WRITE_TODOS_DEFINITION } from './definitions/coreTools.js';
|
||||
@@ -81,16 +82,27 @@ export class WriteTodosTool extends BaseDeclarativeTool<
|
||||
> {
|
||||
static readonly Name = WRITE_TODOS_TOOL_NAME;
|
||||
|
||||
constructor(messageBus: MessageBus) {
|
||||
constructor(
|
||||
private readonly config: Config,
|
||||
messageBus: MessageBus,
|
||||
) {
|
||||
const modelId =
|
||||
typeof config.getActiveModel === 'function'
|
||||
? config.getActiveModel()
|
||||
: undefined;
|
||||
const resolved = resolveToolDeclaration(WRITE_TODOS_DEFINITION, modelId);
|
||||
super(
|
||||
WriteTodosTool.Name,
|
||||
'WriteTodos',
|
||||
WRITE_TODOS_DEFINITION.base.description!,
|
||||
resolved.description!,
|
||||
Kind.Other,
|
||||
WRITE_TODOS_DEFINITION.base.parametersJsonSchema,
|
||||
resolved.parametersJsonSchema,
|
||||
messageBus,
|
||||
true, // isOutputMarkdown
|
||||
false, // canUpdateOutput
|
||||
undefined, // extensionName
|
||||
undefined, // extensionId
|
||||
resolved.instructions,
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user