summaryrefslogtreecommitdiff
path: root/packages/core/src
diff options
context:
space:
mode:
Diffstat (limited to 'packages/core/src')
-rw-r--r--packages/core/src/config/config.ts7
-rw-r--r--packages/core/src/core/client.ts2
-rw-r--r--packages/core/src/core/coreToolScheduler.test.ts5
-rw-r--r--packages/core/src/core/nonInteractiveToolExecutor.test.ts3
-rw-r--r--packages/core/src/index.ts2
-rw-r--r--packages/core/src/tools/edit.ts21
-rw-r--r--packages/core/src/tools/glob.ts3
-rw-r--r--packages/core/src/tools/grep.ts3
-rw-r--r--packages/core/src/tools/ls.ts3
-rw-r--r--packages/core/src/tools/mcp-tool.ts2
-rw-r--r--packages/core/src/tools/memoryTool.ts3
-rw-r--r--packages/core/src/tools/read-file.ts7
-rw-r--r--packages/core/src/tools/read-many-files.ts3
-rw-r--r--packages/core/src/tools/shell.ts2
-rw-r--r--packages/core/src/tools/tool-registry.test.ts6
-rw-r--r--packages/core/src/tools/tool-registry.ts3
-rw-r--r--packages/core/src/tools/tools.ts47
-rw-r--r--packages/core/src/tools/web-fetch.ts2
-rw-r--r--packages/core/src/tools/web-search.ts3
-rw-r--r--packages/core/src/tools/write-file.ts15
-rw-r--r--packages/core/src/utils/retry.ts2
21 files changed, 126 insertions, 18 deletions
diff --git a/packages/core/src/config/config.ts b/packages/core/src/config/config.ts
index 59f1e1ba..9d47fb08 100644
--- a/packages/core/src/config/config.ts
+++ b/packages/core/src/config/config.ts
@@ -145,6 +145,7 @@ export interface ConfigParameters {
model: string;
extensionContextFilePaths?: string[];
maxSessionTurns?: number;
+ experimentalAcp?: boolean;
listExtensions?: boolean;
activeExtensions?: ActiveExtension[];
noBrowser?: boolean;
@@ -199,6 +200,7 @@ export class Config {
private readonly summarizeToolOutput:
| Record<string, SummarizeToolOutputSettings>
| undefined;
+ private readonly experimentalAcp: boolean = false;
constructor(params: ConfigParameters) {
this.sessionId = params.sessionId;
@@ -241,6 +243,7 @@ export class Config {
this.model = params.model;
this.extensionContextFilePaths = params.extensionContextFilePaths ?? [];
this.maxSessionTurns = params.maxSessionTurns ?? -1;
+ this.experimentalAcp = params.experimentalAcp ?? false;
this.listExtensions = params.listExtensions ?? false;
this._activeExtensions = params.activeExtensions ?? [];
this.noBrowser = params.noBrowser ?? false;
@@ -494,6 +497,10 @@ export class Config {
return this.extensionContextFilePaths;
}
+ getExperimentalAcp(): boolean {
+ return this.experimentalAcp;
+ }
+
getListExtensions(): boolean {
return this.listExtensions;
}
diff --git a/packages/core/src/core/client.ts b/packages/core/src/core/client.ts
index 1cffd6a3..7bb8cea4 100644
--- a/packages/core/src/core/client.ts
+++ b/packages/core/src/core/client.ts
@@ -221,7 +221,7 @@ export class GeminiClient {
return initialParts;
}
- private async startChat(extraHistory?: Content[]): Promise<GeminiChat> {
+ async startChat(extraHistory?: Content[]): Promise<GeminiChat> {
const envParts = await this.getEnvironment();
const toolRegistry = await this.config.getToolRegistry();
const toolDeclarations = toolRegistry.getFunctionDeclarations();
diff --git a/packages/core/src/core/coreToolScheduler.test.ts b/packages/core/src/core/coreToolScheduler.test.ts
index 0b2c5124..94d4f7c1 100644
--- a/packages/core/src/core/coreToolScheduler.test.ts
+++ b/packages/core/src/core/coreToolScheduler.test.ts
@@ -19,6 +19,7 @@ import {
ToolConfirmationPayload,
ToolResult,
Config,
+ Icon,
} from '../index.js';
import { Part, PartListUnion } from '@google/genai';
@@ -29,7 +30,7 @@ class MockTool extends BaseTool<Record<string, unknown>, ToolResult> {
executeFn = vi.fn();
constructor(name = 'mockTool') {
- super(name, name, 'A mock tool', {});
+ super(name, name, 'A mock tool', Icon.Hammer, {});
}
async shouldConfirmExecute(
@@ -91,6 +92,8 @@ class MockModifiableTool
title: 'Confirm Mock Tool',
fileName: 'test.txt',
fileDiff: 'diff',
+ originalContent: 'originalContent',
+ newContent: 'newContent',
onConfirm: async () => {},
};
}
diff --git a/packages/core/src/core/nonInteractiveToolExecutor.test.ts b/packages/core/src/core/nonInteractiveToolExecutor.test.ts
index 14b048b4..d52efb06 100644
--- a/packages/core/src/core/nonInteractiveToolExecutor.test.ts
+++ b/packages/core/src/core/nonInteractiveToolExecutor.test.ts
@@ -13,6 +13,7 @@ import {
Tool,
ToolCallConfirmationDetails,
Config,
+ Icon,
} from '../index.js';
import { Part, Type } from '@google/genai';
@@ -32,6 +33,7 @@ describe('executeToolCall', () => {
name: 'testTool',
displayName: 'Test Tool',
description: 'A tool for testing',
+ icon: Icon.Hammer,
schema: {
name: 'testTool',
description: 'A tool for testing',
@@ -51,6 +53,7 @@ describe('executeToolCall', () => {
isOutputMarkdown: false,
canUpdateOutput: false,
getDescription: vi.fn(),
+ toolLocations: vi.fn(() => []),
};
mockToolRegistry = {
diff --git a/packages/core/src/index.ts b/packages/core/src/index.ts
index 5f1dc3e7..ffc06866 100644
--- a/packages/core/src/index.ts
+++ b/packages/core/src/index.ts
@@ -33,6 +33,8 @@ export * from './utils/memoryDiscovery.js';
export * from './utils/gitIgnoreParser.js';
export * from './utils/editor.js';
export * from './utils/quotaErrorDetection.js';
+export * from './utils/fileUtils.js';
+export * from './utils/retry.js';
// Export services
export * from './services/fileDiscoveryService.js';
diff --git a/packages/core/src/tools/edit.ts b/packages/core/src/tools/edit.ts
index 8d8753d4..ccba3d72 100644
--- a/packages/core/src/tools/edit.ts
+++ b/packages/core/src/tools/edit.ts
@@ -9,9 +9,11 @@ import * as path from 'path';
import * as Diff from 'diff';
import {
BaseTool,
+ Icon,
ToolCallConfirmationDetails,
ToolConfirmationOutcome,
ToolEditConfirmationDetails,
+ ToolLocation,
ToolResult,
ToolResultDisplay,
} from './tools.js';
@@ -89,6 +91,7 @@ Expectation for required parameters:
4. NEVER escape \`old_string\` or \`new_string\`, that would break the exact literal text requirement.
**Important:** If ANY of the above are not satisfied, the tool will fail. CRITICAL for \`old_string\`: Must uniquely identify the single instance to change. Include at least 3 lines of context BEFORE and AFTER the target text, matching whitespace and indentation precisely. If this string matches multiple locations, or does not match exactly, the tool will fail.
**Multiple replacements:** Set \`expected_replacements\` to the number of occurrences you want to replace. The tool will replace ALL occurrences that match \`old_string\` exactly. Ensure the number of replacements matches your expectation.`,
+ Icon.Pencil,
{
properties: {
file_path: {
@@ -141,6 +144,15 @@ Expectation for required parameters:
return null;
}
+ /**
+ * Determines any file locations affected by the tool execution
+ * @param params Parameters for the tool execution
+ * @returns A list of such paths
+ */
+ toolLocations(params: EditToolParams): ToolLocation[] {
+ return [{ path: params.file_path }];
+ }
+
private _applyReplacement(
currentContent: string | null,
oldString: string,
@@ -306,6 +318,8 @@ Expectation for required parameters:
title: `Confirm Edit: ${shortenPath(makeRelative(params.file_path, this.config.getTargetDir()))}`,
fileName,
fileDiff,
+ originalContent: editData.currentContent,
+ newContent: editData.newContent,
onConfirm: async (outcome: ToolConfirmationOutcome) => {
if (outcome === ToolConfirmationOutcome.ProceedAlways) {
this.config.setApprovalMode(ApprovalMode.AUTO_EDIT);
@@ -394,7 +408,12 @@ Expectation for required parameters:
'Proposed',
DEFAULT_DIFF_OPTIONS,
);
- displayResult = { fileDiff, fileName };
+ displayResult = {
+ fileDiff,
+ fileName,
+ originalContent: editData.currentContent,
+ newContent: editData.newContent,
+ };
}
const llmSuccessMessageParts = [
diff --git a/packages/core/src/tools/glob.ts b/packages/core/src/tools/glob.ts
index 9381894e..417495fe 100644
--- a/packages/core/src/tools/glob.ts
+++ b/packages/core/src/tools/glob.ts
@@ -8,7 +8,7 @@ import fs from 'fs';
import path from 'path';
import { glob } from 'glob';
import { SchemaValidator } from '../utils/schemaValidator.js';
-import { BaseTool, ToolResult } from './tools.js';
+import { BaseTool, Icon, ToolResult } from './tools.js';
import { Type } from '@google/genai';
import { shortenPath, makeRelative } from '../utils/paths.js';
import { isWithinRoot } from '../utils/fileUtils.js';
@@ -86,6 +86,7 @@ export class GlobTool extends BaseTool<GlobToolParams, ToolResult> {
GlobTool.Name,
'FindFiles',
'Efficiently finds files matching specific glob patterns (e.g., `src/**/*.ts`, `**/*.md`), returning absolute paths sorted by modification time (newest first). Ideal for quickly locating files based on their name or path structure, especially in large codebases.',
+ Icon.FileSearch,
{
properties: {
pattern: {
diff --git a/packages/core/src/tools/grep.ts b/packages/core/src/tools/grep.ts
index afe83050..177bd1aa 100644
--- a/packages/core/src/tools/grep.ts
+++ b/packages/core/src/tools/grep.ts
@@ -10,7 +10,7 @@ import path from 'path';
import { EOL } from 'os';
import { spawn } from 'child_process';
import { globStream } from 'glob';
-import { BaseTool, ToolResult } from './tools.js';
+import { BaseTool, Icon, ToolResult } from './tools.js';
import { Type } from '@google/genai';
import { SchemaValidator } from '../utils/schemaValidator.js';
import { makeRelative, shortenPath } from '../utils/paths.js';
@@ -62,6 +62,7 @@ export class GrepTool extends BaseTool<GrepToolParams, ToolResult> {
GrepTool.Name,
'SearchText',
'Searches for a regular expression pattern within the content of files in a specified directory (or current working directory). Can filter files by a glob pattern. Returns the lines containing matches, along with their file paths and line numbers.',
+ Icon.Regex,
{
properties: {
pattern: {
diff --git a/packages/core/src/tools/ls.ts b/packages/core/src/tools/ls.ts
index 9fb60072..fc4f06dd 100644
--- a/packages/core/src/tools/ls.ts
+++ b/packages/core/src/tools/ls.ts
@@ -6,7 +6,7 @@
import fs from 'fs';
import path from 'path';
-import { BaseTool, ToolResult } from './tools.js';
+import { BaseTool, Icon, ToolResult } from './tools.js';
import { Type } from '@google/genai';
import { SchemaValidator } from '../utils/schemaValidator.js';
import { makeRelative, shortenPath } from '../utils/paths.js';
@@ -74,6 +74,7 @@ export class LSTool extends BaseTool<LSToolParams, ToolResult> {
LSTool.Name,
'ReadFolder',
'Lists the names of files and subdirectories directly within a specified directory path. Can optionally ignore entries matching provided glob patterns.',
+ Icon.Folder,
{
properties: {
path: {
diff --git a/packages/core/src/tools/mcp-tool.ts b/packages/core/src/tools/mcp-tool.ts
index 663ec6ee..aadc484a 100644
--- a/packages/core/src/tools/mcp-tool.ts
+++ b/packages/core/src/tools/mcp-tool.ts
@@ -10,6 +10,7 @@ import {
ToolCallConfirmationDetails,
ToolConfirmationOutcome,
ToolMcpConfirmationDetails,
+ Icon,
} from './tools.js';
import {
CallableTool,
@@ -38,6 +39,7 @@ export class DiscoveredMCPTool extends BaseTool<ToolParams, ToolResult> {
name,
`${serverToolName} (${serverName} MCP Server)`,
description,
+ Icon.Hammer,
{ type: Type.OBJECT }, // this is a dummy Schema for MCP, will be not be used to construct the FunctionDeclaration
true, // isOutputMarkdown
false, // canUpdateOutput
diff --git a/packages/core/src/tools/memoryTool.ts b/packages/core/src/tools/memoryTool.ts
index b4a671b0..f0f1e16b 100644
--- a/packages/core/src/tools/memoryTool.ts
+++ b/packages/core/src/tools/memoryTool.ts
@@ -4,7 +4,7 @@
* SPDX-License-Identifier: Apache-2.0
*/
-import { BaseTool, ToolResult } from './tools.js';
+import { BaseTool, Icon, ToolResult } from './tools.js';
import { FunctionDeclaration, Type } from '@google/genai';
import * as fs from 'fs/promises';
import * as path from 'path';
@@ -105,6 +105,7 @@ export class MemoryTool extends BaseTool<SaveMemoryParams, ToolResult> {
MemoryTool.Name,
'Save Memory',
memoryToolDescription,
+ Icon.LightBulb,
memoryToolSchemaData.parameters as Record<string, unknown>,
);
}
diff --git a/packages/core/src/tools/read-file.ts b/packages/core/src/tools/read-file.ts
index a2ff89c1..9ba80672 100644
--- a/packages/core/src/tools/read-file.ts
+++ b/packages/core/src/tools/read-file.ts
@@ -7,7 +7,7 @@
import path from 'path';
import { SchemaValidator } from '../utils/schemaValidator.js';
import { makeRelative, shortenPath } from '../utils/paths.js';
-import { BaseTool, ToolResult } from './tools.js';
+import { BaseTool, Icon, ToolLocation, ToolResult } from './tools.js';
import { Type } from '@google/genai';
import {
isWithinRoot,
@@ -51,6 +51,7 @@ export class ReadFileTool extends BaseTool<ReadFileToolParams, ToolResult> {
ReadFileTool.Name,
'ReadFile',
'Reads and returns the content of a specified file from the local filesystem. Handles text, images (PNG, JPG, GIF, WEBP, SVG, BMP), and PDF files. For text files, it can read specific line ranges.',
+ Icon.FileSearch,
{
properties: {
absolute_path: {
@@ -118,6 +119,10 @@ export class ReadFileTool extends BaseTool<ReadFileToolParams, ToolResult> {
return shortenPath(relativePath);
}
+ toolLocations(params: ReadFileToolParams): ToolLocation[] {
+ return [{ path: params.absolute_path, line: params.offset }];
+ }
+
async execute(
params: ReadFileToolParams,
_signal: AbortSignal,
diff --git a/packages/core/src/tools/read-many-files.ts b/packages/core/src/tools/read-many-files.ts
index c43841b5..1c01ee9f 100644
--- a/packages/core/src/tools/read-many-files.ts
+++ b/packages/core/src/tools/read-many-files.ts
@@ -4,7 +4,7 @@
* SPDX-License-Identifier: Apache-2.0
*/
-import { BaseTool, ToolResult } from './tools.js';
+import { BaseTool, Icon, ToolResult } from './tools.js';
import { SchemaValidator } from '../utils/schemaValidator.js';
import { getErrorMessage } from '../utils/errors.js';
import * as path from 'path';
@@ -196,6 +196,7 @@ This tool is useful when you need to understand or analyze a collection of files
- When the user asks to "read all files in X directory" or "show me the content of all Y files".
Use this tool when the user's query implies needing the content of several files simultaneously for context, analysis, or summarization. For text files, it uses default UTF-8 encoding and a '--- {filePath} ---' separator between file contents. Ensure paths are relative to the target directory. Glob patterns like 'src/**/*.js' are supported. Avoid using for single files if a more specific single-file reading tool is available, unless the user specifically requests to process a list containing just one file via this tool. Other binary files (not explicitly requested as image/PDF) are generally skipped. Default excludes apply to common non-text files (except for explicitly requested images/PDFs) and large dependency directories unless 'useDefaultExcludes' is false.`,
+ Icon.FileSearch,
parameterSchema,
);
this.geminiIgnorePatterns = config
diff --git a/packages/core/src/tools/shell.ts b/packages/core/src/tools/shell.ts
index 3dc3d0a6..af514546 100644
--- a/packages/core/src/tools/shell.ts
+++ b/packages/core/src/tools/shell.ts
@@ -15,6 +15,7 @@ import {
ToolCallConfirmationDetails,
ToolExecuteConfirmationDetails,
ToolConfirmationOutcome,
+ Icon,
} from './tools.js';
import { Type } from '@google/genai';
import { SchemaValidator } from '../utils/schemaValidator.js';
@@ -52,6 +53,7 @@ Exit Code: Exit code or \`(none)\` if terminated by signal.
Signal: Signal number or \`(none)\` if no signal was received.
Background PIDs: List of background processes started or \`(none)\`.
Process Group PGID: Process group started or \`(none)\``,
+ Icon.Terminal,
{
type: Type.OBJECT,
properties: {
diff --git a/packages/core/src/tools/tool-registry.test.ts b/packages/core/src/tools/tool-registry.test.ts
index 38b058ea..ec709a44 100644
--- a/packages/core/src/tools/tool-registry.test.ts
+++ b/packages/core/src/tools/tool-registry.test.ts
@@ -14,14 +14,14 @@ import {
afterEach,
Mocked,
} from 'vitest';
+import { Config, ConfigParameters, ApprovalMode } from '../config/config.js';
import {
ToolRegistry,
DiscoveredTool,
sanitizeParameters,
} from './tool-registry.js';
import { DiscoveredMCPTool } from './mcp-tool.js';
-import { Config, ConfigParameters, ApprovalMode } from '../config/config.js';
-import { BaseTool, ToolResult } from './tools.js';
+import { BaseTool, Icon, ToolResult } from './tools.js';
import {
FunctionDeclaration,
CallableTool,
@@ -109,7 +109,7 @@ class MockTool extends BaseTool<{ param: string }, ToolResult> {
displayName = 'A mock tool',
description = 'A mock tool description',
) {
- super(name, displayName, description, {
+ super(name, displayName, description, Icon.Hammer, {
type: Type.OBJECT,
properties: {
param: { type: Type.STRING },
diff --git a/packages/core/src/tools/tool-registry.ts b/packages/core/src/tools/tool-registry.ts
index d2303fc9..e6a4121d 100644
--- a/packages/core/src/tools/tool-registry.ts
+++ b/packages/core/src/tools/tool-registry.ts
@@ -5,7 +5,7 @@
*/
import { FunctionDeclaration, Schema, Type } from '@google/genai';
-import { Tool, ToolResult, BaseTool } from './tools.js';
+import { Tool, ToolResult, BaseTool, Icon } from './tools.js';
import { Config } from '../config/config.js';
import { spawn } from 'node:child_process';
import { StringDecoder } from 'node:string_decoder';
@@ -44,6 +44,7 @@ Signal: Signal number or \`(none)\` if no signal was received.
name,
name,
description,
+ Icon.Hammer,
parameterSchema,
false, // isOutputMarkdown
false, // canUpdateOutput
diff --git a/packages/core/src/tools/tools.ts b/packages/core/src/tools/tools.ts
index 6f6d3f58..0d7b402a 100644
--- a/packages/core/src/tools/tools.ts
+++ b/packages/core/src/tools/tools.ts
@@ -29,6 +29,11 @@ export interface Tool<
description: string;
/**
+ * The icon to display when interacting via ACP
+ */
+ icon: Icon;
+
+ /**
* Function declaration schema from @google/genai
*/
schema: FunctionDeclaration;
@@ -61,6 +66,13 @@ export interface Tool<
getDescription(params: TParams): string;
/**
+ * Determines what file system paths the tool will affect
+ * @param params Parameters for the tool execution
+ * @returns A list of such paths
+ */
+ toolLocations(params: TParams): ToolLocation[];
+
+ /**
* Determines if the tool should prompt for confirmation before execution
* @param params Parameters for the tool execution
* @returns Whether execute should be confirmed.
@@ -103,6 +115,7 @@ export abstract class BaseTool<
readonly name: string,
readonly displayName: string,
readonly description: string,
+ readonly icon: Icon,
readonly parameterSchema: Schema,
readonly isOutputMarkdown: boolean = true,
readonly canUpdateOutput: boolean = false,
@@ -159,6 +172,18 @@ export abstract class BaseTool<
}
/**
+ * Determines what file system paths the tool will affect
+ * @param params Parameters for the tool execution
+ * @returns A list of such paths
+ */
+ toolLocations(
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
+ params: TParams,
+ ): ToolLocation[] {
+ return [];
+ }
+
+ /**
* Abstract method to execute the tool with the given parameters
* Must be implemented by derived classes
* @param params Parameters for the tool execution
@@ -199,6 +224,8 @@ export type ToolResultDisplay = string | FileDiff;
export interface FileDiff {
fileDiff: string;
fileName: string;
+ originalContent: string | null;
+ newContent: string;
}
export interface ToolEditConfirmationDetails {
@@ -210,6 +237,8 @@ export interface ToolEditConfirmationDetails {
) => Promise<void>;
fileName: string;
fileDiff: string;
+ originalContent: string | null;
+ newContent: string;
isModifying?: boolean;
}
@@ -258,3 +287,21 @@ export enum ToolConfirmationOutcome {
ModifyWithEditor = 'modify_with_editor',
Cancel = 'cancel',
}
+
+export enum Icon {
+ FileSearch = 'fileSearch',
+ Folder = 'folder',
+ Globe = 'globe',
+ Hammer = 'hammer',
+ LightBulb = 'lightBulb',
+ Pencil = 'pencil',
+ Regex = 'regex',
+ Terminal = 'terminal',
+}
+
+export interface ToolLocation {
+ // Absolute path to the file
+ path: string;
+ // Which line (if known)
+ line?: number;
+}
diff --git a/packages/core/src/tools/web-fetch.ts b/packages/core/src/tools/web-fetch.ts
index ee06880e..c96cae6c 100644
--- a/packages/core/src/tools/web-fetch.ts
+++ b/packages/core/src/tools/web-fetch.ts
@@ -10,6 +10,7 @@ import {
ToolResult,
ToolCallConfirmationDetails,
ToolConfirmationOutcome,
+ Icon,
} from './tools.js';
import { Type } from '@google/genai';
import { getErrorMessage } from '../utils/errors.js';
@@ -70,6 +71,7 @@ export class WebFetchTool extends BaseTool<WebFetchToolParams, ToolResult> {
WebFetchTool.Name,
'WebFetch',
"Processes content from URL(s), including local and private network addresses (e.g., localhost), embedded in a prompt. Include up to 20 URLs and instructions (e.g., summarize, extract specific data) directly in the 'prompt' parameter.",
+ Icon.Globe,
{
properties: {
prompt: {
diff --git a/packages/core/src/tools/web-search.ts b/packages/core/src/tools/web-search.ts
index 98be1f30..480cc7e7 100644
--- a/packages/core/src/tools/web-search.ts
+++ b/packages/core/src/tools/web-search.ts
@@ -5,7 +5,7 @@
*/
import { GroundingMetadata } from '@google/genai';
-import { BaseTool, ToolResult } from './tools.js';
+import { BaseTool, Icon, ToolResult } from './tools.js';
import { Type } from '@google/genai';
import { SchemaValidator } from '../utils/schemaValidator.js';
@@ -69,6 +69,7 @@ export class WebSearchTool extends BaseTool<
WebSearchTool.Name,
'GoogleSearch',
'Performs a web search using Google Search (via the Gemini API) and returns the results. This tool is useful for finding information on the internet based on a query.',
+ Icon.Globe,
{
type: Type.OBJECT,
properties: {
diff --git a/packages/core/src/tools/write-file.ts b/packages/core/src/tools/write-file.ts
index a3756c69..ae37ca8a 100644
--- a/packages/core/src/tools/write-file.ts
+++ b/packages/core/src/tools/write-file.ts
@@ -15,6 +15,7 @@ import {
ToolEditConfirmationDetails,
ToolConfirmationOutcome,
ToolCallConfirmationDetails,
+ Icon,
} from './tools.js';
import { Type } from '@google/genai';
import { SchemaValidator } from '../utils/schemaValidator.js';
@@ -72,9 +73,10 @@ export class WriteFileTool
super(
WriteFileTool.Name,
'WriteFile',
- `Writes content to a specified file in the local filesystem.
-
+ `Writes content to a specified file in the local filesystem.
+
The user has the ability to modify \`content\`. If modified, this will be stated in the response.`,
+ Icon.Pencil,
{
properties: {
file_path: {
@@ -184,6 +186,8 @@ export class WriteFileTool
title: `Confirm Write: ${shortenPath(relativePath)}`,
fileName,
fileDiff,
+ originalContent,
+ newContent: correctedContent,
onConfirm: async (outcome: ToolConfirmationOutcome) => {
if (outcome === ToolConfirmationOutcome.ProceedAlways) {
this.config.setApprovalMode(ApprovalMode.AUTO_EDIT);
@@ -269,7 +273,12 @@ export class WriteFileTool
);
}
- const displayResult: FileDiff = { fileDiff, fileName };
+ const displayResult: FileDiff = {
+ fileDiff,
+ fileName,
+ originalContent: correctedContentResult.originalContent,
+ newContent: correctedContentResult.correctedContent,
+ };
const lines = fileContent.split('\n').length;
const mimetype = getSpecificMimeType(params.file_path);
diff --git a/packages/core/src/utils/retry.ts b/packages/core/src/utils/retry.ts
index e5d65751..bf4532bc 100644
--- a/packages/core/src/utils/retry.ts
+++ b/packages/core/src/utils/retry.ts
@@ -216,7 +216,7 @@ export async function retryWithBackoff<T>(
* @param error The error object.
* @returns The HTTP status code, or undefined if not found.
*/
-function getErrorStatus(error: unknown): number | undefined {
+export function getErrorStatus(error: unknown): number | undefined {
if (typeof error === 'object' && error !== null) {
if ('status' in error && typeof error.status === 'number') {
return error.status;