Skip to content

Commit 633f2aa

Browse files
authored
Update runInTerminalTool to avoid using state when recommending other tools (microsoft#259460)
1 parent bcf2f5b commit 633f2aa

File tree

3 files changed

+20
-23
lines changed

3 files changed

+20
-23
lines changed

src/vs/workbench/contrib/chat/common/chatService.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -277,6 +277,8 @@ export interface IChatTerminalToolInvocationData {
277277
userEdited?: string;
278278
toolEdited?: string;
279279
};
280+
/** Message for model recommending the use of an alternative tool */
281+
alternativeRecommendation?: string;
280282
language: string;
281283
}
282284

src/vs/workbench/contrib/terminalContrib/chatAgentTools/browser/alternativeRecommendation.ts

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
* Licensed under the MIT License. See License.txt in the project root for license information.
44
*--------------------------------------------------------------------------------------------*/
55

6-
import type { ILanguageModelToolsService, IToolResult } from '../../../chat/common/languageModelToolsService.js';
6+
import type { ILanguageModelToolsService } from '../../../chat/common/languageModelToolsService.js';
77

88
let previouslyRecommededInSession = false;
99

@@ -26,7 +26,7 @@ const terminalCommands: { commands: RegExp[]; tags: string[] }[] = [
2626
}
2727
];
2828

29-
export function getRecommendedToolsOverRunInTerminal(commandLine: string, languageModelToolsService: ILanguageModelToolsService): IToolResult | undefined {
29+
export function getRecommendedToolsOverRunInTerminal(commandLine: string, languageModelToolsService: ILanguageModelToolsService): string | undefined {
3030
const tools = languageModelToolsService.getTools();
3131
if (!tools || previouslyRecommededInSession) {
3232
return;
@@ -55,12 +55,7 @@ export function getRecommendedToolsOverRunInTerminal(commandLine: string, langua
5555

5656
if (recommendedTools.size) {
5757
previouslyRecommededInSession = true;
58-
return {
59-
content: [{
60-
kind: 'text',
61-
value: messages.join(' \n')
62-
}],
63-
};
58+
return messages.join(' \n');
6459
}
6560

6661
return undefined;

src/vs/workbench/contrib/terminalContrib/chatAgentTools/browser/runInTerminalTool.ts

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -126,10 +126,6 @@ export class RunInTerminalTool extends Disposable implements IToolImpl {
126126
// Immutable window state
127127
protected readonly _osBackend: Promise<OperatingSystem>;
128128

129-
// HACK: Per-tool call state, saved globally
130-
// TODO: These should not be part of the state as different sessions could get confused https://github.com/microsoft/vscode/issues/255889
131-
private _alternativeRecommendation?: IToolResult;
132-
133129
private static readonly _backgroundExecutions = new Map<string, BackgroundTerminalExecution>();
134130
public static getBackgroundOutput(id: string): string {
135131
const backgroundExecution = RunInTerminalTool._backgroundExecutions.get(id);
@@ -176,8 +172,8 @@ export class RunInTerminalTool extends Disposable implements IToolImpl {
176172
async prepareToolInvocation(context: IToolInvocationPreparationContext, token: CancellationToken): Promise<IPreparedToolInvocation | undefined> {
177173
const args = context.parameters as IRunInTerminalInputParams;
178174

179-
this._alternativeRecommendation = getRecommendedToolsOverRunInTerminal(args.command, this._languageModelToolsService);
180-
const presentation = this._alternativeRecommendation ? 'hidden' : undefined;
175+
const alternativeRecommendation = getRecommendedToolsOverRunInTerminal(args.command, this._languageModelToolsService);
176+
const presentation = alternativeRecommendation ? 'hidden' : undefined;
181177

182178
const os = await this._osBackend;
183179
const shell = await this._terminalProfileResolverService.getDefaultShell({
@@ -193,7 +189,7 @@ export class RunInTerminalTool extends Disposable implements IToolImpl {
193189
}
194190

195191
let confirmationMessages: IToolConfirmationMessages | undefined;
196-
if (this._alternativeRecommendation) {
192+
if (alternativeRecommendation) {
197193
confirmationMessages = undefined;
198194
} else {
199195
const actualCommand = toolEditedCommand ?? args.command;
@@ -250,23 +246,27 @@ export class RunInTerminalTool extends Disposable implements IToolImpl {
250246
toolEdited: toolEditedCommand
251247
},
252248
language,
249+
alternativeRecommendation,
253250
}
254251
};
255252
}
256253

257254
async invoke(invocation: IToolInvocation, _countTokens: CountTokensCallback, _progress: ToolProgress, token: CancellationToken): Promise<IToolResult> {
258-
if (this._alternativeRecommendation) {
259-
return this._alternativeRecommendation;
260-
}
261-
262-
const args = invocation.parameters as IRunInTerminalInputParams;
263-
264-
this._logService.debug(`RunInTerminalTool: Invoking with options ${JSON.stringify(args)}`);
265-
266255
const toolSpecificData = invocation.toolSpecificData as IChatTerminalToolInvocationData | undefined;
267256
if (!toolSpecificData) {
268257
throw new Error('toolSpecificData must be provided for this tool');
269258
}
259+
if (toolSpecificData.alternativeRecommendation) {
260+
return {
261+
content: [{
262+
kind: 'text',
263+
value: toolSpecificData.alternativeRecommendation
264+
}]
265+
};
266+
}
267+
268+
const args = invocation.parameters as IRunInTerminalInputParams;
269+
this._logService.debug(`RunInTerminalTool: Invoking with options ${JSON.stringify(args)}`);
270270
let toolResultMessage: string | IMarkdownString | undefined;
271271

272272
const chatSessionId = invocation.context?.sessionId ?? 'no-chat-session';

0 commit comments

Comments
 (0)