Skip to content

Commit e0812d9

Browse files
authored
Adopt isSubAgent tool call hint (#1173)
See microsoft/vscode#266588
1 parent b94ca92 commit e0812d9

File tree

14 files changed

+53
-16
lines changed

14 files changed

+53
-16
lines changed

src/extension/inlineChat/vscode-node/inlineChatCommands.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -383,7 +383,8 @@ function fetchSuggestion(accessor: ServicesAccessor, thread: vscode.CommentThrea
383383
toolInvocationToken: undefined as never,
384384
model: null!,
385385
tools: new Map(),
386-
id: '1'
386+
id: '1',
387+
sessionId: '1',
387388
};
388389
let markdown = '';
389390
const edits: ReviewSuggestionChange[] = [];

src/extension/mcp/vscode-node/commands.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -257,7 +257,8 @@ Error: ${error}`);
257257
toolInvocationToken: generateUuid() as never,
258258
toolReferences: [],
259259
tools: new Map(),
260-
id: '1'
260+
id: '1',
261+
sessionId: ''
261262
},
262263
props: {
263264
targetSchema: validateArgs.targetConfig,

src/extension/prompt/common/intents.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ export interface IBuildPromptContext {
5656
readonly toolReferences: readonly InternalToolReference[];
5757
readonly toolInvocationToken: vscode.ChatParticipantToolToken;
5858
readonly availableTools: readonly vscode.LanguageModelToolInformation[];
59+
readonly inSubAgent?: boolean;
5960
};
6061
readonly modeInstructions?: vscode.ChatRequestModeInstructions;
6162

src/extension/prompt/node/executePromptToolCalling.ts

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
*--------------------------------------------------------------------------------------------*/
55

66
import { randomUUID } from 'crypto';
7-
import type { CancellationToken, ChatRequest, LanguageModelToolInformation, Progress } from 'vscode';
7+
import type { CancellationToken, ChatRequest, ChatResponseStream, LanguageModelToolInformation, Progress } from 'vscode';
88
import { IAuthenticationChatUpgradeService } from '../../../platform/authentication/common/authenticationUpgrade';
99
import { ChatLocation, ChatResponse } from '../../../platform/chat/common/commonTypes';
1010
import { IEndpointProvider } from '../../../platform/endpoint/common/endpointProvider';
@@ -43,6 +43,17 @@ export class ExecutePromptToolCallingLoop extends ToolCallingLoop<IExecutePrompt
4343
super(options, instantiationService, endpointProvider, logService, requestLogger, authenticationChatUpgradeService, telemetryService);
4444
}
4545

46+
protected override createPromptContext(availableTools: LanguageModelToolInformation[], outputStream: ChatResponseStream | undefined) {
47+
const context = super.createPromptContext(availableTools, outputStream);
48+
if (context.tools) {
49+
context.tools = {
50+
...context.tools,
51+
inSubAgent: true
52+
};
53+
}
54+
return context;
55+
}
56+
4657
private async getEndpoint(request: ChatRequest) {
4758
let endpoint = await this.endpointProvider.getChatEndpoint(this.options.request);
4859
if (!endpoint.supportsToolCalls) {

src/extension/prompt/node/test/defaultIntentRequestHandler.spec.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,7 @@ suite('defaultIntentRequestHandler', () => {
127127
model: LanguageModelChat = { family: '' } as any;
128128
tools = new Map();
129129
id = generateUuid();
130+
sessionId = generateUuid();
130131
}
131132

132133
const responseStream = new ChatResponseStreamImpl(p => response.push(p), () => { });

src/extension/prompts/node/panel/toolCalling.tsx

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55

66
import { RequestMetadata, RequestType } from '@vscode/copilot-api';
77
import { AssistantMessage, BasePromptElementProps, PromptRenderer as BasePromptRenderer, Chunk, IfEmpty, Image, JSONTree, PromptElement, PromptElementProps, PromptMetadata, PromptPiece, PromptSizing, TokenLimit, ToolCall, ToolMessage, useKeepWith, UserMessage } from '@vscode/prompt-tsx';
8-
import type { ChatParticipantToolToken, LanguageModelToolResult2, LanguageModelToolTokenizationOptions } from 'vscode';
8+
import type { ChatParticipantToolToken, LanguageModelToolInvocationOptions, LanguageModelToolResult2, LanguageModelToolTokenizationOptions } from 'vscode';
99
import { IAuthenticationService } from '../../../../platform/authentication/common/authentication';
1010
import { ConfigKey, IConfigurationService } from '../../../../platform/configuration/common/configurationService';
1111
import { modelCanUseMcpResultImageURL } from '../../../../platform/endpoint/common/chatModelCapabilities';
@@ -213,7 +213,17 @@ class ToolResultElement extends PromptElement<ToolResultElementProps, void> {
213213
inputObj = await copilotTool.resolveInput(inputObj, this.props.promptContext, this.props.toolCallMode);
214214
}
215215

216-
toolResult = await this.toolsService.invokeTool(this.props.toolCall.name, { input: inputObj, toolInvocationToken: this.props.toolInvocationToken, tokenizationOptions, chatRequestId: this.props.requestId }, CancellationToken.None);
216+
const invocationOptions: LanguageModelToolInvocationOptions<unknown> = {
217+
input: inputObj,
218+
toolInvocationToken: this.props.toolInvocationToken,
219+
tokenizationOptions,
220+
chatRequestId: this.props.requestId
221+
};
222+
if (this.props.promptContext.tools?.inSubAgent) {
223+
invocationOptions.fromSubAgent = true;
224+
}
225+
226+
toolResult = await this.toolsService.invokeTool(this.props.toolCall.name, invocationOptions, CancellationToken.None);
217227
sendInvokedToolTelemetry(this.promptEndpoint.acquireTokenizer(), this.telemetryService, this.props.toolCall.name, toolResult);
218228
} catch (err) {
219229
const errResult = toolCallErrorToResult(err);

src/extension/test/node/testHelpers.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ export class TestChatRequest implements ChatRequest {
2323
public model = null!;
2424
public tools = new Map();
2525
public id = generateUuid();
26+
public sessionId = generateUuid();
2627

2728
constructor(
2829
public prompt: string

src/extension/tools/node/executeTaskTool.ts

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,14 @@
44
*--------------------------------------------------------------------------------------------*/
55

66
import type * as vscode from 'vscode';
7+
import { ChatResponseStreamImpl } from '../../../util/common/chatResponseStreamImpl';
78
import { IInstantiationService } from '../../../util/vs/platform/instantiation/common/instantiation';
8-
import { ChatResponseMarkdownPart, ExtendedLanguageModelToolResult, LanguageModelTextPart } from '../../../vscodeTypes';
9+
import { ChatPrepareToolInvocationPart, ExtendedLanguageModelToolResult, LanguageModelTextPart } from '../../../vscodeTypes';
910
import { Conversation, Turn } from '../../prompt/common/conversation';
1011
import { IBuildPromptContext } from '../../prompt/common/intents';
1112
import { ExecutePromptToolCallingLoop } from '../../prompt/node/executePromptToolCalling';
1213
import { ToolName } from '../common/toolNames';
1314
import { CopilotToolMode, ICopilotTool, ToolRegistry } from '../common/toolsRegistry';
14-
import { ChatResponseStreamImpl } from '../../../util/common/chatResponseStreamImpl';
1515

1616
export interface IExecuteTaskParams {
1717
prompt: string;
@@ -36,11 +36,10 @@ class ExecuteTaskTool implements ICopilotTool<IExecuteTaskParams> {
3636
promptText: options.input.prompt,
3737
});
3838

39-
// TODO This also prevents codeblock pills from being rendered
40-
// I want to render this content as thinking blocks but couldn't get it to work
39+
// I want to render this content as thinking blocks when we they include tool calls
4140
const stream = this._inputContext?.stream && ChatResponseStreamImpl.filter(
4241
this._inputContext.stream,
43-
part => !(part instanceof ChatResponseMarkdownPart)
42+
part => part instanceof ChatPrepareToolInvocationPart
4443
);
4544

4645
const loopResult = await loop.run(stream, token);

src/extension/vscode.proposed.chatParticipantAdditions.d.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,7 @@ declare module 'vscode' {
103103
isConfirmed?: boolean;
104104
isComplete?: boolean;
105105
toolSpecificData?: ChatTerminalToolInvocationData;
106+
fromSubAgent?: boolean;
106107

107108
constructor(toolName: string, toolCallId: string, isError?: boolean);
108109
}

src/extension/vscode.proposed.chatParticipantPrivate.d.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,11 @@ declare module 'vscode' {
5555
*/
5656
readonly attempt: number;
5757

58+
/**
59+
* The session identifier for this chat request
60+
*/
61+
readonly sessionId: string;
62+
5863
/**
5964
* If automatic command detection is enabled.
6065
*/
@@ -216,6 +221,7 @@ declare module 'vscode' {
216221
chatSessionId?: string;
217222
chatInteractionId?: string;
218223
terminalCommand?: string;
224+
fromSubAgent?: boolean;
219225
}
220226

221227
export interface LanguageModelToolInvocationPrepareOptions<T> {

0 commit comments

Comments
 (0)