mirror of
https://github.com/google-gemini/gemini-cli.git
synced 2026-07-23 00:01:24 -07:00
Compare commits
9 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| b00b467731 | |||
| ca2b0ff6c2 | |||
| bb00d1c943 | |||
| 7550fc3d93 | |||
| 0b2fcb84f4 | |||
| 63a25e8f24 | |||
| 2ed4d8c9e9 | |||
| 4ca26772ea | |||
| aff5da63cb |
@@ -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 Usage 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 Usage Reference
|
||||
|
||||
${instructions.join('\n\n')}
|
||||
`.trim();
|
||||
}
|
||||
|
||||
export function renderOperationalGuidelines(
|
||||
options?: OperationalGuidelinesOptions,
|
||||
): string {
|
||||
|
||||
@@ -1,69 +1,9 @@
|
||||
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
|
||||
|
||||
exports[`ShellTool > getDescription > should return the non-windows description when not on windows 1`] = `
|
||||
"This tool executes a given shell command as \`bash -c <command>\`. Command can start background processes using \`&\`. Command is executed as a subprocess that leads its own process group. Command process group can be terminated as \`kill -- -PGID\` or signaled as \`kill -s SIGNAL -- -PGID\`.
|
||||
exports[`ShellTool > getDescription > should return the non-windows description when not on windows 1`] = `"This tool executes a given shell command as \`bash -c <command>\`."`;
|
||||
|
||||
Efficiency Guidelines:
|
||||
- Quiet Flags: Always prefer silent or quiet flags (e.g., \`npm install --silent\`, \`git --no-pager\`) to reduce output volume while still capturing necessary information.
|
||||
- Pagination: Always disable terminal pagination to ensure commands terminate (e.g., use \`git --no-pager\`, \`systemctl --no-pager\`, or set \`PAGER=cat\`).
|
||||
exports[`ShellTool > getDescription > should return the windows description when on windows 1`] = `"This tool executes a given shell command as \`powershell.exe -NoProfile -Command <command>\`."`;
|
||||
|
||||
The following information is returned:
|
||||
exports[`ShellTool > getSchema > should return the base schema when no modelId is provided 1`] = `"This tool executes a given shell command as \`bash -c <command>\`."`;
|
||||
|
||||
Output: Combined stdout/stderr. Can be \`(empty)\` or partial on error and for any unwaited background processes.
|
||||
Exit Code: Only included if non-zero (command failed).
|
||||
Error: Only included if a process-level error occurred (e.g., spawn failure).
|
||||
Signal: Only included if process was terminated by a signal.
|
||||
Background PIDs: Only included if background processes were started.
|
||||
Process Group PGID: Only included if available."
|
||||
`;
|
||||
|
||||
exports[`ShellTool > getDescription > should return the windows description when on windows 1`] = `
|
||||
"This tool executes a given shell command as \`powershell.exe -NoProfile -Command <command>\`. Command can start background processes using PowerShell constructs such as \`Start-Process -NoNewWindow\` or \`Start-Job\`.
|
||||
|
||||
Efficiency Guidelines:
|
||||
- Quiet Flags: Always prefer silent or quiet flags (e.g., \`npm install --silent\`, \`git --no-pager\`) to reduce output volume while still capturing necessary information.
|
||||
- Pagination: Always disable terminal pagination to ensure commands terminate (e.g., use \`git --no-pager\`, \`systemctl --no-pager\`, or set \`PAGER=cat\`).
|
||||
|
||||
The following information is returned:
|
||||
|
||||
Output: Combined stdout/stderr. Can be \`(empty)\` or partial on error and for any unwaited background processes.
|
||||
Exit Code: Only included if non-zero (command failed).
|
||||
Error: Only included if a process-level error occurred (e.g., spawn failure).
|
||||
Signal: Only included if process was terminated by a signal.
|
||||
Background PIDs: Only included if background processes were started.
|
||||
Process Group PGID: Only included if available."
|
||||
`;
|
||||
|
||||
exports[`ShellTool > getSchema > should return the base schema when no modelId is provided 1`] = `
|
||||
"This tool executes a given shell command as \`bash -c <command>\`. Command can start background processes using \`&\`. Command is executed as a subprocess that leads its own process group. Command process group can be terminated as \`kill -- -PGID\` or signaled as \`kill -s SIGNAL -- -PGID\`.
|
||||
|
||||
Efficiency Guidelines:
|
||||
- Quiet Flags: Always prefer silent or quiet flags (e.g., \`npm install --silent\`, \`git --no-pager\`) to reduce output volume while still capturing necessary information.
|
||||
- Pagination: Always disable terminal pagination to ensure commands terminate (e.g., use \`git --no-pager\`, \`systemctl --no-pager\`, or set \`PAGER=cat\`).
|
||||
|
||||
The following information is returned:
|
||||
|
||||
Output: Combined stdout/stderr. Can be \`(empty)\` or partial on error and for any unwaited background processes.
|
||||
Exit Code: Only included if non-zero (command failed).
|
||||
Error: Only included if a process-level error occurred (e.g., spawn failure).
|
||||
Signal: Only included if process was terminated by a signal.
|
||||
Background PIDs: Only included if background processes were started.
|
||||
Process Group PGID: Only included if available."
|
||||
`;
|
||||
|
||||
exports[`ShellTool > getSchema > should return the schema from the resolver when modelId is provided 1`] = `
|
||||
"This tool executes a given shell command as \`bash -c <command>\`. Command can start background processes using \`&\`. Command is executed as a subprocess that leads its own process group. Command process group can be terminated as \`kill -- -PGID\` or signaled as \`kill -s SIGNAL -- -PGID\`.
|
||||
|
||||
Efficiency Guidelines:
|
||||
- Quiet Flags: Always prefer silent or quiet flags (e.g., \`npm install --silent\`, \`git --no-pager\`) to reduce output volume while still capturing necessary information.
|
||||
- Pagination: Always disable terminal pagination to ensure commands terminate (e.g., use \`git --no-pager\`, \`systemctl --no-pager\`, or set \`PAGER=cat\`).
|
||||
|
||||
The following information is returned:
|
||||
|
||||
Output: Combined stdout/stderr. Can be \`(empty)\` or partial on error and for any unwaited background processes.
|
||||
Exit Code: Only included if non-zero (command failed).
|
||||
Error: Only included if a process-level error occurred (e.g., spawn failure).
|
||||
Signal: Only included if process was terminated by a signal.
|
||||
Background PIDs: Only included if background processes were started.
|
||||
Process Group PGID: Only included if available."
|
||||
`;
|
||||
exports[`ShellTool > getSchema > should return the schema from the resolver when modelId is provided 1`] = `"This tool executes a given shell command as \`bash -c <command>\`."`;
|
||||
|
||||
@@ -201,6 +201,6 @@ export class ActivateSkillTool extends BaseDeclarativeTool<
|
||||
return resolveToolDeclaration(
|
||||
getActivateSkillDefinition(skillNames),
|
||||
modelId,
|
||||
);
|
||||
).declaration;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -111,7 +111,7 @@ export class AskUserTool extends BaseDeclarativeTool<
|
||||
}
|
||||
|
||||
override getSchema(modelId?: string) {
|
||||
return resolveToolDeclaration(ASK_USER_DEFINITION, modelId);
|
||||
return resolveToolDeclaration(ASK_USER_DEFINITION, modelId).declaration;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+1172
-1056
File diff suppressed because it is too large
Load Diff
@@ -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.
|
||||
@@ -420,12 +420,12 @@ export const LS_DEFINITION: ToolDefinition = {
|
||||
// ============================================================================
|
||||
|
||||
/**
|
||||
* Generates the platform-specific description for the shell tool.
|
||||
* Generates the platform-specific description and instructions for the shell tool.
|
||||
*/
|
||||
export function getShellToolDescription(
|
||||
enableInteractiveShell: boolean,
|
||||
enableEfficiency: boolean,
|
||||
): string {
|
||||
): { description: string; instructions: string } {
|
||||
const efficiencyGuidelines = enableEfficiency
|
||||
? `
|
||||
|
||||
@@ -449,12 +449,18 @@ export function getShellToolDescription(
|
||||
const backgroundInstructions = enableInteractiveShell
|
||||
? 'To run a command in the background, set the `is_background` parameter to true. Do NOT use PowerShell background constructs.'
|
||||
: 'Command can start background processes using PowerShell constructs such as `Start-Process -NoNewWindow` or `Start-Job`.';
|
||||
return `This tool executes a given shell command as \`powershell.exe -NoProfile -Command <command>\`. ${backgroundInstructions}${efficiencyGuidelines}${returnedInfo}`;
|
||||
return {
|
||||
description: `This tool executes a given shell command as \`powershell.exe -NoProfile -Command <command>\`.`,
|
||||
instructions: `${backgroundInstructions}${efficiencyGuidelines}${returnedInfo}`,
|
||||
};
|
||||
} else {
|
||||
const backgroundInstructions = enableInteractiveShell
|
||||
? 'To run a command in the background, set the `is_background` parameter to true. Do NOT use `&` to background commands.'
|
||||
: 'Command can start background processes using `&`.';
|
||||
return `This tool executes a given shell command as \`bash -c <command>\`. ${backgroundInstructions} Command is executed as a subprocess that leads its own process group. Command process group can be terminated as \`kill -- -PGID\` or signaled as \`kill -s SIGNAL -- -PGID\`.${efficiencyGuidelines}${returnedInfo}`;
|
||||
return {
|
||||
description: `This tool executes a given shell command as \`bash -c <command>\`.`,
|
||||
instructions: `${backgroundInstructions} Command is executed as a subprocess that leads its own process group. Command process group can be terminated as \`kill -- -PGID\` or signaled as \`kill -s SIGNAL -- -PGID\`.${efficiencyGuidelines}${returnedInfo}`,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -475,13 +481,15 @@ export function getShellDefinition(
|
||||
enableInteractiveShell: boolean,
|
||||
enableEfficiency: boolean,
|
||||
): ToolDefinition {
|
||||
const { description, instructions } = getShellToolDescription(
|
||||
enableInteractiveShell,
|
||||
enableEfficiency,
|
||||
);
|
||||
return {
|
||||
base: {
|
||||
name: SHELL_TOOL_NAME,
|
||||
description: getShellToolDescription(
|
||||
enableInteractiveShell,
|
||||
enableEfficiency,
|
||||
),
|
||||
description,
|
||||
instructions,
|
||||
parametersJsonSchema: {
|
||||
type: 'object',
|
||||
properties: {
|
||||
@@ -655,23 +663,6 @@ Use this tool for complex queries that require multiple steps. If you find that
|
||||
|
||||
DO NOT use this tool for simple tasks that can be completed in less than 2 steps. If the user query is simple and straightforward, do not use the tool. If you can respond with an answer in a single turn then this tool is not required.
|
||||
|
||||
## Task state definitions
|
||||
|
||||
- pending: Work has not begun on a given subtask.
|
||||
- in_progress: Marked just prior to beginning work on a given subtask. You should only have one subtask as in_progress at a time.
|
||||
- completed: Subtask was successfully completed with no errors or issues. If the subtask required more steps to complete, update the todo list with the subtasks. All steps should be identified as completed only when they are completed.
|
||||
- cancelled: As you update the todo list, some tasks are not required anymore due to the dynamic nature of the task. In this case, mark the subtasks as cancelled.
|
||||
|
||||
|
||||
## Methodology for using this tool
|
||||
1. Use this todo list as soon as you receive a user request based on the complexity of the task.
|
||||
2. Keep track of every subtask that you update the list with.
|
||||
3. Mark a subtask as in_progress before you begin working on it. You should only have one subtask as in_progress at a time.
|
||||
4. Update the subtask list as you proceed in executing the task. The subtask list is not static and should reflect your progress and current plans, which may evolve as you acquire new information.
|
||||
5. Mark a subtask as completed when you have completed it.
|
||||
6. Mark a subtask as cancelled if the subtask is no longer needed.
|
||||
7. You must update the todo list as soon as you start, stop or cancel a subtask. Don't batch or wait to update the todo list.
|
||||
|
||||
|
||||
## Examples of When to Use the Todo List
|
||||
|
||||
@@ -709,6 +700,23 @@ Agent:
|
||||
The agent did not use the todo list because this task could be completed by a tight loop of execute test->edit->execute test.
|
||||
</reasoning>
|
||||
</example>`,
|
||||
instructions: `
|
||||
## Task state definitions
|
||||
|
||||
- pending: Work has not begun on a given subtask.
|
||||
- in_progress: Marked just prior to beginning work on a given subtask. You should only have one subtask as in_progress at a time.
|
||||
- completed: Subtask was successfully completed with no errors or issues. If the subtask required more steps to complete, update the todo list with the subtasks. All steps should be identified as completed only when they are completed.
|
||||
- cancelled: As you update the todo list, some tasks are not required anymore due to the dynamic nature of the task. In this case, mark the subtasks as cancelled.
|
||||
|
||||
|
||||
## Methodology for using this tool
|
||||
1. Use this todo list as soon as you receive a user request based on the complexity of the task.
|
||||
2. Keep track of every subtask that you update the list with.
|
||||
3. Mark a subtask as in_progress before you begin working on it. You should only have one subtask as in_progress at a time.
|
||||
4. Update the subtask list as you proceed in executing the task. The subtask list is not static and should reflect your progress and current plans, which may evolve as you acquire new information.
|
||||
5. Mark a subtask as completed when you have completed it.
|
||||
6. Mark a subtask as cancelled if the subtask is no longer needed.
|
||||
7. You must update the todo list as soon as you start, stop or cancel a subtask. Don't batch or wait to update the todo list.`,
|
||||
parametersJsonSchema: {
|
||||
type: 'object',
|
||||
properties: {
|
||||
|
||||
@@ -25,7 +25,7 @@ describe('resolveToolDeclaration', () => {
|
||||
|
||||
it('should return the base definition when no modelId is provided', () => {
|
||||
const result = resolveToolDeclaration(mockDefinition);
|
||||
expect(result).toEqual(mockDefinition.base);
|
||||
expect(result.declaration).toEqual(mockDefinition.base);
|
||||
});
|
||||
|
||||
it('should return overridden description when modelId matches override criteria', () => {
|
||||
@@ -43,8 +43,8 @@ describe('resolveToolDeclaration', () => {
|
||||
definitionWithOverride,
|
||||
'special-model',
|
||||
);
|
||||
expect(result.description).toBe('Overridden description');
|
||||
expect(result.name).toBe(mockDefinition.base.name);
|
||||
expect(result.declaration.description).toBe('Overridden description');
|
||||
expect(result.declaration.name).toBe(mockDefinition.base.name);
|
||||
});
|
||||
|
||||
it('should return base definition when modelId does not match override criteria', () => {
|
||||
@@ -62,11 +62,13 @@ describe('resolveToolDeclaration', () => {
|
||||
definitionWithOverride,
|
||||
'regular-model',
|
||||
);
|
||||
expect(result.description).toBe(mockDefinition.base.description);
|
||||
expect(result.declaration.description).toBe(
|
||||
mockDefinition.base.description,
|
||||
);
|
||||
});
|
||||
|
||||
it('should return the base definition when a modelId is provided but no overrides exist', () => {
|
||||
const result = resolveToolDeclaration(mockDefinition, 'gemini-1.5-pro');
|
||||
expect(result).toEqual(mockDefinition.base);
|
||||
expect(result.declaration).toEqual(mockDefinition.base);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -12,23 +12,38 @@ import type { ToolDefinition } from './types.js';
|
||||
*
|
||||
* @param definition The tool definition containing the base declaration and optional overrides.
|
||||
* @param modelId Optional model identifier to apply specific overrides.
|
||||
* @returns The FunctionDeclaration to be sent to the API.
|
||||
* @returns An object containing the FunctionDeclaration for the API and optional instructions for the system prompt.
|
||||
*/
|
||||
export function resolveToolDeclaration(
|
||||
definition: ToolDefinition,
|
||||
modelId?: string,
|
||||
): FunctionDeclaration {
|
||||
): { declaration: FunctionDeclaration; instructions?: string } {
|
||||
const { instructions: baseInstructions, ...baseDeclaration } =
|
||||
definition.base;
|
||||
|
||||
if (!modelId || !definition.overrides) {
|
||||
return definition.base;
|
||||
return {
|
||||
declaration: baseDeclaration,
|
||||
instructions: baseInstructions,
|
||||
};
|
||||
}
|
||||
|
||||
const override = definition.overrides(modelId);
|
||||
if (!override) {
|
||||
return definition.base;
|
||||
return {
|
||||
declaration: baseDeclaration,
|
||||
instructions: baseInstructions,
|
||||
};
|
||||
}
|
||||
|
||||
const { instructions: overrideInstructions, ...overrideDeclaration } =
|
||||
override;
|
||||
|
||||
return {
|
||||
...definition.base,
|
||||
...override,
|
||||
declaration: {
|
||||
...baseDeclaration,
|
||||
...overrideDeclaration,
|
||||
},
|
||||
instructions: overrideInstructions ?? baseInstructions,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -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,26 @@ export class EditTool
|
||||
private readonly config: Config,
|
||||
messageBus: MessageBus,
|
||||
) {
|
||||
const modelId =
|
||||
typeof config.getActiveModel === 'function'
|
||||
? config.getActiveModel()
|
||||
: undefined;
|
||||
const { declaration, instructions } = resolveToolDeclaration(
|
||||
EDIT_DEFINITION,
|
||||
modelId,
|
||||
);
|
||||
super(
|
||||
EditTool.Name,
|
||||
EDIT_DISPLAY_NAME,
|
||||
EDIT_DEFINITION.base.description!,
|
||||
declaration.description!,
|
||||
Kind.Edit,
|
||||
EDIT_DEFINITION.base.parametersJsonSchema,
|
||||
declaration.parametersJsonSchema,
|
||||
messageBus,
|
||||
true, // isOutputMarkdown
|
||||
false, // canUpdateOutput
|
||||
undefined, // extensionName
|
||||
undefined, // extensionId
|
||||
instructions,
|
||||
);
|
||||
}
|
||||
|
||||
@@ -962,7 +973,7 @@ export class EditTool
|
||||
}
|
||||
|
||||
override getSchema(modelId?: string) {
|
||||
return resolveToolDeclaration(EDIT_DEFINITION, modelId);
|
||||
return resolveToolDeclaration(EDIT_DEFINITION, modelId).declaration;
|
||||
}
|
||||
|
||||
getModifyContext(_: AbortSignal): ModifyContext<EditToolParams> {
|
||||
|
||||
@@ -57,7 +57,8 @@ export class EnterPlanModeTool extends BaseDeclarativeTool<
|
||||
}
|
||||
|
||||
override getSchema(modelId?: string) {
|
||||
return resolveToolDeclaration(ENTER_PLAN_MODE_DEFINITION, modelId);
|
||||
return resolveToolDeclaration(ENTER_PLAN_MODE_DEFINITION, modelId)
|
||||
.declaration;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -112,7 +112,8 @@ export class ExitPlanModeTool extends BaseDeclarativeTool<
|
||||
|
||||
override getSchema(modelId?: string) {
|
||||
const plansDir = this.config.storage.getProjectTempPlansDir();
|
||||
return resolveToolDeclaration(getExitPlanModeDefinition(plansDir), modelId);
|
||||
return resolveToolDeclaration(getExitPlanModeDefinition(plansDir), modelId)
|
||||
.declaration;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -183,6 +183,7 @@ export class GetInternalDocsTool extends BaseDeclarativeTool<
|
||||
}
|
||||
|
||||
override getSchema(modelId?: string) {
|
||||
return resolveToolDeclaration(GET_INTERNAL_DOCS_DEFINITION, modelId);
|
||||
return resolveToolDeclaration(GET_INTERNAL_DOCS_DEFINITION, modelId)
|
||||
.declaration;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -339,6 +339,6 @@ export class GlobTool extends BaseDeclarativeTool<GlobToolParams, ToolResult> {
|
||||
}
|
||||
|
||||
override getSchema(modelId?: string) {
|
||||
return resolveToolDeclaration(GLOB_DEFINITION, modelId);
|
||||
return resolveToolDeclaration(GLOB_DEFINITION, modelId).declaration;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -743,6 +743,6 @@ export class GrepTool extends BaseDeclarativeTool<GrepToolParams, ToolResult> {
|
||||
}
|
||||
|
||||
override getSchema(modelId?: string) {
|
||||
return resolveToolDeclaration(GREP_DEFINITION, modelId);
|
||||
return resolveToolDeclaration(GREP_DEFINITION, modelId).declaration;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -322,6 +322,6 @@ export class LSTool extends BaseDeclarativeTool<LSToolParams, ToolResult> {
|
||||
}
|
||||
|
||||
override getSchema(modelId?: string) {
|
||||
return resolveToolDeclaration(LS_DEFINITION, modelId);
|
||||
return resolveToolDeclaration(LS_DEFINITION, modelId).declaration;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -313,7 +313,7 @@ export class MemoryTool
|
||||
}
|
||||
|
||||
override getSchema(modelId?: string) {
|
||||
return resolveToolDeclaration(MEMORY_DEFINITION, modelId);
|
||||
return resolveToolDeclaration(MEMORY_DEFINITION, modelId).declaration;
|
||||
}
|
||||
|
||||
getModifyContext(_abortSignal: AbortSignal): ModifyContext<SaveMemoryParams> {
|
||||
|
||||
@@ -243,6 +243,6 @@ export class ReadFileTool extends BaseDeclarativeTool<
|
||||
}
|
||||
|
||||
override getSchema(modelId?: string) {
|
||||
return resolveToolDeclaration(READ_FILE_DEFINITION, modelId);
|
||||
return resolveToolDeclaration(READ_FILE_DEFINITION, modelId).declaration;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -493,6 +493,7 @@ export class ReadManyFilesTool extends BaseDeclarativeTool<
|
||||
}
|
||||
|
||||
override getSchema(modelId?: string) {
|
||||
return resolveToolDeclaration(READ_MANY_FILES_DEFINITION, modelId);
|
||||
return resolveToolDeclaration(READ_MANY_FILES_DEFINITION, modelId)
|
||||
.declaration;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -660,6 +660,6 @@ export class RipGrepTool extends BaseDeclarativeTool<
|
||||
}
|
||||
|
||||
override getSchema(modelId?: string) {
|
||||
return resolveToolDeclaration(RIP_GREP_DEFINITION, modelId);
|
||||
return resolveToolDeclaration(RIP_GREP_DEFINITION, modelId).declaration;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -466,19 +466,30 @@ export class ShellTool extends BaseDeclarativeTool<
|
||||
void initializeShellParsers().catch(() => {
|
||||
// Errors are surfaced when parsing commands.
|
||||
});
|
||||
const modelId =
|
||||
typeof config.getActiveModel === 'function'
|
||||
? config.getActiveModel()
|
||||
: undefined;
|
||||
const definition = getShellDefinition(
|
||||
config.getEnableInteractiveShell(),
|
||||
config.getEnableShellOutputEfficiency(),
|
||||
);
|
||||
const { declaration, instructions } = resolveToolDeclaration(
|
||||
definition,
|
||||
modelId,
|
||||
);
|
||||
super(
|
||||
ShellTool.Name,
|
||||
'Shell',
|
||||
definition.base.description!,
|
||||
declaration.description!,
|
||||
Kind.Execute,
|
||||
definition.base.parametersJsonSchema,
|
||||
declaration.parametersJsonSchema,
|
||||
messageBus,
|
||||
false, // output is not markdown
|
||||
true, // output can be updated
|
||||
undefined, // extensionName
|
||||
undefined, // extensionId
|
||||
instructions,
|
||||
);
|
||||
}
|
||||
|
||||
@@ -519,6 +530,6 @@ export class ShellTool extends BaseDeclarativeTool<
|
||||
this.config.getEnableInteractiveShell(),
|
||||
this.config.getEnableShellOutputEfficiency(),
|
||||
);
|
||||
return resolveToolDeclaration(definition, modelId);
|
||||
return resolveToolDeclaration(definition, modelId).declaration;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -461,6 +461,6 @@ export class WebFetchTool extends BaseDeclarativeTool<
|
||||
}
|
||||
|
||||
override getSchema(modelId?: string) {
|
||||
return resolveToolDeclaration(WEB_FETCH_DEFINITION, modelId);
|
||||
return resolveToolDeclaration(WEB_FETCH_DEFINITION, modelId).declaration;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -239,6 +239,6 @@ export class WebSearchTool extends BaseDeclarativeTool<
|
||||
}
|
||||
|
||||
override getSchema(modelId?: string) {
|
||||
return resolveToolDeclaration(WEB_SEARCH_DEFINITION, modelId);
|
||||
return resolveToolDeclaration(WEB_SEARCH_DEFINITION, modelId).declaration;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -502,7 +502,7 @@ export class WriteFileTool
|
||||
}
|
||||
|
||||
override getSchema(modelId?: string) {
|
||||
return resolveToolDeclaration(WRITE_FILE_DEFINITION, modelId);
|
||||
return resolveToolDeclaration(WRITE_FILE_DEFINITION, modelId).declaration;
|
||||
}
|
||||
|
||||
getModifyContext(
|
||||
|
||||
@@ -7,9 +7,10 @@
|
||||
import { describe, expect, it } from 'vitest';
|
||||
import { WriteTodosTool, type WriteTodosToolParams } from './write-todos.js';
|
||||
import { createMockMessageBus } from '../test-utils/mock-message-bus.js';
|
||||
import { makeFakeConfig } from '../test-utils/config.js';
|
||||
|
||||
describe('WriteTodosTool', () => {
|
||||
const tool = new WriteTodosTool(createMockMessageBus());
|
||||
const tool = new WriteTodosTool(makeFakeConfig(), createMockMessageBus());
|
||||
const signal = new AbortController().signal;
|
||||
|
||||
describe('validation', () => {
|
||||
|
||||
@@ -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,21 +82,41 @@ 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 { declaration, instructions } = resolveToolDeclaration(
|
||||
WRITE_TODOS_DEFINITION,
|
||||
modelId,
|
||||
);
|
||||
super(
|
||||
WriteTodosTool.Name,
|
||||
'WriteTodos',
|
||||
WRITE_TODOS_DEFINITION.base.description!,
|
||||
declaration.description!,
|
||||
Kind.Other,
|
||||
WRITE_TODOS_DEFINITION.base.parametersJsonSchema,
|
||||
declaration.parametersJsonSchema,
|
||||
messageBus,
|
||||
true, // isOutputMarkdown
|
||||
false, // canUpdateOutput
|
||||
undefined, // extensionName
|
||||
undefined, // extensionId
|
||||
instructions,
|
||||
);
|
||||
}
|
||||
|
||||
override getSchema(modelId?: string) {
|
||||
return resolveToolDeclaration(WRITE_TODOS_DEFINITION, modelId);
|
||||
const activeModel =
|
||||
modelId ??
|
||||
(typeof this.config.getActiveModel === 'function'
|
||||
? this.config.getActiveModel()
|
||||
: undefined);
|
||||
return resolveToolDeclaration(WRITE_TODOS_DEFINITION, activeModel)
|
||||
.declaration;
|
||||
}
|
||||
|
||||
protected override validateToolParamValues(
|
||||
|
||||
Reference in New Issue
Block a user