@openclaw/codex 2026.5.26-beta.1 → 2026.5.26-beta.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/client-factory-fW4Hh9q_.js +15 -0
- package/dist/{command-handlers-D4C2y46B.js → command-handlers-hYTtzAdy.js} +4 -4
- package/dist/{compact-CRI0BEc_.js → compact-C_1JAB4C.js} +24 -1
- package/dist/{computer-use-CDDlIBhY.js → computer-use-DSdj1hJY.js} +1 -1
- package/dist/{conversation-binding-BnnjOmgs.js → conversation-binding-OjYqDwhw.js} +110 -84
- package/dist/{dynamic-tools-BG9ICyU4.js → dynamic-tools-DlEefKNQ.js} +61 -20
- package/dist/harness.js +4 -4
- package/dist/index.js +7 -6
- package/dist/media-understanding-provider.js +5 -5
- package/dist/{models-ASKu9eOY.js → models-_XwpqjR8.js} +5 -4
- package/dist/{protocol-validators-CSuFMLvY.js → protocol-validators-DtjYmUw_.js} +50 -412
- package/dist/provider.js +1 -1
- package/dist/{request-DmBkYLPy.js → request-OaxhR46w.js} +4 -3
- package/dist/{run-attempt-CFBsGx1T.js → run-attempt-D8Vxo-Jm.js} +293 -131
- package/dist/{shared-client-Fou5nAyt.js → shared-client-8kIrP817.js} +103 -9
- package/dist/{side-question-fq_T2d_x.js → side-question-DU7en3_R.js} +8 -7
- package/dist/test-api.js +2 -2
- package/dist/{thread-lifecycle-BapIT9Qs.js → thread-lifecycle-CUXQezJL.js} +4 -3
- package/dist/{vision-tools-B30YCKRK.js → vision-tools-DqpLmF5H.js} +3 -1
- package/npm-shrinkwrap.json +30 -30
- package/package.json +5 -5
- package/dist/client-factory-CaOpX89B.js +0 -9
|
@@ -1,16 +1,16 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { n as defaultLeasedCodexAppServerClientFactory } from "./client-factory-fW4Hh9q_.js";
|
|
2
2
|
import { c as readCodexPluginConfig, d as resolveCodexPluginsPolicy, f as shouldAutoApproveCodexAppServerApprovals, i as isCodexAppServerApprovalPolicyAllowedByRequirements, l as resolveCodexAppServerRuntimeOptions, o as isCodexSandboxExecServerEnabled, p as withMcpElicitationsApprovalPolicy, u as resolveCodexComputerUseConfig } from "./config-0-UN67Qg.js";
|
|
3
|
-
import { a as readCodexDynamicToolCallParams, c as readCodexTurn, i as assertCodexTurnStartResponse } from "./protocol-validators-
|
|
3
|
+
import { a as readCodexDynamicToolCallParams, c as readCodexTurn, i as assertCodexTurnStartResponse } from "./protocol-validators-DtjYmUw_.js";
|
|
4
4
|
import { a as isCodexAppServerConnectionClosedError, i as isCodexAppServerApprovalRequest, l as isJsonObject, r as compareCodexAppServerVersions, s as MIN_CODEX_SANDBOX_EXEC_SERVER_APP_SERVER_VERSION } from "./client-BVK_jmHW.js";
|
|
5
|
-
import { C as defaultCodexAppInventoryCache, D as projectContextEngineAssemblyForCodex, O as resolveCodexContextEngineProjectionMaxChars, T as sanitizeCodexHistoryImagePayloads, _ as buildCodexPluginThreadConfigInputFingerprint, a as buildDeveloperInstructions, c as buildTurnCollaborationMode, d as isContextEngineBindingCompatible, g as buildCodexPluginThreadConfig, h as isCodexAppServerProfilerEnabled, i as buildContextEngineBinding, k as resolveCodexContextEngineProjectionReserveTokens, l as buildTurnStartParams, m as startOrResumeThread, n as areCodexDynamicToolFingerprintsCompatible, u as codexDynamicToolsFingerprint, v as mergeCodexThreadConfigs, y as shouldBuildCodexPluginThreadConfig } from "./thread-lifecycle-
|
|
5
|
+
import { C as defaultCodexAppInventoryCache, D as projectContextEngineAssemblyForCodex, O as resolveCodexContextEngineProjectionMaxChars, T as sanitizeCodexHistoryImagePayloads, _ as buildCodexPluginThreadConfigInputFingerprint, a as buildDeveloperInstructions, c as buildTurnCollaborationMode, d as isContextEngineBindingCompatible, g as buildCodexPluginThreadConfig, h as isCodexAppServerProfilerEnabled, i as buildContextEngineBinding, k as resolveCodexContextEngineProjectionReserveTokens, l as buildTurnStartParams, m as startOrResumeThread, n as areCodexDynamicToolFingerprintsCompatible, u as codexDynamicToolsFingerprint, v as mergeCodexThreadConfigs, y as shouldBuildCodexPluginThreadConfig } from "./thread-lifecycle-CUXQezJL.js";
|
|
6
6
|
import { i as readCodexAppServerBinding, t as clearCodexAppServerBinding } from "./session-binding-UFjjws4k.js";
|
|
7
|
-
import { n as buildCodexPluginAppCacheKey, r as CODEX_CONTROL_METHODS } from "./request-
|
|
7
|
+
import { n as buildCodexPluginAppCacheKey, r as CODEX_CONTROL_METHODS } from "./request-OaxhR46w.js";
|
|
8
8
|
import { g as shouldRefreshCodexRateLimitsForUsageLimitMessage, h as resolveCodexUsageLimitResetAtMs, i as readCodexNotificationTurnId, m as formatCodexUsageLimitErrorMessage, n as isCodexNotificationForTurn, r as readCodexNotificationThreadId, s as formatCodexDisplayText, t as describeCodexNotificationCorrelation } from "./notification-correlation-YINts3PA.js";
|
|
9
|
-
import {
|
|
9
|
+
import { a as releaseLeasedSharedCodexAppServerClient, d as resolveCodexAppServerAuthProfileId, f as resolveCodexAppServerAuthProfileIdForAgent, l as refreshCodexAppServerAuthTokens, m as resolveCodexAppServerHomeDir, o as retireSharedCodexAppServerClientIfCurrent, p as resolveCodexAppServerFallbackApiKeyCacheKey, t as clearSharedCodexAppServerClientIfCurrent, u as resolveCodexAppServerAuthAccountCacheKey } from "./shared-client-8kIrP817.js";
|
|
10
10
|
import { i as resolveCodexNativeExecutionPolicy } from "./sandbox-guard-CTnEWuor.js";
|
|
11
|
-
import { a as resolveCodexDynamicToolsLoading, i as normalizeCodexDynamicToolName, n as filterCodexDynamicTools, r as isForcedPrivateQaCodexRuntime, t as createCodexDynamicToolBridge } from "./dynamic-tools-
|
|
12
|
-
import { a as handleCodexAppServerElicitationRequest, c as emitDynamicToolTerminalDiagnostic, i as buildCodexNativeHookRelayDisabledConfig, l as handleCodexAppServerApprovalRequest, n as CODEX_NATIVE_HOOK_RELAY_EVENTS, o as emitDynamicToolErrorDiagnostic, r as buildCodexNativeHookRelayConfig, s as emitDynamicToolStartedDiagnostic, t as filterToolsForVisionInputs } from "./vision-tools-
|
|
13
|
-
import { t as ensureCodexComputerUse } from "./computer-use-
|
|
11
|
+
import { a as resolveCodexDynamicToolsLoading, i as normalizeCodexDynamicToolName, n as filterCodexDynamicTools, r as isForcedPrivateQaCodexRuntime, t as createCodexDynamicToolBridge } from "./dynamic-tools-DlEefKNQ.js";
|
|
12
|
+
import { a as handleCodexAppServerElicitationRequest, c as emitDynamicToolTerminalDiagnostic, i as buildCodexNativeHookRelayDisabledConfig, l as handleCodexAppServerApprovalRequest, n as CODEX_NATIVE_HOOK_RELAY_EVENTS, o as emitDynamicToolErrorDiagnostic, r as buildCodexNativeHookRelayConfig, s as emitDynamicToolStartedDiagnostic, t as filterToolsForVisionInputs } from "./vision-tools-DqpLmF5H.js";
|
|
13
|
+
import { t as ensureCodexComputerUse } from "./computer-use-DSdj1hJY.js";
|
|
14
14
|
import { n as rememberCodexRateLimits, t as readRecentCodexRateLimits } from "./rate-limit-cache-N66I-Rd7.js";
|
|
15
15
|
import { createHash, randomUUID } from "node:crypto";
|
|
16
16
|
import fsSync from "node:fs";
|
|
@@ -108,7 +108,7 @@ function buildSenderLabel(params) {
|
|
|
108
108
|
if (!params.senderId || label.includes(params.senderId)) return label;
|
|
109
109
|
return `${label} (${params.senderId})`;
|
|
110
110
|
}
|
|
111
|
-
function
|
|
111
|
+
function buildCodexUserPromptMessageFromPrepared(params, preparedUserMessage) {
|
|
112
112
|
const senderId = normalizeOptionalString(params.senderId);
|
|
113
113
|
const senderName = normalizeOptionalString(params.senderName);
|
|
114
114
|
const senderUsername = normalizeOptionalString(params.senderUsername);
|
|
@@ -120,6 +120,18 @@ function buildCodexUserPromptMessage(params) {
|
|
|
120
120
|
senderE164
|
|
121
121
|
});
|
|
122
122
|
const sourceChannel = normalizeOptionalString(params.inputProvenance?.sourceChannel ?? params.messageChannel ?? params.messageProvider);
|
|
123
|
+
if (preparedUserMessage) return {
|
|
124
|
+
role: "user",
|
|
125
|
+
timestamp: Date.now(),
|
|
126
|
+
...params.inputProvenance ? { provenance: params.inputProvenance } : {},
|
|
127
|
+
...sourceChannel ? { sourceChannel } : {},
|
|
128
|
+
...senderId ? { senderId } : {},
|
|
129
|
+
...senderName ? { senderName } : {},
|
|
130
|
+
...senderUsername ? { senderUsername } : {},
|
|
131
|
+
...senderE164 ? { senderE164 } : {},
|
|
132
|
+
...senderLabel ? { senderLabel } : {},
|
|
133
|
+
...preparedUserMessage
|
|
134
|
+
};
|
|
123
135
|
return {
|
|
124
136
|
role: "user",
|
|
125
137
|
content: params.prompt,
|
|
@@ -133,6 +145,12 @@ function buildCodexUserPromptMessage(params) {
|
|
|
133
145
|
...senderLabel ? { senderLabel } : {}
|
|
134
146
|
};
|
|
135
147
|
}
|
|
148
|
+
function buildCodexUserPromptMessage(params) {
|
|
149
|
+
return buildCodexUserPromptMessageFromPrepared(params, params.userTurnTranscriptRecorder?.message);
|
|
150
|
+
}
|
|
151
|
+
async function buildResolvedCodexUserPromptMessage(params) {
|
|
152
|
+
return buildCodexUserPromptMessageFromPrepared(params, await params.userTurnTranscriptRecorder?.resolveMessage() ?? params.userTurnTranscriptRecorder?.message);
|
|
153
|
+
}
|
|
136
154
|
/**
|
|
137
155
|
* Tag a message with a stable logical identity for mirror dedupe. Callers
|
|
138
156
|
* should use a value that is invariant for the same logical message across
|
|
@@ -174,24 +192,30 @@ function buildMirrorDedupeIdentity(message) {
|
|
|
174
192
|
}
|
|
175
193
|
async function mirrorCodexAppServerTranscript(params) {
|
|
176
194
|
const messages = params.messages.filter((message) => message.role === "user" || message.role === "assistant" || message.role === "toolResult");
|
|
177
|
-
if (messages.length === 0) return;
|
|
195
|
+
if (messages.length === 0) return { userMessagesPresent: [] };
|
|
178
196
|
const lock = await acquireSessionWriteLock({
|
|
179
197
|
sessionFile: params.sessionFile,
|
|
180
198
|
...resolveSessionWriteLockOptions(params.config)
|
|
181
199
|
});
|
|
182
200
|
const appendedUpdates = [];
|
|
201
|
+
const userMessagesPresent = [];
|
|
183
202
|
try {
|
|
184
203
|
const mirrorState = await readTranscriptMirrorState(params.sessionFile);
|
|
185
204
|
let nextMessageSeq = mirrorState.messageCount;
|
|
186
205
|
for (const message of messages) {
|
|
187
206
|
const dedupeIdentity = buildMirrorDedupeIdentity(message);
|
|
188
207
|
const idempotencyKey = params.idempotencyScope ? `${params.idempotencyScope}:${dedupeIdentity}` : void 0;
|
|
189
|
-
|
|
208
|
+
const transcriptMessage = {
|
|
209
|
+
...message,
|
|
210
|
+
...idempotencyKey ? { idempotencyKey } : {}
|
|
211
|
+
};
|
|
212
|
+
if (idempotencyKey && mirrorState.idempotencyKeys.has(idempotencyKey)) {
|
|
213
|
+
const persistedUserMessage = mirrorState.userMessagesByIdempotencyKey.get(idempotencyKey);
|
|
214
|
+
if (persistedUserMessage) userMessagesPresent.push(persistedUserMessage);
|
|
215
|
+
continue;
|
|
216
|
+
}
|
|
190
217
|
const nextMessage = runAgentHarnessBeforeMessageWriteHook({
|
|
191
|
-
message:
|
|
192
|
-
...message,
|
|
193
|
-
...idempotencyKey ? { idempotencyKey } : {}
|
|
194
|
-
},
|
|
218
|
+
message: transcriptMessage,
|
|
195
219
|
agentId: params.agentId,
|
|
196
220
|
sessionKey: params.sessionKey
|
|
197
221
|
});
|
|
@@ -203,8 +227,13 @@ async function mirrorCodexAppServerTranscript(params) {
|
|
|
203
227
|
const { messageId, message: appendedMessage } = await appendSessionTranscriptMessage({
|
|
204
228
|
transcriptPath: params.sessionFile,
|
|
205
229
|
message: messageToAppend,
|
|
230
|
+
idempotencyLookup: idempotencyKey ? "caller-checked" : "scan",
|
|
206
231
|
config: params.config
|
|
207
232
|
});
|
|
233
|
+
if (appendedMessage.role === "user") {
|
|
234
|
+
userMessagesPresent.push(appendedMessage);
|
|
235
|
+
if (idempotencyKey) mirrorState.userMessagesByIdempotencyKey.set(idempotencyKey, appendedMessage);
|
|
236
|
+
}
|
|
208
237
|
nextMessageSeq += 1;
|
|
209
238
|
appendedUpdates.push({
|
|
210
239
|
messageId,
|
|
@@ -223,9 +252,11 @@ async function mirrorCodexAppServerTranscript(params) {
|
|
|
223
252
|
messageId: update.messageId,
|
|
224
253
|
messageSeq: update.messageSeq
|
|
225
254
|
});
|
|
255
|
+
return { userMessagesPresent };
|
|
226
256
|
}
|
|
227
257
|
async function readTranscriptMirrorState(sessionFile) {
|
|
228
258
|
const idempotencyKeys = /* @__PURE__ */ new Set();
|
|
259
|
+
const userMessagesByIdempotencyKey = /* @__PURE__ */ new Map();
|
|
229
260
|
let messageCount = 0;
|
|
230
261
|
let raw;
|
|
231
262
|
try {
|
|
@@ -234,7 +265,8 @@ async function readTranscriptMirrorState(sessionFile) {
|
|
|
234
265
|
if (error.code !== "ENOENT") throw error;
|
|
235
266
|
return {
|
|
236
267
|
idempotencyKeys,
|
|
237
|
-
messageCount
|
|
268
|
+
messageCount,
|
|
269
|
+
userMessagesByIdempotencyKey
|
|
238
270
|
};
|
|
239
271
|
}
|
|
240
272
|
for (const line of raw.split(/\r?\n/)) {
|
|
@@ -242,14 +274,18 @@ async function readTranscriptMirrorState(sessionFile) {
|
|
|
242
274
|
try {
|
|
243
275
|
const parsed = JSON.parse(line);
|
|
244
276
|
if (parsed.type === "message") messageCount += 1;
|
|
245
|
-
if (typeof parsed.message?.idempotencyKey === "string")
|
|
277
|
+
if (typeof parsed.message?.idempotencyKey === "string") {
|
|
278
|
+
idempotencyKeys.add(parsed.message.idempotencyKey);
|
|
279
|
+
if (parsed.message.role === "user") userMessagesByIdempotencyKey.set(parsed.message.idempotencyKey, parsed.message);
|
|
280
|
+
}
|
|
246
281
|
} catch {
|
|
247
282
|
continue;
|
|
248
283
|
}
|
|
249
284
|
}
|
|
250
285
|
return {
|
|
251
286
|
idempotencyKeys,
|
|
252
|
-
messageCount
|
|
287
|
+
messageCount,
|
|
288
|
+
userMessagesByIdempotencyKey
|
|
253
289
|
};
|
|
254
290
|
}
|
|
255
291
|
//#endregion
|
|
@@ -4312,7 +4348,7 @@ function readRequestId(record) {
|
|
|
4312
4348
|
}
|
|
4313
4349
|
//#endregion
|
|
4314
4350
|
//#region extensions/codex/src/app-server/run-attempt.ts
|
|
4315
|
-
const CODEX_DYNAMIC_TOOL_TIMEOUT_MS =
|
|
4351
|
+
const CODEX_DYNAMIC_TOOL_TIMEOUT_MS = 9e4;
|
|
4316
4352
|
const CODEX_DYNAMIC_TOOL_MAX_TIMEOUT_MS = 6e5;
|
|
4317
4353
|
const CODEX_DYNAMIC_IMAGE_GENERATION_TOOL_TIMEOUT_MS = 12e4;
|
|
4318
4354
|
const CODEX_DYNAMIC_IMAGE_TOOL_TIMEOUT_MS = 6e4;
|
|
@@ -4799,7 +4835,7 @@ async function runCodexAppServerAttempt(params, options = {}) {
|
|
|
4799
4835
|
let codexModelCallTerminalEmitted = false;
|
|
4800
4836
|
let codexModelCallRequestPayloadBytes;
|
|
4801
4837
|
const preDynamicStartupStages = createCodexDynamicToolBuildStageTracker({ enabled: profilerEnabled });
|
|
4802
|
-
const attemptClientFactory = options.clientFactory ??
|
|
4838
|
+
const attemptClientFactory = options.clientFactory ?? defaultLeasedCodexAppServerClientFactory;
|
|
4803
4839
|
const pluginConfig = readCodexPluginConfig(options.pluginConfig);
|
|
4804
4840
|
const computerUseConfig = resolveCodexComputerUseConfig({ pluginConfig });
|
|
4805
4841
|
const configuredAppServer = resolveCodexAppServerRuntimeOptions({ pluginConfig });
|
|
@@ -5150,6 +5186,7 @@ async function runCodexAppServerAttempt(params, options = {}) {
|
|
|
5150
5186
|
let thread;
|
|
5151
5187
|
let trajectoryEndRecorded = false;
|
|
5152
5188
|
let nativeHookRelay;
|
|
5189
|
+
let releaseSharedClientLease;
|
|
5153
5190
|
let startupClientForCleanup;
|
|
5154
5191
|
let sandboxExecEnvironmentAcquired = false;
|
|
5155
5192
|
const releaseSandboxExecEnvironment = async () => {
|
|
@@ -5233,106 +5270,120 @@ async function runCodexAppServerAttempt(params, options = {}) {
|
|
|
5233
5270
|
operation: async () => {
|
|
5234
5271
|
let attemptedClient;
|
|
5235
5272
|
const startupAttempt = async () => {
|
|
5236
|
-
|
|
5237
|
-
|
|
5238
|
-
startupClientForCleanup = startupClient;
|
|
5239
|
-
await ensureCodexComputerUse({
|
|
5240
|
-
client: startupClient,
|
|
5241
|
-
pluginConfig,
|
|
5242
|
-
timeoutMs: appServer.requestTimeoutMs,
|
|
5243
|
-
signal: runAbortController.signal
|
|
5244
|
-
});
|
|
5245
|
-
let startupSandboxEnvironment;
|
|
5246
|
-
let startupSandboxEnvironmentAcquired = false;
|
|
5247
|
-
const releaseStartupSandboxEnvironment = async () => {
|
|
5248
|
-
if (startupSandboxEnvironmentAcquired) {
|
|
5249
|
-
startupSandboxEnvironmentAcquired = false;
|
|
5250
|
-
await releaseCodexSandboxExecServerEnvironment(sandbox);
|
|
5251
|
-
}
|
|
5252
|
-
};
|
|
5253
|
-
releaseStartupResourcesOnTimeout = releaseStartupSandboxEnvironment;
|
|
5273
|
+
let startupClientLease;
|
|
5274
|
+
let startupAttemptSucceeded = false;
|
|
5254
5275
|
try {
|
|
5255
|
-
|
|
5256
|
-
|
|
5257
|
-
|
|
5258
|
-
|
|
5259
|
-
|
|
5276
|
+
const startupClient = await attemptClientFactory(appServer.start, startupAuthProfileId, agentDir, params.config);
|
|
5277
|
+
startupClientLease = () => {
|
|
5278
|
+
releaseLeasedSharedCodexAppServerClient(startupClient);
|
|
5279
|
+
};
|
|
5280
|
+
releaseSharedClientLease = startupClientLease;
|
|
5281
|
+
attemptedClient = startupClient;
|
|
5282
|
+
startupClientForCleanup = startupClient;
|
|
5283
|
+
await ensureCodexComputerUse({
|
|
5260
5284
|
client: startupClient,
|
|
5261
|
-
|
|
5262
|
-
appServerStartOptions: appServer.start,
|
|
5285
|
+
pluginConfig,
|
|
5263
5286
|
timeoutMs: appServer.requestTimeoutMs,
|
|
5264
5287
|
signal: runAbortController.signal
|
|
5265
|
-
})
|
|
5266
|
-
|
|
5267
|
-
|
|
5268
|
-
|
|
5269
|
-
|
|
5270
|
-
|
|
5271
|
-
|
|
5272
|
-
|
|
5273
|
-
|
|
5274
|
-
|
|
5275
|
-
|
|
5276
|
-
|
|
5277
|
-
|
|
5278
|
-
|
|
5279
|
-
|
|
5280
|
-
|
|
5281
|
-
|
|
5282
|
-
|
|
5283
|
-
|
|
5284
|
-
|
|
5285
|
-
|
|
5286
|
-
|
|
5287
|
-
|
|
5288
|
-
|
|
5289
|
-
|
|
5290
|
-
|
|
5291
|
-
|
|
5292
|
-
|
|
5293
|
-
|
|
5294
|
-
nativeCodeModeOnlyEnabled: appServer.codeModeOnly,
|
|
5295
|
-
userMcpServersEnabled: nativeToolSurfaceEnabled,
|
|
5296
|
-
mcpServersFingerprint: bundleMcpThreadConfig.fingerprint,
|
|
5297
|
-
mcpServersFingerprintEvaluated: bundleMcpThreadConfig.evaluated,
|
|
5298
|
-
environmentSelection: startupEnvironmentSelection,
|
|
5299
|
-
contextEngineProjection,
|
|
5300
|
-
pluginThreadConfig: pluginThreadConfigRequired ? {
|
|
5301
|
-
enabled: true,
|
|
5302
|
-
inputFingerprint: pluginThreadConfigInputFingerprint,
|
|
5303
|
-
enabledPluginConfigKeys,
|
|
5304
|
-
build: () => buildCodexPluginThreadConfig({
|
|
5305
|
-
pluginConfig: pluginThreadConfigPluginConfig,
|
|
5306
|
-
request: (method, requestParams) => startupClient.request(method, requestParams, {
|
|
5307
|
-
timeoutMs: appServer.requestTimeoutMs,
|
|
5308
|
-
signal: runAbortController.signal
|
|
5309
|
-
}),
|
|
5310
|
-
appCache: defaultCodexAppInventoryCache,
|
|
5311
|
-
appCacheKey: pluginAppCacheKey
|
|
5312
|
-
})
|
|
5313
|
-
} : void 0
|
|
5314
|
-
});
|
|
5315
|
-
try {
|
|
5316
|
-
restartContextEngineCodexThread = () => startOrResumeThread(buildThreadLifecycleParams());
|
|
5317
|
-
const startupThread = await startOrResumeThread(buildThreadLifecycleParams());
|
|
5318
|
-
if (runAbortController.signal.aborted) {
|
|
5288
|
+
});
|
|
5289
|
+
let startupSandboxEnvironment;
|
|
5290
|
+
let startupSandboxEnvironmentAcquired = false;
|
|
5291
|
+
const releaseStartupSandboxEnvironment = async () => {
|
|
5292
|
+
if (startupSandboxEnvironmentAcquired) {
|
|
5293
|
+
startupSandboxEnvironmentAcquired = false;
|
|
5294
|
+
await releaseCodexSandboxExecServerEnvironment(sandbox);
|
|
5295
|
+
}
|
|
5296
|
+
};
|
|
5297
|
+
releaseStartupResourcesOnTimeout = releaseStartupSandboxEnvironment;
|
|
5298
|
+
try {
|
|
5299
|
+
startupSandboxEnvironment = shouldRequireCodexSandboxExecServerEnvironment({
|
|
5300
|
+
sandbox,
|
|
5301
|
+
nativeToolSurfaceEnabled,
|
|
5302
|
+
sandboxExecServerEnabled
|
|
5303
|
+
}) ? await ensureCodexSandboxExecServerEnvironment({
|
|
5304
|
+
client: startupClient,
|
|
5305
|
+
sandbox: sandbox ?? null,
|
|
5306
|
+
appServerStartOptions: appServer.start,
|
|
5307
|
+
timeoutMs: appServer.requestTimeoutMs,
|
|
5308
|
+
signal: runAbortController.signal
|
|
5309
|
+
}) : void 0;
|
|
5310
|
+
startupSandboxEnvironmentAcquired = Boolean(startupSandboxEnvironment);
|
|
5311
|
+
if (runAbortController.signal.aborted) {
|
|
5312
|
+
await releaseStartupSandboxEnvironment();
|
|
5313
|
+
throw new Error("codex app-server startup aborted");
|
|
5314
|
+
}
|
|
5315
|
+
if (sandbox?.enabled && nativeToolSurfaceEnabled && sandboxExecServerEnabled && !startupSandboxEnvironment) throw new Error("Codex app-server did not register an OpenClaw sandbox exec-server environment.");
|
|
5316
|
+
} catch (error) {
|
|
5319
5317
|
await releaseStartupSandboxEnvironment();
|
|
5320
|
-
throw
|
|
5318
|
+
throw error;
|
|
5321
5319
|
}
|
|
5322
|
-
|
|
5323
|
-
|
|
5320
|
+
const startupEnvironmentSelection = resolveCodexSandboxEnvironmentSelection(startupSandboxEnvironment, nativeToolSurfaceEnabled);
|
|
5321
|
+
const startupExecutionCwd = resolveCodexAppServerExecutionCwd({
|
|
5322
|
+
effectiveWorkspace,
|
|
5323
|
+
environment: startupSandboxEnvironment,
|
|
5324
|
+
nativeToolSurfaceEnabled
|
|
5325
|
+
});
|
|
5326
|
+
const startupSandboxPolicy = startupSandboxEnvironment ? resolveCodexExternalSandboxPolicyForOpenClawSandbox(sandbox) : void 0;
|
|
5327
|
+
const buildThreadLifecycleParams = () => ({
|
|
5324
5328
|
client: startupClient,
|
|
5325
|
-
|
|
5326
|
-
|
|
5329
|
+
params: buildActiveRunAttemptParams(),
|
|
5330
|
+
agentId: sessionAgentId,
|
|
5331
|
+
cwd: startupExecutionCwd,
|
|
5332
|
+
dynamicTools: toolBridge.specs,
|
|
5333
|
+
appServer: pluginAppServer,
|
|
5334
|
+
developerInstructions: promptBuild.developerInstructions,
|
|
5335
|
+
config: threadConfig,
|
|
5336
|
+
finalConfigPatch: nativeHookRelayConfig,
|
|
5337
|
+
nativeCodeModeEnabled: nativeToolSurfaceEnabled,
|
|
5338
|
+
nativeCodeModeOnlyEnabled: appServer.codeModeOnly,
|
|
5339
|
+
userMcpServersEnabled: nativeToolSurfaceEnabled,
|
|
5340
|
+
mcpServersFingerprint: bundleMcpThreadConfig.fingerprint,
|
|
5341
|
+
mcpServersFingerprintEvaluated: bundleMcpThreadConfig.evaluated,
|
|
5327
5342
|
environmentSelection: startupEnvironmentSelection,
|
|
5328
|
-
|
|
5329
|
-
|
|
5330
|
-
|
|
5331
|
-
|
|
5332
|
-
|
|
5333
|
-
|
|
5343
|
+
contextEngineProjection,
|
|
5344
|
+
pluginThreadConfig: pluginThreadConfigRequired ? {
|
|
5345
|
+
enabled: true,
|
|
5346
|
+
inputFingerprint: pluginThreadConfigInputFingerprint,
|
|
5347
|
+
enabledPluginConfigKeys,
|
|
5348
|
+
build: () => buildCodexPluginThreadConfig({
|
|
5349
|
+
pluginConfig: pluginThreadConfigPluginConfig,
|
|
5350
|
+
request: (method, requestParams) => startupClient.request(method, requestParams, {
|
|
5351
|
+
timeoutMs: appServer.requestTimeoutMs,
|
|
5352
|
+
signal: runAbortController.signal
|
|
5353
|
+
}),
|
|
5354
|
+
appCache: defaultCodexAppInventoryCache,
|
|
5355
|
+
appCacheKey: pluginAppCacheKey
|
|
5356
|
+
})
|
|
5357
|
+
} : void 0
|
|
5358
|
+
});
|
|
5359
|
+
try {
|
|
5360
|
+
restartContextEngineCodexThread = () => startOrResumeThread(buildThreadLifecycleParams());
|
|
5361
|
+
const startupThread = await startOrResumeThread(buildThreadLifecycleParams());
|
|
5362
|
+
if (runAbortController.signal.aborted) {
|
|
5363
|
+
await releaseStartupSandboxEnvironment();
|
|
5364
|
+
throw new Error("codex app-server startup aborted");
|
|
5365
|
+
}
|
|
5366
|
+
startupSandboxEnvironmentAcquired = false;
|
|
5367
|
+
startupAttemptSucceeded = true;
|
|
5368
|
+
return {
|
|
5369
|
+
client: startupClient,
|
|
5370
|
+
thread: startupThread,
|
|
5371
|
+
sandboxEnvironment: startupSandboxEnvironment,
|
|
5372
|
+
environmentSelection: startupEnvironmentSelection,
|
|
5373
|
+
executionCwd: startupExecutionCwd,
|
|
5374
|
+
sandboxPolicy: startupSandboxPolicy
|
|
5375
|
+
};
|
|
5376
|
+
} catch (error) {
|
|
5377
|
+
await releaseStartupSandboxEnvironment();
|
|
5378
|
+
throw error;
|
|
5379
|
+
} finally {
|
|
5380
|
+
if (releaseStartupResourcesOnTimeout === releaseStartupSandboxEnvironment) releaseStartupResourcesOnTimeout = void 0;
|
|
5381
|
+
}
|
|
5334
5382
|
} finally {
|
|
5335
|
-
if (
|
|
5383
|
+
if (!startupAttemptSucceeded) {
|
|
5384
|
+
if (releaseSharedClientLease === startupClientLease) releaseSharedClientLease = void 0;
|
|
5385
|
+
startupClientLease?.();
|
|
5386
|
+
}
|
|
5336
5387
|
}
|
|
5337
5388
|
};
|
|
5338
5389
|
for (let attempt = 1; attempt <= CODEX_APP_SERVER_STARTUP_CONNECTION_CLOSE_MAX_ATTEMPTS; attempt += 1) try {
|
|
@@ -5539,7 +5590,7 @@ async function runCodexAppServerAttempt(params, options = {}) {
|
|
|
5539
5590
|
runAbortController.abort("turn_progress_idle_timeout");
|
|
5540
5591
|
};
|
|
5541
5592
|
const fireTurnCompletionIdleTimeout = () => {
|
|
5542
|
-
if (completed || runAbortController.signal.aborted || !turnCompletionIdleWatchArmed || activeAppServerTurnRequests > 0) return;
|
|
5593
|
+
if (completed || terminalTurnNotificationQueued || runAbortController.signal.aborted || !turnCompletionIdleWatchArmed || activeAppServerTurnRequests > 0) return;
|
|
5543
5594
|
const timeoutMs = turnCompletionIdleTimeoutOverrideMs ?? turnCompletionIdleTimeoutMs;
|
|
5544
5595
|
const idleMs = Math.max(0, Date.now() - turnCompletionLastActivityAt);
|
|
5545
5596
|
if (idleMs < timeoutMs) {
|
|
@@ -5569,7 +5620,7 @@ async function runCodexAppServerAttempt(params, options = {}) {
|
|
|
5569
5620
|
runAbortController.abort("turn_completion_idle_timeout");
|
|
5570
5621
|
};
|
|
5571
5622
|
const fireTurnTerminalIdleTimeout = () => {
|
|
5572
|
-
if (completed || runAbortController.signal.aborted || !turnTerminalIdleWatchArmed || activeAppServerTurnRequests > 0) return;
|
|
5623
|
+
if (completed || terminalTurnNotificationQueued || runAbortController.signal.aborted || !turnTerminalIdleWatchArmed || activeAppServerTurnRequests > 0) return;
|
|
5573
5624
|
const idleMs = Math.max(0, Date.now() - turnCompletionLastActivityAt);
|
|
5574
5625
|
if (idleMs < turnTerminalIdleTimeoutMs) {
|
|
5575
5626
|
scheduleTurnTerminalIdleWatch();
|
|
@@ -5891,7 +5942,7 @@ async function runCodexAppServerAttempt(params, options = {}) {
|
|
|
5891
5942
|
threadId: thread.threadId,
|
|
5892
5943
|
...turnId ? { turnId } : {}
|
|
5893
5944
|
});
|
|
5894
|
-
embeddedAgentLog.
|
|
5945
|
+
embeddedAgentLog.trace("codex app-server raw notification received", correlation);
|
|
5895
5946
|
if (notification.method === "turn/completed" && correlation.matchesActiveTurn === false) if (correlation.matchesActiveThread) embeddedAgentLog.warn("codex app-server turn/completed did not match active turn", correlation);
|
|
5896
5947
|
else embeddedAgentLog.debug("codex app-server turn/completed ignored for other subscribed thread", correlation);
|
|
5897
5948
|
if (isCodexNotificationOutsideActiveRun(correlation)) return Promise.resolve();
|
|
@@ -5901,6 +5952,13 @@ async function runCodexAppServerAttempt(params, options = {}) {
|
|
|
5901
5952
|
return Promise.resolve();
|
|
5902
5953
|
}
|
|
5903
5954
|
if (isTerminalTurnNotificationForTurn(notification, turnId)) terminalTurnNotificationQueued = true;
|
|
5955
|
+
if (correlation.matchesActiveTurn !== false) {
|
|
5956
|
+
const now = Date.now();
|
|
5957
|
+
turnCompletionLastActivityAt = now;
|
|
5958
|
+
turnCompletionLastActivityReason = `notification:${notification.method}`;
|
|
5959
|
+
turnAttemptLastProgressAt = now;
|
|
5960
|
+
turnAttemptLastProgressReason = `notification:${notification.method}`;
|
|
5961
|
+
}
|
|
5904
5962
|
notificationQueue = notificationQueue.then(() => handleNotification(notification), () => handleNotification(notification));
|
|
5905
5963
|
return notificationQueue;
|
|
5906
5964
|
};
|
|
@@ -6352,6 +6410,8 @@ async function runCodexAppServerAttempt(params, options = {}) {
|
|
|
6352
6410
|
}
|
|
6353
6411
|
});
|
|
6354
6412
|
params.abortSignal?.removeEventListener("abort", abortFromUpstream);
|
|
6413
|
+
releaseSharedClientLease?.();
|
|
6414
|
+
releaseSharedClientLease = void 0;
|
|
6355
6415
|
if (usageLimitError) {
|
|
6356
6416
|
await markCodexAuthProfileBlockedFromRateLimits({
|
|
6357
6417
|
params,
|
|
@@ -6368,7 +6428,11 @@ async function runCodexAppServerAttempt(params, options = {}) {
|
|
|
6368
6428
|
throw turnStartError;
|
|
6369
6429
|
}
|
|
6370
6430
|
}
|
|
6371
|
-
if (!turn)
|
|
6431
|
+
if (!turn) {
|
|
6432
|
+
releaseSharedClientLease?.();
|
|
6433
|
+
releaseSharedClientLease = void 0;
|
|
6434
|
+
throw new Error("codex app-server turn/start failed without an error");
|
|
6435
|
+
}
|
|
6372
6436
|
turnId = turn.turn.id;
|
|
6373
6437
|
const activeTurnId = turn.turn.id;
|
|
6374
6438
|
emitExecutionPhaseOnce("turn_accepted", { phase: "turn_accepted" });
|
|
@@ -6440,9 +6504,11 @@ async function runCodexAppServerAttempt(params, options = {}) {
|
|
|
6440
6504
|
abort: () => runAbortController.abort("aborted")
|
|
6441
6505
|
};
|
|
6442
6506
|
setActiveEmbeddedRun(params.sessionId, handle, params.sessionKey);
|
|
6507
|
+
const notifyUserMessagePersisted = createCodexAppServerUserMessagePersistenceNotifier(params);
|
|
6443
6508
|
mirrorPromptAtTurnStartBestEffort({
|
|
6444
6509
|
params,
|
|
6445
6510
|
agentId: sessionAgentId,
|
|
6511
|
+
notifyUserMessagePersisted,
|
|
6446
6512
|
sessionKey: sandboxSessionKey,
|
|
6447
6513
|
threadId: thread.threadId,
|
|
6448
6514
|
turnId: activeTurnId
|
|
@@ -6451,10 +6517,19 @@ async function runCodexAppServerAttempt(params, options = {}) {
|
|
|
6451
6517
|
turnTerminalIdleWatchArmed = true;
|
|
6452
6518
|
touchTurnCompletionActivity("turn:start", { attemptProgress: true });
|
|
6453
6519
|
const abortListener = () => {
|
|
6520
|
+
if (timedOut) {
|
|
6521
|
+
retireCodexAppServerClientAfterTimedOutTurn(client, {
|
|
6522
|
+
threadId: thread.threadId,
|
|
6523
|
+
turnId: activeTurnId,
|
|
6524
|
+
reason: String(runAbortController.signal.reason ?? "timeout")
|
|
6525
|
+
}).finally(() => {
|
|
6526
|
+
resolveCompletion?.();
|
|
6527
|
+
});
|
|
6528
|
+
return;
|
|
6529
|
+
}
|
|
6454
6530
|
interruptCodexTurnBestEffort(client, {
|
|
6455
6531
|
threadId: thread.threadId,
|
|
6456
|
-
turnId: activeTurnId
|
|
6457
|
-
timeoutMs: timedOut ? CODEX_APP_SERVER_INTERRUPT_TIMEOUT_MS : void 0
|
|
6532
|
+
turnId: activeTurnId
|
|
6458
6533
|
});
|
|
6459
6534
|
resolveCompletion?.();
|
|
6460
6535
|
};
|
|
@@ -6513,6 +6588,7 @@ async function runCodexAppServerAttempt(params, options = {}) {
|
|
|
6513
6588
|
await mirrorTranscriptBestEffort({
|
|
6514
6589
|
params,
|
|
6515
6590
|
agentId: sessionAgentId,
|
|
6591
|
+
notifyUserMessagePersisted,
|
|
6516
6592
|
result,
|
|
6517
6593
|
sessionKey: contextSessionKey,
|
|
6518
6594
|
threadId: thread.threadId,
|
|
@@ -6637,6 +6713,7 @@ async function runCodexAppServerAttempt(params, options = {}) {
|
|
|
6637
6713
|
notificationCleanup();
|
|
6638
6714
|
requestCleanup();
|
|
6639
6715
|
closeCleanup?.();
|
|
6716
|
+
releaseSharedClientLease?.();
|
|
6640
6717
|
if (nativeHookRelay) if (shouldDelayNativeHookRelayUnregister) scheduleCodexNativeHookRelayUnregister({
|
|
6641
6718
|
relay: nativeHookRelay,
|
|
6642
6719
|
hookTimeoutSec: options.nativeHookRelay?.hookTimeoutSec
|
|
@@ -6940,6 +7017,41 @@ async function unsubscribeCodexThreadBestEffort(client, params) {
|
|
|
6940
7017
|
});
|
|
6941
7018
|
}
|
|
6942
7019
|
}
|
|
7020
|
+
async function retireCodexAppServerClientAfterTimedOutTurn(client, params) {
|
|
7021
|
+
const retiredSharedClient = retireSharedCodexAppServerClientIfCurrent(client);
|
|
7022
|
+
const detachedSharedClient = Boolean(retiredSharedClient);
|
|
7023
|
+
interruptCodexTurnBestEffort(client, {
|
|
7024
|
+
threadId: params.threadId,
|
|
7025
|
+
turnId: params.turnId,
|
|
7026
|
+
timeoutMs: CODEX_APP_SERVER_INTERRUPT_TIMEOUT_MS
|
|
7027
|
+
});
|
|
7028
|
+
await unsubscribeCodexThreadBestEffort(client, {
|
|
7029
|
+
threadId: params.threadId,
|
|
7030
|
+
timeoutMs: CODEX_APP_SERVER_UNSUBSCRIBE_TIMEOUT_MS
|
|
7031
|
+
});
|
|
7032
|
+
let closedClient = retiredSharedClient?.closed ?? false;
|
|
7033
|
+
if (!detachedSharedClient) {
|
|
7034
|
+
const close = client.close;
|
|
7035
|
+
if (typeof close === "function") try {
|
|
7036
|
+
close.call(client);
|
|
7037
|
+
closedClient = true;
|
|
7038
|
+
} catch (error) {
|
|
7039
|
+
embeddedAgentLog.debug("codex app-server client close failed during timeout cleanup", {
|
|
7040
|
+
threadId: params.threadId,
|
|
7041
|
+
turnId: params.turnId,
|
|
7042
|
+
error
|
|
7043
|
+
});
|
|
7044
|
+
}
|
|
7045
|
+
}
|
|
7046
|
+
embeddedAgentLog.warn("codex app-server client retired after timed-out turn", {
|
|
7047
|
+
threadId: params.threadId,
|
|
7048
|
+
turnId: params.turnId,
|
|
7049
|
+
reason: params.reason,
|
|
7050
|
+
detachedSharedClient,
|
|
7051
|
+
closedClient,
|
|
7052
|
+
activeSharedClientLeases: retiredSharedClient?.activeLeases ?? 0
|
|
7053
|
+
});
|
|
7054
|
+
}
|
|
6943
7055
|
function resolveOpenClawCodingToolsSessionKeys(params, sandboxSessionKey) {
|
|
6944
7056
|
return {
|
|
6945
7057
|
sessionKey: sandboxSessionKey,
|
|
@@ -7043,7 +7155,7 @@ async function buildDynamicTools(input) {
|
|
|
7043
7155
|
modelCompat: params.model.compat && typeof params.model.compat === "object" ? params.model.compat : void 0,
|
|
7044
7156
|
modelApi: params.model.api,
|
|
7045
7157
|
modelContextWindowTokens: params.model.contextWindow,
|
|
7046
|
-
modelAuthMode: resolveModelAuthMode(params.model.provider, params.config,
|
|
7158
|
+
modelAuthMode: resolveModelAuthMode(params.model.provider, params.config, params.toolAuthProfileStore ?? params.authProfileStore, { workspaceDir: input.effectiveWorkspace }),
|
|
7047
7159
|
suppressManagedWebSearch: false,
|
|
7048
7160
|
currentChannelId: params.currentChannelId,
|
|
7049
7161
|
hookChannelId: resolveCodexAppServerHookChannelId(params, input.sandboxSessionKey),
|
|
@@ -7901,6 +8013,16 @@ function readPositiveNumber(value) {
|
|
|
7901
8013
|
function readNonEmptyString(value) {
|
|
7902
8014
|
return typeof value === "string" && value.trim().length > 0 ? value : void 0;
|
|
7903
8015
|
}
|
|
8016
|
+
const CODEX_DELIVERY_HINT_LINES = ["Delivery: to send a message, use the `message` tool.", "Delivery: Final assistant text is not automatically delivered in this run. Use the `message` tool to send user-visible output."];
|
|
8017
|
+
function splitLeadingCodexDeliveryHint(prompt) {
|
|
8018
|
+
const trimmedStart = prompt.trimStart();
|
|
8019
|
+
const matchedHint = CODEX_DELIVERY_HINT_LINES.find((hint) => trimmedStart.startsWith(hint));
|
|
8020
|
+
if (!matchedHint) return { prompt };
|
|
8021
|
+
return {
|
|
8022
|
+
deliveryHint: matchedHint,
|
|
8023
|
+
prompt: trimmedStart.slice(matchedHint.length).replace(/^\s*\n/, "").trimStart()
|
|
8024
|
+
};
|
|
8025
|
+
}
|
|
7904
8026
|
function buildCodexOpenClawPromptContext(params) {
|
|
7905
8027
|
if (!shouldInjectCodexOpenClawPromptContext(params.params)) return;
|
|
7906
8028
|
const sections = [params.skillsPrompt?.trim() ? [
|
|
@@ -7925,12 +8047,18 @@ function shouldInjectCodexOpenClawPromptContext(params) {
|
|
|
7925
8047
|
}
|
|
7926
8048
|
function prependCodexOpenClawPromptContext(prompt, context) {
|
|
7927
8049
|
if (!context?.trim()) return prompt;
|
|
7928
|
-
const
|
|
8050
|
+
const { deliveryHint, prompt: promptWithoutDeliveryHint } = splitLeadingCodexDeliveryHint(prompt);
|
|
8051
|
+
const promptSection = promptWithoutDeliveryHint.startsWith("OpenClaw assembled context for this turn:") ? promptWithoutDeliveryHint : ["Current user request:", promptWithoutDeliveryHint].join("\n");
|
|
8052
|
+
const deliverySection = deliveryHint ? [
|
|
8053
|
+
"OpenClaw delivery metadata:",
|
|
8054
|
+
"This delivery metadata is runtime routing guidance, not the user's request.",
|
|
8055
|
+
deliveryHint
|
|
8056
|
+
].join("\n") : void 0;
|
|
7929
8057
|
return [
|
|
7930
8058
|
context.trim(),
|
|
7931
|
-
|
|
8059
|
+
deliverySection,
|
|
7932
8060
|
promptSection
|
|
7933
|
-
].join("\n");
|
|
8061
|
+
].filter(Boolean).join("\n\n");
|
|
7934
8062
|
}
|
|
7935
8063
|
function renderCodexWorkspaceBootstrapPromptContext(contextFiles) {
|
|
7936
8064
|
const files = selectCodexWorkspacePromptContextFiles(contextFiles);
|
|
@@ -8041,29 +8169,63 @@ function getCodexContextFileBasename(filePath) {
|
|
|
8041
8169
|
}
|
|
8042
8170
|
async function mirrorTranscriptBestEffort(params) {
|
|
8043
8171
|
try {
|
|
8044
|
-
await
|
|
8172
|
+
const messages = await resolveFinalCodexMirrorMessages({
|
|
8173
|
+
params: params.params,
|
|
8174
|
+
messagesSnapshot: params.result.messagesSnapshot,
|
|
8175
|
+
turnId: params.turnId
|
|
8176
|
+
});
|
|
8177
|
+
const mirrorResult = await mirrorCodexAppServerTranscript({
|
|
8045
8178
|
sessionFile: params.params.sessionFile,
|
|
8046
8179
|
agentId: params.agentId,
|
|
8047
8180
|
sessionKey: params.sessionKey,
|
|
8048
|
-
messages
|
|
8181
|
+
messages,
|
|
8049
8182
|
idempotencyScope: `codex-app-server:${params.threadId}`,
|
|
8050
8183
|
config: params.params.config
|
|
8051
8184
|
});
|
|
8185
|
+
for (const message of mirrorResult.userMessagesPresent) params.notifyUserMessagePersisted(message);
|
|
8052
8186
|
} catch (error) {
|
|
8053
8187
|
embeddedAgentLog.warn("failed to mirror codex app-server transcript", { error });
|
|
8054
8188
|
}
|
|
8055
8189
|
}
|
|
8190
|
+
async function resolveFinalCodexMirrorMessages(params) {
|
|
8191
|
+
if (params.params.suppressNextUserMessagePersistence || !params.params.userTurnTranscriptRecorder) return params.messagesSnapshot;
|
|
8192
|
+
const resolvedPrompt = attachCodexMirrorIdentity(await buildResolvedCodexUserPromptMessage(params.params), `${params.turnId}:prompt`);
|
|
8193
|
+
const firstUserIndex = params.messagesSnapshot.findIndex((message) => message.role === "user");
|
|
8194
|
+
if (firstUserIndex === -1) return [resolvedPrompt, ...params.messagesSnapshot];
|
|
8195
|
+
const messages = params.messagesSnapshot.slice();
|
|
8196
|
+
messages[firstUserIndex] = resolvedPrompt;
|
|
8197
|
+
return messages;
|
|
8198
|
+
}
|
|
8199
|
+
function createCodexAppServerUserMessagePersistenceNotifier(runParams) {
|
|
8200
|
+
let notified = false;
|
|
8201
|
+
return (message) => {
|
|
8202
|
+
if (notified) return;
|
|
8203
|
+
notified = true;
|
|
8204
|
+
runParams.userTurnTranscriptRecorder?.markRuntimePersisted(message);
|
|
8205
|
+
try {
|
|
8206
|
+
runParams.onUserMessagePersisted?.(message);
|
|
8207
|
+
} catch (error) {
|
|
8208
|
+
embeddedAgentLog.warn("codex app-server user persistence notification failed", { error: formatErrorMessage(error) });
|
|
8209
|
+
}
|
|
8210
|
+
};
|
|
8211
|
+
}
|
|
8056
8212
|
async function mirrorPromptAtTurnStartBestEffort(params) {
|
|
8057
8213
|
if (params.params.suppressNextUserMessagePersistence) return;
|
|
8058
8214
|
try {
|
|
8059
|
-
|
|
8060
|
-
|
|
8061
|
-
|
|
8062
|
-
|
|
8063
|
-
|
|
8064
|
-
|
|
8065
|
-
|
|
8066
|
-
|
|
8215
|
+
const mirrorPromise = (async () => {
|
|
8216
|
+
const userPromptMessage = attachCodexMirrorIdentity(await buildResolvedCodexUserPromptMessage(params.params), `${params.turnId}:prompt`);
|
|
8217
|
+
const mirrorResult = await mirrorCodexAppServerTranscript({
|
|
8218
|
+
sessionFile: params.params.sessionFile,
|
|
8219
|
+
agentId: params.agentId,
|
|
8220
|
+
sessionKey: params.sessionKey,
|
|
8221
|
+
messages: [userPromptMessage],
|
|
8222
|
+
idempotencyScope: `codex-app-server:${params.threadId}`,
|
|
8223
|
+
config: params.params.config
|
|
8224
|
+
});
|
|
8225
|
+
for (const message of mirrorResult.userMessagesPresent) params.notifyUserMessagePersisted(message);
|
|
8226
|
+
})();
|
|
8227
|
+
params.params.userTurnTranscriptRecorder?.markRuntimePersistencePending(mirrorPromise);
|
|
8228
|
+
await mirrorPromise;
|
|
8067
8229
|
} catch (error) {
|
|
8068
8230
|
embeddedAgentLog.warn("failed to mirror codex app-server prompt at turn start", { error });
|
|
8069
8231
|
}
|