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

254 LOC · 244 covered · 10 uncovered · 54 ranges · 37 concepts · 26 introducers · 30 tests

File neighbourhood

The centred file is linked to every concept that introduces one of its ranges, every test that runs code from the file, and the gray connector concepts standing between those tests and the file's own introducer concepts. Undirected links join concepts to every file where they introduce source and concepts to the tests they introduce; arrows show specialization between the displayed concepts and bridge only concepts omitted from this view. Concept colors match the source ranges below; connector concepts have no source color and are shown in gray.

Focused file, its introducer and connector concepts, their introduced files, and tests that run code from the file

In the embedded map, ordinary wheel input scrolls the page; use the visible controls to zoom and drag to pan. Open the full-screen map for canvas navigation: wheel pans, Ctrl/Command plus wheel zooms, and arrow keys pan when this region is focused. On touch screens, open the full-screen map to pan or pinch. If JavaScript or WebGL is unavailable, use the related-file, concept, and source links on this page.

Focused file, its introducer and connector concepts, their introduced files, and tests that run code from the filesrc/vs/workbench/contrib/chat/common/chatService/chatService.ts · 2061 LOCchatService/chatService.…src/vs/workbench/contrib/chat/common/tools/languageModelToolsService.ts · 739 LOCtools/languageModelTools…chatImageExtraction.test|title=extractImagesFromChatResponse combines output details images and message URI images|occurrence=1 · 0 introduced LOCchatImageExtraction.test…chatImageExtraction.test|title=extractImagesFromChatResponse preserves interleaved order of tool and inline reference images|occurrence=1 · 0 introduced LOCchatImageExtraction.test…chatImageExtraction.test|title=extractImagesFromChatResponse extracts images from tool invocation message URIs|occurrence=1 · 0 introduced LOCchatImageExtraction.test…chatImageExtraction.test|title=extractImagesFromChatResponse extracts image from tool invocation with IToolResultOutputDetails|occurrence=1 · 0 introduced LOCchatImageExtraction.test…chatImageExtraction.ts ×3 · 12 introduced LOCchatImageExtraction.ts ×…range.ts ×1 · 12 introduced LOCrange.ts ×1chatImageExtraction.ts ×1 · 2 introduced LOCchatImageExtraction.ts ×…chatImageExtraction.test|title=extractImagesFromToolInvocationMessages extracts image from message URI|occurrence=1, chatImageExtraction.test|title=extractImagesFromToolInvocationMessages falls back to invocationMessage when pastTenseMessage is undefined|occurrence=1 · 0 introduced LOCchatImageExtraction.test…chatImageExtraction.ts ×1 · 7 introduced LOCchatImageExtraction.ts ×…chatImageExtraction.ts ×1 · 2 introduced LOCchatImageExtraction.ts ×…chatImageExtraction.ts ×1 · 2 introduced LOCchatImageExtraction.ts ×…chatImageExtraction.ts ×1 · 2 introduced LOCchatImageExtraction.ts ×…chatImageExtraction.ts ×1 · 13 introduced LOCchatImageExtraction.ts ×…chatImageExtraction.ts ×1 · 5 introduced LOCchatImageExtraction.ts ×…chatImageExtraction.ts ×2 · 15 introduced LOCchatImageExtraction.ts ×…chatImageExtraction.ts ×4 · 22 introduced LOCchatImageExtraction.ts ×…chatImageExtraction.test|title=extractImagesFromChatResponse skips tool invocations without image results|occurrence=1 · 0 introduced LOCchatImageExtraction.test…chatImageExtraction.ts ×2 · 3 introduced LOCchatImageExtraction.ts ×…chatImageExtraction.ts ×1 · 3 introduced LOCchatImageExtraction.ts ×…chatImageExtraction.test|title=extractImagesFromChatRequest uses attachment resource URI when available|occurrence=1 · 0 introduced LOCchatImageExtraction.test…chatImageExtraction.ts ×4 · 19 introduced LOCchatImageExtraction.ts ×…chatImageExtraction.ts ×1 · 4 introduced LOCchatImageExtraction.ts ×…chatImageExtraction.test|title=extractImagesFromChatResponse uses attachment summary title when matching request has no message text|occurrence=1 · 0 introduced LOCchatImageExtraction.test…chatImageExtraction.ts ×1 · 2 introduced LOCchatImageExtraction.ts ×…chatImageExtraction.test|title=extractImagesFromChatRequest extracts image attachment from Uint8Array|occurrence=1 · 0 introduced LOCchatImageExtraction.test…chatImageExtraction.ts ×1 · 2 introduced LOCchatImageExtraction.ts ×…chatImageExtraction.ts ×3 · 3 introduced LOCchatImageExtraction.ts ×…chatImageExtraction.ts ×2 · 9 introduced LOCchatImageExtraction.ts ×…chatViewModel.ts ×1 · 2 introduced LOCchatViewModel.ts ×1chatImageExtraction.ts ×2 · 18 introduced LOCchatImageExtraction.ts ×…chatImageExtraction.ts ×2 · 4 introduced LOCchatImageExtraction.ts ×…chatImageExtraction.ts ×2 · 9 introduced LOCchatImageExtraction.ts ×…chatImageExtraction.ts ×1 · 1 introduced LOCchatImageExtraction.ts ×…chatImageExtraction.ts ×6 · 28 introduced LOCchatImageExtraction.ts ×…chatImageExtraction.ts ×1 · 2 introduced LOCchatImageExtraction.ts ×…chatImageExtraction.ts ×1 · 9 introduced LOCchatImageExtraction.ts ×…chatImageExtraction.ts ×8 · 52 introduced LOCchatImageExtraction.ts ×…chatImageExtraction.test|title=extractImagesFromChatRequest does not treat a URI-backed image attachment as inline image bytes|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/workbench/contrib/chat/test/common/chatImageExtraction.test|title=extractImagesFromChatRequest does not treat a URI-backed image attachment as inline image bytes|occurrence=1chatImageExtraction.test…chatImageExtraction.test|title=extractImagesFromChatRequest extracts image attachment from ArrayBuffer|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/workbench/contrib/chat/test/common/chatImageExtraction.test|title=extractImagesFromChatRequest extracts image attachment from ArrayBuffer|occurrence=1chatImageExtraction.test…chatImageExtraction.test|title=extractImagesFromChatRequest extracts image attachment from Uint8Array|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/workbench/contrib/chat/test/common/chatImageExtraction.test|title=extractImagesFromChatRequest extracts image attachment from Uint8Array|occurrence=1chatImageExtraction.test…chatImageExtraction.test|title=extractImagesFromChatRequest extracts restored image attachment from plain object bytes|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/workbench/contrib/chat/test/common/chatImageExtraction.test|title=extractImagesFromChatRequest extracts restored image attachment from plain object bytes|occurrence=1chatImageExtraction.test…chatImageExtraction.test|title=extractImagesFromChatRequest extracts restored image attachment from reordered plain object bytes|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/workbench/contrib/chat/test/common/chatImageExtraction.test|title=extractImagesFromChatRequest extracts restored image attachment from reordered plain object bytes|occurrence=1chatImageExtraction.test…chatImageExtraction.test|title=extractImagesFromChatRequest uses attachment resource URI when available|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/workbench/contrib/chat/test/common/chatImageExtraction.test|title=extractImagesFromChatRequest uses attachment resource URI when available|occurrence=1chatImageExtraction.test…chatImageExtraction.test|title=extractImagesFromChatResponse collection id combines sessionResource and response id|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/workbench/contrib/chat/test/common/chatImageExtraction.test|title=extractImagesFromChatResponse collection id combines sessionResource and response id|occurrence=1chatImageExtraction.test…chatImageExtraction.test|title=extractImagesFromChatResponse combines output details images and message URI images|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/workbench/contrib/chat/test/common/chatImageExtraction.test|title=extractImagesFromChatResponse combines output details images and message URI images|occurrence=1chatImageExtraction.test…chatImageExtraction.test|title=extractImagesFromChatResponse extracts image from inline reference Location|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/workbench/contrib/chat/test/common/chatImageExtraction.test|title=extractImagesFromChatResponse extracts image from inline reference Location|occurrence=1chatImageExtraction.test…chatImageExtraction.test|title=extractImagesFromChatResponse extracts image from inline reference URI when readFile is provided|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/workbench/contrib/chat/test/common/chatImageExtraction.test|title=extractImagesFromChatResponse extracts image from inline reference URI when readFile is provided|occurrence=1chatImageExtraction.test…chatImageExtraction.test|title=extractImagesFromChatResponse extracts image from tool invocation with IToolResultOutputDetails|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/workbench/contrib/chat/test/common/chatImageExtraction.test|title=extractImagesFromChatResponse extracts image from tool invocation with IToolResultOutputDetails|occurrence=1chatImageExtraction.test…chatImageExtraction.test|title=extractImagesFromChatResponse extracts images from tool invocation message URIs|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/workbench/contrib/chat/test/common/chatImageExtraction.test|title=extractImagesFromChatResponse extracts images from tool invocation message URIs|occurrence=1chatImageExtraction.test…chatImageExtraction.test|title=extractImagesFromChatResponse extracts multiple images from tool invocation with IToolResultInputOutputDetails|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/workbench/contrib/chat/test/common/chatImageExtraction.test|title=extractImagesFromChatResponse extracts multiple images from tool invocation with IToolResultInputOutputDetails|occurrence=1chatImageExtraction.test…chatImageExtraction.test|title=extractImagesFromChatResponse preserves interleaved order of tool and inline reference images|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/workbench/contrib/chat/test/common/chatImageExtraction.test|title=extractImagesFromChatResponse preserves interleaved order of tool and inline reference images|occurrence=1chatImageExtraction.test…chatImageExtraction.test|title=extractImagesFromChatResponse returns empty images when response has no items|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/workbench/contrib/chat/test/common/chatImageExtraction.test|title=extractImagesFromChatResponse returns empty images when response has no items|occurrence=1chatImageExtraction.test…chatImageExtraction.test|title=extractImagesFromChatResponse skips inline reference when readFile fails|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/workbench/contrib/chat/test/common/chatImageExtraction.test|title=extractImagesFromChatResponse skips inline reference when readFile fails|occurrence=1chatImageExtraction.test…chatImageExtraction.test|title=extractImagesFromChatResponse skips non-image inline references|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/workbench/contrib/chat/test/common/chatImageExtraction.test|title=extractImagesFromChatResponse skips non-image inline references|occurrence=1chatImageExtraction.test…chatImageExtraction.test|title=extractImagesFromChatResponse skips tool invocations without image results|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/workbench/contrib/chat/test/common/chatImageExtraction.test|title=extractImagesFromChatResponse skips tool invocations without image results|occurrence=1chatImageExtraction.test…chatImageExtraction.test|title=extractImagesFromChatResponse uses attachment summary title when matching request has no message text|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/workbench/contrib/chat/test/common/chatImageExtraction.test|title=extractImagesFromChatResponse uses attachment summary title when matching request has no message text|occurrence=1chatImageExtraction.test…chatImageExtraction.test|title=extractImagesFromChatResponse uses default title when no matching request is found|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/workbench/contrib/chat/test/common/chatImageExtraction.test|title=extractImagesFromChatResponse uses default title when no matching request is found|occurrence=1chatImageExtraction.test…chatImageExtraction.test|title=extractImagesFromChatResponse uses filename from URI path when name is not provided|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/workbench/contrib/chat/test/common/chatImageExtraction.test|title=extractImagesFromChatResponse uses filename from URI path when name is not provided|occurrence=1chatImageExtraction.test…chatImageExtraction.test|title=extractImagesFromToolInvocationMessages continues when readFile fails for one URI|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/workbench/contrib/chat/test/common/chatImageExtraction.test|title=extractImagesFromToolInvocationMessages continues when readFile fails for one URI|occurrence=1chatImageExtraction.test…chatImageExtraction.test|title=extractImagesFromToolInvocationMessages extracts image from message URI|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/workbench/contrib/chat/test/common/chatImageExtraction.test|title=extractImagesFromToolInvocationMessages extracts image from message URI|occurrence=1chatImageExtraction.test…chatImageExtraction.test|title=extractImagesFromToolInvocationMessages extracts multiple images from message URIs|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/workbench/contrib/chat/test/common/chatImageExtraction.test|title=extractImagesFromToolInvocationMessages extracts multiple images from message URIs|occurrence=1chatImageExtraction.test…chatImageExtraction.test|title=extractImagesFromToolInvocationMessages falls back to invocationMessage when pastTenseMessage is undefined|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/workbench/contrib/chat/test/common/chatImageExtraction.test|title=extractImagesFromToolInvocationMessages falls back to invocationMessage when pastTenseMessage is undefined|occurrence=1chatImageExtraction.test…chatImageExtraction.test|title=extractImagesFromToolInvocationMessages returns empty when message has no uris|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/workbench/contrib/chat/test/common/chatImageExtraction.test|title=extractImagesFromToolInvocationMessages returns empty when message has no uris|occurrence=1chatImageExtraction.test…chatImageExtraction.test|title=extractImagesFromToolInvocationMessages returns empty when message is a string|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/workbench/contrib/chat/test/common/chatImageExtraction.test|title=extractImagesFromToolInvocationMessages returns empty when message is a string|occurrence=1chatImageExtraction.test…chatImageExtraction.test|title=extractImagesFromToolInvocationMessages returns empty when message is undefined|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/workbench/contrib/chat/test/common/chatImageExtraction.test|title=extractImagesFromToolInvocationMessages returns empty when message is undefined|occurrence=1chatImageExtraction.test…chatImageExtraction.test|title=extractImagesFromToolInvocationMessages returns empty when message uris are empty|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/workbench/contrib/chat/test/common/chatImageExtraction.test|title=extractImagesFromToolInvocationMessages returns empty when message uris are empty|occurrence=1chatImageExtraction.test…chatImageExtraction.test|title=extractImagesFromToolInvocationMessages skips non-image URIs|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/workbench/contrib/chat/test/common/chatImageExtraction.test|title=extractImagesFromToolInvocationMessages skips non-image URIs|occurrence=1chatImageExtraction.test…Focused file · src/vs/workbench/contrib/chat/common/chatImageExtraction.ts · 254 LOCcommon/chatImageExtracti…

Graph controls are ready.

Interactive rendering requires JavaScript and WebGL. Use the related-file, concept, and source links on this page while the interactive map is unavailable.

1 > /*--------------------------------------------------------------------------------------------- chatImageExtraction.ts ×8
2 > * Copyright (c) Microsoft Corporation. All rights reserved.
3 > * Licensed under the MIT License. See License.txt in the project root for license information.
4 > *--------------------------------------------------------------------------------------------*/
5 >
6 > import { decodeBase64, VSBuffer } from '../../../../base/common/buffer.js';
7 > import { IMarkdownString } from '../../../../base/common/htmlContent.js';
8 > import { getExtensionForMimeType, getMediaMime } from '../../../../base/common/mime.js';
9 > import { URI } from '../../../../base/common/uri.js';
10 > import { localize } from '../../../../nls.js';
11 > import { isLocation } from '../../../../editor/common/languages.js';
12 > import { IChatResponseViewModel, IChatRequestViewModel, isRequestVM } from './model/chatViewModel.js';
13 > import { ChatResponseResource } from './model/chatModel.js';
14 > import { IChatContentInlineReference, IChatToolInvocation, IChatToolInvocationSerialized, IToolResultOutputDetailsSerialized } from './chatService/chatService.js';
15 > import { isToolResultInputOutputDetails, isToolResultOutputDetails, IToolResultOutputDetails } from './tools/languageModelToolsService.js';
16 > import { getExplicitFileOrImageAttachmentSummary, type IChatRequestVariableEntry, isImageVariableEntry } from './attachments/chatVariableEntries.js';
17 >
18 > export interface IChatExtractedImage {
19 > readonly id: string;
20 > readonly uri: URI;
21 > readonly name: string;
22 > readonly mimeType: string;
23 > readonly data: VSBuffer;
24 > readonly source: string;
25 > readonly caption: string | IMarkdownString | undefined;
26 > }
27 >
28 > export interface IChatExtractedImageCollection {
29 > readonly id: string;
30 > readonly title: string;
31 > readonly images: IChatExtractedImage[];
32 > }
33 >
34 > /**
35 > * Extract all images from a chat response's tool invocations and inline references.
36 > * Tool invocation images are extracted from output details and message URIs.
37 > * Inline reference images (file URIs) are read via the provided {@link readFile} callback.
38 > */
39 > export async function extractImagesFromChatResponse( chatImageExtraction.ts ×2
40 > response: IChatResponseViewModel,
41 > readFile: (uri: URI) => Promise<VSBuffer>,
42 > ): Promise<IChatExtractedImageCollection> {
43 > const allImages: IChatExtractedImage[] = [];
44 >
45 > for (const item of response.response.value) {
46 > if (item.kind === 'toolInvocation' || item.kind === 'toolInvocationSerialized') { chatImageExtraction.ts ×3
47 > const images = extractImagesFromToolInvocationOutputDetails(item, response.sessionResource); chatImageExtraction.ts ×4
48 > allImages.push(...images);
49 > const messageImages = await extractImagesFromToolInvocationMessages(item, readFile);
50 > allImages.push(...messageImages);
51 > } else if (item.kind === 'inlineReference') { chatImageExtraction.ts ×3
52 > const image = await extractImageFromInlineReference(item, readFile); chatImageExtraction.ts ×4
53 > if (image) {
54 > allImages.push(image); chatImageExtraction.ts ×1
55 > }
59 > // Use the corresponding user request as the carousel title
60 > const request = response.session.getItems().find((item): item is IChatRequestViewModel => isRequestVM(item) && item.id === response.requestId);
61 > const title = request ? request.messageText.trim() || getExplicitFileOrImageAttachmentSummary(request.variables) || localize('chatImageExtraction.defaultTitle', "Images") : localize('chatImageExtraction.defaultTitle', "Images");
62 >
63 > return {
64 > id: response.sessionResource.toString() + '_' + response.id,
65 > title,
66 > images: allImages,
67 > };
68 > }
70 > export function extractImagesFromToolInvocationOutputDetails(toolInvocation: IChatToolInvocation | IChatToolInvocationSerialized, sessionResource: URI): IChatExtractedImage[] {
71 > const images: IChatExtractedImage[] = []; chatImageExtraction.ts ×4
72 >
73 > const resultDetails = IChatToolInvocation.resultDetails(toolInvocation);
74 >
75 > const caption = toolInvocation.pastTenseMessage ?? toolInvocation.invocationMessage;
76 > const pushImage = (mimeType: string, data: VSBuffer, outputIndex: number) => {
77 > const ext = getExtensionForMimeType(mimeType); chatImageExtraction.ts ×1
78 > const permalinkBasename = ext ? `file${ext}` : 'file.bin';
79 > const uri = ChatResponseResource.createUri(sessionResource, toolInvocation.toolCallId, outputIndex, permalinkBasename);
80 > images.push({
81 > id: `${toolInvocation.toolCallId}_${outputIndex}`,
82 > uri,
83 > name: localize('chatImageExtraction.imageName', "Image {0}", images.length + 1),
84 > mimeType,
85 > data,
86 > source: localize('chatImageExtraction.toolSource', "Tool: {0}", toolInvocation.toolId),
87 > caption,
88 > });
89 > };
91 > if (isToolResultInputOutputDetails(resultDetails)) {
92 > for (let i = 0; i < resultDetails.output.length; i++) { chatImageExtraction.ts ×1
93 > const outputItem = resultDetails.output[i];
94 > if (outputItem.type === 'embed' && outputItem.mimeType?.startsWith('image/') && !outputItem.isText) {
95 > pushImage(outputItem.mimeType, decodeBase64(outputItem.value), i);
96 > }
97 > }
98 > }
99 > else if (isToolResultOutputDetails(resultDetails)) { chatImageExtraction.ts ×1
100 > const output = resultDetails.output; chatImageExtraction.ts ×2
101 > if (output.mimeType?.startsWith('image/')) {
102 > const data = getImageDataFromOutputDetails(resultDetails, toolInvocation); chatImageExtraction.ts ×3
103 > if (data) {
104 > pushImage(output.mimeType, data, 0);
105 > }
106 > }
109 > return images;
110 > }
112 > export async function extractImagesFromToolInvocationMessages( chatImageExtraction.ts ×1
113 > toolInvocation: IChatToolInvocation | IChatToolInvocationSerialized,
114 > readFile: (uri: URI) => Promise<VSBuffer>
115 > ): Promise<IChatExtractedImage[]> {
116 > // Use pastTenseMessage if available, otherwise fall back to invocationMessage.
117 > // When pastTenseMessage exists it visually replaces invocationMessage in the UI,
118 > // so we only look at its URIs — we don't fall back to invocationMessage URIs.
119 > const message = toolInvocation.pastTenseMessage ?? toolInvocation.invocationMessage;
120 > if (!message || typeof message === 'string' || !message.uris || Object.keys(message.uris).length === 0) {
121 > return []; chatImageExtraction.ts ×1
122 > }
124 > const images: IChatExtractedImage[] = [];
125 > for (const uriComponents of Object.values(message.uris)) {
126 > const uri = URI.revive(uriComponents);
127 > const mimeType = getMediaMime(uri.path);
128 > if (mimeType?.startsWith('image/')) {
129 > let data: VSBuffer; chatImageExtraction.ts ×2
130 > try {
131 > data = await readFile(uri);
132 > } catch {
133 > continue; chatImageExtraction.ts ×1
134 > }
135 > const name = uri.path.split('/').pop() ?? 'image'; chatImageExtraction.ts ×2
136 > images.push({
137 > id: uri.toString(),
138 > uri,
139 > name,
140 > mimeType,
141 > data,
142 > source: localize('chatImageExtraction.toolSource', "Tool: {0}", toolInvocation.toolId),
143 > caption: message,
144 > });
145 > }
147 > return images;
148 > }
150 > function getImageDataFromOutputDetails(resultDetails: IToolResultOutputDetails, toolInvocation: IChatToolInvocation | IChatToolInvocationSerialized): VSBuffer | undefined { chatImageExtraction.ts ×3
151 > if (toolInvocation.kind === 'toolInvocationSerialized') {
152 > const serializedDetails = resultDetails as unknown as IToolResultOutputDetailsSerialized;
153 > if (serializedDetails.output.base64Data) {
154 > return decodeBase64(serializedDetails.output.base64Data);
155 > }
156 return undefined;
157 } else {
158 return resultDetails.output.value;
159 }
162 > async function extractImageFromInlineReference( chatImageExtraction.ts ×4
163 > part: IChatContentInlineReference,
164 > readFile: (uri: URI) => Promise<VSBuffer>,
165 > ): Promise<IChatExtractedImage | undefined> {
166 > const ref = part.inlineReference;
167 > const refUri = URI.isUri(ref) ? ref : isLocation(ref) ? ref.uri : ref.location.uri;
168 > const mime = getMediaMime(refUri.path);
169 > if (!mime?.startsWith('image/')) {
170 > return undefined; chatImageExtraction.ts ×1
171 > }
173 > let data: VSBuffer;
174 > try {
175 > data = await readFile(refUri);
176 > } catch {
177 > return undefined; chatImageExtraction.ts ×1
178 > }
179 > const name = part.name ?? refUri.path.split('/').pop() ?? 'image'; chatImageExtraction.ts ×4
180 > return {
181 > id: refUri.toString(),
182 > uri: refUri,
183 > name,
184 > mimeType: mime,
185 > data,
186 > source: localize('chatImageExtraction.inlineReference', "File"),
187 > caption: undefined,
188 > };
189 > }
191 > export function coerceImageBuffer(value: unknown): Uint8Array | undefined {
192 > if (value instanceof Uint8Array) { chatImageExtraction.ts ×6
193 > return value; chatImageExtraction.ts ×1
194 > }
195 > if (value instanceof ArrayBuffer) { chatImageExtraction.ts ×1
196 > return new Uint8Array(value); chatImageExtraction.ts ×1
197 > }
198 > if (!value || typeof value !== 'object' || Array.isArray(value)) { chatImageExtraction.ts ×6
199 return undefined;
200 }
202 > const record = value as Record<string, unknown>;
203 > const keys = Object.keys(record).sort((a, b) => Number(a) - Number(b));
204 > if (keys.length === 0) {
205 return undefined;
206 }
208 > const result = new Uint8Array(keys.length);
209 > for (let index = 0; index < keys.length; index++) {
210 > const byte = record[keys[index]];
211 > if (keys[index] !== String(index) || typeof byte !== 'number' || !Number.isInteger(byte) || byte < 0 || byte > 255) {
212 > return undefined; chatImageExtraction.ts ×2
213 > }
214 > result[index] = byte; chatImageExtraction.ts ×1
215 > }
216 > return result;
217 > }
219 > /**
220 > * Extract images from a chat request's variable attachments (user-attached images).
221 > */
222 > export function extractImagesFromChatRequest(
223 > request: IChatRequestViewModel, chatImageExtraction.ts ×6
224 > ): IChatExtractedImage[] {
225 > return extractImagesFromChatVariables(request.variables);
226 > }
228 > export function extractImagesFromChatVariables(
229 > variables: readonly IChatRequestVariableEntry[], chatImageExtraction.ts ×6
230 > ): IChatExtractedImage[] {
231 > const images: IChatExtractedImage[] = [];
232 > for (const variable of variables) {
233 > if (!isImageVariableEntry(variable)) {
234 continue;
235 }
236 > const buffer = coerceImageBuffer(variable.value); chatImageExtraction.ts ×6
237 > if (!buffer) {
238 > continue; chatImageExtraction.ts ×2
239 > }
240 > const mimeType = variable.mimeType ?? getMediaMime(variable.name) ?? 'image/png'; chatImageExtraction.ts ×6
241 > const uri = variable.references?.[0]?.reference;
242 > const imageUri = URI.isUri(uri) ? uri : URI.from({ scheme: 'data', path: `${variable.id}/${encodeURIComponent(variable.name)}` });
243 > images.push({
244 > id: imageUri.toString(),
245 > uri: imageUri,
246 > name: variable.name,
247 > mimeType,
248 > data: VSBuffer.wrap(buffer),
249 > source: localize('chatImageExtraction.userAttachment', "Attachment"),
250 > caption: undefined,
251 > });
252 > }
253 > return images;
254 > }