@openclaw/codex 2026.5.28 → 2026.5.30-beta.1
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-DMXvboVu.js → client-B08x7Y93.js} +6 -0
- package/dist/client-factory-bqIbmRDu.js +20 -0
- package/dist/{command-handlers-C2t6-ChO.js → command-handlers-VSWuNdgc.js} +10 -10
- package/dist/{compact-Dlnt5G3v.js → compact-DJruF_vy.js} +3 -3
- package/dist/{computer-use-Ba4vW9fO.js → computer-use-Cq-EEnLL.js} +1 -1
- package/dist/{conversation-binding-CC9XMAwn.js → conversation-binding-DzF_JII7.js} +67 -90
- package/dist/harness.js +6 -10
- package/dist/index.js +16 -56
- package/dist/media-understanding-provider.js +5 -5
- package/dist/{models-QT-XOhE7.js → models-DuyStYTT.js} +1 -1
- package/dist/{native-hook-relay-B8qM8ZwR.js → native-hook-relay-zY7m-pAu.js} +74 -6
- package/dist/{notification-correlation-BDakP_d3.js → notification-correlation-DR9cQN_M.js} +3 -3
- package/dist/provider-catalog.js +2 -2
- package/dist/provider.js +1 -1
- package/dist/{request-CF4f5hWY.js → request-DGOj3AyX.js} +4 -4
- package/dist/{run-attempt-CuhGEh0u.js → run-attempt-lD4FLxNV.js} +424 -244
- package/dist/{sandbox-guard-mXE4_vE_.js → sandbox-guard-DMCJlzmz.js} +4 -1
- package/dist/{session-binding-ueMCn4om.js → session-binding-BGOpicy0.js} +17 -2
- package/dist/{shared-client-Duh1bHaP.js → shared-client-2d0XB7wz.js} +32 -3
- package/dist/{side-question-B-Cjb9wm.js → side-question-BsyY3v3K.js} +7 -7
- package/dist/{thread-lifecycle-Dv9Npl7a.js → thread-lifecycle-BR74qMaY.js} +32 -90
- package/npm-shrinkwrap.json +2 -2
- package/openclaw.plugin.json +4 -3
- package/package.json +4 -4
- package/dist/client-factory-qZvhyyXr.js +0 -15
|
@@ -1,15 +1,15 @@
|
|
|
1
|
-
import { n as defaultLeasedCodexAppServerClientFactory } from "./client-factory-
|
|
1
|
+
import { n as defaultLeasedCodexAppServerClientFactory } from "./client-factory-bqIbmRDu.js";
|
|
2
2
|
import { c as readCodexPluginConfig, d as resolveCodexPluginsPolicy, f as resolveOpenClawExecPolicyForCodexAppServer, i as isCodexAppServerApprovalPolicyAllowedByRequirements, l as resolveCodexAppServerRuntimeOptions, m as withMcpElicitationsApprovalPolicy, o as isCodexSandboxExecServerEnabled, p as shouldAutoApproveCodexAppServerApprovals, u as resolveCodexComputerUseConfig } from "./config--tW89bHH.js";
|
|
3
3
|
import { a as readCodexDynamicToolCallParams, c as readCodexTurn, i as assertCodexTurnStartResponse } from "./protocol-validators-DtjYmUw_.js";
|
|
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-
|
|
5
|
-
import { C as sanitizeCodexHistoryImagePayloads, D as resolveCodexContextEngineProjectionReserveTokens, E as resolveCodexContextEngineProjectionMaxChars, T as projectContextEngineAssemblyForCodex, _ as shouldBuildCodexPluginThreadConfig, a as buildDeveloperInstructions, c as codexDynamicToolsFingerprint, f as startOrResumeThread, g as mergeCodexThreadConfigs, h as buildCodexPluginThreadConfigInputFingerprint, i as buildContextEngineBinding, l as isContextEngineBindingCompatible, m as buildCodexPluginThreadConfig, n as areCodexDynamicToolFingerprintsCompatible, o as buildTurnCollaborationMode, p as isCodexAppServerProfilerEnabled, s as buildTurnStartParams, x as defaultCodexAppInventoryCache } from "./thread-lifecycle-
|
|
6
|
-
import {
|
|
7
|
-
import { n as buildCodexPluginAppCacheKey, r as CODEX_CONTROL_METHODS } from "./request-
|
|
8
|
-
import { _ as shouldRefreshCodexRateLimitsForUsageLimitMessage, g as resolveCodexUsageLimitResetAtMs, h as formatCodexUsageLimitErrorMessage, i as readCodexNotificationTurnId, n as isCodexNotificationForTurn, r as readCodexNotificationThreadId, s as formatCodexDisplayText, t as describeCodexNotificationCorrelation } from "./notification-correlation-
|
|
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-
|
|
10
|
-
import { i as resolveCodexNativeExecutionPolicy } from "./sandbox-guard-
|
|
11
|
-
import { _ as normalizeCodexDynamicToolName$1, a as createCodexNativeHookRelay, c as scheduleCodexNativeHookRelayUnregister, d as emitDynamicToolErrorDiagnostic, f as emitDynamicToolStartedDiagnostic, g as isForcedPrivateQaCodexRuntime, h as filterCodexDynamicTools, i as buildCodexNativeHookRelayDisabledConfig, l as handleCodexAppServerElicitationRequest, m as filterToolsForVisionInputs, n as CODEX_NATIVE_HOOK_RELAY_TTL_GRACE_MS, o as resolveCodexNativeHookRelayEvents, p as emitDynamicToolTerminalDiagnostic, r as buildCodexNativeHookRelayConfig, s as resolveCodexNativeHookRelayTtlMs, u as createCodexDynamicToolBridge, v as resolveCodexDynamicToolsLoading, y as handleCodexAppServerApprovalRequest } from "./native-hook-relay-
|
|
12
|
-
import { t as ensureCodexComputerUse } from "./computer-use-
|
|
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-B08x7Y93.js";
|
|
5
|
+
import { C as sanitizeCodexHistoryImagePayloads, D as resolveCodexContextEngineProjectionReserveTokens, E as resolveCodexContextEngineProjectionMaxChars, T as projectContextEngineAssemblyForCodex, _ as shouldBuildCodexPluginThreadConfig, a as buildDeveloperInstructions, c as codexDynamicToolsFingerprint, f as startOrResumeThread, g as mergeCodexThreadConfigs, h as buildCodexPluginThreadConfigInputFingerprint, i as buildContextEngineBinding, l as isContextEngineBindingCompatible, m as buildCodexPluginThreadConfig, n as areCodexDynamicToolFingerprintsCompatible, o as buildTurnCollaborationMode, p as isCodexAppServerProfilerEnabled, s as buildTurnStartParams, x as defaultCodexAppInventoryCache } from "./thread-lifecycle-BR74qMaY.js";
|
|
6
|
+
import { a as readCodexAppServerBinding, n as clearCodexAppServerBindingForThread, t as clearCodexAppServerBinding } from "./session-binding-BGOpicy0.js";
|
|
7
|
+
import { n as buildCodexPluginAppCacheKey, r as CODEX_CONTROL_METHODS } from "./request-DGOj3AyX.js";
|
|
8
|
+
import { _ as shouldRefreshCodexRateLimitsForUsageLimitMessage, g as resolveCodexUsageLimitResetAtMs, h as formatCodexUsageLimitErrorMessage, i as readCodexNotificationTurnId, n as isCodexNotificationForTurn, r as readCodexNotificationThreadId, s as formatCodexDisplayText, t as describeCodexNotificationCorrelation } from "./notification-correlation-DR9cQN_M.js";
|
|
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-2d0XB7wz.js";
|
|
10
|
+
import { i as resolveCodexNativeExecutionPolicy } from "./sandbox-guard-DMCJlzmz.js";
|
|
11
|
+
import { C as resolveCodexTurnAssistantCompletionIdleTimeoutMs, E as withCodexStartupTimeout, S as resolveCodexStartupTimeoutMs, T as resolveCodexTurnTerminalIdleTimeoutMs, _ as normalizeCodexDynamicToolName$1, a as createCodexNativeHookRelay, b as CODEX_POST_REASONING_REPLY_IDLE_TIMEOUT_MS, c as scheduleCodexNativeHookRelayUnregister, d as emitDynamicToolErrorDiagnostic, f as emitDynamicToolStartedDiagnostic, g as isForcedPrivateQaCodexRuntime, h as filterCodexDynamicTools, i as buildCodexNativeHookRelayDisabledConfig, l as handleCodexAppServerElicitationRequest, m as filterToolsForVisionInputs, n as CODEX_NATIVE_HOOK_RELAY_TTL_GRACE_MS, o as resolveCodexNativeHookRelayEvents, p as emitDynamicToolTerminalDiagnostic, r as buildCodexNativeHookRelayConfig, s as resolveCodexNativeHookRelayTtlMs, u as createCodexDynamicToolBridge, v as resolveCodexDynamicToolsLoading, w as resolveCodexTurnCompletionIdleTimeoutMs, x as resolveCodexPostToolRawAssistantCompletionIdleTimeoutMs, y as handleCodexAppServerApprovalRequest } from "./native-hook-relay-zY7m-pAu.js";
|
|
12
|
+
import { t as ensureCodexComputerUse } from "./computer-use-Cq-EEnLL.js";
|
|
13
13
|
import { n as rememberCodexRateLimits, t as readRecentCodexRateLimits } from "./rate-limit-cache-N66I-Rd7.js";
|
|
14
14
|
import { createHash, randomUUID } from "node:crypto";
|
|
15
15
|
import fsSync from "node:fs";
|
|
@@ -20,15 +20,17 @@ import { spawn } from "node:child_process";
|
|
|
20
20
|
import { once } from "node:events";
|
|
21
21
|
import { WebSocketServer } from "ws";
|
|
22
22
|
import { redactSensitiveFieldValue, redactToolPayloadText } from "openclaw/plugin-sdk/logging-core";
|
|
23
|
+
import { parseStrictNonNegativeInteger } from "openclaw/plugin-sdk/number-runtime";
|
|
23
24
|
import fs from "node:fs/promises";
|
|
24
25
|
import path, { posix } from "node:path";
|
|
25
26
|
import { createDiagnosticTraceContextFromActiveScope, emitTrustedDiagnosticEvent, emitTrustedDiagnosticEventWithPrivateData, freezeDiagnosticTraceContext, hasPendingInternalDiagnosticEvent, onInternalDiagnosticEvent, resolveDiagnosticModelContentCapturePolicy } from "openclaw/plugin-sdk/diagnostic-runtime";
|
|
26
27
|
import { markAuthProfileBlockedUntil, resolveAgentDir as resolveAgentDir$1, resolveAgentWorkspaceDir } from "openclaw/plugin-sdk/agent-runtime";
|
|
27
28
|
import { isToolAllowed } from "openclaw/plugin-sdk/sandbox";
|
|
28
29
|
import { appendRegularFile, pathExists } from "openclaw/plugin-sdk/security-runtime";
|
|
29
|
-
import { parseStrictNonNegativeInteger, resolveTimerTimeoutMs } from "openclaw/plugin-sdk/number-runtime";
|
|
30
30
|
import { buildSessionContext, migrateSessionEntries, parseSessionEntries } from "openclaw/plugin-sdk/agent-sessions";
|
|
31
31
|
import { isIP } from "node:net";
|
|
32
|
+
import { generatedImageAssetFromBase64 } from "openclaw/plugin-sdk/image-generation";
|
|
33
|
+
import { saveMediaBuffer } from "openclaw/plugin-sdk/media-store";
|
|
32
34
|
import { createAgentHarnessTaskRuntime, deliverAgentHarnessTaskCompletion, isDurableAgentHarnessCompletionDelivery } from "openclaw/plugin-sdk/agent-harness-task-runtime";
|
|
33
35
|
//#region extensions/codex/src/app-server/app-server-policy.ts
|
|
34
36
|
function resolveCodexAppServerForOpenClawToolPolicy(params) {
|
|
@@ -155,37 +157,6 @@ async function readMirroredSessionHistoryMessages(sessionFile) {
|
|
|
155
157
|
if (!messages) embeddedAgentLog.warn("failed to read mirrored session history for codex harness hooks", { sessionFile });
|
|
156
158
|
return messages;
|
|
157
159
|
}
|
|
158
|
-
function shouldProjectMirroredHistoryForCodexStart(params) {
|
|
159
|
-
if (!params.historyMessages.some((message) => message.role === "user")) return false;
|
|
160
|
-
if (params.forceProject) return true;
|
|
161
|
-
if (!params.startupBinding?.threadId) return true;
|
|
162
|
-
if (hasUserVisibleHistoryAfterCodexBinding({
|
|
163
|
-
startupBinding: params.startupBinding,
|
|
164
|
-
historyMessages: params.historyMessages
|
|
165
|
-
})) return true;
|
|
166
|
-
return !areCodexDynamicToolFingerprintsCompatible({
|
|
167
|
-
previous: params.startupBinding.dynamicToolsFingerprint,
|
|
168
|
-
next: params.dynamicToolsFingerprint
|
|
169
|
-
});
|
|
170
|
-
}
|
|
171
|
-
function hasUserVisibleHistoryAfterCodexBinding(params) {
|
|
172
|
-
const bindingUpdatedAt = Date.parse(params.startupBinding.updatedAt);
|
|
173
|
-
if (!Number.isFinite(bindingUpdatedAt)) return false;
|
|
174
|
-
return params.historyMessages.some((message) => {
|
|
175
|
-
if (message.role !== "user" && message.role !== "assistant") return false;
|
|
176
|
-
if (isCodexAppServerMirroredTranscriptMessage(message)) return false;
|
|
177
|
-
const timestamp = typeof message.timestamp === "number" ? message.timestamp : typeof message.timestamp === "string" ? Date.parse(message.timestamp) : NaN;
|
|
178
|
-
return Number.isFinite(timestamp) && timestamp > bindingUpdatedAt;
|
|
179
|
-
});
|
|
180
|
-
}
|
|
181
|
-
function isCodexAppServerMirroredTranscriptMessage(message) {
|
|
182
|
-
const record = message;
|
|
183
|
-
const idempotencyKey = record.idempotencyKey;
|
|
184
|
-
if (typeof idempotencyKey === "string" && idempotencyKey.startsWith("codex-app-server:")) return true;
|
|
185
|
-
const meta = record["__openclaw"];
|
|
186
|
-
if (!meta || typeof meta !== "object" || Array.isArray(meta)) return false;
|
|
187
|
-
return typeof meta.mirrorIdentity === "string";
|
|
188
|
-
}
|
|
189
160
|
function readContextEngineThreadBootstrapProjection(projection) {
|
|
190
161
|
if (projection?.mode !== "thread_bootstrap") return;
|
|
191
162
|
const epoch = projection.epoch?.trim();
|
|
@@ -284,6 +255,10 @@ async function buildCodexWorkspaceBootstrapContext(params) {
|
|
|
284
255
|
promptContext: renderCodexWorkspaceBootstrapPromptContext(promptContextFiles),
|
|
285
256
|
developerInstructions: renderCodexWorkspaceThreadDeveloperInstructions(developerInstructionFiles),
|
|
286
257
|
turnScopedDeveloperInstructions: renderCodexWorkspaceCollaborationDeveloperInstructions(turnScopedDeveloperInstructionFiles),
|
|
258
|
+
memoryCollaborationInstructions: shouldInjectCodexOpenClawPromptContext(params.params) ? renderCodexWorkspaceMemoryReference({
|
|
259
|
+
files: memoryReferenceFiles,
|
|
260
|
+
toolNames: params.memoryToolNames
|
|
261
|
+
}) : void 0,
|
|
287
262
|
heartbeatCollaborationInstructions: renderCodexWorkspaceHeartbeatReference(heartbeatReferenceFiles)
|
|
288
263
|
};
|
|
289
264
|
} catch (error) {
|
|
@@ -454,19 +429,11 @@ function readNonEmptyString$1(value) {
|
|
|
454
429
|
}
|
|
455
430
|
function buildCodexOpenClawPromptContext(params) {
|
|
456
431
|
if (!shouldInjectCodexOpenClawPromptContext(params.params)) return;
|
|
457
|
-
const sections = [
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
].join("\n") : void 0,
|
|
463
|
-
params.workspaceMemoryReference?.trim() ? params.workspaceMemoryReference.trim() : void 0,
|
|
464
|
-
params.workspacePromptContext?.trim() ? [
|
|
465
|
-
"## OpenClaw Workspace Context",
|
|
466
|
-
"",
|
|
467
|
-
params.workspacePromptContext.trim()
|
|
468
|
-
].join("\n") : void 0
|
|
469
|
-
].filter(isNonEmptyString$2);
|
|
432
|
+
const sections = [params.workspacePromptContext?.trim() ? [
|
|
433
|
+
"## OpenClaw Workspace Context",
|
|
434
|
+
"",
|
|
435
|
+
params.workspacePromptContext.trim()
|
|
436
|
+
].join("\n") : void 0].filter(isNonEmptyString$2);
|
|
470
437
|
if (sections.length === 0) return;
|
|
471
438
|
return [
|
|
472
439
|
"OpenClaw runtime context for this turn:",
|
|
@@ -478,9 +445,17 @@ function buildCodexOpenClawPromptContext(params) {
|
|
|
478
445
|
function shouldInjectCodexOpenClawPromptContext(params) {
|
|
479
446
|
return !(params.bootstrapContextMode === "lightweight" && params.bootstrapContextRunKind === "cron");
|
|
480
447
|
}
|
|
481
|
-
function
|
|
482
|
-
if (!
|
|
448
|
+
function renderCodexSkillsCollaborationInstructions(params) {
|
|
449
|
+
if (!shouldInjectCodexOpenClawPromptContext(params.attempt)) return;
|
|
450
|
+
return params.skillsPrompt?.trim() ? [
|
|
451
|
+
"## OpenClaw Skills",
|
|
452
|
+
"",
|
|
453
|
+
params.skillsPrompt.trim()
|
|
454
|
+
].join("\n") : void 0;
|
|
455
|
+
}
|
|
456
|
+
function prependCodexOpenClawPromptContext(prompt, context, options = {}) {
|
|
483
457
|
const { deliveryHint, prompt: promptWithoutDeliveryHint } = splitLeadingCodexDeliveryHint(prompt);
|
|
458
|
+
if (!context?.trim() && (!deliveryHint || options.preservePromptWithoutContext)) return prompt;
|
|
484
459
|
const promptSection = promptWithoutDeliveryHint.startsWith("OpenClaw assembled context for this turn:") ? promptWithoutDeliveryHint : ["Current user request:", promptWithoutDeliveryHint].join("\n");
|
|
485
460
|
const deliverySection = deliveryHint ? [
|
|
486
461
|
"OpenClaw delivery metadata:",
|
|
@@ -488,7 +463,7 @@ function prependCodexOpenClawPromptContext(prompt, context) {
|
|
|
488
463
|
deliveryHint
|
|
489
464
|
].join("\n") : void 0;
|
|
490
465
|
return [
|
|
491
|
-
context
|
|
466
|
+
context?.trim(),
|
|
492
467
|
deliverySection,
|
|
493
468
|
promptSection
|
|
494
469
|
].filter(Boolean).join("\n\n");
|
|
@@ -550,11 +525,12 @@ function renderCodexWorkspaceCollaborationDeveloperInstructions(files) {
|
|
|
550
525
|
return renderCodexWorkspaceDeveloperInstructions({
|
|
551
526
|
files,
|
|
552
527
|
header: "## OpenClaw Agent Soul",
|
|
553
|
-
preamble: "OpenClaw loaded these workspace instruction files from the active agent workspace. They are the canonical definitions of who you are, how you think and work, and the human you work alongside. Internalize and follow them accordingly."
|
|
528
|
+
preamble: "OpenClaw loaded these workspace instruction files from the active agent workspace. They are the canonical definitions of who you are, how you think and work, and the human you work alongside. Internalize and follow them accordingly.",
|
|
529
|
+
wrapperTag: "AGENT_SOUL"
|
|
554
530
|
});
|
|
555
531
|
}
|
|
556
532
|
function renderCodexWorkspaceDeveloperInstructions(params) {
|
|
557
|
-
const { files, header, preamble } = params;
|
|
533
|
+
const { files, header, preamble, wrapperTag } = params;
|
|
558
534
|
if (files.length === 0) return;
|
|
559
535
|
const lines = [
|
|
560
536
|
header,
|
|
@@ -562,7 +538,9 @@ function renderCodexWorkspaceDeveloperInstructions(params) {
|
|
|
562
538
|
preamble,
|
|
563
539
|
""
|
|
564
540
|
];
|
|
541
|
+
if (wrapperTag) lines.push(`<${wrapperTag}>`, "");
|
|
565
542
|
for (const file of files) lines.push(`### ${file.path}`, "", file.content, "");
|
|
543
|
+
if (wrapperTag) lines.push(`</${wrapperTag}>`);
|
|
566
544
|
return lines.join("\n").trim();
|
|
567
545
|
}
|
|
568
546
|
function selectCodexWorkspaceHeartbeatReferenceFiles(contextFiles) {
|
|
@@ -594,7 +572,7 @@ function renderCodexWorkspaceMemoryReference(params) {
|
|
|
594
572
|
const lines = [
|
|
595
573
|
"## OpenClaw Workspace Memory",
|
|
596
574
|
"",
|
|
597
|
-
`MEMORY.md exists in the active agent workspace. OpenClaw does not paste its contents into native Codex turns; use ${(params.toolNames?.length ? params.toolNames : Array.from(CODEX_MEMORY_TOOL_NAMES)).join(" or ")} when durable memory is relevant and the tools are available.`,
|
|
575
|
+
`MEMORY.md exists in the active agent workspace as a memory file, not an instruction file. OpenClaw does not paste its contents into native Codex turns; use ${(params.toolNames?.length ? params.toolNames : Array.from(CODEX_MEMORY_TOOL_NAMES)).join(" or ")} when durable memory is relevant and the tools are available.`,
|
|
598
576
|
""
|
|
599
577
|
];
|
|
600
578
|
for (const file of params.files) lines.push(`- ${file.path}`);
|
|
@@ -825,6 +803,11 @@ function isReasoningItemCompletionNotification(notification) {
|
|
|
825
803
|
const item = isJsonObject(notification.params.item) ? notification.params.item : void 0;
|
|
826
804
|
return item ? readString$6(item, "type") === "reasoning" : false;
|
|
827
805
|
}
|
|
806
|
+
function isAssistantCommentaryCompletionNotification(notification) {
|
|
807
|
+
if (!isJsonObject(notification.params) || notification.method !== "item/completed") return false;
|
|
808
|
+
const item = isJsonObject(notification.params.item) ? notification.params.item : void 0;
|
|
809
|
+
return Boolean(item && readString$6(item, "type") === "agentMessage" && readString$6(item, "phase") === "commentary");
|
|
810
|
+
}
|
|
828
811
|
function isRawReasoningCompletionNotification(notification) {
|
|
829
812
|
if (!isJsonObject(notification.params) || notification.method !== "rawResponseItem/completed") return false;
|
|
830
813
|
const item = isJsonObject(notification.params.item) ? notification.params.item : void 0;
|
|
@@ -870,10 +853,21 @@ function isNativeToolProgressNotification(notification) {
|
|
|
870
853
|
default: return false;
|
|
871
854
|
}
|
|
872
855
|
}
|
|
873
|
-
function
|
|
856
|
+
function isNativeResponseStreamDeltaNotification(notification) {
|
|
857
|
+
return notification.method.startsWith("response.") && notification.method.endsWith(".delta");
|
|
858
|
+
}
|
|
859
|
+
function isFileChangePatchUpdatedNotification(notification) {
|
|
860
|
+
return notification.method === "item/fileChange/patchUpdated" && isJsonObject(notification.params);
|
|
861
|
+
}
|
|
862
|
+
function isRawAssistantProgressNotification(notification) {
|
|
874
863
|
if (notification.method !== "rawResponseItem/completed" || !isJsonObject(notification.params)) return false;
|
|
875
864
|
const item = isJsonObject(notification.params.item) ? notification.params.item : void 0;
|
|
876
|
-
return Boolean(item && readString$6(item, "type") === "message" && readString$6(item, "role") === "assistant" &&
|
|
865
|
+
return Boolean(item && readString$6(item, "type") === "message" && readString$6(item, "role") === "assistant" && readRawAssistantTextPreview(item));
|
|
866
|
+
}
|
|
867
|
+
function isRawAssistantCompletionNotification(notification) {
|
|
868
|
+
if (!isRawAssistantProgressNotification(notification) || !isJsonObject(notification.params)) return false;
|
|
869
|
+
const item = isJsonObject(notification.params.item) ? notification.params.item : void 0;
|
|
870
|
+
return Boolean(item && readString$6(item, "phase") !== "commentary");
|
|
877
871
|
}
|
|
878
872
|
function readRawAssistantTextPreview(item) {
|
|
879
873
|
if (readString$6(item, "role") !== "assistant" || !Array.isArray(item.content)) return;
|
|
@@ -964,67 +958,6 @@ function codexExecutionToolName(item) {
|
|
|
964
958
|
function isNonEmptyString$1(value) {
|
|
965
959
|
return typeof value === "string" && value.length > 0;
|
|
966
960
|
}
|
|
967
|
-
const CODEX_TURN_COMPLETION_IDLE_TIMEOUT_MS = 6e4;
|
|
968
|
-
const CODEX_TURN_ASSISTANT_COMPLETION_IDLE_TIMEOUT_MS = 1e4;
|
|
969
|
-
const CODEX_POST_REASONING_SOURCE_REPLY_IDLE_TIMEOUT_MS = 5 * 6e4;
|
|
970
|
-
const CODEX_TURN_TERMINAL_IDLE_TIMEOUT_MS = 30 * 6e4;
|
|
971
|
-
function resolvePositiveIntegerTimeoutMs(value, fallbackMs) {
|
|
972
|
-
return resolveTimerTimeoutMs(value, resolveTimerTimeoutMs(fallbackMs, 1));
|
|
973
|
-
}
|
|
974
|
-
async function withCodexStartupTimeout(params) {
|
|
975
|
-
if (params.signal.aborted) throw new Error("codex app-server startup aborted");
|
|
976
|
-
let timeout;
|
|
977
|
-
let abortCleanup;
|
|
978
|
-
let timeoutError;
|
|
979
|
-
let timeoutCleanup;
|
|
980
|
-
try {
|
|
981
|
-
return await Promise.race([params.operation(), new Promise((_, reject) => {
|
|
982
|
-
const rejectOnce = (error) => {
|
|
983
|
-
if (timeout) {
|
|
984
|
-
clearTimeout(timeout);
|
|
985
|
-
timeout = void 0;
|
|
986
|
-
}
|
|
987
|
-
reject(error);
|
|
988
|
-
};
|
|
989
|
-
timeout = setTimeout(() => {
|
|
990
|
-
timeoutError = /* @__PURE__ */ new Error("codex app-server startup timed out");
|
|
991
|
-
timeoutCleanup = Promise.resolve(params.onTimeout?.()).then(() => void 0, () => void 0);
|
|
992
|
-
timeoutCleanup.finally(() => {
|
|
993
|
-
rejectOnce(timeoutError);
|
|
994
|
-
});
|
|
995
|
-
}, params.timeoutMs);
|
|
996
|
-
const abortListener = () => rejectOnce(/* @__PURE__ */ new Error("codex app-server startup aborted"));
|
|
997
|
-
params.signal.addEventListener("abort", abortListener, { once: true });
|
|
998
|
-
abortCleanup = () => params.signal.removeEventListener("abort", abortListener);
|
|
999
|
-
})]);
|
|
1000
|
-
} catch (error) {
|
|
1001
|
-
if (timeoutError) {
|
|
1002
|
-
await timeoutCleanup;
|
|
1003
|
-
throw timeoutError;
|
|
1004
|
-
}
|
|
1005
|
-
throw error;
|
|
1006
|
-
} finally {
|
|
1007
|
-
if (timeout) clearTimeout(timeout);
|
|
1008
|
-
abortCleanup?.();
|
|
1009
|
-
}
|
|
1010
|
-
}
|
|
1011
|
-
function resolveCodexStartupTimeoutMs(params) {
|
|
1012
|
-
const timeoutFloorMs = resolvePositiveIntegerTimeoutMs(params.timeoutFloorMs, 100);
|
|
1013
|
-
const timeoutMs = resolvePositiveIntegerTimeoutMs(params.timeoutMs, timeoutFloorMs);
|
|
1014
|
-
return Math.max(timeoutFloorMs, timeoutMs);
|
|
1015
|
-
}
|
|
1016
|
-
function resolveCodexTurnCompletionIdleTimeoutMs(value) {
|
|
1017
|
-
return resolvePositiveIntegerTimeoutMs(value, CODEX_TURN_COMPLETION_IDLE_TIMEOUT_MS);
|
|
1018
|
-
}
|
|
1019
|
-
function resolveCodexTurnAssistantCompletionIdleTimeoutMs(value) {
|
|
1020
|
-
return resolvePositiveIntegerTimeoutMs(value, CODEX_TURN_ASSISTANT_COMPLETION_IDLE_TIMEOUT_MS);
|
|
1021
|
-
}
|
|
1022
|
-
function resolveCodexPostToolRawAssistantCompletionIdleTimeoutMs(value, fallbackMs) {
|
|
1023
|
-
return resolvePositiveIntegerTimeoutMs(value, fallbackMs);
|
|
1024
|
-
}
|
|
1025
|
-
function resolveCodexTurnTerminalIdleTimeoutMs(value) {
|
|
1026
|
-
return resolvePositiveIntegerTimeoutMs(value, CODEX_TURN_TERMINAL_IDLE_TIMEOUT_MS);
|
|
1027
|
-
}
|
|
1028
961
|
//#endregion
|
|
1029
962
|
//#region extensions/codex/src/app-server/attempt-notification-state.ts
|
|
1030
963
|
function reportCodexExecutionNotification(params) {
|
|
@@ -1055,8 +988,9 @@ function applyCodexTurnNotificationState(params) {
|
|
|
1055
988
|
const { notification, turnWatches } = params;
|
|
1056
989
|
const isCurrentTurnNotification = isTurnNotification(notification.params, params.threadId, params.turnId);
|
|
1057
990
|
const isTurnCompletion = notification.method === "turn/completed" && isCurrentTurnNotification;
|
|
991
|
+
const isNativeResponseStreamDelta = isNativeResponseStreamDeltaNotification(notification);
|
|
1058
992
|
let turnCrossedToolHandoff = params.turnCrossedToolHandoff;
|
|
1059
|
-
if (isCurrentTurnNotification) {
|
|
993
|
+
if (isCurrentTurnNotification && !isNativeResponseStreamDelta) {
|
|
1060
994
|
turnWatches.touchActivity(`notification:${notification.method}`, {
|
|
1061
995
|
details: describeNotificationActivity(notification),
|
|
1062
996
|
attemptProgress: true
|
|
@@ -1070,25 +1004,37 @@ function applyCodexTurnNotificationState(params) {
|
|
|
1070
1004
|
const rawToolOutputCompletion = isRawToolOutputCompletionNotification(notification);
|
|
1071
1005
|
if (isCurrentTurnNotification && (rawToolOutputCompletion || isNativeToolProgressNotification(notification))) turnCrossedToolHandoff = true;
|
|
1072
1006
|
const assistantCompletionCanRelease = isAssistantCompletionReleaseNotification(notification, turnCrossedToolHandoff);
|
|
1073
|
-
const postToolRawAssistantCompletionNeedsTerminalGuard = isCurrentTurnNotification && turnCrossedToolHandoff &&
|
|
1074
|
-
const
|
|
1075
|
-
const
|
|
1076
|
-
const
|
|
1077
|
-
const
|
|
1007
|
+
const postToolRawAssistantCompletionNeedsTerminalGuard = isCurrentTurnNotification && turnCrossedToolHandoff && isRawAssistantProgressNotification(notification) && params.activeTurnItemIds.size === 0;
|
|
1008
|
+
const postToolPatchUpdateNeedsTerminalGuard = isCurrentTurnNotification && turnCrossedToolHandoff && isFileChangePatchUpdatedNotification(notification);
|
|
1009
|
+
const rawResponseItemCompletedWithNoActiveItems = isCurrentTurnNotification && notification.method === "rawResponseItem/completed" && params.activeTurnItemIds.size === 0 && params.activeAppServerTurnRequests === 0 && !assistantCompletionCanRelease && !postToolRawAssistantCompletionNeedsTerminalGuard && !rawToolOutputCompletion;
|
|
1010
|
+
const shouldArmNoToolPostProgressReplyWatch = isCurrentTurnNotification && !turnCrossedToolHandoff && params.activeTurnItemIds.size === 0 && (isReasoningItemCompletionNotification(notification) || isAssistantCommentaryCompletionNotification(notification));
|
|
1011
|
+
const shouldArmNoToolPostRawProgressReplyWatch = !turnCrossedToolHandoff && rawResponseItemCompletedWithNoActiveItems && (isRawReasoningCompletionNotification(notification) || isRawAssistantProgressNotification(notification));
|
|
1012
|
+
const shouldRearmCompletionIdleWatchAfterLastCurrentTurnItem = isCurrentTurnNotification && notification.method === "item/completed" && params.activeTurnItemIds.size === 0 && !trackedDynamicToolCompletion && !assistantCompletionCanRelease && !shouldArmNoToolPostProgressReplyWatch;
|
|
1013
|
+
const shouldUsePostToolContinuationWatch = turnCrossedToolHandoff && (postToolRawAssistantCompletionNeedsTerminalGuard || postToolPatchUpdateNeedsTerminalGuard || rawToolOutputCompletion || trackedDynamicToolCompletion || shouldRearmCompletionIdleWatchAfterLastCurrentTurnItem);
|
|
1014
|
+
const armPostToolContinuationWatch = () => {
|
|
1015
|
+
turnWatches.armCompletionIdleWatch({ timeoutMs: params.postToolRawAssistantCompletionIdleTimeoutMs });
|
|
1016
|
+
turnWatches.extendAttemptIdleWatch(params.postToolRawAssistantCompletionIdleTimeoutMs);
|
|
1017
|
+
};
|
|
1018
|
+
const armPostProgressReplyWatch = () => {
|
|
1019
|
+
turnWatches.armCompletionIdleWatch({ timeoutMs: CODEX_POST_REASONING_REPLY_IDLE_TIMEOUT_MS });
|
|
1020
|
+
turnWatches.extendAttemptIdleWatch(CODEX_POST_REASONING_REPLY_IDLE_TIMEOUT_MS);
|
|
1021
|
+
};
|
|
1078
1022
|
if (isCurrentTurnNotification && notification.method === "error") {
|
|
1079
1023
|
if (isRetryableErrorNotification(notification.params)) turnWatches.disarmCompletionIdleWatch();
|
|
1080
1024
|
else turnWatches.armCompletionIdleWatch({ pinnedByTerminalError: true });
|
|
1081
1025
|
turnWatches.disarmAssistantCompletionIdleWatch();
|
|
1082
1026
|
} else if (isTurnCompletion) turnWatches.disarmAssistantCompletionIdleWatch();
|
|
1083
1027
|
else if (isCurrentTurnNotification && assistantCompletionCanRelease) turnWatches.armAssistantCompletionIdleWatch(describeNotificationActivity(notification));
|
|
1084
|
-
else if (postToolRawAssistantCompletionNeedsTerminalGuard)
|
|
1085
|
-
else if (
|
|
1028
|
+
else if (postToolRawAssistantCompletionNeedsTerminalGuard || postToolPatchUpdateNeedsTerminalGuard) armPostToolContinuationWatch();
|
|
1029
|
+
else if (shouldArmNoToolPostProgressReplyWatch || shouldArmNoToolPostRawProgressReplyWatch) armPostProgressReplyWatch();
|
|
1030
|
+
else if (trackedDynamicToolCompletion) armPostToolContinuationWatch();
|
|
1086
1031
|
else if (unblockedAssistantCompletionRelease) turnWatches.armAssistantCompletionIdleWatch(describeNotificationActivity(notification));
|
|
1087
|
-
else if (shouldRearmCompletionIdleWatchAfterLastCurrentTurnItem)
|
|
1032
|
+
else if (shouldRearmCompletionIdleWatchAfterLastCurrentTurnItem) if (shouldUsePostToolContinuationWatch) armPostToolContinuationWatch();
|
|
1033
|
+
else turnWatches.armCompletionIdleWatch();
|
|
1088
1034
|
else if (rawResponseItemCompletedWithNoActiveItems) turnWatches.armCompletionIdleWatch();
|
|
1089
|
-
else if (isCurrentTurnNotification && rawToolOutputCompletion)
|
|
1035
|
+
else if (isCurrentTurnNotification && rawToolOutputCompletion) armPostToolContinuationWatch();
|
|
1090
1036
|
else if (isCurrentTurnNotification && shouldDisarmAssistantCompletionIdleWatch(notification)) turnWatches.disarmAssistantCompletionIdleWatch();
|
|
1091
|
-
if (turnWatches.isCompletionIdleWatchArmed() && !turnWatches.isCompletionIdleWatchPinnedByTerminalError() && notification.method !== "turn/completed" && isCurrentTurnNotification && !trackedDynamicToolCompletion && !rawToolOutputCompletion && !postToolRawAssistantCompletionNeedsTerminalGuard && !rawResponseItemCompletedWithNoActiveItems && !
|
|
1037
|
+
if (turnWatches.isCompletionIdleWatchArmed() && !turnWatches.isCompletionIdleWatchPinnedByTerminalError() && notification.method !== "turn/completed" && isCurrentTurnNotification && !isNativeResponseStreamDelta && !trackedDynamicToolCompletion && !rawToolOutputCompletion && !postToolRawAssistantCompletionNeedsTerminalGuard && !postToolPatchUpdateNeedsTerminalGuard && !rawResponseItemCompletedWithNoActiveItems && !shouldArmNoToolPostProgressReplyWatch && !shouldArmNoToolPostRawProgressReplyWatch && !shouldRearmCompletionIdleWatchAfterLastCurrentTurnItem) turnWatches.disarmCompletionIdleWatch();
|
|
1092
1038
|
if (trackedDynamicToolCompletion) {
|
|
1093
1039
|
const itemId = readNotificationItemId(notification);
|
|
1094
1040
|
if (itemId) {
|
|
@@ -1120,7 +1066,8 @@ function hasCodexAppServerPotentialSideEffectEvidence(result) {
|
|
|
1120
1066
|
}
|
|
1121
1067
|
function buildCodexAppServerPromptTimeoutOutcome(params) {
|
|
1122
1068
|
const completionIdleTimeoutHadPotentialSideEffects = hasCodexAppServerPotentialSideEffectEvidence(params.result);
|
|
1123
|
-
|
|
1069
|
+
const replayBlockedReason = resolveCodexAppServerReplayBlockedReason(params.result);
|
|
1070
|
+
if (!params.turnCompletionIdleTimedOut || params.result.itemLifecycle.completedCount === 0 && !completionIdleTimeoutHadPotentialSideEffects && replayBlockedReason === void 0) return;
|
|
1124
1071
|
return {
|
|
1125
1072
|
message: completionIdleTimeoutHadPotentialSideEffects ? CODEX_APP_SERVER_MISSING_TERMINAL_EVENT_SIDE_EFFECT_USER_MESSAGE : CODEX_APP_SERVER_MISSING_TERMINAL_EVENT_USER_MESSAGE,
|
|
1126
1073
|
...completionIdleTimeoutHadPotentialSideEffects ? {
|
|
@@ -3013,6 +2960,7 @@ function createCodexAttemptTurnWatchController(params) {
|
|
|
3013
2960
|
let completionLastActivityAt = Date.now();
|
|
3014
2961
|
let completionLastActivityReason = "startup";
|
|
3015
2962
|
let completionLastActivityDetails;
|
|
2963
|
+
let attemptIdleTimeoutOverrideMs;
|
|
3016
2964
|
let attemptLastProgressAt = Date.now();
|
|
3017
2965
|
let attemptLastProgressReason = "startup";
|
|
3018
2966
|
let attemptLastProgressDetails;
|
|
@@ -3067,7 +3015,8 @@ function createCodexAttemptTurnWatchController(params) {
|
|
|
3067
3015
|
clearAttemptIdleTimer();
|
|
3068
3016
|
if (params.isCompleted() || params.signal.aborted || !attemptIdleWatchArmed) return;
|
|
3069
3017
|
const elapsedMs = Math.max(0, Date.now() - attemptLastProgressAt);
|
|
3070
|
-
const
|
|
3018
|
+
const timeoutMs = attemptIdleTimeoutOverrideMs ?? params.turnAttemptIdleTimeoutMs;
|
|
3019
|
+
const delayMs = Math.max(1, timeoutMs - elapsedMs);
|
|
3071
3020
|
attemptIdleTimer = setTimeout(fireAttemptIdleTimeout, delayMs);
|
|
3072
3021
|
attemptIdleTimer.unref?.();
|
|
3073
3022
|
}
|
|
@@ -3084,6 +3033,14 @@ function createCodexAttemptTurnWatchController(params) {
|
|
|
3084
3033
|
scheduleCompletionIdleWatch();
|
|
3085
3034
|
scheduleTerminalIdleWatch();
|
|
3086
3035
|
}
|
|
3036
|
+
function recordAttemptProgress(reason, options) {
|
|
3037
|
+
attemptIdleTimeoutOverrideMs = options?.attemptTimeoutMs !== void 0 ? Math.max(1, Math.floor(options.attemptTimeoutMs)) : void 0;
|
|
3038
|
+
attemptLastProgressAt = completionLastActivityAt;
|
|
3039
|
+
attemptLastProgressReason = reason;
|
|
3040
|
+
attemptLastProgressDetails = options?.details;
|
|
3041
|
+
params.onAttemptProgress(reason, options?.details);
|
|
3042
|
+
scheduleAttemptIdleWatch();
|
|
3043
|
+
}
|
|
3087
3044
|
function fireAssistantCompletionIdleRelease() {
|
|
3088
3045
|
if (params.isCompleted() || params.signal.aborted || !assistantCompletionIdleWatchArmed) return;
|
|
3089
3046
|
if (params.getActiveAppServerTurnRequests() > 0 || params.getActiveTurnItemCount() > 0) {
|
|
@@ -3124,14 +3081,15 @@ function createCodexAttemptTurnWatchController(params) {
|
|
|
3124
3081
|
function fireAttemptIdleTimeout() {
|
|
3125
3082
|
if (params.isCompleted() || params.signal.aborted || !attemptIdleWatchArmed) return;
|
|
3126
3083
|
const idleMs = Math.max(0, Date.now() - attemptLastProgressAt);
|
|
3127
|
-
|
|
3084
|
+
const timeoutMs = attemptIdleTimeoutOverrideMs ?? params.turnAttemptIdleTimeoutMs;
|
|
3085
|
+
if (idleMs < timeoutMs) {
|
|
3128
3086
|
scheduleAttemptIdleWatch();
|
|
3129
3087
|
return;
|
|
3130
3088
|
}
|
|
3131
3089
|
const timeout = {
|
|
3132
3090
|
kind: "progress",
|
|
3133
3091
|
idleMs,
|
|
3134
|
-
timeoutMs
|
|
3092
|
+
timeoutMs,
|
|
3135
3093
|
lastActivityReason: attemptLastProgressReason,
|
|
3136
3094
|
details: attemptLastProgressDetails
|
|
3137
3095
|
};
|
|
@@ -3264,12 +3222,7 @@ function createCodexAttemptTurnWatchController(params) {
|
|
|
3264
3222
|
completionLastActivityReason = reason;
|
|
3265
3223
|
completionLastActivityDetails = options?.details;
|
|
3266
3224
|
completionIdleTimeoutOverrideMs = void 0;
|
|
3267
|
-
if (options?.attemptProgress)
|
|
3268
|
-
attemptLastProgressAt = completionLastActivityAt;
|
|
3269
|
-
attemptLastProgressReason = reason;
|
|
3270
|
-
attemptLastProgressDetails = options.details;
|
|
3271
|
-
params.onAttemptProgress(reason, options.details);
|
|
3272
|
-
}
|
|
3225
|
+
if (options?.attemptProgress) recordAttemptProgress(reason, options);
|
|
3273
3226
|
params.onProgressDiagnostic(reason);
|
|
3274
3227
|
if (options?.arm) {
|
|
3275
3228
|
completionIdleWatchArmed = true;
|
|
@@ -3277,9 +3230,15 @@ function createCodexAttemptTurnWatchController(params) {
|
|
|
3277
3230
|
}
|
|
3278
3231
|
scheduleProgressWatches();
|
|
3279
3232
|
},
|
|
3280
|
-
noteNotificationReceived: (method) => {
|
|
3233
|
+
noteNotificationReceived: (method, options) => {
|
|
3281
3234
|
completionLastActivityAt = Date.now();
|
|
3282
3235
|
completionLastActivityReason = `notification:${method}`;
|
|
3236
|
+
if (options?.details !== void 0) completionLastActivityDetails = options.details;
|
|
3237
|
+
if (options?.attemptProgress) recordAttemptProgress(completionLastActivityReason, options);
|
|
3238
|
+
},
|
|
3239
|
+
extendAttemptIdleWatch: (timeoutMs) => {
|
|
3240
|
+
attemptIdleTimeoutOverrideMs = Math.max(1, Math.floor(timeoutMs));
|
|
3241
|
+
scheduleAttemptIdleWatch();
|
|
3283
3242
|
},
|
|
3284
3243
|
scheduleProgressWatches,
|
|
3285
3244
|
clearCompletionIdleTimer,
|
|
@@ -3486,15 +3445,14 @@ function clampDynamicToolTimeoutMs(timeoutMs) {
|
|
|
3486
3445
|
//#region extensions/codex/src/app-server/local-runtime-attribution.ts
|
|
3487
3446
|
const OPENAI_PROVIDER_ID = "openai";
|
|
3488
3447
|
const OPENAI_RESPONSES_API = "openai-responses";
|
|
3489
|
-
const
|
|
3490
|
-
const OPENAI_CODEX_RESPONSES_API = "openai-codex-responses";
|
|
3448
|
+
const OPENAI_CODEX_RESPONSES_API = "openai-chatgpt-responses";
|
|
3491
3449
|
function normalizeRuntimeId(value) {
|
|
3492
3450
|
return value?.trim().toLowerCase() ?? "";
|
|
3493
3451
|
}
|
|
3494
3452
|
function resolveCodexLocalRuntimeAttribution(params) {
|
|
3495
3453
|
const authProfileProvider = normalizeRuntimeId(params.runtimePlan?.auth?.authProfileProviderForAuth);
|
|
3496
3454
|
if (normalizeRuntimeId(params.runtimePlan?.observability.harnessId) === "codex" && authProfileProvider !== OPENAI_PROVIDER_ID && normalizeRuntimeId(params.model.provider) === OPENAI_PROVIDER_ID && normalizeRuntimeId(params.model.api) === OPENAI_RESPONSES_API) return {
|
|
3497
|
-
provider:
|
|
3455
|
+
provider: OPENAI_PROVIDER_ID,
|
|
3498
3456
|
api: OPENAI_CODEX_RESPONSES_API
|
|
3499
3457
|
};
|
|
3500
3458
|
return {
|
|
@@ -3754,6 +3712,7 @@ async function mirrorCodexAppServerTranscript(params) {
|
|
|
3754
3712
|
for (const update of appendedUpdates) emitSessionTranscriptUpdate({
|
|
3755
3713
|
sessionFile: params.sessionFile,
|
|
3756
3714
|
...params.sessionKey ? { sessionKey: params.sessionKey } : {},
|
|
3715
|
+
...params.agentId ? { agentId: params.agentId } : {},
|
|
3757
3716
|
message: update.message,
|
|
3758
3717
|
messageId: update.messageId,
|
|
3759
3718
|
messageSeq: update.messageSeq
|
|
@@ -3826,6 +3785,9 @@ const CODEX_PROMPT_TOTAL_INPUT_KEYS = [
|
|
|
3826
3785
|
];
|
|
3827
3786
|
const MAX_TOOL_OUTPUT_DELTA_MESSAGES_PER_ITEM = 20;
|
|
3828
3787
|
const TOOL_TRANSCRIPT_OUTPUT_MAX_CHARS = 12e3;
|
|
3788
|
+
const GENERATED_IMAGE_MEDIA_SUBDIR = "tool-image-generation";
|
|
3789
|
+
const BYTES_PER_MB = 1024 * 1024;
|
|
3790
|
+
const DEFAULT_GENERATED_IMAGE_MAX_BYTES = 6 * BYTES_PER_MB;
|
|
3829
3791
|
const TRANSCRIPT_PROGRESS_SUPPRESSED_TOOL_NAMES = new Set([
|
|
3830
3792
|
"message",
|
|
3831
3793
|
"messages",
|
|
@@ -3871,6 +3833,8 @@ var CodexAppServerEventProjector = class {
|
|
|
3871
3833
|
this.toolTranscriptResultIds = /* @__PURE__ */ new Set();
|
|
3872
3834
|
this.transcriptToolProgressCallIds = /* @__PURE__ */ new Set();
|
|
3873
3835
|
this.nativeGeneratedMediaUrls = /* @__PURE__ */ new Set();
|
|
3836
|
+
this.nativeGeneratedMediaItemIds = /* @__PURE__ */ new Set();
|
|
3837
|
+
this.nativeGeneratedMediaUrlsByItemId = /* @__PURE__ */ new Map();
|
|
3874
3838
|
this.diagnosticToolStartedAtByItem = /* @__PURE__ */ new Map();
|
|
3875
3839
|
this.afterToolCallObservedItemIds = /* @__PURE__ */ new Set();
|
|
3876
3840
|
this.assistantStarted = false;
|
|
@@ -3936,7 +3900,7 @@ var CodexAppServerEventProjector = class {
|
|
|
3936
3900
|
await this.handleTurnCompleted(params);
|
|
3937
3901
|
break;
|
|
3938
3902
|
case "rawResponseItem/completed":
|
|
3939
|
-
this.handleRawResponseItemCompleted(params);
|
|
3903
|
+
await this.handleRawResponseItemCompleted(params);
|
|
3940
3904
|
break;
|
|
3941
3905
|
case "error":
|
|
3942
3906
|
if (readBooleanAlias(params, ["willRetry", "will_retry"]) === true) break;
|
|
@@ -3967,7 +3931,7 @@ var CodexAppServerEventProjector = class {
|
|
|
3967
3931
|
turnCompleted: Boolean(this.completedTurn)
|
|
3968
3932
|
});
|
|
3969
3933
|
const toolMetas = [...this.toolMetas.values()];
|
|
3970
|
-
const hadPotentialSideEffects = toolTelemetry.didSendViaMessagingTool || (toolTelemetry.successfulCronAdds ?? 0) > 0 || this.sideEffectingToolItemIds.size > 0 || this.sideEffectingDynamicToolCallIds.size > 0;
|
|
3934
|
+
const hadPotentialSideEffects = toolTelemetry.didSendViaMessagingTool || (toolTelemetry.successfulCronAdds ?? 0) > 0 || this.nativeGeneratedMediaItemIds.size > 0 || this.sideEffectingToolItemIds.size > 0 || this.sideEffectingDynamicToolCallIds.size > 0;
|
|
3971
3935
|
return {
|
|
3972
3936
|
aborted: this.aborted,
|
|
3973
3937
|
externalAbort: false,
|
|
@@ -4388,9 +4352,11 @@ var CodexAppServerEventProjector = class {
|
|
|
4388
4352
|
text: formatToolOutput(toolName, void 0, reachedLimit ? `${chunk}\n...(truncated)...` : chunk)
|
|
4389
4353
|
});
|
|
4390
4354
|
}
|
|
4391
|
-
handleRawResponseItemCompleted(params) {
|
|
4355
|
+
async handleRawResponseItemCompleted(params) {
|
|
4392
4356
|
const item = isJsonObject(params.item) ? params.item : void 0;
|
|
4393
|
-
if (!item
|
|
4357
|
+
if (!item) return;
|
|
4358
|
+
await this.recordRawGeneratedImageMedia(item);
|
|
4359
|
+
if (readString$5(item, "role") !== "assistant") return;
|
|
4394
4360
|
const text = extractRawAssistantText(item);
|
|
4395
4361
|
if (!text) return;
|
|
4396
4362
|
const itemId = readString$5(item, "id") ?? `raw-assistant-${this.assistantItemOrder.length + 1}`;
|
|
@@ -4406,7 +4372,56 @@ var CodexAppServerEventProjector = class {
|
|
|
4406
4372
|
recordNativeGeneratedMedia(item) {
|
|
4407
4373
|
if (item?.type !== "imageGeneration") return;
|
|
4408
4374
|
const savedPath = readItemString(item, "savedPath")?.trim();
|
|
4409
|
-
if (savedPath) this.
|
|
4375
|
+
if (savedPath) this.recordNativeGeneratedMediaUrl({
|
|
4376
|
+
itemId: item.id,
|
|
4377
|
+
mediaUrl: savedPath
|
|
4378
|
+
});
|
|
4379
|
+
}
|
|
4380
|
+
async recordRawGeneratedImageMedia(item) {
|
|
4381
|
+
if (readString$5(item, "type") !== "image_generation_call") return;
|
|
4382
|
+
const result = readString$5(item, "result");
|
|
4383
|
+
if (!result) return;
|
|
4384
|
+
const itemId = readString$5(item, "id") ?? `raw-image-${this.nativeGeneratedMediaItemIds.size}`;
|
|
4385
|
+
this.nativeGeneratedMediaItemIds.add(itemId);
|
|
4386
|
+
const maxBytes = resolveGeneratedImageMaxBytes(this.params.config);
|
|
4387
|
+
const estimatedDecodedBytes = estimateBase64DecodedBytes(result);
|
|
4388
|
+
if (estimatedDecodedBytes !== void 0 && estimatedDecodedBytes > maxBytes) {
|
|
4389
|
+
embeddedAgentLog.warn("codex app-server raw image generation result exceeds media limit", {
|
|
4390
|
+
itemId,
|
|
4391
|
+
estimatedDecodedBytes,
|
|
4392
|
+
maxBytes
|
|
4393
|
+
});
|
|
4394
|
+
return;
|
|
4395
|
+
}
|
|
4396
|
+
const asset = generatedImageAssetFromBase64({
|
|
4397
|
+
base64: result,
|
|
4398
|
+
index: this.nativeGeneratedMediaItemIds.size,
|
|
4399
|
+
revisedPrompt: readString$5(item, "revised_prompt") ?? readString$5(item, "revisedPrompt"),
|
|
4400
|
+
fileNamePrefix: "codex-image-generation",
|
|
4401
|
+
sniffMimeType: true
|
|
4402
|
+
});
|
|
4403
|
+
if (!asset) return;
|
|
4404
|
+
try {
|
|
4405
|
+
const saved = await saveMediaBuffer(asset.buffer, asset.mimeType, GENERATED_IMAGE_MEDIA_SUBDIR, maxBytes, asset.fileName);
|
|
4406
|
+
this.recordNativeGeneratedMediaUrl({
|
|
4407
|
+
itemId,
|
|
4408
|
+
mediaUrl: saved.path
|
|
4409
|
+
});
|
|
4410
|
+
} catch (error) {
|
|
4411
|
+
embeddedAgentLog.warn("codex app-server raw image generation result save failed", {
|
|
4412
|
+
itemId,
|
|
4413
|
+
error
|
|
4414
|
+
});
|
|
4415
|
+
}
|
|
4416
|
+
}
|
|
4417
|
+
recordNativeGeneratedMediaUrl(params) {
|
|
4418
|
+
if (this.nativeGeneratedMediaUrlsByItemId.has(params.itemId)) {
|
|
4419
|
+
this.nativeGeneratedMediaItemIds.add(params.itemId);
|
|
4420
|
+
return;
|
|
4421
|
+
}
|
|
4422
|
+
this.nativeGeneratedMediaUrlsByItemId.set(params.itemId, params.mediaUrl);
|
|
4423
|
+
this.nativeGeneratedMediaUrls.add(params.mediaUrl);
|
|
4424
|
+
this.nativeGeneratedMediaItemIds.add(params.itemId);
|
|
4410
4425
|
}
|
|
4411
4426
|
buildToolMediaUrls(toolTelemetry) {
|
|
4412
4427
|
const mediaUrls = new Set(toolTelemetry.toolMediaUrls?.map((url) => url.trim()).filter(Boolean) ?? []);
|
|
@@ -4833,7 +4848,7 @@ var CodexAppServerEventProjector = class {
|
|
|
4833
4848
|
type: "text",
|
|
4834
4849
|
text
|
|
4835
4850
|
}],
|
|
4836
|
-
api: attribution.api ?? "openai-
|
|
4851
|
+
api: attribution.api ?? "openai-chatgpt-responses",
|
|
4837
4852
|
provider: attribution.provider,
|
|
4838
4853
|
model: this.params.modelId,
|
|
4839
4854
|
usage,
|
|
@@ -4850,7 +4865,7 @@ var CodexAppServerEventProjector = class {
|
|
|
4850
4865
|
type: "text",
|
|
4851
4866
|
text: `${title}:\n${text}`
|
|
4852
4867
|
}],
|
|
4853
|
-
api: attribution.api ?? "openai-
|
|
4868
|
+
api: attribution.api ?? "openai-chatgpt-responses",
|
|
4854
4869
|
provider: attribution.provider,
|
|
4855
4870
|
model: this.params.modelId,
|
|
4856
4871
|
usage: ZERO_USAGE,
|
|
@@ -4870,7 +4885,7 @@ var CodexAppServerEventProjector = class {
|
|
|
4870
4885
|
arguments: args,
|
|
4871
4886
|
input: args
|
|
4872
4887
|
}],
|
|
4873
|
-
api: attribution.api ?? "openai-
|
|
4888
|
+
api: attribution.api ?? "openai-chatgpt-responses",
|
|
4874
4889
|
provider: attribution.provider,
|
|
4875
4890
|
model: this.params.modelId,
|
|
4876
4891
|
usage: ZERO_USAGE,
|
|
@@ -4920,6 +4935,30 @@ function readString$5(record, key) {
|
|
|
4920
4935
|
const value = record[key];
|
|
4921
4936
|
return typeof value === "string" ? value : void 0;
|
|
4922
4937
|
}
|
|
4938
|
+
function estimateBase64DecodedBytes(base64) {
|
|
4939
|
+
let nonWhitespaceLength = 0;
|
|
4940
|
+
let previousCode = -1;
|
|
4941
|
+
let lastCode = -1;
|
|
4942
|
+
for (let i = 0; i < base64.length; i += 1) {
|
|
4943
|
+
const code = base64.charCodeAt(i);
|
|
4944
|
+
if (isBase64WhitespaceCode(code)) continue;
|
|
4945
|
+
nonWhitespaceLength += 1;
|
|
4946
|
+
previousCode = lastCode;
|
|
4947
|
+
lastCode = code;
|
|
4948
|
+
}
|
|
4949
|
+
if (nonWhitespaceLength === 0) return;
|
|
4950
|
+
const equalsCode = "=".charCodeAt(0);
|
|
4951
|
+
const padding = lastCode === equalsCode ? previousCode === equalsCode ? 2 : 1 : 0;
|
|
4952
|
+
return Math.max(0, Math.floor(nonWhitespaceLength * 3 / 4) - padding);
|
|
4953
|
+
}
|
|
4954
|
+
function isBase64WhitespaceCode(code) {
|
|
4955
|
+
return code === 32 || code === 9 || code === 10 || code === 13;
|
|
4956
|
+
}
|
|
4957
|
+
function resolveGeneratedImageMaxBytes(config) {
|
|
4958
|
+
const configured = config?.agents?.defaults?.mediaMaxMb;
|
|
4959
|
+
if (typeof configured === "number" && Number.isFinite(configured) && configured > 0) return Math.floor(configured * BYTES_PER_MB);
|
|
4960
|
+
return DEFAULT_GENERATED_IMAGE_MAX_BYTES;
|
|
4961
|
+
}
|
|
4923
4962
|
function normalizeNonEmptyString(value) {
|
|
4924
4963
|
if (typeof value !== "string") return;
|
|
4925
4964
|
return value.trim() || void 0;
|
|
@@ -6349,6 +6388,9 @@ function unrefTimer(timer) {
|
|
|
6349
6388
|
//#endregion
|
|
6350
6389
|
//#region extensions/codex/src/app-server/startup-binding.ts
|
|
6351
6390
|
const CODEX_APP_SERVER_NATIVE_THREAD_FALLBACK_MAX_TOKENS = 3e5;
|
|
6391
|
+
const CODEX_APP_SERVER_NATIVE_THREAD_DEFAULT_RESERVE_TOKENS = 2e4;
|
|
6392
|
+
const CODEX_APP_SERVER_NATIVE_THREAD_MIN_PROMPT_BUDGET_TOKENS = 8e3;
|
|
6393
|
+
const CODEX_APP_SERVER_NATIVE_THREAD_MIN_PROMPT_BUDGET_RATIO = .5;
|
|
6352
6394
|
const CODEX_APP_SERVER_BYTE_UNITS = {
|
|
6353
6395
|
b: 1,
|
|
6354
6396
|
k: 1024,
|
|
@@ -6364,6 +6406,7 @@ const CODEX_APP_SERVER_BYTE_UNITS = {
|
|
|
6364
6406
|
tb: 1024 * 1024 * 1024 * 1024,
|
|
6365
6407
|
tib: 1024 * 1024 * 1024 * 1024
|
|
6366
6408
|
};
|
|
6409
|
+
const codexSessionRecordCache = /* @__PURE__ */ new Map();
|
|
6367
6410
|
function parseCodexAppServerByteLimit(value) {
|
|
6368
6411
|
if (typeof value === "number" && Number.isFinite(value) && value > 0) return Math.floor(value);
|
|
6369
6412
|
if (typeof value !== "string") return;
|
|
@@ -6419,22 +6462,44 @@ async function listCodexAppServerRolloutFilesForThread(agentDir, threadId, codex
|
|
|
6419
6462
|
}
|
|
6420
6463
|
async function readCodexSessionRecordForSessionFile(sessionFile) {
|
|
6421
6464
|
const sessionsFile = path.join(path.dirname(sessionFile), "sessions.json");
|
|
6465
|
+
const resolvedSessionFile = path.resolve(sessionFile);
|
|
6466
|
+
let stat;
|
|
6467
|
+
try {
|
|
6468
|
+
stat = await fs.stat(sessionsFile);
|
|
6469
|
+
} catch {
|
|
6470
|
+
codexSessionRecordCache.delete(resolvedSessionFile);
|
|
6471
|
+
return;
|
|
6472
|
+
}
|
|
6473
|
+
const cached = codexSessionRecordCache.get(resolvedSessionFile);
|
|
6474
|
+
if (cached?.sessionsFile === sessionsFile && cached.mtimeMs === stat.mtimeMs && cached.size === stat.size) return cached.record;
|
|
6422
6475
|
let store;
|
|
6423
6476
|
try {
|
|
6424
6477
|
store = JSON.parse(await fs.readFile(sessionsFile, "utf8"));
|
|
6425
6478
|
} catch {
|
|
6479
|
+
codexSessionRecordCache.delete(resolvedSessionFile);
|
|
6426
6480
|
return;
|
|
6427
6481
|
}
|
|
6428
|
-
if (!isJsonObject(store))
|
|
6429
|
-
|
|
6482
|
+
if (!isJsonObject(store)) {
|
|
6483
|
+
codexSessionRecordCache.delete(resolvedSessionFile);
|
|
6484
|
+
return;
|
|
6485
|
+
}
|
|
6486
|
+
let found;
|
|
6430
6487
|
for (const [sessionKey, record] of Object.entries(store)) {
|
|
6431
6488
|
if (!isJsonObject(record) || typeof record.sessionFile !== "string") continue;
|
|
6432
6489
|
if (path.resolve(record.sessionFile) !== resolvedSessionFile) continue;
|
|
6433
|
-
|
|
6490
|
+
found = {
|
|
6434
6491
|
sessionKey,
|
|
6435
6492
|
...record
|
|
6436
6493
|
};
|
|
6494
|
+
break;
|
|
6437
6495
|
}
|
|
6496
|
+
codexSessionRecordCache.set(resolvedSessionFile, {
|
|
6497
|
+
sessionsFile,
|
|
6498
|
+
mtimeMs: stat.mtimeMs,
|
|
6499
|
+
size: stat.size,
|
|
6500
|
+
record: found
|
|
6501
|
+
});
|
|
6502
|
+
return found;
|
|
6438
6503
|
}
|
|
6439
6504
|
async function readCodexAppServerRolloutTokenSnapshot(file) {
|
|
6440
6505
|
let handle;
|
|
@@ -6478,52 +6543,75 @@ function readCodexAppServerRolloutTokenSnapshotLine(line) {
|
|
|
6478
6543
|
return;
|
|
6479
6544
|
}
|
|
6480
6545
|
}
|
|
6481
|
-
function
|
|
6482
|
-
|
|
6546
|
+
function toNonNegativeInt(value) {
|
|
6547
|
+
if (typeof value !== "number" || !Number.isFinite(value) || value < 0) return;
|
|
6548
|
+
return Math.floor(value);
|
|
6549
|
+
}
|
|
6550
|
+
function readCompactionConfig(config) {
|
|
6551
|
+
return isJsonObject(config?.agents?.defaults?.compaction) ? config.agents.defaults.compaction : void 0;
|
|
6552
|
+
}
|
|
6553
|
+
function resolveCodexAppServerNativeThreadReserveTokens(config) {
|
|
6554
|
+
const compaction = readCompactionConfig(config);
|
|
6555
|
+
const reserveTokens = toNonNegativeInt(compaction?.reserveTokens);
|
|
6556
|
+
const reserveTokensFloor = toNonNegativeInt(compaction?.reserveTokensFloor);
|
|
6557
|
+
if (reserveTokens !== void 0) return Math.max(reserveTokens, reserveTokensFloor ?? CODEX_APP_SERVER_NATIVE_THREAD_DEFAULT_RESERVE_TOKENS);
|
|
6558
|
+
return reserveTokensFloor ?? CODEX_APP_SERVER_NATIVE_THREAD_DEFAULT_RESERVE_TOKENS;
|
|
6559
|
+
}
|
|
6560
|
+
function resolveCodexAppServerNativeThreadTokenFuse(params) {
|
|
6561
|
+
const projectedTurnTokens = typeof params.projectedTurnTokens === "number" && Number.isFinite(params.projectedTurnTokens) && params.projectedTurnTokens > 0 ? Math.floor(params.projectedTurnTokens) : 0;
|
|
6562
|
+
const contextWindow = params.modelContextWindow ?? CODEX_APP_SERVER_NATIVE_THREAD_FALLBACK_MAX_TOKENS;
|
|
6563
|
+
const minPromptBudget = Math.min(CODEX_APP_SERVER_NATIVE_THREAD_MIN_PROMPT_BUDGET_TOKENS, Math.max(1, Math.floor(contextWindow * CODEX_APP_SERVER_NATIVE_THREAD_MIN_PROMPT_BUDGET_RATIO)));
|
|
6564
|
+
const effectiveReserveTokens = Math.min(params.reserveTokens, Math.max(0, contextWindow - minPromptBudget));
|
|
6565
|
+
return Math.max(1, contextWindow - effectiveReserveTokens - projectedTurnTokens);
|
|
6483
6566
|
}
|
|
6484
6567
|
function maxFiniteNumber(values) {
|
|
6485
6568
|
const nums = values.filter((value) => typeof value === "number" && Number.isFinite(value));
|
|
6486
6569
|
if (nums.length === 0) return;
|
|
6487
6570
|
return Math.max(...nums);
|
|
6488
6571
|
}
|
|
6572
|
+
function minFiniteNumber(values) {
|
|
6573
|
+
const nums = values.filter((value) => typeof value === "number" && Number.isFinite(value));
|
|
6574
|
+
if (nums.length === 0) return;
|
|
6575
|
+
return Math.min(...nums);
|
|
6576
|
+
}
|
|
6489
6577
|
function hasContextEngineThreadBootstrapProjection(binding) {
|
|
6490
6578
|
return binding.contextEngine?.projection?.mode === "thread_bootstrap";
|
|
6491
6579
|
}
|
|
6492
6580
|
async function rotateOversizedCodexAppServerStartupBinding(params) {
|
|
6493
6581
|
const binding = params.binding;
|
|
6494
6582
|
if (!binding?.threadId) return binding;
|
|
6495
|
-
if (params.config?.agents?.defaults?.compaction?.truncateAfterCompaction !== true) return binding;
|
|
6496
|
-
if (params.contextEngineActive === true && hasContextEngineThreadBootstrapProjection(binding)) {
|
|
6497
|
-
embeddedAgentLog.debug("codex app-server deferring native transcript size guard for context-engine thread bootstrap", {
|
|
6498
|
-
threadId: binding.threadId,
|
|
6499
|
-
engineId: binding.contextEngine?.engineId,
|
|
6500
|
-
epoch: binding.contextEngine?.projection?.epoch,
|
|
6501
|
-
fingerprint: binding.contextEngine?.projection?.fingerprint
|
|
6502
|
-
});
|
|
6503
|
-
return binding;
|
|
6504
|
-
}
|
|
6505
6583
|
const sessionRecord = await readCodexSessionRecordForSessionFile(params.sessionFile);
|
|
6506
|
-
const maxBytes = parseCodexAppServerByteLimit(params.config?.agents?.defaults?.compaction?.maxActiveTranscriptBytes);
|
|
6507
6584
|
const rolloutFiles = await listCodexAppServerRolloutFilesForThread(params.agentDir, binding.threadId, params.codexHome);
|
|
6508
|
-
|
|
6509
|
-
|
|
6510
|
-
|
|
6511
|
-
|
|
6512
|
-
|
|
6513
|
-
|
|
6514
|
-
|
|
6515
|
-
|
|
6516
|
-
|
|
6517
|
-
|
|
6518
|
-
|
|
6519
|
-
|
|
6520
|
-
|
|
6585
|
+
const compaction = readCompactionConfig(params.config);
|
|
6586
|
+
const shouldDeferByteGuard = compaction?.truncateAfterCompaction === true && params.contextEngineActive === true && hasContextEngineThreadBootstrapProjection(binding);
|
|
6587
|
+
if (compaction?.truncateAfterCompaction === true && !shouldDeferByteGuard) {
|
|
6588
|
+
const maxBytes = parseCodexAppServerByteLimit(compaction.maxActiveTranscriptBytes);
|
|
6589
|
+
if (maxBytes !== void 0) {
|
|
6590
|
+
const oversizedFiles = rolloutFiles.filter((file) => file.bytes >= maxBytes);
|
|
6591
|
+
if (oversizedFiles.length > 0) {
|
|
6592
|
+
embeddedAgentLog.warn("codex app-server native transcript exceeded active byte limit; starting a fresh thread", {
|
|
6593
|
+
threadId: binding.threadId,
|
|
6594
|
+
maxBytes,
|
|
6595
|
+
files: oversizedFiles.map((file) => ({
|
|
6596
|
+
path: file.path,
|
|
6597
|
+
bytes: file.bytes
|
|
6598
|
+
}))
|
|
6599
|
+
});
|
|
6600
|
+
await clearCodexAppServerBinding(params.sessionFile);
|
|
6601
|
+
return;
|
|
6602
|
+
}
|
|
6521
6603
|
}
|
|
6522
6604
|
}
|
|
6523
6605
|
const nativeTokenSnapshots = await Promise.all(rolloutFiles.map(async (file) => readCodexAppServerRolloutTokenSnapshot(file.path)));
|
|
6524
6606
|
const nativeTokens = maxFiniteNumber(nativeTokenSnapshots.map((snapshot) => snapshot?.totalTokens));
|
|
6525
6607
|
const nativeModelContextWindow = maxFiniteNumber(nativeTokenSnapshots.map((snapshot) => snapshot?.modelContextWindow));
|
|
6526
|
-
const
|
|
6608
|
+
const sessionModelContextWindow = typeof sessionRecord?.contextTokens === "number" && Number.isFinite(sessionRecord.contextTokens) && sessionRecord.contextTokens > 0 ? Math.floor(sessionRecord.contextTokens) : void 0;
|
|
6609
|
+
const reserveTokens = resolveCodexAppServerNativeThreadReserveTokens(params.config);
|
|
6610
|
+
const maxTokens = resolveCodexAppServerNativeThreadTokenFuse({
|
|
6611
|
+
modelContextWindow: minFiniteNumber([nativeModelContextWindow, sessionModelContextWindow]),
|
|
6612
|
+
reserveTokens,
|
|
6613
|
+
projectedTurnTokens: params.projectedTurnTokens
|
|
6614
|
+
});
|
|
6527
6615
|
const sessionTokens = sessionRecord?.totalTokensFresh !== false && typeof sessionRecord?.totalTokens === "number" && Number.isFinite(sessionRecord.totalTokens) ? sessionRecord.totalTokens : void 0;
|
|
6528
6616
|
const tokenCount = maxFiniteNumber([sessionTokens, nativeTokens]);
|
|
6529
6617
|
if (tokenCount !== void 0 && tokenCount >= maxTokens) {
|
|
@@ -6533,11 +6621,24 @@ async function rotateOversizedCodexAppServerStartupBinding(params) {
|
|
|
6533
6621
|
sessionKey: sessionRecord?.sessionKey,
|
|
6534
6622
|
sessionTokens,
|
|
6535
6623
|
nativeTokens,
|
|
6536
|
-
nativeModelContextWindow
|
|
6624
|
+
nativeModelContextWindow,
|
|
6625
|
+
sessionModelContextWindow,
|
|
6626
|
+
reserveTokens,
|
|
6627
|
+
projectedTurnTokens: params.projectedTurnTokens
|
|
6537
6628
|
});
|
|
6538
6629
|
await clearCodexAppServerBinding(params.sessionFile);
|
|
6539
6630
|
return;
|
|
6540
6631
|
}
|
|
6632
|
+
if (compaction?.truncateAfterCompaction !== true) return binding;
|
|
6633
|
+
if (shouldDeferByteGuard) {
|
|
6634
|
+
embeddedAgentLog.debug("codex app-server deferring native transcript byte guard for context-engine thread bootstrap", {
|
|
6635
|
+
threadId: binding.threadId,
|
|
6636
|
+
engineId: binding.contextEngine?.engineId,
|
|
6637
|
+
epoch: binding.contextEngine?.projection?.epoch,
|
|
6638
|
+
fingerprint: binding.contextEngine?.projection?.fingerprint
|
|
6639
|
+
});
|
|
6640
|
+
return binding;
|
|
6641
|
+
}
|
|
6541
6642
|
return binding;
|
|
6542
6643
|
}
|
|
6543
6644
|
//#endregion
|
|
@@ -7056,7 +7157,12 @@ function readRequestId(record) {
|
|
|
7056
7157
|
//#endregion
|
|
7057
7158
|
//#region extensions/codex/src/app-server/run-attempt.ts
|
|
7058
7159
|
const CODEX_NATIVE_HOOK_RELAY_RENEW_INTERVAL_MS = 6e4;
|
|
7160
|
+
const CODEX_APP_SERVER_PROJECTED_CHARS_PER_TOKEN = 4;
|
|
7059
7161
|
const ensuredCodexWorkspaceDirs = /* @__PURE__ */ new Set();
|
|
7162
|
+
function estimateCodexAppServerProjectedTurnTokens(params) {
|
|
7163
|
+
const inputChars = params.prompt.length + (params.developerInstructions?.length ?? 0);
|
|
7164
|
+
return Math.max(1, Math.ceil(inputChars / CODEX_APP_SERVER_PROJECTED_CHARS_PER_TOKEN));
|
|
7165
|
+
}
|
|
7060
7166
|
async function ensureCodexWorkspaceDirOnce(workspaceDir) {
|
|
7061
7167
|
const normalized = path.resolve(workspaceDir);
|
|
7062
7168
|
if (ensuredCodexWorkspaceDirs.has(normalized)) {
|
|
@@ -7363,12 +7469,11 @@ async function runCodexAppServerAttempt(params, options = {}) {
|
|
|
7363
7469
|
const baseDeveloperInstructions = joinPresentSections(buildDeveloperInstructions(params, { dynamicTools: toolBridge.availableSpecs }), workspaceBootstrapContext.developerInstructions);
|
|
7364
7470
|
const openClawPromptContext = buildCodexOpenClawPromptContext({
|
|
7365
7471
|
params,
|
|
7366
|
-
|
|
7367
|
-
|
|
7368
|
-
|
|
7369
|
-
|
|
7370
|
-
|
|
7371
|
-
})
|
|
7472
|
+
workspacePromptContext: workspaceBootstrapContext.promptContext
|
|
7473
|
+
});
|
|
7474
|
+
const skillsCollaborationInstructions = renderCodexSkillsCollaborationInstructions({
|
|
7475
|
+
attempt: params,
|
|
7476
|
+
skillsPrompt: params.skillsSnapshot?.prompt
|
|
7372
7477
|
});
|
|
7373
7478
|
let promptText = params.prompt;
|
|
7374
7479
|
let developerInstructions = baseDeveloperInstructions;
|
|
@@ -7435,41 +7540,69 @@ async function runCodexAppServerAttempt(params, options = {}) {
|
|
|
7435
7540
|
} catch (assembleErr) {
|
|
7436
7541
|
embeddedAgentLog.warn("context engine assemble failed; using Codex baseline prompt", { error: formatErrorMessage(assembleErr) });
|
|
7437
7542
|
}
|
|
7438
|
-
|
|
7439
|
-
startupBinding,
|
|
7440
|
-
dynamicToolsFingerprint: codexDynamicToolsFingerprint(toolBridge.specs),
|
|
7441
|
-
historyMessages,
|
|
7442
|
-
forceProject: !nativeToolSurfaceEnabled
|
|
7443
|
-
})) {
|
|
7444
|
-
const projection = projectContextEngineAssemblyForCodex({
|
|
7445
|
-
assembledMessages: historyMessages,
|
|
7446
|
-
originalHistoryMessages: historyMessages,
|
|
7447
|
-
prompt: params.prompt
|
|
7448
|
-
});
|
|
7449
|
-
promptText = projection.promptText;
|
|
7450
|
-
prePromptMessageCount = projection.prePromptMessageCount;
|
|
7451
|
-
}
|
|
7543
|
+
const codexModelInputHistoryMessages = [];
|
|
7452
7544
|
const buildPromptFromCurrentInputs = () => resolveAgentHarnessBeforePromptBuildResult({
|
|
7453
7545
|
prompt: prependCurrentInboundContext(promptText, params.currentInboundContext),
|
|
7454
7546
|
developerInstructions,
|
|
7455
|
-
messages:
|
|
7547
|
+
messages: codexModelInputHistoryMessages,
|
|
7456
7548
|
ctx: hookContext
|
|
7457
7549
|
});
|
|
7458
7550
|
let promptBuild = await buildPromptFromCurrentInputs();
|
|
7459
|
-
const decorateCodexTurnPromptText = (prompt) => prependCodexOpenClawPromptContext(prompt, openClawPromptContext);
|
|
7551
|
+
const decorateCodexTurnPromptText = (prompt) => prependCodexOpenClawPromptContext(prompt, openClawPromptContext, { preservePromptWithoutContext: params.bootstrapContextMode === "lightweight" && params.bootstrapContextRunKind === "cron" });
|
|
7460
7552
|
let codexTurnPromptText = decorateCodexTurnPromptText(promptBuild.prompt);
|
|
7461
7553
|
const buildCodexTurnCollaborationDeveloperInstructions = () => buildTurnCollaborationMode(params, {
|
|
7462
7554
|
turnScopedDeveloperInstructions: workspaceBootstrapContext.turnScopedDeveloperInstructions,
|
|
7555
|
+
skillsCollaborationInstructions,
|
|
7556
|
+
memoryCollaborationInstructions: workspaceBootstrapContext.memoryCollaborationInstructions,
|
|
7463
7557
|
heartbeatCollaborationInstructions: workspaceBootstrapContext.heartbeatCollaborationInstructions
|
|
7464
7558
|
}).settings.developer_instructions ?? void 0;
|
|
7465
7559
|
const buildRenderedCodexDeveloperInstructions = () => joinPresentSections(promptBuild.developerInstructions, buildCodexTurnCollaborationDeveloperInstructions());
|
|
7560
|
+
const rebuildCodexTurnPromptFromCurrentProjection = async () => {
|
|
7561
|
+
promptBuild = await buildPromptFromCurrentInputs();
|
|
7562
|
+
codexTurnPromptText = decorateCodexTurnPromptText(promptBuild.prompt);
|
|
7563
|
+
};
|
|
7564
|
+
const rotateStartupBindingForProjectedTurn = async () => {
|
|
7565
|
+
if (!startupBinding?.threadId) return;
|
|
7566
|
+
const previousThreadId = startupBinding.threadId;
|
|
7567
|
+
const projectedTurnTokens = estimateCodexAppServerProjectedTurnTokens({
|
|
7568
|
+
prompt: codexTurnPromptText,
|
|
7569
|
+
developerInstructions: buildRenderedCodexDeveloperInstructions()
|
|
7570
|
+
});
|
|
7571
|
+
startupBinding = await rotateOversizedCodexAppServerStartupBinding({
|
|
7572
|
+
binding: startupBinding,
|
|
7573
|
+
sessionFile: params.sessionFile,
|
|
7574
|
+
agentDir,
|
|
7575
|
+
codexHome: appServer.start.env?.CODEX_HOME,
|
|
7576
|
+
config: params.config,
|
|
7577
|
+
contextEngineActive: Boolean(activeContextEngine),
|
|
7578
|
+
projectedTurnTokens
|
|
7579
|
+
});
|
|
7580
|
+
if (startupBinding?.threadId) return;
|
|
7581
|
+
if (activeContextEngine) {
|
|
7582
|
+
contextEngineProjection = void 0;
|
|
7583
|
+
try {
|
|
7584
|
+
await applyActiveContextEngineProjection(void 0);
|
|
7585
|
+
} catch (assembleErr) {
|
|
7586
|
+
embeddedAgentLog.warn("context engine assemble failed; using Codex baseline prompt", { error: formatErrorMessage(assembleErr) });
|
|
7587
|
+
}
|
|
7588
|
+
}
|
|
7589
|
+
await rebuildCodexTurnPromptFromCurrentProjection();
|
|
7590
|
+
embeddedAgentLog.info("codex app-server rebuilt turn prompt after native thread rotation", {
|
|
7591
|
+
sessionId: params.sessionId,
|
|
7592
|
+
sessionKey: contextSessionKey,
|
|
7593
|
+
previousThreadId,
|
|
7594
|
+
promptChars: codexTurnPromptText.length,
|
|
7595
|
+
developerInstructionChars: buildRenderedCodexDeveloperInstructions()?.length ?? 0
|
|
7596
|
+
});
|
|
7597
|
+
};
|
|
7598
|
+
await rotateStartupBindingForProjectedTurn();
|
|
7466
7599
|
const systemPromptReport = buildCodexSystemPromptReport({
|
|
7467
7600
|
attempt: params,
|
|
7468
7601
|
sessionKey: contextSessionKey,
|
|
7469
7602
|
workspaceDir: effectiveWorkspace,
|
|
7470
7603
|
developerInstructions: buildRenderedCodexDeveloperInstructions(),
|
|
7471
7604
|
workspaceBootstrapContext,
|
|
7472
|
-
skillsPrompt:
|
|
7605
|
+
skillsPrompt: skillsCollaborationInstructions ? params.skillsSnapshot?.prompt ?? "" : "",
|
|
7473
7606
|
tools: toolBridge.availableSpecs
|
|
7474
7607
|
});
|
|
7475
7608
|
const trajectoryRecorder = createCodexTrajectoryRecorder({
|
|
@@ -7592,7 +7725,7 @@ async function runCodexAppServerAttempt(params, options = {}) {
|
|
|
7592
7725
|
recordCodexTrajectoryContext(trajectoryRecorder, {
|
|
7593
7726
|
attempt: params,
|
|
7594
7727
|
cwd: effectiveCwd,
|
|
7595
|
-
developerInstructions:
|
|
7728
|
+
developerInstructions: buildRenderedCodexDeveloperInstructions(),
|
|
7596
7729
|
prompt: codexTurnPromptText,
|
|
7597
7730
|
tools: toolBridge.availableSpecs
|
|
7598
7731
|
});
|
|
@@ -7605,6 +7738,7 @@ async function runCodexAppServerAttempt(params, options = {}) {
|
|
|
7605
7738
|
let terminalTurnNotificationQueued = false;
|
|
7606
7739
|
let timedOut = false;
|
|
7607
7740
|
let turnCompletionIdleTimedOut = false;
|
|
7741
|
+
let turnWatchTimeoutKind;
|
|
7608
7742
|
let turnCompletionIdleTimeoutMessage;
|
|
7609
7743
|
let clientClosedPromptError;
|
|
7610
7744
|
let clientClosedAbort = false;
|
|
@@ -7657,9 +7791,10 @@ async function runCodexAppServerAttempt(params, options = {}) {
|
|
|
7657
7791
|
turnTerminalIdleTimeoutMs,
|
|
7658
7792
|
interruptTimeoutMs: CODEX_APP_SERVER_INTERRUPT_TIMEOUT_MS,
|
|
7659
7793
|
onInterruptTurn: (input) => interruptCodexTurnBestEffort(client, input),
|
|
7660
|
-
onTimeout: () => {
|
|
7794
|
+
onTimeout: (timeout) => {
|
|
7661
7795
|
timedOut = true;
|
|
7662
7796
|
turnCompletionIdleTimedOut = true;
|
|
7797
|
+
turnWatchTimeoutKind = timeout.kind;
|
|
7663
7798
|
turnCompletionIdleTimeoutMessage = "codex app-server turn idle timed out waiting for turn/completed";
|
|
7664
7799
|
},
|
|
7665
7800
|
onMarkTimedOut: () => projector?.markTimedOut(),
|
|
@@ -7803,7 +7938,6 @@ async function runCodexAppServerAttempt(params, options = {}) {
|
|
|
7803
7938
|
threadId: thread.threadId,
|
|
7804
7939
|
turnId,
|
|
7805
7940
|
currentPromptTexts: [codexTurnPromptText],
|
|
7806
|
-
sourceReplyDeliveryMode: params.sourceReplyDeliveryMode,
|
|
7807
7941
|
turnWatches,
|
|
7808
7942
|
activeTurnItemIds,
|
|
7809
7943
|
activeAppServerTurnRequests,
|
|
@@ -7850,7 +7984,13 @@ async function runCodexAppServerAttempt(params, options = {}) {
|
|
|
7850
7984
|
return Promise.resolve();
|
|
7851
7985
|
}
|
|
7852
7986
|
if (isTerminalTurnNotificationForTurn(notification, turnId)) terminalTurnNotificationQueued = true;
|
|
7853
|
-
|
|
7987
|
+
const isNativeResponseStreamDelta = isNativeResponseStreamDeltaNotification(notification);
|
|
7988
|
+
const nativeResponseStreamDeltaMatchesActiveTurn = isNativeResponseStreamDelta && (correlation.matchesActiveTurn === true || isUnscopedCodexNotification(correlation) && canAttributeUnscopedNativeResponseDeltaToThisTurn(client));
|
|
7989
|
+
if (correlation.matchesActiveTurn === true || !isNativeResponseStreamDelta && correlation.matchesActiveTurn !== false || nativeResponseStreamDeltaMatchesActiveTurn) turnWatches.noteNotificationReceived(notification.method, isNativeResponseStreamDelta ? {
|
|
7990
|
+
attemptProgress: true,
|
|
7991
|
+
...turnCrossedToolHandoff ? { attemptTimeoutMs: postToolRawAssistantCompletionIdleTimeoutMs } : {},
|
|
7992
|
+
details: { lastNotificationMethod: notification.method }
|
|
7993
|
+
} : void 0);
|
|
7854
7994
|
notificationQueue = notificationQueue.then(() => handleNotification(notification), () => handleNotification(notification));
|
|
7855
7995
|
return notificationQueue;
|
|
7856
7996
|
};
|
|
@@ -8077,10 +8217,13 @@ async function runCodexAppServerAttempt(params, options = {}) {
|
|
|
8077
8217
|
} finally {
|
|
8078
8218
|
if (requestCountsAsTurnActivity) {
|
|
8079
8219
|
activeAppServerTurnRequests = Math.max(0, activeAppServerTurnRequests - 1);
|
|
8220
|
+
const postToolContinuationTimeoutMs = request.method === "item/tool/call" && turnCrossedToolHandoff ? postToolRawAssistantCompletionIdleTimeoutMs : void 0;
|
|
8080
8221
|
turnWatches.touchActivity(`request:${request.method}:response`, {
|
|
8081
8222
|
arm: armCompletionWatchOnResponse,
|
|
8082
|
-
attemptProgress: true
|
|
8223
|
+
attemptProgress: true,
|
|
8224
|
+
...postToolContinuationTimeoutMs !== void 0 ? { attemptTimeoutMs: postToolContinuationTimeoutMs } : {}
|
|
8083
8225
|
});
|
|
8226
|
+
if (armCompletionWatchOnResponse && postToolContinuationTimeoutMs !== void 0) turnWatches.armCompletionIdleWatch({ timeoutMs: postToolContinuationTimeoutMs });
|
|
8084
8227
|
scheduleTerminalDynamicToolReleaseCheck();
|
|
8085
8228
|
} else turnWatches.scheduleProgressWatches();
|
|
8086
8229
|
}
|
|
@@ -8093,11 +8236,11 @@ async function runCodexAppServerAttempt(params, options = {}) {
|
|
|
8093
8236
|
model: params.modelId,
|
|
8094
8237
|
systemPrompt: buildRenderedCodexDeveloperInstructions(),
|
|
8095
8238
|
prompt: codexTurnPromptText,
|
|
8096
|
-
historyMessages,
|
|
8239
|
+
historyMessages: codexModelInputHistoryMessages,
|
|
8097
8240
|
imagesCount: params.images?.length ?? 0,
|
|
8098
8241
|
tools
|
|
8099
8242
|
});
|
|
8100
|
-
const
|
|
8243
|
+
const buildCodexModelInputMessages = () => [...codexModelInputHistoryMessages, buildCodexUserPromptMessage({
|
|
8101
8244
|
...params,
|
|
8102
8245
|
prompt: codexTurnPromptText
|
|
8103
8246
|
})];
|
|
@@ -8116,7 +8259,7 @@ async function runCodexAppServerAttempt(params, options = {}) {
|
|
|
8116
8259
|
},
|
|
8117
8260
|
capture: codexModelContentCapture,
|
|
8118
8261
|
tools,
|
|
8119
|
-
buildInputMessages:
|
|
8262
|
+
buildInputMessages: buildCodexModelInputMessages,
|
|
8120
8263
|
buildSystemPrompt: buildRenderedCodexDeveloperInstructions,
|
|
8121
8264
|
onErrorDiagnostic: (error) => {
|
|
8122
8265
|
embeddedAgentLog.debug("codex app-server model call diagnostic ended with error", { error: formatErrorMessage(error) });
|
|
@@ -8132,6 +8275,8 @@ async function runCodexAppServerAttempt(params, options = {}) {
|
|
|
8132
8275
|
sandboxPolicy: codexSandboxPolicy,
|
|
8133
8276
|
environmentSelection: codexEnvironmentSelection,
|
|
8134
8277
|
turnScopedDeveloperInstructions: workspaceBootstrapContext.turnScopedDeveloperInstructions,
|
|
8278
|
+
skillsCollaborationInstructions,
|
|
8279
|
+
memoryCollaborationInstructions: workspaceBootstrapContext.memoryCollaborationInstructions,
|
|
8135
8280
|
heartbeatCollaborationInstructions: workspaceBootstrapContext.heartbeatCollaborationInstructions
|
|
8136
8281
|
});
|
|
8137
8282
|
codexModelCallDiagnostics.setRequestPayloadBytes(utf8JsonByteLength(turnStartParams));
|
|
@@ -8157,7 +8302,7 @@ async function runCodexAppServerAttempt(params, options = {}) {
|
|
|
8157
8302
|
turn = await startCodexTurn();
|
|
8158
8303
|
} catch (error) {
|
|
8159
8304
|
let turnStartError = error;
|
|
8160
|
-
if (
|
|
8305
|
+
if (shouldUseFreshCodexThreadAfterContextEngineOverflow({
|
|
8161
8306
|
error: turnStartError,
|
|
8162
8307
|
contextEngineActive: Boolean(activeContextEngine),
|
|
8163
8308
|
thread
|
|
@@ -8168,20 +8313,26 @@ async function runCodexAppServerAttempt(params, options = {}) {
|
|
|
8168
8313
|
});
|
|
8169
8314
|
try {
|
|
8170
8315
|
const preRetrySessionFile = activeSessionFile;
|
|
8171
|
-
await
|
|
8172
|
-
|
|
8173
|
-
|
|
8174
|
-
|
|
8175
|
-
|
|
8176
|
-
data: {
|
|
8177
|
-
phase: "thread_ready_retry",
|
|
8178
|
-
threadId: thread.threadId
|
|
8179
|
-
}
|
|
8316
|
+
const clearedPreRetryBinding = await clearCodexAppServerBindingForThread(preRetrySessionFile, thread.threadId);
|
|
8317
|
+
const clearedActiveBinding = activeSessionFile !== preRetrySessionFile ? await clearCodexAppServerBindingForThread(activeSessionFile, thread.threadId) : false;
|
|
8318
|
+
if (!clearedPreRetryBinding && !clearedActiveBinding) embeddedAgentLog.warn("codex app-server preserved newer context-engine binding after resume overflow; skipping fresh retry", {
|
|
8319
|
+
threadId: thread.threadId,
|
|
8320
|
+
error: formatErrorMessage(turnStartError)
|
|
8180
8321
|
});
|
|
8181
|
-
|
|
8182
|
-
|
|
8183
|
-
|
|
8184
|
-
|
|
8322
|
+
else {
|
|
8323
|
+
thread = await restartContextEngineCodexThread();
|
|
8324
|
+
emitCodexAppServerEvent(params, {
|
|
8325
|
+
stream: "codex_app_server.lifecycle",
|
|
8326
|
+
data: {
|
|
8327
|
+
phase: "thread_ready_retry",
|
|
8328
|
+
threadId: thread.threadId
|
|
8329
|
+
}
|
|
8330
|
+
});
|
|
8331
|
+
try {
|
|
8332
|
+
turn = await startCodexTurn();
|
|
8333
|
+
} catch (retryError) {
|
|
8334
|
+
turnStartError = retryError;
|
|
8335
|
+
}
|
|
8185
8336
|
}
|
|
8186
8337
|
} catch (retrySetupError) {
|
|
8187
8338
|
turnStartError = retrySetupError;
|
|
@@ -8240,9 +8391,13 @@ async function runCodexAppServerAttempt(params, options = {}) {
|
|
|
8240
8391
|
formatError: formatErrorMessage
|
|
8241
8392
|
});
|
|
8242
8393
|
codexModelCallDiagnostics.emitError(turnStartErrorMessage, turnStartFailureKind ? { failureKind: turnStartFailureKind } : {});
|
|
8394
|
+
const turnStartFailureMessages = [...historyMessages, buildCodexUserPromptMessage({
|
|
8395
|
+
...params,
|
|
8396
|
+
prompt: codexTurnPromptText
|
|
8397
|
+
})];
|
|
8243
8398
|
await runCodexAgentEndHook(params, {
|
|
8244
8399
|
event: {
|
|
8245
|
-
messages:
|
|
8400
|
+
messages: turnStartFailureMessages,
|
|
8246
8401
|
success: false,
|
|
8247
8402
|
error: turnStartErrorMessage,
|
|
8248
8403
|
durationMs: Date.now() - attemptStartedAt
|
|
@@ -8279,7 +8434,7 @@ async function runCodexAppServerAttempt(params, options = {}) {
|
|
|
8279
8434
|
return { ...buildCodexTurnStartFailureResult({
|
|
8280
8435
|
params,
|
|
8281
8436
|
message: usageLimitError.message,
|
|
8282
|
-
messagesSnapshot:
|
|
8437
|
+
messagesSnapshot: turnStartFailureMessages,
|
|
8283
8438
|
systemPromptReport
|
|
8284
8439
|
}) };
|
|
8285
8440
|
}
|
|
@@ -8332,6 +8487,8 @@ async function runCodexAppServerAttempt(params, options = {}) {
|
|
|
8332
8487
|
const activeProjector = projector;
|
|
8333
8488
|
turnWatches.armTerminalIdleWatch();
|
|
8334
8489
|
turnWatches.touchActivity("turn:start", { arm: true });
|
|
8490
|
+
turnWatches.armAttemptIdleWatch();
|
|
8491
|
+
turnWatches.touchActivity("turn:start", { attemptProgress: true });
|
|
8335
8492
|
for (const notification of pendingNotifications.splice(0)) await enqueueNotification(notification);
|
|
8336
8493
|
if (!completed && isTerminalTurnStatus(turn.turn.status)) await enqueueNotification({
|
|
8337
8494
|
method: "turn/completed",
|
|
@@ -8369,16 +8526,16 @@ async function runCodexAppServerAttempt(params, options = {}) {
|
|
|
8369
8526
|
threadId: thread.threadId,
|
|
8370
8527
|
turnId: activeTurnId
|
|
8371
8528
|
});
|
|
8372
|
-
turnWatches.armAttemptIdleWatch();
|
|
8373
|
-
turnWatches.armTerminalIdleWatch();
|
|
8374
|
-
turnWatches.touchActivity("turn:start", { attemptProgress: true });
|
|
8375
8529
|
const abortListener = () => {
|
|
8376
8530
|
if (timedOut) {
|
|
8377
|
-
|
|
8378
|
-
|
|
8379
|
-
|
|
8380
|
-
|
|
8381
|
-
|
|
8531
|
+
(async () => {
|
|
8532
|
+
await clearCodexAppServerBindingForThread(activeSessionFile, thread.threadId);
|
|
8533
|
+
await retireCodexAppServerClientAfterTimedOutTurn(client, {
|
|
8534
|
+
threadId: thread.threadId,
|
|
8535
|
+
turnId: activeTurnId,
|
|
8536
|
+
reason: String(runAbortController.signal.reason ?? "timeout")
|
|
8537
|
+
});
|
|
8538
|
+
})().finally(() => {
|
|
8382
8539
|
resolveCompletion?.();
|
|
8383
8540
|
});
|
|
8384
8541
|
return;
|
|
@@ -8393,6 +8550,7 @@ async function runCodexAppServerAttempt(params, options = {}) {
|
|
|
8393
8550
|
if (runAbortController.signal.aborted) abortListener();
|
|
8394
8551
|
try {
|
|
8395
8552
|
await completion;
|
|
8553
|
+
await notificationQueue;
|
|
8396
8554
|
const result = activeProjector.buildResult(toolBridge.telemetry, { yieldDetected });
|
|
8397
8555
|
const finalAborted = result.aborted || runAbortController.signal.aborted && !clientClosedAbort;
|
|
8398
8556
|
let finalPromptError = clientClosedPromptError ?? (turnCompletionIdleTimedOut ? turnCompletionIdleTimeoutMessage : timedOut ? "codex app-server attempt timed out" : result.promptError);
|
|
@@ -8403,6 +8561,20 @@ async function runCodexAppServerAttempt(params, options = {}) {
|
|
|
8403
8561
|
turnId: activeTurnId,
|
|
8404
8562
|
error: finalPromptErrorMessage
|
|
8405
8563
|
});
|
|
8564
|
+
if (shouldUseFreshCodexThreadAfterContextEngineOverflow({
|
|
8565
|
+
error: finalPromptError,
|
|
8566
|
+
contextEngineActive: Boolean(activeContextEngine),
|
|
8567
|
+
thread
|
|
8568
|
+
})) {
|
|
8569
|
+
embeddedAgentLog.warn("codex app-server context-engine turn overflowed after resume; clearing thread binding for recovery", {
|
|
8570
|
+
threadId: thread.threadId,
|
|
8571
|
+
turnId: activeTurnId,
|
|
8572
|
+
error: finalPromptErrorMessage
|
|
8573
|
+
});
|
|
8574
|
+
const preClearSessionFile = activeSessionFile;
|
|
8575
|
+
await clearCodexAppServerBindingForThread(preClearSessionFile, thread.threadId);
|
|
8576
|
+
if (activeSessionFile !== preClearSessionFile) await clearCodexAppServerBindingForThread(activeSessionFile, thread.threadId);
|
|
8577
|
+
}
|
|
8406
8578
|
const refreshedUsageLimitPromptError = await refreshCodexUsageLimitPromptError({
|
|
8407
8579
|
client,
|
|
8408
8580
|
message: finalPromptErrorMessage,
|
|
@@ -8534,6 +8706,7 @@ async function runCodexAppServerAttempt(params, options = {}) {
|
|
|
8534
8706
|
promptErrorSource: finalPromptErrorSource,
|
|
8535
8707
|
...codexAppServerFailureKind ? { codexAppServerFailure: {
|
|
8536
8708
|
kind: codexAppServerFailureKind,
|
|
8709
|
+
...codexAppServerFailureKind === "turn_completion_idle_timeout" && turnWatchTimeoutKind ? { turnWatchTimeoutKind } : {},
|
|
8537
8710
|
transport: appServer.start.transport,
|
|
8538
8711
|
threadId: thread.threadId,
|
|
8539
8712
|
turnId: activeTurnId,
|
|
@@ -8606,7 +8779,14 @@ async function clearCodexBindingAfterInvalidImagePayload(sessionFile, fields) {
|
|
|
8606
8779
|
function isNonEmptyString(value) {
|
|
8607
8780
|
return typeof value === "string" && value.length > 0;
|
|
8608
8781
|
}
|
|
8609
|
-
function
|
|
8782
|
+
function canAttributeUnscopedNativeResponseDeltaToThisTurn(client) {
|
|
8783
|
+
const activeLeases = client.getActiveSharedLeaseCountForUnscopedNotifications?.();
|
|
8784
|
+
return activeLeases === void 0 || activeLeases <= 1;
|
|
8785
|
+
}
|
|
8786
|
+
function isUnscopedCodexNotification(correlation) {
|
|
8787
|
+
return !correlation.threadId && !correlation.turnId && !correlation.nestedTurnThreadId && !correlation.nestedTurnId;
|
|
8788
|
+
}
|
|
8789
|
+
function shouldUseFreshCodexThreadAfterContextEngineOverflow(params) {
|
|
8610
8790
|
if (!params.contextEngineActive || params.thread.lifecycle.action !== "resumed") return false;
|
|
8611
8791
|
return isCodexContextWindowError(params.error);
|
|
8612
8792
|
}
|