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

217 LOC · 170 covered · 47 uncovered · 30 ranges · 36 concepts · 10 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 ×158codexReplayMapper.ts ×1 · 3 introduced LOCcodexReplayMapper.ts ×1codexReplayMapper.ts ×2 · 10 introduced LOCcodexReplayMapper.ts ×2codexReplayMapper.ts ×5 · 33 introduced LOCcodexReplayMapper.ts ×5codexReplayMapper.ts ×1 · 7 introduced LOCcodexReplayMapper.ts ×1codexReplayMapper.test|title=codexReplayMapper failed turn maps to TurnState.Error|occurrence=1 · 0 introduced LOCcodexReplayMapper.test|t…codexReplayMapper.ts ×3 · 19 introduced LOCcodexReplayMapper.ts ×3codexReplayMapper.ts ×2 · 3 introduced LOCcodexReplayMapper.ts ×2codexReplayMapper.ts ×1 · 1 introduced LOCcodexReplayMapper.ts ×1codexReplayMapper.ts ×7 · 32 introduced LOCcodexReplayMapper.ts ×7codexReplayMapper.ts ×2 · 4 introduced LOCcodexReplayMapper.ts ×2codexReplayMapper.ts ×6 · 58 introduced LOCcodexReplayMapper.ts ×6codexModelRefresh.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…codexReplayMapper.test|title=codexReplayMapper commandExecution coalesces a sandbox pre-flight with its re-run into one box|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/platform/agentHost/test/node/codex/codexReplayMapper.test|title=codexReplayMapper commandExecution coalesces a sandbox pre-flight with its re-run into one box|occurrence=1codexReplayMapper.test|t…codexReplayMapper.test|title=codexReplayMapper commandExecution renders a completed terminal tool call|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/platform/agentHost/test/node/codex/codexReplayMapper.test|title=codexReplayMapper commandExecution renders a completed terminal tool call|occurrence=1codexReplayMapper.test|t…codexReplayMapper.test|title=codexReplayMapper empty thread → no turns|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/platform/agentHost/test/node/codex/codexReplayMapper.test|title=codexReplayMapper empty thread → no turns|occurrence=1codexReplayMapper.test|t…codexReplayMapper.test|title=codexReplayMapper failed turn maps to TurnState.Error|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/platform/agentHost/test/node/codex/codexReplayMapper.test|title=codexReplayMapper failed turn maps to TurnState.Error|occurrence=1codexReplayMapper.test|t…codexReplayMapper.test|title=codexReplayMapper multi-turn thread preserves order|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/platform/agentHost/test/node/codex/codexReplayMapper.test|title=codexReplayMapper multi-turn thread preserves order|occurrence=1codexReplayMapper.test|t…agent exchange → one Turn|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/platform/agentHost/test/node/codex/codexReplayMapper.test|title=codexReplayMapper thread with one user/agent exchange → one Turn|occurrence=1agent exchange → one Tur…codexReplayMapper.test|title=codexReplayMapper turn with no recognizable items is dropped|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/platform/agentHost/test/node/codex/codexReplayMapper.test|title=codexReplayMapper turn with no recognizable items is dropped|occurrence=1codexReplayMapper.test|t…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/codexReplayMapper.ts · 217 LOCcodex/codexReplayMapper.…

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 > /*--------------------------------------------------------------------------------------------- codexReplayMapper.ts ×6
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 { generateUuid } from '../../../../base/common/uuid.js';
7 > import { toToolCallMeta } from '../../common/meta/agentToolCallMeta.js';
8 > import {
9 > MessageKind,
10 > ResponsePartKind,
11 > ToolCallConfirmationReason,
12 > ToolCallStatus,
13 > ToolResultContentType,
14 > type ResponsePart,
15 > type ToolCallResponsePart,
16 > type ToolResultContent,
17 > type Turn,
18 > } from '../../common/state/sessionState.js';
19 > import {
20 > describeFileChange,
21 > describeWebSearch,
22 > fileChangeOutput,
23 > turnStateFromStatus,
24 > } from './codexMapAppServerEvents.js';
25 > import { unwrapShellInvocation } from './codexShellCommand.js';
26 > import type { Thread } from './protocol/generated/v2/Thread.js';
27 > import type { ThreadItem } from './protocol/generated/v2/ThreadItem.js';
28 > import type { Turn as CodexTurn } from './protocol/generated/v2/Turn.js';
29 >
30 > /**
31 > * Reconstruct protocol {@link Turn}s from codex's `thread/read` response.
32 > *
33 > * Codex stores each conversation as a stream of {@link CodexTurn}, each
34 > * with an array of {@link ThreadItem}s. We collapse that into the agent
35 > * host's turn shape: each user message opens a turn; subsequent assistant
36 > * items become response parts on that turn until `turn/completed` closes it.
37 > *
38 > * Produces:
39 > * - `userMessage` → opens a `Turn` with `userMessage: { text }`
40 > * - `agentMessage` → `MarkdownResponsePart` with the full text
41 > * - `commandExecution` → completed terminal `ToolCallResponsePart`
42 > * - `webSearch` → completed web-search `ToolCallResponsePart`
43 > * - `fileChange` → completed file-edit `ToolCallResponsePart`
44 > * - everything else → currently dropped (reasoning/plan/mcp/collab)
45 > *
46 > * Mirrors the live mapper's translation kernel — including the sandbox
47 > * pre-flight coalescing (see {@link codexMapAppServerEvents}) — so restored
48 > * sessions render identically to active ones.
49 > */
50 > export function replayThreadToTurns(thread: Thread): Turn[] {
51 > const turns: Turn[] = []; codexReplayMapper.ts ×2
52 > for (const codexTurn of thread.turns ?? []) {
53 > const turn = replayTurnToTurn(codexTurn); codexReplayMapper.ts ×7
54 > if (turn) {
55 > turns.push(turn); codexReplayMapper.ts ×3
56 > }
58 > return turns; codexReplayMapper.ts ×2
59 > }
61 > /** A completed `commandExecution` item narrowed to its terminal fields. */
62 > type CommandExecutionItem = Extract<ThreadItem, { type: 'commandExecution' }>;
63 >
64 > function replayTurnToTurn(codexTurn: CodexTurn): Turn | undefined { codexReplayMapper.ts ×7
65 > let userText = '';
66 > const parts: ResponsePart[] = [];
67 > // A successful command that produced no output may be a sandbox pre-flight
68 > // that codex immediately re-ran under an approval prompt (same command, new
69 > // item). Defer emitting it so the re-run can coalesce into a single box —
70 > // mirroring the live mapper's `pendingPreflight` state machine.
71 > let pendingPreflight: { command: string; item: CommandExecutionItem } | undefined;
72 > const flushPreflight = () => {
73 > if (pendingPreflight) {
74 parts.push(shellToolCallPart(pendingPreflight.item, pendingPreflight.command));
75 pendingPreflight = undefined;
76 }
78 >
79 > for (const item of codexTurn.items ?? []) {
80 > if (item.type === 'commandExecution') {
81 > const command = unwrapShellInvocation(item.command ?? ''); codexReplayMapper.ts ×5
82 > if (pendingPreflight && pendingPreflight.command === command) {
83 > // Escalated re-run of the deferred pre-flight: render only this codexReplayMapper.ts ×2
84 > // item (it carries the real output/approval), dropping the
85 > // output-less pre-flight box.
86 > pendingPreflight = undefined;
87 > parts.push(shellToolCallPart(item, command));
88 > continue;
89 > }
90 > flushPreflight(); codexReplayMapper.ts ×5
91 > const success = item.status === 'completed' && (item.exitCode === 0 || item.exitCode === null);
92 > const output = item.aggregatedOutput ?? '';
93 > if (success && !output) {
94 > pendingPreflight = { command, item }; codexReplayMapper.ts ×2
95 > continue;
96 > }
97 > parts.push(shellToolCallPart(item, command)); codexReplayMapper.ts ×1
98 > continue;
99 > }
101 > // Any other item supersedes a deferred pre-flight: finalize it first so
102 > // a genuinely output-less command still renders as a single box.
103 > flushPreflight();
104 >
105 > if (item.type === 'userMessage') {
106 > const collected: string[] = []; codexReplayMapper.ts ×3
107 > for (const c of item.content) {
108 > if (c.type === 'text') {
109 > collected.push(c.text);
110 > }
111 > }
112 > if (collected.length > 0) {
113 > userText = collected.join('\n\n');
114 > }
115 > } else if (item.type === 'agentMessage') { codexReplayMapper.ts ×7
116 > if (item.text && item.text.length > 0) { codexReplayMapper.ts ×1
117 > parts.push({
118 > kind: ResponsePartKind.Markdown,
119 > id: generateUuid(),
120 > content: item.text,
121 > });
122 > }
123 > } else if (item.type === 'webSearch') { codexReplayMapper.ts ×1
124 parts.push(webSearchToolCallPart(item));
125 > } else if (item.type === 'fileChange') { codexReplayMapper.ts ×2
126 parts.push(fileChangeToolCallPart(item));
127 }
128 > // Other item types (plan/reasoning/mcpToolCall/collabAgentToolCall/…) codexReplayMapper.ts ×7
129 > // are not yet reconstructed in replay.
130 > }
131 > flushPreflight();
132 >
133 > // If we got nothing recognizable, drop the turn — there's nothing for
134 > // the UI to render.
135 > if (!userText && parts.length === 0) {
136 > return undefined; codexReplayMapper.ts ×2
137 > }
138 > return { codexReplayMapper.ts ×3
139 > id: codexTurn.id,
140 > message: { text: userText, origin: { kind: MessageKind.User } },
141 > responseParts: parts,
142 > usage: undefined,
143 > state: turnStateFromStatus(codexTurn.status),
144 > };
145 > }
147 > function textContent(output: string): ToolResultContent[] | undefined { codexReplayMapper.ts ×5
148 > return output ? [{ type: ToolResultContentType.Text, text: output }] : undefined;
149 > }
151 > function shellToolCallPart(item: CommandExecutionItem, command: string): ToolCallResponsePart { codexReplayMapper.ts ×5
152 > const success = item.status === 'completed' && (item.exitCode === 0 || item.exitCode === null);
153 > const output = item.aggregatedOutput ?? '';
154 > const exit = item.exitCode;
155 > const pastTense = success
156 > ? `Ran \`${command}\``
157 : exit !== null
158 ? `Ran \`${command}\` (exit ${exit})`
159 : `Ran \`${command}\` (failed)`;
160 > return { codexReplayMapper.ts ×5
161 > kind: ResponsePartKind.ToolCall,
162 > toolCall: {
163 > status: ToolCallStatus.Completed,
164 > toolCallId: generateUuid(),
165 > toolName: 'shell',
166 > displayName: 'Run shell command',
167 > _meta: toToolCallMeta({ toolKind: 'terminal' }),
168 > invocationMessage: command,
169 > toolInput: command,
170 > confirmed: ToolCallConfirmationReason.NotNeeded,
171 > success,
172 > pastTenseMessage: pastTense,
173 > content: textContent(output),
174 > error: success ? undefined : { message: exit !== null ? `Exit code ${exit}` : 'Command failed' },
175 > },
176 > };
177 > }
179 function webSearchToolCallPart(item: Extract<ThreadItem, { type: 'webSearch' }>): ToolCallResponsePart {
180 const query = describeWebSearch(item.query, item.action);
181 return {
182 kind: ResponsePartKind.ToolCall,
183 toolCall: {
184 status: ToolCallStatus.Completed,
185 toolCallId: generateUuid(),
186 toolName: 'web_search',
187 displayName: 'Web search',
188 _meta: toToolCallMeta({ toolKind: 'search' }),
189 invocationMessage: query,
190 toolInput: query,
191 confirmed: ToolCallConfirmationReason.NotNeeded,
192 success: true,
193 pastTenseMessage: `Searched ${query}`,
194 },
195 };
196 }
198 function fileChangeToolCallPart(item: Extract<ThreadItem, { type: 'fileChange' }>): ToolCallResponsePart {
199 const success = item.status === 'completed';
200 const summary = describeFileChange(item.changes) || 'Apply file changes';
201 const output = fileChangeOutput(item.changes);
202 return {
203 kind: ResponsePartKind.ToolCall,
204 toolCall: {
205 status: ToolCallStatus.Completed,
206 toolCallId: generateUuid(),
207 toolName: 'file_edit',
208 displayName: 'Apply file changes',
209 invocationMessage: summary,
210 confirmed: ToolCallConfirmationReason.NotNeeded,
211 success,
212 pastTenseMessage: success ? 'Applied file changes' : 'Failed to apply file changes',
213 content: textContent(output),
214 error: success ? undefined : { message: `Patch ${item.status}` },
215 },
216 };
217 }