mirror of
https://github.com/google-gemini/gemini-cli.git
synced 2026-05-13 05:12:55 -07:00
chore: rename smart-edit to edit (#15923)
This commit is contained in:
@@ -297,7 +297,7 @@ Captures startup configuration and user prompt submissions.
|
|||||||
|
|
||||||
#### Tools
|
#### Tools
|
||||||
|
|
||||||
Captures tool executions, output truncation, and Smart Edit behavior.
|
Captures tool executions, output truncation, and Edit behavior.
|
||||||
|
|
||||||
- `gemini_cli.tool_call`: Emitted for each tool (function) call.
|
- `gemini_cli.tool_call`: Emitted for each tool (function) call.
|
||||||
- **Attributes**:
|
- **Attributes**:
|
||||||
@@ -325,11 +325,11 @@ Captures tool executions, output truncation, and Smart Edit behavior.
|
|||||||
- `lines` (int)
|
- `lines` (int)
|
||||||
- `prompt_id` (string)
|
- `prompt_id` (string)
|
||||||
|
|
||||||
- `gemini_cli.smart_edit_strategy`: Smart Edit strategy chosen.
|
- `gemini_cli.edit_strategy`: Edit strategy chosen.
|
||||||
- **Attributes**:
|
- **Attributes**:
|
||||||
- `strategy` (string)
|
- `strategy` (string)
|
||||||
|
|
||||||
- `gemini_cli.smart_edit_correction`: Smart Edit correction result.
|
- `gemini_cli.edit_correction`: Edit correction result.
|
||||||
- **Attributes**:
|
- **Attributes**:
|
||||||
- `correction` ("success" | "failure")
|
- `correction` ("success" | "failure")
|
||||||
|
|
||||||
|
|||||||
@@ -75,7 +75,6 @@ export const INFORMATIVE_TIPS = [
|
|||||||
'Set the character threshold for truncating tool outputs (/settings)...',
|
'Set the character threshold for truncating tool outputs (/settings)...',
|
||||||
'Set the number of lines to keep when truncating outputs (/settings)...',
|
'Set the number of lines to keep when truncating outputs (/settings)...',
|
||||||
'Enable policy-based tool confirmation via message bus (/settings)...',
|
'Enable policy-based tool confirmation via message bus (/settings)...',
|
||||||
'Enable smart-edit tool for more precise editing (/settings)...',
|
|
||||||
'Enable write_todos_list tool to generate task lists (/settings)...',
|
'Enable write_todos_list tool to generate task lists (/settings)...',
|
||||||
'Enable model routing based on complexity (/settings)...',
|
'Enable model routing based on complexity (/settings)...',
|
||||||
'Enable experimental subagents for task delegation (/settings)...',
|
'Enable experimental subagents for task delegation (/settings)...',
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ import { GrepTool } from '../tools/grep.js';
|
|||||||
import { canUseRipgrep, RipGrepTool } from '../tools/ripGrep.js';
|
import { canUseRipgrep, RipGrepTool } from '../tools/ripGrep.js';
|
||||||
import { GlobTool } from '../tools/glob.js';
|
import { GlobTool } from '../tools/glob.js';
|
||||||
import { ActivateSkillTool } from '../tools/activate-skill.js';
|
import { ActivateSkillTool } from '../tools/activate-skill.js';
|
||||||
import { SmartEditTool } from '../tools/smart-edit.js';
|
import { EditTool } from '../tools/edit.js';
|
||||||
import { ShellTool } from '../tools/shell.js';
|
import { ShellTool } from '../tools/shell.js';
|
||||||
import { WriteFileTool } from '../tools/write-file.js';
|
import { WriteFileTool } from '../tools/write-file.js';
|
||||||
import { WebFetchTool } from '../tools/web-fetch.js';
|
import { WebFetchTool } from '../tools/web-fetch.js';
|
||||||
@@ -1690,7 +1690,7 @@ export class Config {
|
|||||||
|
|
||||||
registerCoreTool(GlobTool, this);
|
registerCoreTool(GlobTool, this);
|
||||||
registerCoreTool(ActivateSkillTool, this);
|
registerCoreTool(ActivateSkillTool, this);
|
||||||
registerCoreTool(SmartEditTool, this);
|
registerCoreTool(EditTool, this);
|
||||||
registerCoreTool(WriteFileTool, this);
|
registerCoreTool(WriteFileTool, this);
|
||||||
registerCoreTool(WebFetchTool, this);
|
registerCoreTool(WebFetchTool, this);
|
||||||
registerCoreTool(ShellTool, this);
|
registerCoreTool(ShellTool, this);
|
||||||
|
|||||||
@@ -124,7 +124,7 @@ export * from './tools/ls.js';
|
|||||||
export * from './tools/grep.js';
|
export * from './tools/grep.js';
|
||||||
export * from './tools/ripGrep.js';
|
export * from './tools/ripGrep.js';
|
||||||
export * from './tools/glob.js';
|
export * from './tools/glob.js';
|
||||||
export * from './tools/smart-edit.js';
|
export * from './tools/edit.js';
|
||||||
export * from './tools/write-file.js';
|
export * from './tools/write-file.js';
|
||||||
export * from './tools/web-fetch.js';
|
export * from './tools/web-fetch.js';
|
||||||
export * from './tools/memoryTool.js';
|
export * from './tools/memoryTool.js';
|
||||||
|
|||||||
@@ -31,8 +31,8 @@ import type {
|
|||||||
ExtensionEnableEvent,
|
ExtensionEnableEvent,
|
||||||
ModelSlashCommandEvent,
|
ModelSlashCommandEvent,
|
||||||
ExtensionDisableEvent,
|
ExtensionDisableEvent,
|
||||||
SmartEditStrategyEvent,
|
EditStrategyEvent,
|
||||||
SmartEditCorrectionEvent,
|
EditCorrectionEvent,
|
||||||
AgentStartEvent,
|
AgentStartEvent,
|
||||||
AgentFinishEvent,
|
AgentFinishEvent,
|
||||||
RecoveryAttemptEvent,
|
RecoveryAttemptEvent,
|
||||||
@@ -89,8 +89,8 @@ export enum EventNames {
|
|||||||
TOOL_OUTPUT_TRUNCATED = 'tool_output_truncated',
|
TOOL_OUTPUT_TRUNCATED = 'tool_output_truncated',
|
||||||
MODEL_ROUTING = 'model_routing',
|
MODEL_ROUTING = 'model_routing',
|
||||||
MODEL_SLASH_COMMAND = 'model_slash_command',
|
MODEL_SLASH_COMMAND = 'model_slash_command',
|
||||||
SMART_EDIT_STRATEGY = 'smart_edit_strategy',
|
EDIT_STRATEGY = 'edit_strategy',
|
||||||
SMART_EDIT_CORRECTION = 'smart_edit_correction',
|
EDIT_CORRECTION = 'edit_correction',
|
||||||
AGENT_START = 'agent_start',
|
AGENT_START = 'agent_start',
|
||||||
AGENT_FINISH = 'agent_finish',
|
AGENT_FINISH = 'agent_finish',
|
||||||
RECOVERY_ATTEMPT = 'recovery_attempt',
|
RECOVERY_ATTEMPT = 'recovery_attempt',
|
||||||
@@ -1235,31 +1235,27 @@ export class ClearcutLogger {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
logSmartEditStrategyEvent(event: SmartEditStrategyEvent): void {
|
logEditStrategyEvent(event: EditStrategyEvent): void {
|
||||||
const data: EventValue[] = [
|
const data: EventValue[] = [
|
||||||
{
|
{
|
||||||
gemini_cli_key: EventMetadataKey.GEMINI_CLI_SMART_EDIT_STRATEGY,
|
gemini_cli_key: EventMetadataKey.GEMINI_CLI_EDIT_STRATEGY,
|
||||||
value: event.strategy,
|
value: event.strategy,
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
this.enqueueLogEvent(
|
this.enqueueLogEvent(this.createLogEvent(EventNames.EDIT_STRATEGY, data));
|
||||||
this.createLogEvent(EventNames.SMART_EDIT_STRATEGY, data),
|
|
||||||
);
|
|
||||||
this.flushIfNeeded();
|
this.flushIfNeeded();
|
||||||
}
|
}
|
||||||
|
|
||||||
logSmartEditCorrectionEvent(event: SmartEditCorrectionEvent): void {
|
logEditCorrectionEvent(event: EditCorrectionEvent): void {
|
||||||
const data: EventValue[] = [
|
const data: EventValue[] = [
|
||||||
{
|
{
|
||||||
gemini_cli_key: EventMetadataKey.GEMINI_CLI_SMART_EDIT_CORRECTION,
|
gemini_cli_key: EventMetadataKey.GEMINI_CLI_EDIT_CORRECTION,
|
||||||
value: event.correction,
|
value: event.correction,
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
this.enqueueLogEvent(
|
this.enqueueLogEvent(this.createLogEvent(EventNames.EDIT_CORRECTION, data));
|
||||||
this.createLogEvent(EventNames.SMART_EDIT_CORRECTION, data),
|
|
||||||
);
|
|
||||||
this.flushIfNeeded();
|
this.flushIfNeeded();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -93,11 +93,11 @@ export enum EventMetadataKey {
|
|||||||
// Replace Tool Call Event Keys
|
// Replace Tool Call Event Keys
|
||||||
// ===========================================================================
|
// ===========================================================================
|
||||||
|
|
||||||
// Logs a smart edit tool strategy choice.
|
// Logs a edit tool strategy choice.
|
||||||
GEMINI_CLI_SMART_EDIT_STRATEGY = 109,
|
GEMINI_CLI_EDIT_STRATEGY = 109,
|
||||||
|
|
||||||
// Logs a smart edit correction event.
|
// Logs a edit correction event.
|
||||||
GEMINI_CLI_SMART_EDIT_CORRECTION = 110,
|
GEMINI_CLI_EDIT_CORRECTION = 110,
|
||||||
|
|
||||||
// Logs the reason for web fetch fallback.
|
// Logs the reason for web fetch fallback.
|
||||||
GEMINI_CLI_WEB_FETCH_FALLBACK_REASON = 116,
|
GEMINI_CLI_WEB_FETCH_FALLBACK_REASON = 116,
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ import type {
|
|||||||
} from '../index.js';
|
} from '../index.js';
|
||||||
import {
|
import {
|
||||||
AuthType,
|
AuthType,
|
||||||
SmartEditTool,
|
EditTool,
|
||||||
GeminiClient,
|
GeminiClient,
|
||||||
ToolConfirmationOutcome,
|
ToolConfirmationOutcome,
|
||||||
ToolErrorType,
|
ToolErrorType,
|
||||||
@@ -1034,7 +1034,7 @@ describe('loggers', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('should log a tool call with all fields', () => {
|
it('should log a tool call with all fields', () => {
|
||||||
const tool = new SmartEditTool(mockConfig, createMockMessageBus());
|
const tool = new EditTool(mockConfig, createMockMessageBus());
|
||||||
const call: CompletedToolCall = {
|
const call: CompletedToolCall = {
|
||||||
status: 'success',
|
status: 'success',
|
||||||
request: {
|
request: {
|
||||||
@@ -1250,7 +1250,7 @@ describe('loggers', () => {
|
|||||||
contentLength: 13,
|
contentLength: 13,
|
||||||
},
|
},
|
||||||
outcome: ToolConfirmationOutcome.ModifyWithEditor,
|
outcome: ToolConfirmationOutcome.ModifyWithEditor,
|
||||||
tool: new SmartEditTool(mockConfig, createMockMessageBus()),
|
tool: new EditTool(mockConfig, createMockMessageBus()),
|
||||||
invocation: {} as AnyToolInvocation,
|
invocation: {} as AnyToolInvocation,
|
||||||
durationMs: 100,
|
durationMs: 100,
|
||||||
};
|
};
|
||||||
@@ -1329,7 +1329,7 @@ describe('loggers', () => {
|
|||||||
errorType: undefined,
|
errorType: undefined,
|
||||||
contentLength: 13,
|
contentLength: 13,
|
||||||
},
|
},
|
||||||
tool: new SmartEditTool(mockConfig, createMockMessageBus()),
|
tool: new EditTool(mockConfig, createMockMessageBus()),
|
||||||
invocation: {} as AnyToolInvocation,
|
invocation: {} as AnyToolInvocation,
|
||||||
durationMs: 100,
|
durationMs: 100,
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -41,8 +41,8 @@ import type {
|
|||||||
ExtensionUninstallEvent,
|
ExtensionUninstallEvent,
|
||||||
ExtensionInstallEvent,
|
ExtensionInstallEvent,
|
||||||
ModelSlashCommandEvent,
|
ModelSlashCommandEvent,
|
||||||
SmartEditStrategyEvent,
|
EditStrategyEvent,
|
||||||
SmartEditCorrectionEvent,
|
EditCorrectionEvent,
|
||||||
AgentStartEvent,
|
AgentStartEvent,
|
||||||
AgentFinishEvent,
|
AgentFinishEvent,
|
||||||
RecoveryAttemptEvent,
|
RecoveryAttemptEvent,
|
||||||
@@ -568,11 +568,11 @@ export async function logExtensionDisable(
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
export function logSmartEditStrategy(
|
export function logEditStrategy(
|
||||||
config: Config,
|
config: Config,
|
||||||
event: SmartEditStrategyEvent,
|
event: EditStrategyEvent,
|
||||||
): void {
|
): void {
|
||||||
ClearcutLogger.getInstance(config)?.logSmartEditStrategyEvent(event);
|
ClearcutLogger.getInstance(config)?.logEditStrategyEvent(event);
|
||||||
bufferTelemetryEvent(() => {
|
bufferTelemetryEvent(() => {
|
||||||
const logger = logs.getLogger(SERVICE_NAME);
|
const logger = logs.getLogger(SERVICE_NAME);
|
||||||
const logRecord: LogRecord = {
|
const logRecord: LogRecord = {
|
||||||
@@ -583,11 +583,11 @@ export function logSmartEditStrategy(
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
export function logSmartEditCorrectionEvent(
|
export function logEditCorrectionEvent(
|
||||||
config: Config,
|
config: Config,
|
||||||
event: SmartEditCorrectionEvent,
|
event: EditCorrectionEvent,
|
||||||
): void {
|
): void {
|
||||||
ClearcutLogger.getInstance(config)?.logSmartEditCorrectionEvent(event);
|
ClearcutLogger.getInstance(config)?.logEditCorrectionEvent(event);
|
||||||
bufferTelemetryEvent(() => {
|
bufferTelemetryEvent(() => {
|
||||||
const logger = logs.getLogger(SERVICE_NAME);
|
const logger = logs.getLogger(SERVICE_NAME);
|
||||||
const logRecord: LogRecord = {
|
const logRecord: LogRecord = {
|
||||||
|
|||||||
@@ -1548,7 +1548,9 @@ export type TelemetryEvent =
|
|||||||
| RecoveryAttemptEvent
|
| RecoveryAttemptEvent
|
||||||
| LlmLoopCheckEvent
|
| LlmLoopCheckEvent
|
||||||
| StartupStatsEvent
|
| StartupStatsEvent
|
||||||
| WebFetchFallbackAttemptEvent;
|
| WebFetchFallbackAttemptEvent
|
||||||
|
| EditStrategyEvent
|
||||||
|
| EditCorrectionEvent;
|
||||||
|
|
||||||
export const EVENT_EXTENSION_DISABLE = 'gemini_cli.extension_disable';
|
export const EVENT_EXTENSION_DISABLE = 'gemini_cli.extension_disable';
|
||||||
export class ExtensionDisableEvent implements BaseTelemetryEvent {
|
export class ExtensionDisableEvent implements BaseTelemetryEvent {
|
||||||
@@ -1588,14 +1590,14 @@ export class ExtensionDisableEvent implements BaseTelemetryEvent {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export const EVENT_SMART_EDIT_STRATEGY = 'gemini_cli.smart_edit_strategy';
|
export const EVENT_EDIT_STRATEGY = 'gemini_cli.edit_strategy';
|
||||||
export class SmartEditStrategyEvent implements BaseTelemetryEvent {
|
export class EditStrategyEvent implements BaseTelemetryEvent {
|
||||||
'event.name': 'smart_edit_strategy';
|
'event.name': 'edit_strategy';
|
||||||
'event.timestamp': string;
|
'event.timestamp': string;
|
||||||
strategy: string;
|
strategy: string;
|
||||||
|
|
||||||
constructor(strategy: string) {
|
constructor(strategy: string) {
|
||||||
this['event.name'] = 'smart_edit_strategy';
|
this['event.name'] = 'edit_strategy';
|
||||||
this['event.timestamp'] = new Date().toISOString();
|
this['event.timestamp'] = new Date().toISOString();
|
||||||
this.strategy = strategy;
|
this.strategy = strategy;
|
||||||
}
|
}
|
||||||
@@ -1603,25 +1605,25 @@ export class SmartEditStrategyEvent implements BaseTelemetryEvent {
|
|||||||
toOpenTelemetryAttributes(config: Config): LogAttributes {
|
toOpenTelemetryAttributes(config: Config): LogAttributes {
|
||||||
return {
|
return {
|
||||||
...getCommonAttributes(config),
|
...getCommonAttributes(config),
|
||||||
'event.name': EVENT_SMART_EDIT_STRATEGY,
|
'event.name': EVENT_EDIT_STRATEGY,
|
||||||
'event.timestamp': this['event.timestamp'],
|
'event.timestamp': this['event.timestamp'],
|
||||||
strategy: this.strategy,
|
strategy: this.strategy,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
toLogBody(): string {
|
toLogBody(): string {
|
||||||
return `Smart Edit Tool Strategy: ${this.strategy}`;
|
return `Edit Tool Strategy: ${this.strategy}`;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export const EVENT_SMART_EDIT_CORRECTION = 'gemini_cli.smart_edit_correction';
|
export const EVENT_EDIT_CORRECTION = 'gemini_cli.edit_correction';
|
||||||
export class SmartEditCorrectionEvent implements BaseTelemetryEvent {
|
export class EditCorrectionEvent implements BaseTelemetryEvent {
|
||||||
'event.name': 'smart_edit_correction';
|
'event.name': 'edit_correction';
|
||||||
'event.timestamp': string;
|
'event.timestamp': string;
|
||||||
correction: 'success' | 'failure';
|
correction: 'success' | 'failure';
|
||||||
|
|
||||||
constructor(correction: 'success' | 'failure') {
|
constructor(correction: 'success' | 'failure') {
|
||||||
this['event.name'] = 'smart_edit_correction';
|
this['event.name'] = 'edit_correction';
|
||||||
this['event.timestamp'] = new Date().toISOString();
|
this['event.timestamp'] = new Date().toISOString();
|
||||||
this.correction = correction;
|
this.correction = correction;
|
||||||
}
|
}
|
||||||
@@ -1629,14 +1631,14 @@ export class SmartEditCorrectionEvent implements BaseTelemetryEvent {
|
|||||||
toOpenTelemetryAttributes(config: Config): LogAttributes {
|
toOpenTelemetryAttributes(config: Config): LogAttributes {
|
||||||
return {
|
return {
|
||||||
...getCommonAttributes(config),
|
...getCommonAttributes(config),
|
||||||
'event.name': EVENT_SMART_EDIT_CORRECTION,
|
'event.name': EVENT_EDIT_CORRECTION,
|
||||||
'event.timestamp': this['event.timestamp'],
|
'event.timestamp': this['event.timestamp'],
|
||||||
correction: this.correction,
|
correction: this.correction,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
toLogBody(): string {
|
toLogBody(): string {
|
||||||
return `Smart Edit Tool Correction: ${this.correction}`;
|
return `Edit Tool Correction: ${this.correction}`;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
/* eslint-disable @typescript-eslint/no-explicit-any */
|
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||||
|
|
||||||
import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
|
import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
|
||||||
import { SmartEditTool } from './smart-edit.js';
|
import { EditTool } from './edit.js';
|
||||||
import { WriteFileTool } from './write-file.js';
|
import { WriteFileTool } from './write-file.js';
|
||||||
import { WebFetchTool } from './web-fetch.js';
|
import { WebFetchTool } from './web-fetch.js';
|
||||||
import { ToolConfirmationOutcome } from './tools.js';
|
import { ToolConfirmationOutcome } from './tools.js';
|
||||||
@@ -21,8 +21,8 @@ import os from 'node:os';
|
|||||||
|
|
||||||
// Mock telemetry loggers to avoid failures
|
// Mock telemetry loggers to avoid failures
|
||||||
vi.mock('../telemetry/loggers.js', () => ({
|
vi.mock('../telemetry/loggers.js', () => ({
|
||||||
logSmartEditStrategy: vi.fn(),
|
logEditStrategy: vi.fn(),
|
||||||
logSmartEditCorrectionEvent: vi.fn(),
|
logEditCorrectionEvent: vi.fn(),
|
||||||
logFileOperation: vi.fn(),
|
logFileOperation: vi.fn(),
|
||||||
}));
|
}));
|
||||||
|
|
||||||
@@ -81,9 +81,8 @@ describe('Tool Confirmation Policy Updates', () => {
|
|||||||
|
|
||||||
const tools = [
|
const tools = [
|
||||||
{
|
{
|
||||||
name: 'SmartEditTool',
|
name: 'EditTool',
|
||||||
create: (config: Config, bus: MessageBus) =>
|
create: (config: Config, bus: MessageBus) => new EditTool(config, bus),
|
||||||
new SmartEditTool(config, bus),
|
|
||||||
params: {
|
params: {
|
||||||
file_path: 'test.txt',
|
file_path: 'test.txt',
|
||||||
instruction: 'change content',
|
instruction: 'change content',
|
||||||
|
|||||||
@@ -43,11 +43,11 @@ import {
|
|||||||
type Mock,
|
type Mock,
|
||||||
} from 'vitest';
|
} from 'vitest';
|
||||||
import {
|
import {
|
||||||
SmartEditTool,
|
EditTool,
|
||||||
type EditToolParams,
|
type EditToolParams,
|
||||||
applyReplacement,
|
applyReplacement,
|
||||||
calculateReplacement,
|
calculateReplacement,
|
||||||
} from './smart-edit.js';
|
} from './edit.js';
|
||||||
import { type FileDiff, ToolConfirmationOutcome } from './tools.js';
|
import { type FileDiff, ToolConfirmationOutcome } from './tools.js';
|
||||||
import { ToolErrorType } from './tool-error.js';
|
import { ToolErrorType } from './tool-error.js';
|
||||||
import {
|
import {
|
||||||
@@ -64,8 +64,8 @@ import { createMockWorkspaceContext } from '../test-utils/mockWorkspaceContext.j
|
|||||||
import { StandardFileSystemService } from '../services/fileSystemService.js';
|
import { StandardFileSystemService } from '../services/fileSystemService.js';
|
||||||
import type { BaseLlmClient } from '../core/baseLlmClient.js';
|
import type { BaseLlmClient } from '../core/baseLlmClient.js';
|
||||||
|
|
||||||
describe('SmartEditTool', () => {
|
describe('EditTool', () => {
|
||||||
let tool: SmartEditTool;
|
let tool: EditTool;
|
||||||
let tempDir: string;
|
let tempDir: string;
|
||||||
let rootDir: string;
|
let rootDir: string;
|
||||||
let mockConfig: Config;
|
let mockConfig: Config;
|
||||||
@@ -75,7 +75,7 @@ describe('SmartEditTool', () => {
|
|||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
vi.restoreAllMocks();
|
vi.restoreAllMocks();
|
||||||
tempDir = fs.mkdtempSync(path.join(os.tmpdir(), 'smart-edit-tool-test-'));
|
tempDir = fs.mkdtempSync(path.join(os.tmpdir(), 'edit-tool-test-'));
|
||||||
rootDir = path.join(tempDir, 'root');
|
rootDir = path.join(tempDir, 'root');
|
||||||
fs.mkdirSync(rootDir);
|
fs.mkdirSync(rootDir);
|
||||||
|
|
||||||
@@ -172,7 +172,7 @@ describe('SmartEditTool', () => {
|
|||||||
|
|
||||||
const bus = createMockMessageBus();
|
const bus = createMockMessageBus();
|
||||||
getMockMessageBusInstance(bus).defaultToolDecision = 'ask_user';
|
getMockMessageBusInstance(bus).defaultToolDecision = 'ask_user';
|
||||||
tool = new SmartEditTool(mockConfig, bus);
|
tool = new EditTool(mockConfig, bus);
|
||||||
});
|
});
|
||||||
|
|
||||||
afterEach(() => {
|
afterEach(() => {
|
||||||
@@ -393,9 +393,7 @@ describe('SmartEditTool', () => {
|
|||||||
|
|
||||||
const invocation = tool.build(params);
|
const invocation = tool.build(params);
|
||||||
const abortController = new AbortController();
|
const abortController = new AbortController();
|
||||||
const abortError = new Error(
|
const abortError = new Error('Abort requested during edit execution');
|
||||||
'Abort requested during smart edit execution',
|
|
||||||
);
|
|
||||||
|
|
||||||
const calculateSpy = vi
|
const calculateSpy = vi
|
||||||
.spyOn(invocation as any, 'calculateEdit')
|
.spyOn(invocation as any, 'calculateEdit')
|
||||||
@@ -755,9 +753,7 @@ describe('SmartEditTool', () => {
|
|||||||
|
|
||||||
const invocation = tool.build(params);
|
const invocation = tool.build(params);
|
||||||
const abortController = new AbortController();
|
const abortController = new AbortController();
|
||||||
const abortError = new Error(
|
const abortError = new Error('Abort requested during edit confirmation');
|
||||||
'Abort requested during smart edit confirmation',
|
|
||||||
);
|
|
||||||
|
|
||||||
const calculateSpy = vi
|
const calculateSpy = vi
|
||||||
.spyOn(invocation as any, 'calculateEdit')
|
.spyOn(invocation as any, 'calculateEdit')
|
||||||
@@ -35,10 +35,10 @@ import {
|
|||||||
import { IdeClient } from '../ide/ide-client.js';
|
import { IdeClient } from '../ide/ide-client.js';
|
||||||
import { FixLLMEditWithInstruction } from '../utils/llm-edit-fixer.js';
|
import { FixLLMEditWithInstruction } from '../utils/llm-edit-fixer.js';
|
||||||
import { safeLiteralReplace } from '../utils/textUtils.js';
|
import { safeLiteralReplace } from '../utils/textUtils.js';
|
||||||
import { SmartEditStrategyEvent } from '../telemetry/types.js';
|
import { EditStrategyEvent } from '../telemetry/types.js';
|
||||||
import { logSmartEditStrategy } from '../telemetry/loggers.js';
|
import { logEditStrategy } from '../telemetry/loggers.js';
|
||||||
import { SmartEditCorrectionEvent } from '../telemetry/types.js';
|
import { EditCorrectionEvent } from '../telemetry/types.js';
|
||||||
import { logSmartEditCorrectionEvent } from '../telemetry/loggers.js';
|
import { logEditCorrectionEvent } from '../telemetry/loggers.js';
|
||||||
|
|
||||||
import { correctPath } from '../utils/pathCorrector.js';
|
import { correctPath } from '../utils/pathCorrector.js';
|
||||||
import { EDIT_TOOL_NAME, READ_FILE_TOOL_NAME } from './tool-names.js';
|
import { EDIT_TOOL_NAME, READ_FILE_TOOL_NAME } from './tool-names.js';
|
||||||
@@ -289,22 +289,22 @@ export async function calculateReplacement(
|
|||||||
|
|
||||||
const exactResult = await calculateExactReplacement(context);
|
const exactResult = await calculateExactReplacement(context);
|
||||||
if (exactResult) {
|
if (exactResult) {
|
||||||
const event = new SmartEditStrategyEvent('exact');
|
const event = new EditStrategyEvent('exact');
|
||||||
logSmartEditStrategy(config, event);
|
logEditStrategy(config, event);
|
||||||
return exactResult;
|
return exactResult;
|
||||||
}
|
}
|
||||||
|
|
||||||
const flexibleResult = await calculateFlexibleReplacement(context);
|
const flexibleResult = await calculateFlexibleReplacement(context);
|
||||||
if (flexibleResult) {
|
if (flexibleResult) {
|
||||||
const event = new SmartEditStrategyEvent('flexible');
|
const event = new EditStrategyEvent('flexible');
|
||||||
logSmartEditStrategy(config, event);
|
logEditStrategy(config, event);
|
||||||
return flexibleResult;
|
return flexibleResult;
|
||||||
}
|
}
|
||||||
|
|
||||||
const regexResult = await calculateRegexReplacement(context);
|
const regexResult = await calculateRegexReplacement(context);
|
||||||
if (regexResult) {
|
if (regexResult) {
|
||||||
const event = new SmartEditStrategyEvent('regex');
|
const event = new EditStrategyEvent('regex');
|
||||||
logSmartEditStrategy(config, event);
|
logEditStrategy(config, event);
|
||||||
return regexResult;
|
return regexResult;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -500,8 +500,8 @@ class EditToolInvocation
|
|||||||
|
|
||||||
if (secondError) {
|
if (secondError) {
|
||||||
// The fix failed, log failure and return the original error
|
// The fix failed, log failure and return the original error
|
||||||
const event = new SmartEditCorrectionEvent('failure');
|
const event = new EditCorrectionEvent('failure');
|
||||||
logSmartEditCorrectionEvent(this.config, event);
|
logEditCorrectionEvent(this.config, event);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
currentContent: contentForLlmEditFixer,
|
currentContent: contentForLlmEditFixer,
|
||||||
@@ -513,8 +513,8 @@ class EditToolInvocation
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
const event = new SmartEditCorrectionEvent('success');
|
const event = new EditCorrectionEvent('success');
|
||||||
logSmartEditCorrectionEvent(this.config, event);
|
logEditCorrectionEvent(this.config, event);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
currentContent: contentForLlmEditFixer,
|
currentContent: contentForLlmEditFixer,
|
||||||
@@ -703,7 +703,7 @@ class EditToolInvocation
|
|||||||
onConfirm: async (outcome: ToolConfirmationOutcome) => {
|
onConfirm: async (outcome: ToolConfirmationOutcome) => {
|
||||||
if (outcome === ToolConfirmationOutcome.ProceedAlways) {
|
if (outcome === ToolConfirmationOutcome.ProceedAlways) {
|
||||||
// No need to publish a policy update as the default policy for
|
// No need to publish a policy update as the default policy for
|
||||||
// AUTO_EDIT already reflects always approving smart-edit.
|
// AUTO_EDIT already reflects always approving edit.
|
||||||
this.config.setApprovalMode(ApprovalMode.AUTO_EDIT);
|
this.config.setApprovalMode(ApprovalMode.AUTO_EDIT);
|
||||||
} else {
|
} else {
|
||||||
await this.publishPolicyUpdate(outcome);
|
await this.publishPolicyUpdate(outcome);
|
||||||
@@ -866,7 +866,7 @@ class EditToolInvocation
|
|||||||
/**
|
/**
|
||||||
* Implementation of the Edit tool logic
|
* Implementation of the Edit tool logic
|
||||||
*/
|
*/
|
||||||
export class SmartEditTool
|
export class EditTool
|
||||||
extends BaseDeclarativeTool<EditToolParams, ToolResult>
|
extends BaseDeclarativeTool<EditToolParams, ToolResult>
|
||||||
implements ModifiableDeclarativeTool<EditToolParams>
|
implements ModifiableDeclarativeTool<EditToolParams>
|
||||||
{
|
{
|
||||||
@@ -877,7 +877,7 @@ export class SmartEditTool
|
|||||||
messageBus: MessageBus,
|
messageBus: MessageBus,
|
||||||
) {
|
) {
|
||||||
super(
|
super(
|
||||||
SmartEditTool.Name,
|
EditTool.Name,
|
||||||
'Edit',
|
'Edit',
|
||||||
`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.
|
`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.
|
||||||
|
|
||||||
@@ -23,7 +23,7 @@ import type {
|
|||||||
ToolResult,
|
ToolResult,
|
||||||
} from './tools.js';
|
} from './tools.js';
|
||||||
import { ToolConfirmationOutcome } from './tools.js';
|
import { ToolConfirmationOutcome } from './tools.js';
|
||||||
import { type EditToolParams } from './smart-edit.js';
|
import { type EditToolParams } from './edit.js';
|
||||||
import type { Config } from '../config/config.js';
|
import type { Config } from '../config/config.js';
|
||||||
import { ApprovalMode } from '../policy/types.js';
|
import { ApprovalMode } from '../policy/types.js';
|
||||||
import type { ToolRegistry } from './tool-registry.js';
|
import type { ToolRegistry } from './tool-registry.js';
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
import type { Content } from '@google/genai';
|
import type { Content } from '@google/genai';
|
||||||
import type { GeminiClient } from '../core/client.js';
|
import type { GeminiClient } from '../core/client.js';
|
||||||
import type { BaseLlmClient } from '../core/baseLlmClient.js';
|
import type { BaseLlmClient } from '../core/baseLlmClient.js';
|
||||||
import type { EditToolParams } from '../tools/smart-edit.js';
|
import type { EditToolParams } from '../tools/edit.js';
|
||||||
import {
|
import {
|
||||||
EDIT_TOOL_NAME,
|
EDIT_TOOL_NAME,
|
||||||
GREP_TOOL_NAME,
|
GREP_TOOL_NAME,
|
||||||
|
|||||||
Reference in New Issue
Block a user