Conversation
Contributor
There was a problem hiding this comment.
Pull request overview
This PR adds support for tracking external tool invocations from extensions in the chat system. It enables extensions to create live, in-progress tool invocations that can be updated and completed asynchronously, providing better visibility into tool execution status.
Changes:
- Introduced
createExternalfactory method and update/complete methods for external tool invocations - Added new DTO type
IChatExternalToolInvocationUpdateDtofor streaming external tool invocation updates - Implemented handling logic in
mainThreadChatAgents2to track and update external tool invocations
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 4 comments.
| File | Description |
|---|---|
| src/vs/workbench/contrib/chat/common/model/chatProgressTypes/chatToolInvocation.ts | Adds factory method, interface, and update/complete methods for external tool invocations |
| src/vs/workbench/api/common/extHostTypeConverters.ts | Converts ChatToolInvocationPart to either legacy serialized format or new update DTO based on isComplete field |
| src/vs/workbench/api/common/extHost.protocol.ts | Defines IChatExternalToolInvocationUpdateDto for external tool invocation updates |
| src/vs/workbench/api/browser/mainThreadChatAgents2.ts | Implements tracking map and handler for external tool invocation lifecycle |
Comments suppressed due to low confidence (3)
src/vs/workbench/api/browser/mainThreadChatAgents2.ts:409
- When creating an external tool invocation that is already completed (isComplete: true on first push), it's added to the pending map and then immediately removed. This is inefficient - the invocation should only be added to
_pendingExternalToolInvocationsif it's not complete (isComplete: false).
if (progress.isComplete) {
// Already completed on first push
invocation.completeExternalInvocation({
pastTenseMessage: progress.pastTenseMessage,
isError: progress.isError,
});
} else {
// Track for future updates
this._pendingExternalToolInvocations.set(progress.toolCallId, invocation);
}
src/vs/workbench/api/browser/mainThreadChatAgents2.ts:388
- The check for
existingInvocationand the early return on line 388 means that if an extension sends an update withisComplete: falseafter the invocation already exists, nothing is returned and no progress is added. However, if an invocation is created as complete on first push (line 400-405), it won't be in the pending map for any subsequent updates. This creates an inconsistent state where updating an already-completed invocation is silently ignored.
private _handleExternalToolInvocationUpdate(progress: IChatExternalToolInvocationUpdateDto): ChatToolInvocation | undefined {
const existingInvocation = this._pendingExternalToolInvocations.get(progress.toolCallId);
if (existingInvocation) {
if (progress.isComplete) {
existingInvocation.completeExternalInvocation({
pastTenseMessage: progress.pastTenseMessage,
isError: progress.isError,
});
this._pendingExternalToolInvocations.delete(progress.toolCallId);
} else {
existingInvocation.updateExternalInvocation({
invocationMessage: progress.invocationMessage,
pastTenseMessage: progress.pastTenseMessage,
});
}
return undefined;
src/vs/workbench/api/browser/mainThreadChatAgents2.ts:412
- The new external tool invocation functionality lacks test coverage. Consider adding tests for the following scenarios: (1) creating and completing external tool invocations, (2) updating in-progress invocations, (3) handling duplicate toolCallIds, (4) memory cleanup when requests complete, and (5) error state propagation. The existing test suite at
src/vs/workbench/contrib/chat/test/browser/tools/languageModelToolsService.test.tsprovides a good pattern to follow.
/**
* Handle external tool invocation updates from extensions.
* Returns the invocation if it's new and should be added to progress, otherwise undefined.
*/
private _handleExternalToolInvocationUpdate(progress: IChatExternalToolInvocationUpdateDto): ChatToolInvocation | undefined {
const existingInvocation = this._pendingExternalToolInvocations.get(progress.toolCallId);
if (existingInvocation) {
if (progress.isComplete) {
existingInvocation.completeExternalInvocation({
pastTenseMessage: progress.pastTenseMessage,
isError: progress.isError,
});
this._pendingExternalToolInvocations.delete(progress.toolCallId);
} else {
existingInvocation.updateExternalInvocation({
invocationMessage: progress.invocationMessage,
pastTenseMessage: progress.pastTenseMessage,
});
}
return undefined;
}
// Create a new external tool invocation
const invocation = ChatToolInvocation.createExternal({
toolCallId: progress.toolCallId,
toolName: progress.toolName,
invocationMessage: progress.invocationMessage,
pastTenseMessage: progress.pastTenseMessage,
toolSpecificData: progress.toolSpecificData as IPreparedToolInvocation['toolSpecificData'],
});
if (progress.isComplete) {
// Already completed on first push
invocation.completeExternalInvocation({
pastTenseMessage: progress.pastTenseMessage,
isError: progress.isError,
});
} else {
// Track for future updates
this._pendingExternalToolInvocations.set(progress.toolCallId, invocation);
}
return invocation;
}
src/vs/workbench/contrib/chat/common/model/chatProgressTypes/chatToolInvocation.ts
Outdated
Show resolved
Hide resolved
Because this would lead to showing all tool calls twice in CC
TylerLeonhardt
approved these changes
Feb 7, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
No description provided.