mirror of
https://github.com/microsoft/vscode.git
synced 2026-07-10 16:58:55 -05:00
* fix: filter images from telemetry render to prevent supportsVision crash (fixes #315729) The sendInvokedToolTelemetry function renders tool results in a fire-and-forget async call to count tokens. This async render can outlive the parent PromptRenderer's DI tree, which is disposed after the parent render completes (PromptRenderer.render() line 133). When PrimitiveToolResult is instantiated during the telemetry render after the parent DI is disposed, @IPromptEndpoint resolves to undefined, causing 'Cannot read properties of undefined (reading supportsVision)' in PrimitiveToolResult.onImage(). Fix: filter out image data parts before passing content to the telemetry renderer. Images trigger onImage() which accesses this.endpoint.supportsVision — the only code path that crashes. Images contribute ~1 token each in the tokenizer, so the impact on token counting is minimal. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * fix: make IPromptEndpoint and IAuthenticationService optional in PrimitiveToolResult Address review feedback from @connor4312: these DI services should not be expected to be available when PrimitiveToolResult is rendered in the fire-and-forget telemetry context where the parent DI tree may be disposed. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --------- Co-authored-by: vs-code-engineering[bot] <122617954+vs-code-engineering[bot]@users.noreply.github.com> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Co-authored-by: Bryan Chen <41454397+bryanchen-d@users.noreply.github.com>
This commit is contained in:
committed by
GitHub
parent
da7155bb4f
commit
d503bd0e26
@@ -728,8 +728,8 @@ class PrimitiveToolResult<T extends IPrimitiveToolResultProps> extends PromptEle
|
||||
|
||||
constructor(
|
||||
props: T,
|
||||
@IPromptEndpoint protected readonly endpoint: IPromptEndpoint,
|
||||
@IAuthenticationService private readonly authService: IAuthenticationService,
|
||||
@IPromptEndpoint protected readonly endpoint?: IPromptEndpoint,
|
||||
@IAuthenticationService private readonly authService?: IAuthenticationService,
|
||||
@ILogService private readonly logService?: ILogService,
|
||||
@IImageService private readonly imageService?: IImageService,
|
||||
@IConfigurationService private readonly configurationService?: IConfigurationService,
|
||||
@@ -780,7 +780,7 @@ class PrimitiveToolResult<T extends IPrimitiveToolResultProps> extends PromptEle
|
||||
}
|
||||
|
||||
protected async onImage(part: LanguageModelDataPart, _imageIndex?: number) {
|
||||
if (!this.endpoint.supportsVision) {
|
||||
if (!this.endpoint?.supportsVision) {
|
||||
return '[Image content is not available because vision is not supported by the current model or is disabled by your organization.]';
|
||||
}
|
||||
|
||||
@@ -789,7 +789,7 @@ class PrimitiveToolResult<T extends IPrimitiveToolResultProps> extends PromptEle
|
||||
: false;
|
||||
|
||||
// Anthropic (from CAPI) currently does not support image uploads from tool calls.
|
||||
const canUpload = uploadsEnabled && modelCanUseMcpResultImageURL(this.endpoint);
|
||||
const canUpload = uploadsEnabled && !!this.endpoint && modelCanUseMcpResultImageURL(this.endpoint);
|
||||
|
||||
// Enforce image budgets only when images will be inlined as base64.
|
||||
// When uploads are available, the request body stays small (URL reference).
|
||||
@@ -820,10 +820,10 @@ class PrimitiveToolResult<T extends IPrimitiveToolResultProps> extends PromptEle
|
||||
// Only call getGitHubSession when uploads are potentially available
|
||||
let uploadToken: string | undefined;
|
||||
if (canUpload) {
|
||||
uploadToken = (await this.authService.getGitHubSession('any', { silent: true }))?.accessToken;
|
||||
uploadToken = (await this.authService?.getGitHubSession('any', { silent: true }))?.accessToken;
|
||||
}
|
||||
|
||||
return Promise.resolve(imageDataPartToTSX(part, uploadToken, this.endpoint.urlOrRequestMetadata, this.logService, this.imageService));
|
||||
return Promise.resolve(imageDataPartToTSX(part, uploadToken, this.endpoint?.urlOrRequestMetadata, this.logService, this.imageService));
|
||||
}
|
||||
|
||||
protected onTSX(part: JSONTree.PromptElementJSON) {
|
||||
@@ -956,8 +956,8 @@ export class ToolResult extends PrimitiveToolResult<IToolResultProps> {
|
||||
return content;
|
||||
}
|
||||
|
||||
const tokens = await this.endpoint.acquireTokenizer().tokenLength(content);
|
||||
if (tokens < truncateAtTokens) {
|
||||
const tokens = await this.endpoint?.acquireTokenizer().tokenLength(content);
|
||||
if (!tokens || tokens < truncateAtTokens) {
|
||||
return content;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user