src/vs/platform/agentHost/common/state/chatAttachmentContext.ts

80 LOC · 79 covered · 1 uncovered · 10 ranges · 1057 concepts · 7 introducers · 512 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.

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 > /*--------------------------------------------------------------------------------------------- chatAttachmentContext.ts ×3
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 { MessageAttachmentKind, ResponsePartKind, type MessageChatAttachment, type SimpleMessageAttachment, type Turn } from './protocol/state.js';
7 >
8 > /**
9 > * Model-facing preamble that frames the resolved transcript for the SDK. It is
10 > * intentionally hard-coded English (like Claude's `<system-reminder>` text):
11 > * this string is consumed by the model, not shown in the UI, so it must not be
12 > * localized.
13 > */
14 > const CHAT_TRANSCRIPT_PREAMBLE =
15 > 'The user referenced another chat in the same session. ' +
16 > 'The transcript below is that chat up to the selected turn, provided as background context. ' +
17 > 'Treat it as reference material that may or may not be relevant to the new question.';
18 >
19 > /**
20 > * Returns the referenced chat's turns bounded through {@link endTurn}, inclusive.
21 > * Throws when {@link endTurn} is not a retained completed turn.
22 > */
23 > export function boundChatTranscriptTurns(turns: readonly Turn[], endTurn: string): readonly Turn[] {
24 > const index = turns.findIndex(t => t.id === endTurn); chatAttachmentContext.ts ×1
25 > if (index < 0) {
26 > throw new Error(`Chat attachment endTurn ${endTurn} was not found in the retained transcript.`); chatAttachmentContext.ts ×1
27 > }
28 > return turns.slice(0, index + 1); chatAttachmentContext.ts ×1
29 > }
31 > /**
32 > * Formats bounded transcript turns into a plain-text conversation for the
33 > * model. Only user message text and assistant markdown are rendered; tool
34 > * calls, reasoning, and other parts are omitted to keep the context bounded.
35 > *
36 > * This never expands nested attachments, so a {@link MessageChatAttachment}
37 > * referenced inside the source transcript is not recursively resolved.
38 > */
39 > export function formatChatTranscript(turns: readonly Turn[]): string {
40 > const blocks: string[] = []; chatAttachmentContext.ts ×1
41 > for (const turn of turns) {
42 > const userText = turn.message?.text?.trim();
43 > if (userText) {
44 > blocks.push(`User: ${userText}`);
45 > }
46 > const assistantText = turn.responseParts
47 > .map(part => (part.kind === ResponsePartKind.Markdown ? part.content : ''))
48 > .join('')
49 > .trim();
50 > if (assistantText) {
51 > blocks.push(`Assistant: ${assistantText}`);
52 > }
53 > }
54 > return blocks.join('\n\n');
55 > }
57 > /**
58 > * Resolves a {@link MessageChatAttachment} into an SDK-compatible
59 > * {@link SimpleMessageAttachment}: the bounded transcript rendered as the
60 > * attachment's {@link SimpleMessageAttachment.modelRepresentation}. Every
61 > * provider adapter already inlines a `Simple` attachment's model
62 > * representation, so this keeps transcript formatting in one place instead of
63 > * duplicating it per agent.
64 > *
65 > * The resolution is non-recursive: it renders {@link sourceTurns} directly and
66 > * never re-resolves chat attachments found within them.
67 > */
68 > export function resolveChatAttachment(attachment: MessageChatAttachment, sourceTurns: readonly Turn[]): SimpleMessageAttachment {
69 > const bounded = boundChatTranscriptTurns(sourceTurns, attachment.endTurn); chatAttachmentContext.ts ×2
70 > const transcript = formatChatTranscript(bounded);
71 > const modelRepresentation = transcript
72 > ? `${CHAT_TRANSCRIPT_PREAMBLE}\n\n${transcript}` chatAttachmentContext.ts ×1
73 : CHAT_TRANSCRIPT_PREAMBLE;
75 > type: MessageAttachmentKind.Simple,
76 > label: attachment.label,
77 > modelRepresentation,
78 > ...(attachment.range !== undefined ? { range: attachment.range } : {}),
79 > };
80 > }