Support rendering subagent details from external agents#293705
Support rendering subagent details from external agents#293705roblourens merged 2 commits intomainfrom
Conversation
There was a problem hiding this comment.
Pull request overview
This PR extends VS Code’s chat tool invocation rendering to support subagent grouping/details when the subagent is spawned by external agents/tools (not only the built-in runSubagent tool), and exposes a proposed API type to carry subagent metadata.
Changes:
- Add proposed API
ChatSubagentToolInvocationDataand bump thechatParticipantAdditionsproposal version to 3. - Plumb a subagent invocation id through external tool invocation updates and into the chat model’s tool invocation objects.
- Update chat UI grouping logic to detect “parent subagent tools” via
toolSpecificData.kind === 'subagent'instead of hard-codingRunSubagentTool.Id.
Reviewed changes
Copilot reviewed 9 out of 10 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| src/vscode-dts/vscode.proposed.chatParticipantAdditions.d.ts | Adds ChatSubagentToolInvocationData to the proposed API and extends toolSpecificData union; bumps proposal version. |
| src/vs/workbench/contrib/chat/common/model/chatModel.ts | Passes through subagentInvocationId when creating external tool invocations. |
| src/vs/workbench/contrib/chat/common/chatService/chatService.ts | Extends IChatExternalToolInvocationUpdate with a subagent invocation id field. |
| src/vs/workbench/contrib/chat/browser/widget/chatListRenderer.ts | Switches subagent grouping logic to rely on toolSpecificData.kind === 'subagent' and adds helper functions for determining subagent grouping id. |
| src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatSubagentContentPart.ts | Updates subagent info extraction/completion watching to apply to “parent subagent tools” identified by toolSpecificData rather than tool id. |
| src/vs/workbench/api/common/extHostTypes.ts | Adds the ext host runtime class ChatSubagentToolInvocationData. |
| src/vs/workbench/api/common/extHostTypeConverters.ts | Converts ChatSubagentToolInvocationData into internal kind:'subagent' tool data and wires subagentInvocationId for external tool invocation updates. |
| src/vs/workbench/api/common/extHost.protocol.ts | Removes now-unneeded IChatExternalToolInvocationUpdateDto from the progress DTO union. |
| src/vs/platform/extensions/common/extensionsApiProposals.ts | Updates the chatParticipantAdditions proposal version to 3. |
Comments suppressed due to low confidence (1)
src/vs/workbench/api/common/extHostTypeConverters.ts:3040
convertToolSpecificDataonly recognizes subagent tool data viadata instanceof types.ChatSubagentToolInvocationData. Because TypeScript is structural, extensions can (and often do) pass plain object literals that satisfy the shape, which will fail thisinstanceofcheck and skip conversion to{ kind: 'subagent', ... }. That will prevent subagent grouping/rendering logic (which keys offtoolSpecificData.kind === 'subagent') from working for external agents. Please switch to a shape-based guard (similar to the MCP/todo/resources cases) or otherwise ensure subagent data is reliably tagged askind: 'subagent'regardless of how the extension constructs it.
} else if (data instanceof types.ChatSubagentToolInvocationData) {
// Convert extension API subagent tool data to internal format
return {
kind: 'subagent',
description: data.description,
agentName: data.agentName,
prompt: data.prompt,
result: data.result,
};
}
| if (part.enablePartialUpdate) { | ||
| return { | ||
| kind: 'externalToolInvocationUpdate', | ||
| toolCallId: part.toolCallId, | ||
| toolName: part.toolName, | ||
| isComplete: !!part.isComplete, | ||
| invocationMessage: part.invocationMessage ? MarkdownString.from(part.invocationMessage) : undefined, | ||
| pastTenseMessage: part.pastTenseMessage ? MarkdownString.from(part.pastTenseMessage) : undefined, | ||
| toolSpecificData, | ||
| subagentInvocationId: part.subAgentInvocationId, | ||
| }; |
There was a problem hiding this comment.
There are currently no unit tests covering ChatToolInvocationPart.from conversion, and this change adds new behavior (subagent toolSpecificData conversion + wiring subagentInvocationId for external tool updates). Please add a focused test in src/vs/workbench/api/test/... to verify: (1) subagent toolSpecificData is converted to { kind: 'subagent', ... } and (2) subAgentInvocationId is propagated into the externalToolInvocationUpdate payload.
This issue also appears on line 3031 of the same file.
| toolSpecificData?: IChatTerminalToolInvocationData | IChatToolInputInvocationData | IChatExtensionsContent | IChatTodoListContent | IChatSubagentToolInvocationData; | ||
| subagentInvocationId?: string; | ||
| } |
There was a problem hiding this comment.
The new property is named subagentInvocationId, but the rest of the tool-invocation surface uses subAgentInvocationId (e.g. IChatToolInvocation.subAgentInvocationId, IChatToolInvocationSerialized.subAgentInvocationId, and the extension API ChatToolInvocationPart.subAgentInvocationId). Consider renaming this to subAgentInvocationId for consistency and to avoid wiring mistakes across the internal/external types.
No description provided.