src/vs/platform/agentHost/node/codex/codexPromptResolver.ts

189 LOC · 171 covered · 18 uncovered · 35 ranges · 37 concepts · 12 introducers · 20 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 filecodexAgent.ts ×13 · 83 introduced LOCcodexAgent.ts ×13codexSessionConfigKeys.test|title=codexSessionConfigKeys resolveSessionConfig preserves legacy read-only permissions on restore|occurrence=1 · 0 introduced LOCcodexSessionConfigKeys.t…codexSessionConfigKeys.test|title=codexSessionConfigKeys resolveSessionConfig exposes a single permissions-preset chip|occurrence=1 · 0 introduced LOCcodexSessionConfigKeys.t…codexAgent.ts ×1 · 27 introduced LOCcodexAgent.ts ×1codexAgent.ts ×24 · 89 introduced LOCcodexAgent.ts ×24codexSessionConfigKeys.ts ×1 · 7 introduced LOCcodexSessionConfigKeys.t…codexSessionConfigKeys.ts ×1 · 2 introduced LOCcodexSessionConfigKeys.t…codexSessionConfigKeys.ts ×7 · 49 introduced LOCcodexSessionConfigKeys.t…codexSessionConfigKeys.ts ×1 · 11 introduced LOCcodexSessionConfigKeys.t…codexSessionConfigKeys.ts ×1 · 2 introduced LOCcodexSessionConfigKeys.t…codexSessionConfigKeys.ts ×2 · 4 introduced LOCcodexSessionConfigKeys.t…codexSessionConfigKeys.ts ×3 · 18 introduced LOCcodexSessionConfigKeys.t…codexSessionConfigKeys.ts ×3 · 19 introduced LOCcodexSessionConfigKeys.t…codexSessionConfigKeys.ts ×2 · 3 introduced LOCcodexSessionConfigKeys.t…codexSessionConfigKeys.ts ×2 · 2 introduced LOCcodexSessionConfigKeys.t…codexSessionConfigKeys.ts ×6 · 23 introduced LOCcodexSessionConfigKeys.t…codexAgent.ts ×1 · 2 introduced LOCcodexAgent.ts ×1codexAgent.ts ×1 · 2 introduced LOCcodexAgent.ts ×1codexAgent.ts ×3 · 7 introduced LOCcodexAgent.ts ×3codexAgent.ts ×1 · 2 introduced LOCcodexAgent.ts ×1codexAgent.ts ×1 · 2 introduced LOCcodexAgent.ts ×1codexAgent.ts ×1 · 2 introduced LOCcodexAgent.ts ×1codexAgent.ts ×1 · 10 introduced LOCcodexAgent.ts ×1codexAgent.ts ×8 · 19 introduced LOCcodexAgent.ts ×8codexAgent.ts ×158 · 1640 introduced LOCcodexAgent.ts ×158codexPromptResolver.ts ×2 · 10 introduced LOCcodexPromptResolver.ts ×…codexPromptResolver.ts ×8 · 22 introduced LOCcodexPromptResolver.ts ×…codexPromptResolver.ts ×1 · 1 introduced LOCcodexPromptResolver.ts ×…codexPromptResolver.ts ×1 · 1 introduced LOCcodexPromptResolver.ts ×…codexPromptResolver.ts ×6 · 28 introduced LOCcodexPromptResolver.ts ×…codexPromptResolver.ts ×2 · 11 introduced LOCcodexPromptResolver.ts ×…codexPromptResolver.ts ×3 · 5 introduced LOCcodexPromptResolver.ts ×…codexPromptResolver.ts ×1 · 1 introduced LOCcodexPromptResolver.ts ×…codexPromptResolver.ts ×1 · 6 introduced LOCcodexPromptResolver.ts ×…codexPromptResolver.ts ×4 · 8 introduced LOCcodexPromptResolver.ts ×…codexPromptResolver.ts ×2 · 16 introduced LOCcodexPromptResolver.ts ×…codexPromptResolver.ts ×4 · 62 introduced LOCcodexPromptResolver.ts ×…codexModelRefresh.test|title=CodexAgent model refresh keeps the last known-good models when a periodic refresh fails|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/platform/agentHost/test/node/codex/codexModelRefresh.test|title=CodexAgent model refresh keeps the last known-good models when a periodic refresh fails|occurrence=1codexModelRefresh.test|t…codexPackagePaths.test|title=codex package paths codexBinaryTriple every suffix produced by codexPackageSuffix maps to a rust target triple|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/platform/agentHost/test/node/codex/codexPackagePaths.test|title=codex package paths codexBinaryTriple every suffix produced by codexPackageSuffix maps to a rust target triple|occurrence=1codexPackagePaths.test|t…codexPackagePaths.test|title=codex package paths codexBinaryTriple returns undefined for unknown suffixes|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/platform/agentHost/test/node/codex/codexPackagePaths.test|title=codex package paths codexBinaryTriple returns undefined for unknown suffixes|occurrence=1codexPackagePaths.test|t…codexPackagePaths.test|title=codex package paths codexPackageSuffix every supported (platform, arch) returns the npm optionalDependencies suffix|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/platform/agentHost/test/node/codex/codexPackagePaths.test|title=codex package paths codexPackageSuffix every supported (platform, arch) returns the npm optionalDependencies suffix|occurrence=1codexPackagePaths.test|t…codexPackagePaths.test|title=codex package paths codexPackageSuffix never returns a -musl suffix on Linux (Codex is statically musl-linked)|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/platform/agentHost/test/node/codex/codexPackagePaths.test|title=codex package paths codexPackageSuffix never returns a -musl suffix on Linux (Codex is statically musl-linked)|occurrence=1codexPackagePaths.test|t…codexPackagePaths.test|title=codex package paths codexPackageSuffix returns undefined for unsupported platforms and architectures|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/platform/agentHost/test/node/codex/codexPackagePaths.test|title=codex package paths codexPackageSuffix returns undefined for unsupported platforms and architectures|occurrence=1codexPackagePaths.test|t…codex resolves|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/platform/agentHost/test/node/codex/codexPackagePaths.test|title=codex package paths resolveCodexDevSdkRoot returns the directory containing node_modules when @openai/codex resolves|occurrence=1codex resolves|occurrenc…codexPackagePaths.test|title=codex package paths resolveCodexDevSdkRoot returns undefined when resolution throws (e.g. built product without the devDependency)|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/platform/agentHost/test/node/codex/codexPackagePaths.test|title=codex package paths resolveCodexDevSdkRoot returns undefined when resolution throws (e.g. built product without the devDependency)|occurrence=1codexPackagePaths.test|t…codexPromptResolver.test|title=codexPromptResolver EmbeddedResource image becomes localImage and tracks cleanup|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/platform/agentHost/test/node/codex/codexPromptResolver.test|title=codexPromptResolver EmbeddedResource image becomes localImage and tracks cleanup|occurrence=1codexPromptResolver.test…codexPromptResolver.test|title=codexPromptResolver Resource (file:) attachment becomes @<path> mention|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/platform/agentHost/test/node/codex/codexPromptResolver.test|title=codexPromptResolver Resource (file:) attachment becomes @<path> mention|occurrence=1codexPromptResolver.test…codexPromptResolver.test|title=codexPromptResolver Simple attachment with modelRepresentation is appended|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/platform/agentHost/test/node/codex/codexPromptResolver.test|title=codexPromptResolver Simple attachment with modelRepresentation is appended|occurrence=1codexPromptResolver.test…codexPromptResolver.test|title=codexPromptResolver non-image EmbeddedResource is dropped silently|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/platform/agentHost/test/node/codex/codexPromptResolver.test|title=codexPromptResolver non-image EmbeddedResource is dropped silently|occurrence=1codexPromptResolver.test…codexPromptResolver.test|title=codexPromptResolver plain prompt becomes a single text input|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/platform/agentHost/test/node/codex/codexPromptResolver.test|title=codexPromptResolver plain prompt becomes a single text input|occurrence=1codexPromptResolver.test…codexPromptResolver.test|title=codexPromptResolver textual EmbeddedResource (unsaved document) is inlined with label|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/platform/agentHost/test/node/codex/codexPromptResolver.test|title=codexPromptResolver textual EmbeddedResource (unsaved document) is inlined with label|occurrence=1codexPromptResolver.test…codexPromptResolver.test|title=codexPromptResolver textual EmbeddedResource selection annotates a one-based line range|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/platform/agentHost/test/node/codex/codexPromptResolver.test|title=codexPromptResolver textual EmbeddedResource selection annotates a one-based line range|occurrence=1codexPromptResolver.test…codexSessionConfigKeys.test|title=codexSessionConfigKeys expands permissions presets and falls back to legacy axes|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/platform/agentHost/test/node/codex/codexSessionConfigKeys.test|title=codexSessionConfigKeys expands permissions presets and falls back to legacy axes|occurrence=1codexSessionConfigKeys.t…codexSessionConfigKeys.test|title=codexSessionConfigKeys inverts presets and migrates legacy axes without escalating|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/platform/agentHost/test/node/codex/codexSessionConfigKeys.test|title=codexSessionConfigKeys inverts presets and migrates legacy axes without escalating|occurrence=1codexSessionConfigKeys.t…codexSessionConfigKeys.test|title=codexSessionConfigKeys narrows valid values and rejects invalid values|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/platform/agentHost/test/node/codex/codexSessionConfigKeys.test|title=codexSessionConfigKeys narrows valid values and rejects invalid values|occurrence=1codexSessionConfigKeys.t…codexSessionConfigKeys.test|title=codexSessionConfigKeys resolveSessionConfig exposes a single permissions-preset chip|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/platform/agentHost/test/node/codex/codexSessionConfigKeys.test|title=codexSessionConfigKeys resolveSessionConfig exposes a single permissions-preset chip|occurrence=1codexSessionConfigKeys.t…codexSessionConfigKeys.test|title=codexSessionConfigKeys resolveSessionConfig preserves legacy read-only permissions on restore|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/platform/agentHost/test/node/codex/codexSessionConfigKeys.test|title=codexSessionConfigKeys resolveSessionConfig preserves legacy read-only permissions on restore|occurrence=1codexSessionConfigKeys.t…Focused file · src/vs/platform/agentHost/node/codex/codexPromptResolver.ts · 189 LOCcodex/codexPromptResolve…

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 > /*--------------------------------------------------------------------------------------------- codexPromptResolver.ts ×4
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 * as crypto from 'crypto';
7 > import * as fs from 'fs';
8 > import * as os from 'os';
9 > import { join } from '../../../../base/common/path.js';
10 > import { URI } from '../../../../base/common/uri.js';
11 > import { MessageAttachmentKind, type MessageAttachment, type MessageEmbeddedResourceAttachment } from '../../common/state/sessionState.js';
12 > import type { UserInput } from './protocol/generated/v2/UserInput.js';
13 > import type { TextElement } from './protocol/generated/v2/TextElement.js';
14 >
15 > /**
16 > * Translate the agent host's `(prompt, attachments)` shape into codex's
17 > * `turn/start.input[]`.
18 > *
19 > * Phase 2 minimum:
20 > * - The prompt text becomes a single `{ type: 'text' }` input item.
21 > * - `Resource` attachments referencing local files are inlined into the
22 > * text as `@<path>` mentions so codex's prompt template picks them up.
23 > * - `Simple` attachments with a `modelRepresentation` get appended to the
24 > * prompt text as a separate paragraph.
25 > * - `EmbeddedResource` attachments with an `image/*` content type are
26 > * written to a temp file and surfaced as `{ type: 'localImage' }`. The
27 > * returned files are tracked in `cleanupPaths` so the caller can unlink
28 > * them after the turn completes.
29 > * - `EmbeddedResource` attachments carrying textual content (e.g. the live
30 > * text of an unsaved / dirty editor or a code selection, which the client
31 > * inlines as a `text/plain` embedded resource) are base64-decoded and
32 > * inlined into the prompt as a labelled fenced block so codex sees the
33 > * exact in-memory content — a path mention would read the stale on-disk
34 > * file (or nothing at all for untitled buffers). Non-textual, non-image
35 > * embedded resources (e.g. `application/pdf`) are still dropped.
36 > *
37 > * Skill / app mentions are deferred to a later phase.
38 > */
39 > export interface IResolvedCodexInput {
40 > readonly input: ReadonlyArray<UserInput>;
41 > /** Temporary files created during resolution. Caller MUST unlink. */
42 > readonly cleanupPaths: readonly string[];
43 > }
44 >
45 > const EMPTY_TEXT_ELEMENTS: TextElement[] = [];
46 >
47 > export function resolveCodexInput(
48 > prompt: string, codexPromptResolver.ts ×2
49 > attachments: readonly MessageAttachment[] | undefined,
50 > ): IResolvedCodexInput {
51 > const cleanupPaths: string[] = [];
52 > const input: UserInput[] = [];
53 > const textChunks: string[] = [prompt];
54 >
55 > if (attachments && attachments.length > 0) {
56 > for (const att of attachments) { codexPromptResolver.ts ×4
57 > switch (att.type) {
58 > case MessageAttachmentKind.Resource: {
59 > // Resource attachments reference a URI (on the wire, codexPromptResolver.ts ×2
60 > // already a string). For file URIs we inline the
61 > // absolute path as a `@<path>` mention so the codex
62 > // prompt template can render / read it.
63 > const uri = URI.parse(att.uri);
64 > if (uri.scheme === 'file') {
65 > textChunks.push(`@${uri.fsPath}`);
66 > } else {
67 // Non-file URIs (vscode-userdata://, untitled://, …)
68 // are surfaced as a plain string so they still show
69 // up in the prompt, even if codex can't resolve them.
70 textChunks.push(uri.toString());
71 }
73 > }
74 > case MessageAttachmentKind.EmbeddedResource: { codexPromptResolver.ts ×4
75 > if (att.contentType.startsWith('image/')) { codexPromptResolver.ts ×1
76 > const ext = guessImageExtension(att.contentType); codexPromptResolver.ts ×8
77 > const tmp = join(os.tmpdir(), `codex-img-${crypto.randomBytes(8).toString('hex')}${ext}`);
78 > try {
79 > fs.writeFileSync(tmp, Buffer.from(att.data, 'base64'));
80 > cleanupPaths.push(tmp);
81 > input.push({ type: 'localImage', path: tmp });
82 > } catch {
83 // If writing the temp file fails, drop the
84 // attachment silently — better to send the prompt
85 // without the image than to fail the whole turn.
86 }
88 > }
89 > if (isTextualContentType(att.contentType)) { codexPromptResolver.ts ×3
90 > // The client inlines the live text of an unsaved / dirty codexPromptResolver.ts ×6
91 > // editor (or a selection within one) as a `text/plain`
92 > // embedded resource. Decode it and inline it into the
93 > // prompt so codex sees the exact in-memory content — a
94 > // `@<path>` mention would read the stale on-disk file (or
95 > // nothing at all for an untitled buffer).
96 > const inlined = renderTextualEmbeddedResource(att);
97 > if (inlined) {
98 > textChunks.push(inlined);
99 > }
100 > break;
101 > }
102 > // Non-textual, non-image embedded resources (e.g. codexPromptResolver.ts ×2
103 > // application/pdf) are not supported and are dropped.
104 > break;
105 > }
106 > case MessageAttachmentKind.Simple: { codexPromptResolver.ts ×4
107 > const rep = att.modelRepresentation; codexPromptResolver.ts ×1
108 > if (typeof rep === 'string' && rep.length > 0) {
109 > textChunks.push(rep);
110 > }
111 > break;
112 > }
114 > }
115 > }
117 > const text = textChunks.filter(s => s.length > 0).join('\n\n');
118 > // Always include a text input first, even if empty (codex needs at
119 > // least one element).
120 > input.unshift({ type: 'text', text, text_elements: EMPTY_TEXT_ELEMENTS });
121 >
122 > return { input, cleanupPaths };
123 > }
125 > function guessImageExtension(contentType: string): string { codexPromptResolver.ts ×8
126 > const subtype = contentType.slice('image/'.length).toLowerCase();
127 > switch (subtype) {
128 > case 'jpeg':
129 > case 'jpg':
130 return '.jpg';
131 > case 'png': codexPromptResolver.ts ×8
132 > return '.png';
133 > case 'gif':
134 return '.gif';
135 > case 'webp': codexPromptResolver.ts ×8
136 return '.webp';
137 > case 'bmp': codexPromptResolver.ts ×8
138 return '.bmp';
140 return '';
142 > }
144 > /**
145 > * Whether an embedded resource's content type carries UTF-8 text that can be
146 > * inlined into the prompt. Covers `text/*` plus a small allow-list of textual
147 > * `application/*` types. Anything else (e.g. `application/pdf`,
148 > * `application/octet-stream`) is treated as binary and dropped.
149 > */
150 > function isTextualContentType(contentType: string): boolean { codexPromptResolver.ts ×3
151 > const type = contentType.toLowerCase().split(';', 1)[0].trim();
152 > if (type.startsWith('text/')) {
153 > return true; codexPromptResolver.ts ×6
154 > }
155 > // Structured-text application subtypes and the `+json` / `+xml` suffixes. codexPromptResolver.ts ×2
156 > return type === 'application/json'
157 > || type === 'application/xml'
158 > || type === 'application/javascript'
159 > || type === 'application/typescript'
160 > || type.endsWith('+json')
161 > || type.endsWith('+xml');
164 > /**
165 > * Decode a textual {@link MessageEmbeddedResourceAttachment} (e.g. the live
166 > * text of an unsaved / dirty editor or a selection within one) and render it
167 > * as a labelled fenced block for inlining into the prompt. Returns `undefined`
168 > * when the payload decodes to empty text so the caller can skip it.
169 > */
170 > function renderTextualEmbeddedResource(att: MessageEmbeddedResourceAttachment): string | undefined { codexPromptResolver.ts ×6
171 > let content: string;
172 > try {
173 > content = Buffer.from(att.data, 'base64').toString('utf8');
174 > } catch {
175 return undefined;
176 }
177 > if (content.length === 0) { codexPromptResolver.ts ×6
178 return undefined;
179 }
180 > const label = att.label || 'attachment'; codexPromptResolver.ts ×6
181 > const range = att.selection?.range;
182 > // Positions on the wire are zero-based; render them one-based for humans.
183 > const suffix = range
184 > ? ` (lines ${range.start.line + 1}-${range.end.line + 1})` codexPromptResolver.ts ×1
186 > // A fenced block keeps the inlined text visually distinct from the prompt codexPromptResolver.ts ×6
187 > // and prevents backtick-free content from bleeding into surrounding markup.
188 > return `${label}${suffix}:\n\`\`\`\n${content}\n\`\`\``;
189 > }