@openclaw/codex 2026.5.28-beta.4 → 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-C6EMmamz.js → run-attempt-lD4FLxNV.js} +424 -246
- 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 { parseFiniteNumber, parseStrictNonNegativeInteger } 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,69 +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
|
-
const fallback = parseFiniteNumber(fallbackMs) ?? 1;
|
|
973
|
-
const candidate = parseFiniteNumber(value) ?? fallback;
|
|
974
|
-
return Math.max(1, Math.floor(candidate));
|
|
975
|
-
}
|
|
976
|
-
async function withCodexStartupTimeout(params) {
|
|
977
|
-
if (params.signal.aborted) throw new Error("codex app-server startup aborted");
|
|
978
|
-
let timeout;
|
|
979
|
-
let abortCleanup;
|
|
980
|
-
let timeoutError;
|
|
981
|
-
let timeoutCleanup;
|
|
982
|
-
try {
|
|
983
|
-
return await Promise.race([params.operation(), new Promise((_, reject) => {
|
|
984
|
-
const rejectOnce = (error) => {
|
|
985
|
-
if (timeout) {
|
|
986
|
-
clearTimeout(timeout);
|
|
987
|
-
timeout = void 0;
|
|
988
|
-
}
|
|
989
|
-
reject(error);
|
|
990
|
-
};
|
|
991
|
-
timeout = setTimeout(() => {
|
|
992
|
-
timeoutError = /* @__PURE__ */ new Error("codex app-server startup timed out");
|
|
993
|
-
timeoutCleanup = Promise.resolve(params.onTimeout?.()).then(() => void 0, () => void 0);
|
|
994
|
-
timeoutCleanup.finally(() => {
|
|
995
|
-
rejectOnce(timeoutError);
|
|
996
|
-
});
|
|
997
|
-
}, params.timeoutMs);
|
|
998
|
-
const abortListener = () => rejectOnce(/* @__PURE__ */ new Error("codex app-server startup aborted"));
|
|
999
|
-
params.signal.addEventListener("abort", abortListener, { once: true });
|
|
1000
|
-
abortCleanup = () => params.signal.removeEventListener("abort", abortListener);
|
|
1001
|
-
})]);
|
|
1002
|
-
} catch (error) {
|
|
1003
|
-
if (timeoutError) {
|
|
1004
|
-
await timeoutCleanup;
|
|
1005
|
-
throw timeoutError;
|
|
1006
|
-
}
|
|
1007
|
-
throw error;
|
|
1008
|
-
} finally {
|
|
1009
|
-
if (timeout) clearTimeout(timeout);
|
|
1010
|
-
abortCleanup?.();
|
|
1011
|
-
}
|
|
1012
|
-
}
|
|
1013
|
-
function resolveCodexStartupTimeoutMs(params) {
|
|
1014
|
-
const timeoutFloorMs = resolvePositiveIntegerTimeoutMs(params.timeoutFloorMs, 100);
|
|
1015
|
-
const timeoutMs = resolvePositiveIntegerTimeoutMs(params.timeoutMs, timeoutFloorMs);
|
|
1016
|
-
return Math.max(timeoutFloorMs, timeoutMs);
|
|
1017
|
-
}
|
|
1018
|
-
function resolveCodexTurnCompletionIdleTimeoutMs(value) {
|
|
1019
|
-
return resolvePositiveIntegerTimeoutMs(value, CODEX_TURN_COMPLETION_IDLE_TIMEOUT_MS);
|
|
1020
|
-
}
|
|
1021
|
-
function resolveCodexTurnAssistantCompletionIdleTimeoutMs(value) {
|
|
1022
|
-
return resolvePositiveIntegerTimeoutMs(value, CODEX_TURN_ASSISTANT_COMPLETION_IDLE_TIMEOUT_MS);
|
|
1023
|
-
}
|
|
1024
|
-
function resolveCodexPostToolRawAssistantCompletionIdleTimeoutMs(value, fallbackMs) {
|
|
1025
|
-
return resolvePositiveIntegerTimeoutMs(value, fallbackMs);
|
|
1026
|
-
}
|
|
1027
|
-
function resolveCodexTurnTerminalIdleTimeoutMs(value) {
|
|
1028
|
-
return resolvePositiveIntegerTimeoutMs(value, CODEX_TURN_TERMINAL_IDLE_TIMEOUT_MS);
|
|
1029
|
-
}
|
|
1030
961
|
//#endregion
|
|
1031
962
|
//#region extensions/codex/src/app-server/attempt-notification-state.ts
|
|
1032
963
|
function reportCodexExecutionNotification(params) {
|
|
@@ -1057,8 +988,9 @@ function applyCodexTurnNotificationState(params) {
|
|
|
1057
988
|
const { notification, turnWatches } = params;
|
|
1058
989
|
const isCurrentTurnNotification = isTurnNotification(notification.params, params.threadId, params.turnId);
|
|
1059
990
|
const isTurnCompletion = notification.method === "turn/completed" && isCurrentTurnNotification;
|
|
991
|
+
const isNativeResponseStreamDelta = isNativeResponseStreamDeltaNotification(notification);
|
|
1060
992
|
let turnCrossedToolHandoff = params.turnCrossedToolHandoff;
|
|
1061
|
-
if (isCurrentTurnNotification) {
|
|
993
|
+
if (isCurrentTurnNotification && !isNativeResponseStreamDelta) {
|
|
1062
994
|
turnWatches.touchActivity(`notification:${notification.method}`, {
|
|
1063
995
|
details: describeNotificationActivity(notification),
|
|
1064
996
|
attemptProgress: true
|
|
@@ -1072,25 +1004,37 @@ function applyCodexTurnNotificationState(params) {
|
|
|
1072
1004
|
const rawToolOutputCompletion = isRawToolOutputCompletionNotification(notification);
|
|
1073
1005
|
if (isCurrentTurnNotification && (rawToolOutputCompletion || isNativeToolProgressNotification(notification))) turnCrossedToolHandoff = true;
|
|
1074
1006
|
const assistantCompletionCanRelease = isAssistantCompletionReleaseNotification(notification, turnCrossedToolHandoff);
|
|
1075
|
-
const postToolRawAssistantCompletionNeedsTerminalGuard = isCurrentTurnNotification && turnCrossedToolHandoff &&
|
|
1076
|
-
const
|
|
1077
|
-
const
|
|
1078
|
-
const
|
|
1079
|
-
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
|
+
};
|
|
1080
1022
|
if (isCurrentTurnNotification && notification.method === "error") {
|
|
1081
1023
|
if (isRetryableErrorNotification(notification.params)) turnWatches.disarmCompletionIdleWatch();
|
|
1082
1024
|
else turnWatches.armCompletionIdleWatch({ pinnedByTerminalError: true });
|
|
1083
1025
|
turnWatches.disarmAssistantCompletionIdleWatch();
|
|
1084
1026
|
} else if (isTurnCompletion) turnWatches.disarmAssistantCompletionIdleWatch();
|
|
1085
1027
|
else if (isCurrentTurnNotification && assistantCompletionCanRelease) turnWatches.armAssistantCompletionIdleWatch(describeNotificationActivity(notification));
|
|
1086
|
-
else if (postToolRawAssistantCompletionNeedsTerminalGuard)
|
|
1087
|
-
else if (
|
|
1028
|
+
else if (postToolRawAssistantCompletionNeedsTerminalGuard || postToolPatchUpdateNeedsTerminalGuard) armPostToolContinuationWatch();
|
|
1029
|
+
else if (shouldArmNoToolPostProgressReplyWatch || shouldArmNoToolPostRawProgressReplyWatch) armPostProgressReplyWatch();
|
|
1030
|
+
else if (trackedDynamicToolCompletion) armPostToolContinuationWatch();
|
|
1088
1031
|
else if (unblockedAssistantCompletionRelease) turnWatches.armAssistantCompletionIdleWatch(describeNotificationActivity(notification));
|
|
1089
|
-
else if (shouldRearmCompletionIdleWatchAfterLastCurrentTurnItem)
|
|
1032
|
+
else if (shouldRearmCompletionIdleWatchAfterLastCurrentTurnItem) if (shouldUsePostToolContinuationWatch) armPostToolContinuationWatch();
|
|
1033
|
+
else turnWatches.armCompletionIdleWatch();
|
|
1090
1034
|
else if (rawResponseItemCompletedWithNoActiveItems) turnWatches.armCompletionIdleWatch();
|
|
1091
|
-
else if (isCurrentTurnNotification && rawToolOutputCompletion)
|
|
1035
|
+
else if (isCurrentTurnNotification && rawToolOutputCompletion) armPostToolContinuationWatch();
|
|
1092
1036
|
else if (isCurrentTurnNotification && shouldDisarmAssistantCompletionIdleWatch(notification)) turnWatches.disarmAssistantCompletionIdleWatch();
|
|
1093
|
-
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();
|
|
1094
1038
|
if (trackedDynamicToolCompletion) {
|
|
1095
1039
|
const itemId = readNotificationItemId(notification);
|
|
1096
1040
|
if (itemId) {
|
|
@@ -1122,7 +1066,8 @@ function hasCodexAppServerPotentialSideEffectEvidence(result) {
|
|
|
1122
1066
|
}
|
|
1123
1067
|
function buildCodexAppServerPromptTimeoutOutcome(params) {
|
|
1124
1068
|
const completionIdleTimeoutHadPotentialSideEffects = hasCodexAppServerPotentialSideEffectEvidence(params.result);
|
|
1125
|
-
|
|
1069
|
+
const replayBlockedReason = resolveCodexAppServerReplayBlockedReason(params.result);
|
|
1070
|
+
if (!params.turnCompletionIdleTimedOut || params.result.itemLifecycle.completedCount === 0 && !completionIdleTimeoutHadPotentialSideEffects && replayBlockedReason === void 0) return;
|
|
1126
1071
|
return {
|
|
1127
1072
|
message: completionIdleTimeoutHadPotentialSideEffects ? CODEX_APP_SERVER_MISSING_TERMINAL_EVENT_SIDE_EFFECT_USER_MESSAGE : CODEX_APP_SERVER_MISSING_TERMINAL_EVENT_USER_MESSAGE,
|
|
1128
1073
|
...completionIdleTimeoutHadPotentialSideEffects ? {
|
|
@@ -3015,6 +2960,7 @@ function createCodexAttemptTurnWatchController(params) {
|
|
|
3015
2960
|
let completionLastActivityAt = Date.now();
|
|
3016
2961
|
let completionLastActivityReason = "startup";
|
|
3017
2962
|
let completionLastActivityDetails;
|
|
2963
|
+
let attemptIdleTimeoutOverrideMs;
|
|
3018
2964
|
let attemptLastProgressAt = Date.now();
|
|
3019
2965
|
let attemptLastProgressReason = "startup";
|
|
3020
2966
|
let attemptLastProgressDetails;
|
|
@@ -3069,7 +3015,8 @@ function createCodexAttemptTurnWatchController(params) {
|
|
|
3069
3015
|
clearAttemptIdleTimer();
|
|
3070
3016
|
if (params.isCompleted() || params.signal.aborted || !attemptIdleWatchArmed) return;
|
|
3071
3017
|
const elapsedMs = Math.max(0, Date.now() - attemptLastProgressAt);
|
|
3072
|
-
const
|
|
3018
|
+
const timeoutMs = attemptIdleTimeoutOverrideMs ?? params.turnAttemptIdleTimeoutMs;
|
|
3019
|
+
const delayMs = Math.max(1, timeoutMs - elapsedMs);
|
|
3073
3020
|
attemptIdleTimer = setTimeout(fireAttemptIdleTimeout, delayMs);
|
|
3074
3021
|
attemptIdleTimer.unref?.();
|
|
3075
3022
|
}
|
|
@@ -3086,6 +3033,14 @@ function createCodexAttemptTurnWatchController(params) {
|
|
|
3086
3033
|
scheduleCompletionIdleWatch();
|
|
3087
3034
|
scheduleTerminalIdleWatch();
|
|
3088
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
|
+
}
|
|
3089
3044
|
function fireAssistantCompletionIdleRelease() {
|
|
3090
3045
|
if (params.isCompleted() || params.signal.aborted || !assistantCompletionIdleWatchArmed) return;
|
|
3091
3046
|
if (params.getActiveAppServerTurnRequests() > 0 || params.getActiveTurnItemCount() > 0) {
|
|
@@ -3126,14 +3081,15 @@ function createCodexAttemptTurnWatchController(params) {
|
|
|
3126
3081
|
function fireAttemptIdleTimeout() {
|
|
3127
3082
|
if (params.isCompleted() || params.signal.aborted || !attemptIdleWatchArmed) return;
|
|
3128
3083
|
const idleMs = Math.max(0, Date.now() - attemptLastProgressAt);
|
|
3129
|
-
|
|
3084
|
+
const timeoutMs = attemptIdleTimeoutOverrideMs ?? params.turnAttemptIdleTimeoutMs;
|
|
3085
|
+
if (idleMs < timeoutMs) {
|
|
3130
3086
|
scheduleAttemptIdleWatch();
|
|
3131
3087
|
return;
|
|
3132
3088
|
}
|
|
3133
3089
|
const timeout = {
|
|
3134
3090
|
kind: "progress",
|
|
3135
3091
|
idleMs,
|
|
3136
|
-
timeoutMs
|
|
3092
|
+
timeoutMs,
|
|
3137
3093
|
lastActivityReason: attemptLastProgressReason,
|
|
3138
3094
|
details: attemptLastProgressDetails
|
|
3139
3095
|
};
|
|
@@ -3266,12 +3222,7 @@ function createCodexAttemptTurnWatchController(params) {
|
|
|
3266
3222
|
completionLastActivityReason = reason;
|
|
3267
3223
|
completionLastActivityDetails = options?.details;
|
|
3268
3224
|
completionIdleTimeoutOverrideMs = void 0;
|
|
3269
|
-
if (options?.attemptProgress)
|
|
3270
|
-
attemptLastProgressAt = completionLastActivityAt;
|
|
3271
|
-
attemptLastProgressReason = reason;
|
|
3272
|
-
attemptLastProgressDetails = options.details;
|
|
3273
|
-
params.onAttemptProgress(reason, options.details);
|
|
3274
|
-
}
|
|
3225
|
+
if (options?.attemptProgress) recordAttemptProgress(reason, options);
|
|
3275
3226
|
params.onProgressDiagnostic(reason);
|
|
3276
3227
|
if (options?.arm) {
|
|
3277
3228
|
completionIdleWatchArmed = true;
|
|
@@ -3279,9 +3230,15 @@ function createCodexAttemptTurnWatchController(params) {
|
|
|
3279
3230
|
}
|
|
3280
3231
|
scheduleProgressWatches();
|
|
3281
3232
|
},
|
|
3282
|
-
noteNotificationReceived: (method) => {
|
|
3233
|
+
noteNotificationReceived: (method, options) => {
|
|
3283
3234
|
completionLastActivityAt = Date.now();
|
|
3284
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();
|
|
3285
3242
|
},
|
|
3286
3243
|
scheduleProgressWatches,
|
|
3287
3244
|
clearCompletionIdleTimer,
|
|
@@ -3488,15 +3445,14 @@ function clampDynamicToolTimeoutMs(timeoutMs) {
|
|
|
3488
3445
|
//#region extensions/codex/src/app-server/local-runtime-attribution.ts
|
|
3489
3446
|
const OPENAI_PROVIDER_ID = "openai";
|
|
3490
3447
|
const OPENAI_RESPONSES_API = "openai-responses";
|
|
3491
|
-
const
|
|
3492
|
-
const OPENAI_CODEX_RESPONSES_API = "openai-codex-responses";
|
|
3448
|
+
const OPENAI_CODEX_RESPONSES_API = "openai-chatgpt-responses";
|
|
3493
3449
|
function normalizeRuntimeId(value) {
|
|
3494
3450
|
return value?.trim().toLowerCase() ?? "";
|
|
3495
3451
|
}
|
|
3496
3452
|
function resolveCodexLocalRuntimeAttribution(params) {
|
|
3497
3453
|
const authProfileProvider = normalizeRuntimeId(params.runtimePlan?.auth?.authProfileProviderForAuth);
|
|
3498
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 {
|
|
3499
|
-
provider:
|
|
3455
|
+
provider: OPENAI_PROVIDER_ID,
|
|
3500
3456
|
api: OPENAI_CODEX_RESPONSES_API
|
|
3501
3457
|
};
|
|
3502
3458
|
return {
|
|
@@ -3756,6 +3712,7 @@ async function mirrorCodexAppServerTranscript(params) {
|
|
|
3756
3712
|
for (const update of appendedUpdates) emitSessionTranscriptUpdate({
|
|
3757
3713
|
sessionFile: params.sessionFile,
|
|
3758
3714
|
...params.sessionKey ? { sessionKey: params.sessionKey } : {},
|
|
3715
|
+
...params.agentId ? { agentId: params.agentId } : {},
|
|
3759
3716
|
message: update.message,
|
|
3760
3717
|
messageId: update.messageId,
|
|
3761
3718
|
messageSeq: update.messageSeq
|
|
@@ -3828,6 +3785,9 @@ const CODEX_PROMPT_TOTAL_INPUT_KEYS = [
|
|
|
3828
3785
|
];
|
|
3829
3786
|
const MAX_TOOL_OUTPUT_DELTA_MESSAGES_PER_ITEM = 20;
|
|
3830
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;
|
|
3831
3791
|
const TRANSCRIPT_PROGRESS_SUPPRESSED_TOOL_NAMES = new Set([
|
|
3832
3792
|
"message",
|
|
3833
3793
|
"messages",
|
|
@@ -3873,6 +3833,8 @@ var CodexAppServerEventProjector = class {
|
|
|
3873
3833
|
this.toolTranscriptResultIds = /* @__PURE__ */ new Set();
|
|
3874
3834
|
this.transcriptToolProgressCallIds = /* @__PURE__ */ new Set();
|
|
3875
3835
|
this.nativeGeneratedMediaUrls = /* @__PURE__ */ new Set();
|
|
3836
|
+
this.nativeGeneratedMediaItemIds = /* @__PURE__ */ new Set();
|
|
3837
|
+
this.nativeGeneratedMediaUrlsByItemId = /* @__PURE__ */ new Map();
|
|
3876
3838
|
this.diagnosticToolStartedAtByItem = /* @__PURE__ */ new Map();
|
|
3877
3839
|
this.afterToolCallObservedItemIds = /* @__PURE__ */ new Set();
|
|
3878
3840
|
this.assistantStarted = false;
|
|
@@ -3938,7 +3900,7 @@ var CodexAppServerEventProjector = class {
|
|
|
3938
3900
|
await this.handleTurnCompleted(params);
|
|
3939
3901
|
break;
|
|
3940
3902
|
case "rawResponseItem/completed":
|
|
3941
|
-
this.handleRawResponseItemCompleted(params);
|
|
3903
|
+
await this.handleRawResponseItemCompleted(params);
|
|
3942
3904
|
break;
|
|
3943
3905
|
case "error":
|
|
3944
3906
|
if (readBooleanAlias(params, ["willRetry", "will_retry"]) === true) break;
|
|
@@ -3969,7 +3931,7 @@ var CodexAppServerEventProjector = class {
|
|
|
3969
3931
|
turnCompleted: Boolean(this.completedTurn)
|
|
3970
3932
|
});
|
|
3971
3933
|
const toolMetas = [...this.toolMetas.values()];
|
|
3972
|
-
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;
|
|
3973
3935
|
return {
|
|
3974
3936
|
aborted: this.aborted,
|
|
3975
3937
|
externalAbort: false,
|
|
@@ -4390,9 +4352,11 @@ var CodexAppServerEventProjector = class {
|
|
|
4390
4352
|
text: formatToolOutput(toolName, void 0, reachedLimit ? `${chunk}\n...(truncated)...` : chunk)
|
|
4391
4353
|
});
|
|
4392
4354
|
}
|
|
4393
|
-
handleRawResponseItemCompleted(params) {
|
|
4355
|
+
async handleRawResponseItemCompleted(params) {
|
|
4394
4356
|
const item = isJsonObject(params.item) ? params.item : void 0;
|
|
4395
|
-
if (!item
|
|
4357
|
+
if (!item) return;
|
|
4358
|
+
await this.recordRawGeneratedImageMedia(item);
|
|
4359
|
+
if (readString$5(item, "role") !== "assistant") return;
|
|
4396
4360
|
const text = extractRawAssistantText(item);
|
|
4397
4361
|
if (!text) return;
|
|
4398
4362
|
const itemId = readString$5(item, "id") ?? `raw-assistant-${this.assistantItemOrder.length + 1}`;
|
|
@@ -4408,7 +4372,56 @@ var CodexAppServerEventProjector = class {
|
|
|
4408
4372
|
recordNativeGeneratedMedia(item) {
|
|
4409
4373
|
if (item?.type !== "imageGeneration") return;
|
|
4410
4374
|
const savedPath = readItemString(item, "savedPath")?.trim();
|
|
4411
|
-
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);
|
|
4412
4425
|
}
|
|
4413
4426
|
buildToolMediaUrls(toolTelemetry) {
|
|
4414
4427
|
const mediaUrls = new Set(toolTelemetry.toolMediaUrls?.map((url) => url.trim()).filter(Boolean) ?? []);
|
|
@@ -4835,7 +4848,7 @@ var CodexAppServerEventProjector = class {
|
|
|
4835
4848
|
type: "text",
|
|
4836
4849
|
text
|
|
4837
4850
|
}],
|
|
4838
|
-
api: attribution.api ?? "openai-
|
|
4851
|
+
api: attribution.api ?? "openai-chatgpt-responses",
|
|
4839
4852
|
provider: attribution.provider,
|
|
4840
4853
|
model: this.params.modelId,
|
|
4841
4854
|
usage,
|
|
@@ -4852,7 +4865,7 @@ var CodexAppServerEventProjector = class {
|
|
|
4852
4865
|
type: "text",
|
|
4853
4866
|
text: `${title}:\n${text}`
|
|
4854
4867
|
}],
|
|
4855
|
-
api: attribution.api ?? "openai-
|
|
4868
|
+
api: attribution.api ?? "openai-chatgpt-responses",
|
|
4856
4869
|
provider: attribution.provider,
|
|
4857
4870
|
model: this.params.modelId,
|
|
4858
4871
|
usage: ZERO_USAGE,
|
|
@@ -4872,7 +4885,7 @@ var CodexAppServerEventProjector = class {
|
|
|
4872
4885
|
arguments: args,
|
|
4873
4886
|
input: args
|
|
4874
4887
|
}],
|
|
4875
|
-
api: attribution.api ?? "openai-
|
|
4888
|
+
api: attribution.api ?? "openai-chatgpt-responses",
|
|
4876
4889
|
provider: attribution.provider,
|
|
4877
4890
|
model: this.params.modelId,
|
|
4878
4891
|
usage: ZERO_USAGE,
|
|
@@ -4922,6 +4935,30 @@ function readString$5(record, key) {
|
|
|
4922
4935
|
const value = record[key];
|
|
4923
4936
|
return typeof value === "string" ? value : void 0;
|
|
4924
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
|
+
}
|
|
4925
4962
|
function normalizeNonEmptyString(value) {
|
|
4926
4963
|
if (typeof value !== "string") return;
|
|
4927
4964
|
return value.trim() || void 0;
|
|
@@ -6351,6 +6388,9 @@ function unrefTimer(timer) {
|
|
|
6351
6388
|
//#endregion
|
|
6352
6389
|
//#region extensions/codex/src/app-server/startup-binding.ts
|
|
6353
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;
|
|
6354
6394
|
const CODEX_APP_SERVER_BYTE_UNITS = {
|
|
6355
6395
|
b: 1,
|
|
6356
6396
|
k: 1024,
|
|
@@ -6366,6 +6406,7 @@ const CODEX_APP_SERVER_BYTE_UNITS = {
|
|
|
6366
6406
|
tb: 1024 * 1024 * 1024 * 1024,
|
|
6367
6407
|
tib: 1024 * 1024 * 1024 * 1024
|
|
6368
6408
|
};
|
|
6409
|
+
const codexSessionRecordCache = /* @__PURE__ */ new Map();
|
|
6369
6410
|
function parseCodexAppServerByteLimit(value) {
|
|
6370
6411
|
if (typeof value === "number" && Number.isFinite(value) && value > 0) return Math.floor(value);
|
|
6371
6412
|
if (typeof value !== "string") return;
|
|
@@ -6421,22 +6462,44 @@ async function listCodexAppServerRolloutFilesForThread(agentDir, threadId, codex
|
|
|
6421
6462
|
}
|
|
6422
6463
|
async function readCodexSessionRecordForSessionFile(sessionFile) {
|
|
6423
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;
|
|
6424
6475
|
let store;
|
|
6425
6476
|
try {
|
|
6426
6477
|
store = JSON.parse(await fs.readFile(sessionsFile, "utf8"));
|
|
6427
6478
|
} catch {
|
|
6479
|
+
codexSessionRecordCache.delete(resolvedSessionFile);
|
|
6428
6480
|
return;
|
|
6429
6481
|
}
|
|
6430
|
-
if (!isJsonObject(store))
|
|
6431
|
-
|
|
6482
|
+
if (!isJsonObject(store)) {
|
|
6483
|
+
codexSessionRecordCache.delete(resolvedSessionFile);
|
|
6484
|
+
return;
|
|
6485
|
+
}
|
|
6486
|
+
let found;
|
|
6432
6487
|
for (const [sessionKey, record] of Object.entries(store)) {
|
|
6433
6488
|
if (!isJsonObject(record) || typeof record.sessionFile !== "string") continue;
|
|
6434
6489
|
if (path.resolve(record.sessionFile) !== resolvedSessionFile) continue;
|
|
6435
|
-
|
|
6490
|
+
found = {
|
|
6436
6491
|
sessionKey,
|
|
6437
6492
|
...record
|
|
6438
6493
|
};
|
|
6494
|
+
break;
|
|
6439
6495
|
}
|
|
6496
|
+
codexSessionRecordCache.set(resolvedSessionFile, {
|
|
6497
|
+
sessionsFile,
|
|
6498
|
+
mtimeMs: stat.mtimeMs,
|
|
6499
|
+
size: stat.size,
|
|
6500
|
+
record: found
|
|
6501
|
+
});
|
|
6502
|
+
return found;
|
|
6440
6503
|
}
|
|
6441
6504
|
async function readCodexAppServerRolloutTokenSnapshot(file) {
|
|
6442
6505
|
let handle;
|
|
@@ -6480,52 +6543,75 @@ function readCodexAppServerRolloutTokenSnapshotLine(line) {
|
|
|
6480
6543
|
return;
|
|
6481
6544
|
}
|
|
6482
6545
|
}
|
|
6483
|
-
function
|
|
6484
|
-
|
|
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);
|
|
6485
6566
|
}
|
|
6486
6567
|
function maxFiniteNumber(values) {
|
|
6487
6568
|
const nums = values.filter((value) => typeof value === "number" && Number.isFinite(value));
|
|
6488
6569
|
if (nums.length === 0) return;
|
|
6489
6570
|
return Math.max(...nums);
|
|
6490
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
|
+
}
|
|
6491
6577
|
function hasContextEngineThreadBootstrapProjection(binding) {
|
|
6492
6578
|
return binding.contextEngine?.projection?.mode === "thread_bootstrap";
|
|
6493
6579
|
}
|
|
6494
6580
|
async function rotateOversizedCodexAppServerStartupBinding(params) {
|
|
6495
6581
|
const binding = params.binding;
|
|
6496
6582
|
if (!binding?.threadId) return binding;
|
|
6497
|
-
if (params.config?.agents?.defaults?.compaction?.truncateAfterCompaction !== true) return binding;
|
|
6498
|
-
if (params.contextEngineActive === true && hasContextEngineThreadBootstrapProjection(binding)) {
|
|
6499
|
-
embeddedAgentLog.debug("codex app-server deferring native transcript size guard for context-engine thread bootstrap", {
|
|
6500
|
-
threadId: binding.threadId,
|
|
6501
|
-
engineId: binding.contextEngine?.engineId,
|
|
6502
|
-
epoch: binding.contextEngine?.projection?.epoch,
|
|
6503
|
-
fingerprint: binding.contextEngine?.projection?.fingerprint
|
|
6504
|
-
});
|
|
6505
|
-
return binding;
|
|
6506
|
-
}
|
|
6507
6583
|
const sessionRecord = await readCodexSessionRecordForSessionFile(params.sessionFile);
|
|
6508
|
-
const maxBytes = parseCodexAppServerByteLimit(params.config?.agents?.defaults?.compaction?.maxActiveTranscriptBytes);
|
|
6509
6584
|
const rolloutFiles = await listCodexAppServerRolloutFilesForThread(params.agentDir, binding.threadId, params.codexHome);
|
|
6510
|
-
|
|
6511
|
-
|
|
6512
|
-
|
|
6513
|
-
|
|
6514
|
-
|
|
6515
|
-
|
|
6516
|
-
|
|
6517
|
-
|
|
6518
|
-
|
|
6519
|
-
|
|
6520
|
-
|
|
6521
|
-
|
|
6522
|
-
|
|
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
|
+
}
|
|
6523
6603
|
}
|
|
6524
6604
|
}
|
|
6525
6605
|
const nativeTokenSnapshots = await Promise.all(rolloutFiles.map(async (file) => readCodexAppServerRolloutTokenSnapshot(file.path)));
|
|
6526
6606
|
const nativeTokens = maxFiniteNumber(nativeTokenSnapshots.map((snapshot) => snapshot?.totalTokens));
|
|
6527
6607
|
const nativeModelContextWindow = maxFiniteNumber(nativeTokenSnapshots.map((snapshot) => snapshot?.modelContextWindow));
|
|
6528
|
-
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
|
+
});
|
|
6529
6615
|
const sessionTokens = sessionRecord?.totalTokensFresh !== false && typeof sessionRecord?.totalTokens === "number" && Number.isFinite(sessionRecord.totalTokens) ? sessionRecord.totalTokens : void 0;
|
|
6530
6616
|
const tokenCount = maxFiniteNumber([sessionTokens, nativeTokens]);
|
|
6531
6617
|
if (tokenCount !== void 0 && tokenCount >= maxTokens) {
|
|
@@ -6535,11 +6621,24 @@ async function rotateOversizedCodexAppServerStartupBinding(params) {
|
|
|
6535
6621
|
sessionKey: sessionRecord?.sessionKey,
|
|
6536
6622
|
sessionTokens,
|
|
6537
6623
|
nativeTokens,
|
|
6538
|
-
nativeModelContextWindow
|
|
6624
|
+
nativeModelContextWindow,
|
|
6625
|
+
sessionModelContextWindow,
|
|
6626
|
+
reserveTokens,
|
|
6627
|
+
projectedTurnTokens: params.projectedTurnTokens
|
|
6539
6628
|
});
|
|
6540
6629
|
await clearCodexAppServerBinding(params.sessionFile);
|
|
6541
6630
|
return;
|
|
6542
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
|
+
}
|
|
6543
6642
|
return binding;
|
|
6544
6643
|
}
|
|
6545
6644
|
//#endregion
|
|
@@ -7058,7 +7157,12 @@ function readRequestId(record) {
|
|
|
7058
7157
|
//#endregion
|
|
7059
7158
|
//#region extensions/codex/src/app-server/run-attempt.ts
|
|
7060
7159
|
const CODEX_NATIVE_HOOK_RELAY_RENEW_INTERVAL_MS = 6e4;
|
|
7160
|
+
const CODEX_APP_SERVER_PROJECTED_CHARS_PER_TOKEN = 4;
|
|
7061
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
|
+
}
|
|
7062
7166
|
async function ensureCodexWorkspaceDirOnce(workspaceDir) {
|
|
7063
7167
|
const normalized = path.resolve(workspaceDir);
|
|
7064
7168
|
if (ensuredCodexWorkspaceDirs.has(normalized)) {
|
|
@@ -7365,12 +7469,11 @@ async function runCodexAppServerAttempt(params, options = {}) {
|
|
|
7365
7469
|
const baseDeveloperInstructions = joinPresentSections(buildDeveloperInstructions(params, { dynamicTools: toolBridge.availableSpecs }), workspaceBootstrapContext.developerInstructions);
|
|
7366
7470
|
const openClawPromptContext = buildCodexOpenClawPromptContext({
|
|
7367
7471
|
params,
|
|
7368
|
-
|
|
7369
|
-
|
|
7370
|
-
|
|
7371
|
-
|
|
7372
|
-
|
|
7373
|
-
})
|
|
7472
|
+
workspacePromptContext: workspaceBootstrapContext.promptContext
|
|
7473
|
+
});
|
|
7474
|
+
const skillsCollaborationInstructions = renderCodexSkillsCollaborationInstructions({
|
|
7475
|
+
attempt: params,
|
|
7476
|
+
skillsPrompt: params.skillsSnapshot?.prompt
|
|
7374
7477
|
});
|
|
7375
7478
|
let promptText = params.prompt;
|
|
7376
7479
|
let developerInstructions = baseDeveloperInstructions;
|
|
@@ -7437,41 +7540,69 @@ async function runCodexAppServerAttempt(params, options = {}) {
|
|
|
7437
7540
|
} catch (assembleErr) {
|
|
7438
7541
|
embeddedAgentLog.warn("context engine assemble failed; using Codex baseline prompt", { error: formatErrorMessage(assembleErr) });
|
|
7439
7542
|
}
|
|
7440
|
-
|
|
7441
|
-
startupBinding,
|
|
7442
|
-
dynamicToolsFingerprint: codexDynamicToolsFingerprint(toolBridge.specs),
|
|
7443
|
-
historyMessages,
|
|
7444
|
-
forceProject: !nativeToolSurfaceEnabled
|
|
7445
|
-
})) {
|
|
7446
|
-
const projection = projectContextEngineAssemblyForCodex({
|
|
7447
|
-
assembledMessages: historyMessages,
|
|
7448
|
-
originalHistoryMessages: historyMessages,
|
|
7449
|
-
prompt: params.prompt
|
|
7450
|
-
});
|
|
7451
|
-
promptText = projection.promptText;
|
|
7452
|
-
prePromptMessageCount = projection.prePromptMessageCount;
|
|
7453
|
-
}
|
|
7543
|
+
const codexModelInputHistoryMessages = [];
|
|
7454
7544
|
const buildPromptFromCurrentInputs = () => resolveAgentHarnessBeforePromptBuildResult({
|
|
7455
7545
|
prompt: prependCurrentInboundContext(promptText, params.currentInboundContext),
|
|
7456
7546
|
developerInstructions,
|
|
7457
|
-
messages:
|
|
7547
|
+
messages: codexModelInputHistoryMessages,
|
|
7458
7548
|
ctx: hookContext
|
|
7459
7549
|
});
|
|
7460
7550
|
let promptBuild = await buildPromptFromCurrentInputs();
|
|
7461
|
-
const decorateCodexTurnPromptText = (prompt) => prependCodexOpenClawPromptContext(prompt, openClawPromptContext);
|
|
7551
|
+
const decorateCodexTurnPromptText = (prompt) => prependCodexOpenClawPromptContext(prompt, openClawPromptContext, { preservePromptWithoutContext: params.bootstrapContextMode === "lightweight" && params.bootstrapContextRunKind === "cron" });
|
|
7462
7552
|
let codexTurnPromptText = decorateCodexTurnPromptText(promptBuild.prompt);
|
|
7463
7553
|
const buildCodexTurnCollaborationDeveloperInstructions = () => buildTurnCollaborationMode(params, {
|
|
7464
7554
|
turnScopedDeveloperInstructions: workspaceBootstrapContext.turnScopedDeveloperInstructions,
|
|
7555
|
+
skillsCollaborationInstructions,
|
|
7556
|
+
memoryCollaborationInstructions: workspaceBootstrapContext.memoryCollaborationInstructions,
|
|
7465
7557
|
heartbeatCollaborationInstructions: workspaceBootstrapContext.heartbeatCollaborationInstructions
|
|
7466
7558
|
}).settings.developer_instructions ?? void 0;
|
|
7467
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();
|
|
7468
7599
|
const systemPromptReport = buildCodexSystemPromptReport({
|
|
7469
7600
|
attempt: params,
|
|
7470
7601
|
sessionKey: contextSessionKey,
|
|
7471
7602
|
workspaceDir: effectiveWorkspace,
|
|
7472
7603
|
developerInstructions: buildRenderedCodexDeveloperInstructions(),
|
|
7473
7604
|
workspaceBootstrapContext,
|
|
7474
|
-
skillsPrompt:
|
|
7605
|
+
skillsPrompt: skillsCollaborationInstructions ? params.skillsSnapshot?.prompt ?? "" : "",
|
|
7475
7606
|
tools: toolBridge.availableSpecs
|
|
7476
7607
|
});
|
|
7477
7608
|
const trajectoryRecorder = createCodexTrajectoryRecorder({
|
|
@@ -7594,7 +7725,7 @@ async function runCodexAppServerAttempt(params, options = {}) {
|
|
|
7594
7725
|
recordCodexTrajectoryContext(trajectoryRecorder, {
|
|
7595
7726
|
attempt: params,
|
|
7596
7727
|
cwd: effectiveCwd,
|
|
7597
|
-
developerInstructions:
|
|
7728
|
+
developerInstructions: buildRenderedCodexDeveloperInstructions(),
|
|
7598
7729
|
prompt: codexTurnPromptText,
|
|
7599
7730
|
tools: toolBridge.availableSpecs
|
|
7600
7731
|
});
|
|
@@ -7607,6 +7738,7 @@ async function runCodexAppServerAttempt(params, options = {}) {
|
|
|
7607
7738
|
let terminalTurnNotificationQueued = false;
|
|
7608
7739
|
let timedOut = false;
|
|
7609
7740
|
let turnCompletionIdleTimedOut = false;
|
|
7741
|
+
let turnWatchTimeoutKind;
|
|
7610
7742
|
let turnCompletionIdleTimeoutMessage;
|
|
7611
7743
|
let clientClosedPromptError;
|
|
7612
7744
|
let clientClosedAbort = false;
|
|
@@ -7659,9 +7791,10 @@ async function runCodexAppServerAttempt(params, options = {}) {
|
|
|
7659
7791
|
turnTerminalIdleTimeoutMs,
|
|
7660
7792
|
interruptTimeoutMs: CODEX_APP_SERVER_INTERRUPT_TIMEOUT_MS,
|
|
7661
7793
|
onInterruptTurn: (input) => interruptCodexTurnBestEffort(client, input),
|
|
7662
|
-
onTimeout: () => {
|
|
7794
|
+
onTimeout: (timeout) => {
|
|
7663
7795
|
timedOut = true;
|
|
7664
7796
|
turnCompletionIdleTimedOut = true;
|
|
7797
|
+
turnWatchTimeoutKind = timeout.kind;
|
|
7665
7798
|
turnCompletionIdleTimeoutMessage = "codex app-server turn idle timed out waiting for turn/completed";
|
|
7666
7799
|
},
|
|
7667
7800
|
onMarkTimedOut: () => projector?.markTimedOut(),
|
|
@@ -7805,7 +7938,6 @@ async function runCodexAppServerAttempt(params, options = {}) {
|
|
|
7805
7938
|
threadId: thread.threadId,
|
|
7806
7939
|
turnId,
|
|
7807
7940
|
currentPromptTexts: [codexTurnPromptText],
|
|
7808
|
-
sourceReplyDeliveryMode: params.sourceReplyDeliveryMode,
|
|
7809
7941
|
turnWatches,
|
|
7810
7942
|
activeTurnItemIds,
|
|
7811
7943
|
activeAppServerTurnRequests,
|
|
@@ -7852,7 +7984,13 @@ async function runCodexAppServerAttempt(params, options = {}) {
|
|
|
7852
7984
|
return Promise.resolve();
|
|
7853
7985
|
}
|
|
7854
7986
|
if (isTerminalTurnNotificationForTurn(notification, turnId)) terminalTurnNotificationQueued = true;
|
|
7855
|
-
|
|
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);
|
|
7856
7994
|
notificationQueue = notificationQueue.then(() => handleNotification(notification), () => handleNotification(notification));
|
|
7857
7995
|
return notificationQueue;
|
|
7858
7996
|
};
|
|
@@ -8079,10 +8217,13 @@ async function runCodexAppServerAttempt(params, options = {}) {
|
|
|
8079
8217
|
} finally {
|
|
8080
8218
|
if (requestCountsAsTurnActivity) {
|
|
8081
8219
|
activeAppServerTurnRequests = Math.max(0, activeAppServerTurnRequests - 1);
|
|
8220
|
+
const postToolContinuationTimeoutMs = request.method === "item/tool/call" && turnCrossedToolHandoff ? postToolRawAssistantCompletionIdleTimeoutMs : void 0;
|
|
8082
8221
|
turnWatches.touchActivity(`request:${request.method}:response`, {
|
|
8083
8222
|
arm: armCompletionWatchOnResponse,
|
|
8084
|
-
attemptProgress: true
|
|
8223
|
+
attemptProgress: true,
|
|
8224
|
+
...postToolContinuationTimeoutMs !== void 0 ? { attemptTimeoutMs: postToolContinuationTimeoutMs } : {}
|
|
8085
8225
|
});
|
|
8226
|
+
if (armCompletionWatchOnResponse && postToolContinuationTimeoutMs !== void 0) turnWatches.armCompletionIdleWatch({ timeoutMs: postToolContinuationTimeoutMs });
|
|
8086
8227
|
scheduleTerminalDynamicToolReleaseCheck();
|
|
8087
8228
|
} else turnWatches.scheduleProgressWatches();
|
|
8088
8229
|
}
|
|
@@ -8095,11 +8236,11 @@ async function runCodexAppServerAttempt(params, options = {}) {
|
|
|
8095
8236
|
model: params.modelId,
|
|
8096
8237
|
systemPrompt: buildRenderedCodexDeveloperInstructions(),
|
|
8097
8238
|
prompt: codexTurnPromptText,
|
|
8098
|
-
historyMessages,
|
|
8239
|
+
historyMessages: codexModelInputHistoryMessages,
|
|
8099
8240
|
imagesCount: params.images?.length ?? 0,
|
|
8100
8241
|
tools
|
|
8101
8242
|
});
|
|
8102
|
-
const
|
|
8243
|
+
const buildCodexModelInputMessages = () => [...codexModelInputHistoryMessages, buildCodexUserPromptMessage({
|
|
8103
8244
|
...params,
|
|
8104
8245
|
prompt: codexTurnPromptText
|
|
8105
8246
|
})];
|
|
@@ -8118,7 +8259,7 @@ async function runCodexAppServerAttempt(params, options = {}) {
|
|
|
8118
8259
|
},
|
|
8119
8260
|
capture: codexModelContentCapture,
|
|
8120
8261
|
tools,
|
|
8121
|
-
buildInputMessages:
|
|
8262
|
+
buildInputMessages: buildCodexModelInputMessages,
|
|
8122
8263
|
buildSystemPrompt: buildRenderedCodexDeveloperInstructions,
|
|
8123
8264
|
onErrorDiagnostic: (error) => {
|
|
8124
8265
|
embeddedAgentLog.debug("codex app-server model call diagnostic ended with error", { error: formatErrorMessage(error) });
|
|
@@ -8134,6 +8275,8 @@ async function runCodexAppServerAttempt(params, options = {}) {
|
|
|
8134
8275
|
sandboxPolicy: codexSandboxPolicy,
|
|
8135
8276
|
environmentSelection: codexEnvironmentSelection,
|
|
8136
8277
|
turnScopedDeveloperInstructions: workspaceBootstrapContext.turnScopedDeveloperInstructions,
|
|
8278
|
+
skillsCollaborationInstructions,
|
|
8279
|
+
memoryCollaborationInstructions: workspaceBootstrapContext.memoryCollaborationInstructions,
|
|
8137
8280
|
heartbeatCollaborationInstructions: workspaceBootstrapContext.heartbeatCollaborationInstructions
|
|
8138
8281
|
});
|
|
8139
8282
|
codexModelCallDiagnostics.setRequestPayloadBytes(utf8JsonByteLength(turnStartParams));
|
|
@@ -8159,7 +8302,7 @@ async function runCodexAppServerAttempt(params, options = {}) {
|
|
|
8159
8302
|
turn = await startCodexTurn();
|
|
8160
8303
|
} catch (error) {
|
|
8161
8304
|
let turnStartError = error;
|
|
8162
|
-
if (
|
|
8305
|
+
if (shouldUseFreshCodexThreadAfterContextEngineOverflow({
|
|
8163
8306
|
error: turnStartError,
|
|
8164
8307
|
contextEngineActive: Boolean(activeContextEngine),
|
|
8165
8308
|
thread
|
|
@@ -8170,20 +8313,26 @@ async function runCodexAppServerAttempt(params, options = {}) {
|
|
|
8170
8313
|
});
|
|
8171
8314
|
try {
|
|
8172
8315
|
const preRetrySessionFile = activeSessionFile;
|
|
8173
|
-
await
|
|
8174
|
-
|
|
8175
|
-
|
|
8176
|
-
|
|
8177
|
-
|
|
8178
|
-
data: {
|
|
8179
|
-
phase: "thread_ready_retry",
|
|
8180
|
-
threadId: thread.threadId
|
|
8181
|
-
}
|
|
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)
|
|
8182
8321
|
});
|
|
8183
|
-
|
|
8184
|
-
|
|
8185
|
-
|
|
8186
|
-
|
|
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
|
+
}
|
|
8187
8336
|
}
|
|
8188
8337
|
} catch (retrySetupError) {
|
|
8189
8338
|
turnStartError = retrySetupError;
|
|
@@ -8242,9 +8391,13 @@ async function runCodexAppServerAttempt(params, options = {}) {
|
|
|
8242
8391
|
formatError: formatErrorMessage
|
|
8243
8392
|
});
|
|
8244
8393
|
codexModelCallDiagnostics.emitError(turnStartErrorMessage, turnStartFailureKind ? { failureKind: turnStartFailureKind } : {});
|
|
8394
|
+
const turnStartFailureMessages = [...historyMessages, buildCodexUserPromptMessage({
|
|
8395
|
+
...params,
|
|
8396
|
+
prompt: codexTurnPromptText
|
|
8397
|
+
})];
|
|
8245
8398
|
await runCodexAgentEndHook(params, {
|
|
8246
8399
|
event: {
|
|
8247
|
-
messages:
|
|
8400
|
+
messages: turnStartFailureMessages,
|
|
8248
8401
|
success: false,
|
|
8249
8402
|
error: turnStartErrorMessage,
|
|
8250
8403
|
durationMs: Date.now() - attemptStartedAt
|
|
@@ -8281,7 +8434,7 @@ async function runCodexAppServerAttempt(params, options = {}) {
|
|
|
8281
8434
|
return { ...buildCodexTurnStartFailureResult({
|
|
8282
8435
|
params,
|
|
8283
8436
|
message: usageLimitError.message,
|
|
8284
|
-
messagesSnapshot:
|
|
8437
|
+
messagesSnapshot: turnStartFailureMessages,
|
|
8285
8438
|
systemPromptReport
|
|
8286
8439
|
}) };
|
|
8287
8440
|
}
|
|
@@ -8334,6 +8487,8 @@ async function runCodexAppServerAttempt(params, options = {}) {
|
|
|
8334
8487
|
const activeProjector = projector;
|
|
8335
8488
|
turnWatches.armTerminalIdleWatch();
|
|
8336
8489
|
turnWatches.touchActivity("turn:start", { arm: true });
|
|
8490
|
+
turnWatches.armAttemptIdleWatch();
|
|
8491
|
+
turnWatches.touchActivity("turn:start", { attemptProgress: true });
|
|
8337
8492
|
for (const notification of pendingNotifications.splice(0)) await enqueueNotification(notification);
|
|
8338
8493
|
if (!completed && isTerminalTurnStatus(turn.turn.status)) await enqueueNotification({
|
|
8339
8494
|
method: "turn/completed",
|
|
@@ -8371,16 +8526,16 @@ async function runCodexAppServerAttempt(params, options = {}) {
|
|
|
8371
8526
|
threadId: thread.threadId,
|
|
8372
8527
|
turnId: activeTurnId
|
|
8373
8528
|
});
|
|
8374
|
-
turnWatches.armAttemptIdleWatch();
|
|
8375
|
-
turnWatches.armTerminalIdleWatch();
|
|
8376
|
-
turnWatches.touchActivity("turn:start", { attemptProgress: true });
|
|
8377
8529
|
const abortListener = () => {
|
|
8378
8530
|
if (timedOut) {
|
|
8379
|
-
|
|
8380
|
-
|
|
8381
|
-
|
|
8382
|
-
|
|
8383
|
-
|
|
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(() => {
|
|
8384
8539
|
resolveCompletion?.();
|
|
8385
8540
|
});
|
|
8386
8541
|
return;
|
|
@@ -8395,6 +8550,7 @@ async function runCodexAppServerAttempt(params, options = {}) {
|
|
|
8395
8550
|
if (runAbortController.signal.aborted) abortListener();
|
|
8396
8551
|
try {
|
|
8397
8552
|
await completion;
|
|
8553
|
+
await notificationQueue;
|
|
8398
8554
|
const result = activeProjector.buildResult(toolBridge.telemetry, { yieldDetected });
|
|
8399
8555
|
const finalAborted = result.aborted || runAbortController.signal.aborted && !clientClosedAbort;
|
|
8400
8556
|
let finalPromptError = clientClosedPromptError ?? (turnCompletionIdleTimedOut ? turnCompletionIdleTimeoutMessage : timedOut ? "codex app-server attempt timed out" : result.promptError);
|
|
@@ -8405,6 +8561,20 @@ async function runCodexAppServerAttempt(params, options = {}) {
|
|
|
8405
8561
|
turnId: activeTurnId,
|
|
8406
8562
|
error: finalPromptErrorMessage
|
|
8407
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
|
+
}
|
|
8408
8578
|
const refreshedUsageLimitPromptError = await refreshCodexUsageLimitPromptError({
|
|
8409
8579
|
client,
|
|
8410
8580
|
message: finalPromptErrorMessage,
|
|
@@ -8536,6 +8706,7 @@ async function runCodexAppServerAttempt(params, options = {}) {
|
|
|
8536
8706
|
promptErrorSource: finalPromptErrorSource,
|
|
8537
8707
|
...codexAppServerFailureKind ? { codexAppServerFailure: {
|
|
8538
8708
|
kind: codexAppServerFailureKind,
|
|
8709
|
+
...codexAppServerFailureKind === "turn_completion_idle_timeout" && turnWatchTimeoutKind ? { turnWatchTimeoutKind } : {},
|
|
8539
8710
|
transport: appServer.start.transport,
|
|
8540
8711
|
threadId: thread.threadId,
|
|
8541
8712
|
turnId: activeTurnId,
|
|
@@ -8608,7 +8779,14 @@ async function clearCodexBindingAfterInvalidImagePayload(sessionFile, fields) {
|
|
|
8608
8779
|
function isNonEmptyString(value) {
|
|
8609
8780
|
return typeof value === "string" && value.length > 0;
|
|
8610
8781
|
}
|
|
8611
|
-
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) {
|
|
8612
8790
|
if (!params.contextEngineActive || params.thread.lifecycle.action !== "resumed") return false;
|
|
8613
8791
|
return isCodexContextWindowError(params.error);
|
|
8614
8792
|
}
|