@openclaw/codex 2026.5.25-beta.1 → 2026.5.26-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.
Files changed (25) hide show
  1. package/dist/{client-SrtuTTVa.js → client-BVK_jmHW.js} +1 -1
  2. package/dist/{client-factory-A7DQkSLq.js → client-factory-CaOpX89B.js} +1 -1
  3. package/dist/{command-handlers-CLtPT37L.js → command-handlers-D4C2y46B.js} +8 -8
  4. package/dist/{compact-acCua7zr.js → compact-CRI0BEc_.js} +3 -3
  5. package/dist/{computer-use-CVfE2Vfb.js → computer-use-CDDlIBhY.js} +2 -2
  6. package/dist/{config-D6TUuyo2.js → config-0-UN67Qg.js} +2 -1
  7. package/dist/{conversation-binding-B-GevkEb.js → conversation-binding-BnnjOmgs.js} +7 -7
  8. package/dist/{dynamic-tools-BXAE1U1-.js → dynamic-tools-BG9ICyU4.js} +1 -1
  9. package/dist/harness.js +5 -5
  10. package/dist/index.js +8 -8
  11. package/dist/media-understanding-provider.js +7 -7
  12. package/dist/{models-CC2IusQs.js → models-ASKu9eOY.js} +2 -2
  13. package/dist/{notification-correlation-D7tJW3FW.js → notification-correlation-YINts3PA.js} +1 -1
  14. package/dist/{protocol-validators-_gKDcd0x.js → protocol-validators-CSuFMLvY.js} +138 -29
  15. package/dist/provider.js +2 -2
  16. package/dist/{request-BO0z3vA8.js → request-DmBkYLPy.js} +3 -3
  17. package/dist/{run-attempt-BjoI3hUJ.js → run-attempt-CFBsGx1T.js} +221 -62
  18. package/dist/{session-binding-CwNOIDP2.js → session-binding-UFjjws4k.js} +1 -1
  19. package/dist/{shared-client-CZP1DjaN.js → shared-client-Fou5nAyt.js} +65 -9
  20. package/dist/{side-question-Cb4COOQ9.js → side-question-fq_T2d_x.js} +9 -9
  21. package/dist/test-api.js +3 -3
  22. package/dist/{thread-lifecycle-CXMd9UgJ.js → thread-lifecycle-BapIT9Qs.js} +107 -20
  23. package/dist/{vision-tools-CETeQgze.js → vision-tools-B30YCKRK.js} +2 -2
  24. package/npm-shrinkwrap.json +7 -77
  25. package/package.json +5 -5
@@ -1,19 +1,19 @@
1
- import { t as defaultCodexAppServerClientFactory } from "./client-factory-A7DQkSLq.js";
2
- import { c as readCodexPluginConfig, d as resolveCodexPluginsPolicy, f as shouldAutoApproveCodexAppServerApprovals, i as isCodexAppServerApprovalPolicyAllowedByRequirements, l as resolveCodexAppServerRuntimeOptions, o as isCodexSandboxExecServerEnabled, p as withMcpElicitationsApprovalPolicy, u as resolveCodexComputerUseConfig } from "./config-D6TUuyo2.js";
3
- import { a as readCodexDynamicToolCallParams, c as readCodexTurn, i as assertCodexTurnStartResponse } from "./protocol-validators-_gKDcd0x.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-SrtuTTVa.js";
5
- import { D as resolveCodexContextEngineProjectionMaxChars, E as projectContextEngineAssemblyForCodex, O as resolveCodexContextEngineProjectionReserveTokens, S as defaultCodexAppInventoryCache, _ as mergeCodexThreadConfigs, a as buildDeveloperInstructions, c as buildTurnCollaborationMode, d as isContextEngineBindingCompatible, g as buildCodexPluginThreadConfigInputFingerprint, h as buildCodexPluginThreadConfig, i as buildContextEngineBinding, l as buildTurnStartParams, m as startOrResumeThread, n as areCodexDynamicToolFingerprintsCompatible, u as codexDynamicToolsFingerprint, v as shouldBuildCodexPluginThreadConfig, w as sanitizeCodexHistoryImagePayloads } from "./thread-lifecycle-CXMd9UgJ.js";
6
- import { i as readCodexAppServerBinding, t as clearCodexAppServerBinding } from "./session-binding-CwNOIDP2.js";
7
- import { n as buildCodexPluginAppCacheKey, r as CODEX_CONTROL_METHODS } from "./request-BO0z3vA8.js";
8
- import { g as shouldRefreshCodexRateLimitsForUsageLimitMessage, h as resolveCodexUsageLimitResetAtMs, i as readCodexNotificationTurnId, m as formatCodexUsageLimitErrorMessage, n as isCodexNotificationForTurn, r as readCodexNotificationThreadId, s as formatCodexDisplayText, t as describeCodexNotificationCorrelation } from "./notification-correlation-D7tJW3FW.js";
9
- import { c as resolveCodexAppServerAuthAccountCacheKey, d as resolveCodexAppServerEnvApiKeyCacheKey, f as resolveCodexAppServerHomeDir, l as resolveCodexAppServerAuthProfileId, s as refreshCodexAppServerAuthTokens, t as clearSharedCodexAppServerClientIfCurrent, u as resolveCodexAppServerAuthProfileIdForAgent } from "./shared-client-CZP1DjaN.js";
1
+ import { t as defaultCodexAppServerClientFactory } from "./client-factory-CaOpX89B.js";
2
+ import { c as readCodexPluginConfig, d as resolveCodexPluginsPolicy, f as shouldAutoApproveCodexAppServerApprovals, i as isCodexAppServerApprovalPolicyAllowedByRequirements, l as resolveCodexAppServerRuntimeOptions, o as isCodexSandboxExecServerEnabled, p as withMcpElicitationsApprovalPolicy, u as resolveCodexComputerUseConfig } from "./config-0-UN67Qg.js";
3
+ import { a as readCodexDynamicToolCallParams, c as readCodexTurn, i as assertCodexTurnStartResponse } from "./protocol-validators-CSuFMLvY.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-BVK_jmHW.js";
5
+ import { C as defaultCodexAppInventoryCache, D as projectContextEngineAssemblyForCodex, O as resolveCodexContextEngineProjectionMaxChars, T as sanitizeCodexHistoryImagePayloads, _ as buildCodexPluginThreadConfigInputFingerprint, a as buildDeveloperInstructions, c as buildTurnCollaborationMode, d as isContextEngineBindingCompatible, g as buildCodexPluginThreadConfig, h as isCodexAppServerProfilerEnabled, i as buildContextEngineBinding, k as resolveCodexContextEngineProjectionReserveTokens, l as buildTurnStartParams, m as startOrResumeThread, n as areCodexDynamicToolFingerprintsCompatible, u as codexDynamicToolsFingerprint, v as mergeCodexThreadConfigs, y as shouldBuildCodexPluginThreadConfig } from "./thread-lifecycle-BapIT9Qs.js";
6
+ import { i as readCodexAppServerBinding, t as clearCodexAppServerBinding } from "./session-binding-UFjjws4k.js";
7
+ import { n as buildCodexPluginAppCacheKey, r as CODEX_CONTROL_METHODS } from "./request-DmBkYLPy.js";
8
+ import { g as shouldRefreshCodexRateLimitsForUsageLimitMessage, h as resolveCodexUsageLimitResetAtMs, i as readCodexNotificationTurnId, m as formatCodexUsageLimitErrorMessage, n as isCodexNotificationForTurn, r as readCodexNotificationThreadId, s as formatCodexDisplayText, t as describeCodexNotificationCorrelation } from "./notification-correlation-YINts3PA.js";
9
+ import { c as resolveCodexAppServerAuthAccountCacheKey, d as resolveCodexAppServerFallbackApiKeyCacheKey, f as resolveCodexAppServerHomeDir, l as resolveCodexAppServerAuthProfileId, s as refreshCodexAppServerAuthTokens, t as clearSharedCodexAppServerClientIfCurrent, u as resolveCodexAppServerAuthProfileIdForAgent } from "./shared-client-Fou5nAyt.js";
10
10
  import { i as resolveCodexNativeExecutionPolicy } from "./sandbox-guard-CTnEWuor.js";
11
- import { a as resolveCodexDynamicToolsLoading, i as normalizeCodexDynamicToolName, n as filterCodexDynamicTools, r as isForcedPrivateQaCodexRuntime, t as createCodexDynamicToolBridge } from "./dynamic-tools-BXAE1U1-.js";
12
- import { a as handleCodexAppServerElicitationRequest, c as emitDynamicToolTerminalDiagnostic, i as buildCodexNativeHookRelayDisabledConfig, l as handleCodexAppServerApprovalRequest, n as CODEX_NATIVE_HOOK_RELAY_EVENTS, o as emitDynamicToolErrorDiagnostic, r as buildCodexNativeHookRelayConfig, s as emitDynamicToolStartedDiagnostic, t as filterToolsForVisionInputs } from "./vision-tools-CETeQgze.js";
13
- import { t as ensureCodexComputerUse } from "./computer-use-CVfE2Vfb.js";
11
+ import { a as resolveCodexDynamicToolsLoading, i as normalizeCodexDynamicToolName, n as filterCodexDynamicTools, r as isForcedPrivateQaCodexRuntime, t as createCodexDynamicToolBridge } from "./dynamic-tools-BG9ICyU4.js";
12
+ import { a as handleCodexAppServerElicitationRequest, c as emitDynamicToolTerminalDiagnostic, i as buildCodexNativeHookRelayDisabledConfig, l as handleCodexAppServerApprovalRequest, n as CODEX_NATIVE_HOOK_RELAY_EVENTS, o as emitDynamicToolErrorDiagnostic, r as buildCodexNativeHookRelayConfig, s as emitDynamicToolStartedDiagnostic, t as filterToolsForVisionInputs } from "./vision-tools-B30YCKRK.js";
13
+ import { t as ensureCodexComputerUse } from "./computer-use-CDDlIBhY.js";
14
14
  import { n as rememberCodexRateLimits, t as readRecentCodexRateLimits } from "./rate-limit-cache-N66I-Rd7.js";
15
15
  import { createHash, randomUUID } from "node:crypto";
16
- import nodeFs from "node:fs";
16
+ import fsSync from "node:fs";
17
17
  import { asBoolean, asFiniteNumber, normalizeOptionalString, normalizeStringEntries } from "openclaw/plugin-sdk/string-coerce-runtime";
18
18
  import { CODEX_APP_SERVER_CONTEXT_ENGINE_HOST, TOOL_PROGRESS_OUTPUT_MAX_CHARS, acquireSessionWriteLock, appendSessionTranscriptMessage, assembleHarnessContextEngine, assertContextEngineHostSupport, awaitAgentHarnessAgentEndHook, bootstrapHarnessContextEngine, buildAgentHookContextChannelFields, buildEmbeddedAttemptToolRunContext, buildHarnessContextEngineRuntimeContext, buildHarnessContextEngineRuntimeContextFromUsage, classifyAgentHarnessTerminalOutcome, clearActiveEmbeddedRun, embeddedAgentLog, emitAgentEvent, emitSessionTranscriptUpdate, finalizeHarnessContextEngineTurn, formatErrorMessage, formatToolAggregate, formatToolProgressOutput, getBeforeToolCallPolicyDiagnosticState, inferToolMetaFromArgs, isActiveHarnessContextEngine, isSubagentSessionKey, loadCodexBundleMcpThreadConfig, normalizeAgentRuntimeTools, normalizeUsage, registerNativeHookRelay, resolveAgentHarnessBeforePromptBuildResult, resolveAttemptSpawnWorkspaceDir, resolveBootstrapContextForRun, resolveContextEngineOwnerPluginId, resolveModelAuthMode, resolveSandboxContext, resolveSessionAgentIds, resolveSessionWriteLockOptions, resolveUserPath, runAgentCleanupStep, runAgentHarnessAfterCompactionHook, runAgentHarnessAfterToolCallHook, runAgentHarnessAgentEndHook, runAgentHarnessBeforeCompactionHook, runAgentHarnessBeforeMessageWriteHook, runAgentHarnessLlmInputHook, runAgentHarnessLlmOutputHook, runHarnessContextEngineMaintenance, setActiveEmbeddedRun, supportsModelTools } from "openclaw/plugin-sdk/agent-harness-runtime";
19
19
  import { spawn } from "node:child_process";
@@ -22,10 +22,10 @@ import { WebSocketServer } from "ws";
22
22
  import { redactSensitiveFieldValue, redactToolPayloadText } from "openclaw/plugin-sdk/logging-core";
23
23
  import fs from "node:fs/promises";
24
24
  import path, { posix } from "node:path";
25
+ import { createDiagnosticTraceContextFromActiveScope, emitTrustedDiagnosticEvent, emitTrustedDiagnosticEventWithPrivateData, freezeDiagnosticTraceContext, hasPendingInternalDiagnosticEvent, onInternalDiagnosticEvent, resolveDiagnosticModelContentCapturePolicy } from "openclaw/plugin-sdk/diagnostic-runtime";
25
26
  import { markAuthProfileBlockedUntil, resolveAgentDir as resolveAgentDir$1 } from "openclaw/plugin-sdk/agent-runtime";
26
27
  import { isToolAllowed } from "openclaw/plugin-sdk/sandbox";
27
28
  import { appendRegularFile, pathExists } from "openclaw/plugin-sdk/security-runtime";
28
- import { createDiagnosticTraceContextFromActiveScope, emitTrustedDiagnosticEvent, emitTrustedDiagnosticEventWithPrivateData, freezeDiagnosticTraceContext, hasPendingInternalDiagnosticEvent, onInternalDiagnosticEvent, resolveDiagnosticModelContentCapturePolicy } from "openclaw/plugin-sdk/diagnostic-runtime";
29
29
  import { buildSessionContext, migrateSessionEntries, parseSessionEntries } from "@earendil-works/pi-coding-agent";
30
30
  import { createAgentHarnessTaskRuntime, deliverAgentHarnessTaskCompletion, isDurableAgentHarnessCompletionDelivery } from "openclaw/plugin-sdk/agent-harness-task-runtime";
31
31
  import { isIP } from "node:net";
@@ -3946,7 +3946,7 @@ const JWT_VALUE_RE = /\beyJ[A-Za-z0-9_-]{10,}\.[A-Za-z0-9_-]{10,}\.[A-Za-z0-9_-]
3946
3946
  const COOKIE_PAIR_RE = /\b([A-Za-z][A-Za-z0-9_.-]{1,64})=([A-Za-z0-9+/._~%=-]{16,})(?=;|\s|$)/gu;
3947
3947
  const TRAJECTORY_RUNTIME_FILE_MAX_BYTES = 50 * 1024 * 1024;
3948
3948
  const TRAJECTORY_RUNTIME_EVENT_MAX_BYTES = 256 * 1024;
3949
- function resolveCodexTrajectoryPointerFlags(constants = nodeFs.constants) {
3949
+ function resolveCodexTrajectoryPointerFlags(constants = fsSync.constants) {
3950
3950
  const noFollow = constants.O_NOFOLLOW;
3951
3951
  return constants.O_CREAT | constants.O_TRUNC | constants.O_WRONLY | (typeof noFollow === "number" ? noFollow : 0);
3952
3952
  }
@@ -3980,23 +3980,23 @@ function writeTrajectoryPointerBestEffort(params) {
3980
3980
  const pointerPath = resolveTrajectoryPointerFilePath(params.sessionFile);
3981
3981
  try {
3982
3982
  const pointerDir = path.resolve(path.dirname(pointerPath));
3983
- if (nodeFs.lstatSync(pointerDir).isSymbolicLink()) return;
3983
+ if (fsSync.lstatSync(pointerDir).isSymbolicLink()) return;
3984
3984
  try {
3985
- if (nodeFs.lstatSync(pointerPath).isSymbolicLink()) return;
3985
+ if (fsSync.lstatSync(pointerPath).isSymbolicLink()) return;
3986
3986
  } catch (error) {
3987
3987
  if (error.code !== "ENOENT") return;
3988
3988
  }
3989
- const fd = nodeFs.openSync(pointerPath, resolveCodexTrajectoryPointerFlags(), 384);
3989
+ const fd = fsSync.openSync(pointerPath, resolveCodexTrajectoryPointerFlags(), 384);
3990
3990
  try {
3991
- nodeFs.writeFileSync(fd, `${JSON.stringify({
3991
+ fsSync.writeFileSync(fd, `${JSON.stringify({
3992
3992
  traceSchema: "openclaw-trajectory-pointer",
3993
3993
  schemaVersion: 1,
3994
3994
  sessionId: params.sessionId,
3995
3995
  runtimeFile: params.filePath
3996
3996
  }, null, 2)}\n`, "utf8");
3997
- nodeFs.fchmodSync(fd, 384);
3997
+ fsSync.fchmodSync(fd, 384);
3998
3998
  } finally {
3999
- nodeFs.closeSync(fd);
3999
+ fsSync.closeSync(fd);
4000
4000
  }
4001
4001
  } catch {}
4002
4002
  }
@@ -4361,6 +4361,7 @@ const CODEX_BOOTSTRAP_CONTEXT_ORDER = new Map([
4361
4361
  ["memory.md", 60],
4362
4362
  ["heartbeat.md", 70]
4363
4363
  ]);
4364
+ const ensuredCodexWorkspaceDirs = /* @__PURE__ */ new Set();
4364
4365
  const pendingCodexNativeHookRelayUnregisters = /* @__PURE__ */ new Set();
4365
4366
  function scheduleCodexNativeHookRelayUnregister(params) {
4366
4367
  let pending;
@@ -4383,6 +4384,19 @@ function resolveCodexNativeHookRelayUnregisterGraceMs(hookTimeoutSec) {
4383
4384
  const hookTimeoutMs = typeof hookTimeoutSec === "number" && Number.isFinite(hookTimeoutSec) && hookTimeoutSec > 0 ? Math.ceil(hookTimeoutSec) * 1e3 : 0;
4384
4385
  return Math.max(CODEX_NATIVE_HOOK_RELAY_UNREGISTER_GRACE_MS, hookTimeoutMs + CODEX_NATIVE_HOOK_RELAY_UNREGISTER_EXTRA_GRACE_MS);
4385
4386
  }
4387
+ async function ensureCodexWorkspaceDirOnce(workspaceDir) {
4388
+ const normalized = path.resolve(workspaceDir);
4389
+ if (ensuredCodexWorkspaceDirs.has(normalized)) {
4390
+ try {
4391
+ if ((await fs.stat(normalized)).isDirectory()) return;
4392
+ } catch (error) {
4393
+ if ((typeof error === "object" && error ? error.code : void 0) !== "ENOENT") throw error;
4394
+ }
4395
+ ensuredCodexWorkspaceDirs.delete(normalized);
4396
+ }
4397
+ await fs.mkdir(normalized, { recursive: true });
4398
+ ensuredCodexWorkspaceDirs.add(normalized);
4399
+ }
4386
4400
  function emitCodexAppServerEvent(params, event) {
4387
4401
  try {
4388
4402
  emitAgentEvent({
@@ -4565,7 +4579,7 @@ function isCodexAppServerPolicyMode(value) {
4565
4579
  function isCodexAppServerApprovalPolicy(value) {
4566
4580
  return value === "never" || value === "on-request" || value === "on-failure" || value === "untrusted";
4567
4581
  }
4568
- const CODEX_APP_SERVER_NATIVE_THREAD_MAX_TOKENS = 7e4;
4582
+ const CODEX_APP_SERVER_NATIVE_THREAD_FALLBACK_MAX_TOKENS = 3e5;
4569
4583
  const CODEX_APP_SERVER_BYTE_UNITS = {
4570
4584
  b: 1,
4571
4585
  k: 1024,
@@ -4653,25 +4667,29 @@ async function readCodexSessionRecordForSessionFile(sessionFile) {
4653
4667
  };
4654
4668
  }
4655
4669
  }
4656
- async function readCodexAppServerRolloutTokenUsage(file) {
4670
+ async function readCodexAppServerRolloutTokenSnapshot(file) {
4657
4671
  let handle;
4658
4672
  try {
4659
4673
  handle = await fs.open(file, "r");
4660
4674
  } catch {
4661
4675
  return;
4662
4676
  }
4663
- let totalTokens;
4677
+ let snapshot;
4664
4678
  try {
4665
4679
  for await (const line of handle.readLines()) {
4666
- const lineTokens = readCodexAppServerRolloutTokenUsageLine(line);
4667
- if (lineTokens !== void 0) totalTokens = lineTokens;
4680
+ const lineSnapshot = readCodexAppServerRolloutTokenSnapshotLine(line);
4681
+ if (lineSnapshot !== void 0) {
4682
+ snapshot ??= {};
4683
+ if (lineSnapshot.totalTokens !== void 0) snapshot.totalTokens = lineSnapshot.totalTokens;
4684
+ if (lineSnapshot.modelContextWindow !== void 0) snapshot.modelContextWindow = lineSnapshot.modelContextWindow;
4685
+ }
4668
4686
  }
4669
4687
  } finally {
4670
4688
  await handle.close();
4671
4689
  }
4672
- return totalTokens;
4690
+ return snapshot;
4673
4691
  }
4674
- function readCodexAppServerRolloutTokenUsageLine(line) {
4692
+ function readCodexAppServerRolloutTokenSnapshotLine(line) {
4675
4693
  if (!line.trim()) return;
4676
4694
  try {
4677
4695
  const parsed = JSON.parse(line);
@@ -4680,11 +4698,20 @@ function readCodexAppServerRolloutTokenUsageLine(line) {
4680
4698
  if (!info) return;
4681
4699
  const usage = isJsonObject(info.last_token_usage) ? info.last_token_usage : isJsonObject(info.total_token_usage) ? info.total_token_usage : void 0;
4682
4700
  const value = usage?.total_tokens ?? usage?.totalTokens;
4683
- return typeof value === "number" && Number.isFinite(value) ? value : void 0;
4701
+ const totalTokens = typeof value === "number" && Number.isFinite(value) ? value : void 0;
4702
+ const windowValue = info.model_context_window ?? info.modelContextWindow;
4703
+ const modelContextWindow = typeof windowValue === "number" && Number.isFinite(windowValue) && windowValue > 0 ? Math.floor(windowValue) : void 0;
4704
+ const snapshot = {};
4705
+ if (totalTokens !== void 0) snapshot.totalTokens = totalTokens;
4706
+ if (modelContextWindow !== void 0) snapshot.modelContextWindow = modelContextWindow;
4707
+ return snapshot.totalTokens !== void 0 || snapshot.modelContextWindow !== void 0 ? snapshot : void 0;
4684
4708
  } catch {
4685
4709
  return;
4686
4710
  }
4687
4711
  }
4712
+ function resolveCodexAppServerNativeThreadTokenFuse(modelContextWindow) {
4713
+ return modelContextWindow ?? CODEX_APP_SERVER_NATIVE_THREAD_FALLBACK_MAX_TOKENS;
4714
+ }
4688
4715
  function utf8JsonByteLength(value) {
4689
4716
  try {
4690
4717
  return Buffer.byteLength(JSON.stringify(value), "utf8");
@@ -4697,10 +4724,22 @@ function maxFiniteNumber(values) {
4697
4724
  if (nums.length === 0) return;
4698
4725
  return Math.max(...nums);
4699
4726
  }
4727
+ function hasContextEngineThreadBootstrapProjection(binding) {
4728
+ return binding.contextEngine?.projection?.mode === "thread_bootstrap";
4729
+ }
4700
4730
  async function rotateOversizedCodexAppServerStartupBinding(params) {
4701
4731
  const binding = params.binding;
4702
4732
  if (!binding?.threadId) return binding;
4703
4733
  if (params.config?.agents?.defaults?.compaction?.truncateAfterCompaction !== true) return binding;
4734
+ if (params.contextEngineActive === true && hasContextEngineThreadBootstrapProjection(binding)) {
4735
+ embeddedAgentLog.debug("codex app-server deferring native transcript size guard for context-engine thread bootstrap", {
4736
+ threadId: binding.threadId,
4737
+ engineId: binding.contextEngine?.engineId,
4738
+ epoch: binding.contextEngine?.projection?.epoch,
4739
+ fingerprint: binding.contextEngine?.projection?.fingerprint
4740
+ });
4741
+ return binding;
4742
+ }
4704
4743
  const sessionRecord = await readCodexSessionRecordForSessionFile(params.sessionFile);
4705
4744
  const maxBytes = parseCodexAppServerByteLimit(params.config?.agents?.defaults?.compaction?.maxActiveTranscriptBytes);
4706
4745
  const rolloutFiles = await listCodexAppServerRolloutFilesForThread(params.agentDir, binding.threadId, params.codexHome);
@@ -4719,16 +4758,20 @@ async function rotateOversizedCodexAppServerStartupBinding(params) {
4719
4758
  return;
4720
4759
  }
4721
4760
  }
4722
- const nativeTokens = maxFiniteNumber(await Promise.all(rolloutFiles.map(async (file) => readCodexAppServerRolloutTokenUsage(file.path))));
4761
+ const nativeTokenSnapshots = await Promise.all(rolloutFiles.map(async (file) => readCodexAppServerRolloutTokenSnapshot(file.path)));
4762
+ const nativeTokens = maxFiniteNumber(nativeTokenSnapshots.map((snapshot) => snapshot?.totalTokens));
4763
+ const nativeModelContextWindow = maxFiniteNumber(nativeTokenSnapshots.map((snapshot) => snapshot?.modelContextWindow));
4764
+ const maxTokens = resolveCodexAppServerNativeThreadTokenFuse(nativeModelContextWindow);
4723
4765
  const sessionTokens = sessionRecord?.totalTokensFresh !== false && typeof sessionRecord?.totalTokens === "number" && Number.isFinite(sessionRecord.totalTokens) ? sessionRecord.totalTokens : void 0;
4724
4766
  const tokenCount = maxFiniteNumber([sessionTokens, nativeTokens]);
4725
- if (tokenCount !== void 0 && tokenCount >= CODEX_APP_SERVER_NATIVE_THREAD_MAX_TOKENS) {
4767
+ if (tokenCount !== void 0 && tokenCount >= maxTokens) {
4726
4768
  embeddedAgentLog.warn("codex app-server native transcript exceeded active token limit; starting a fresh thread", {
4727
4769
  threadId: binding.threadId,
4728
- maxTokens: CODEX_APP_SERVER_NATIVE_THREAD_MAX_TOKENS,
4770
+ maxTokens,
4729
4771
  sessionKey: sessionRecord?.sessionKey,
4730
4772
  sessionTokens,
4731
- nativeTokens
4773
+ nativeTokens,
4774
+ nativeModelContextWindow
4732
4775
  });
4733
4776
  await clearCodexAppServerBinding(params.sessionFile);
4734
4777
  return;
@@ -4747,6 +4790,7 @@ async function runCodexAgentEndHook(params, hookParams) {
4747
4790
  }
4748
4791
  async function runCodexAppServerAttempt(params, options = {}) {
4749
4792
  const attemptStartedAt = Date.now();
4793
+ const profilerEnabled = isCodexAppServerProfilerEnabled(params.config);
4750
4794
  const codexModelCallTrace = freezeDiagnosticTraceContext(createDiagnosticTraceContextFromActiveScope());
4751
4795
  const codexModelContentCapture = resolveDiagnosticModelContentCapturePolicy(params.config);
4752
4796
  const codexModelCallId = `${params.runId}:codex-model:1`;
@@ -4754,13 +4798,16 @@ async function runCodexAppServerAttempt(params, options = {}) {
4754
4798
  let codexModelCallStarted = false;
4755
4799
  let codexModelCallTerminalEmitted = false;
4756
4800
  let codexModelCallRequestPayloadBytes;
4801
+ const preDynamicStartupStages = createCodexDynamicToolBuildStageTracker({ enabled: profilerEnabled });
4757
4802
  const attemptClientFactory = options.clientFactory ?? defaultCodexAppServerClientFactory;
4758
4803
  const pluginConfig = readCodexPluginConfig(options.pluginConfig);
4759
4804
  const computerUseConfig = resolveCodexComputerUseConfig({ pluginConfig });
4760
4805
  const configuredAppServer = resolveCodexAppServerRuntimeOptions({ pluginConfig });
4761
4806
  const beforeToolCallPolicy = getBeforeToolCallPolicyDiagnosticState();
4807
+ preDynamicStartupStages.mark("config");
4762
4808
  const resolvedWorkspace = resolveUserPath(params.workspaceDir);
4763
- await fs.mkdir(resolvedWorkspace, { recursive: true });
4809
+ await ensureCodexWorkspaceDirOnce(resolvedWorkspace);
4810
+ preDynamicStartupStages.mark("workspace");
4764
4811
  const sandboxSessionKey = params.sandboxSessionKey?.trim() || params.sessionKey?.trim() || params.sessionId;
4765
4812
  const contextSessionKey = params.sessionKey?.trim() || sandboxSessionKey;
4766
4813
  const sandbox = await resolveSandboxContext({
@@ -4768,8 +4815,10 @@ async function runCodexAppServerAttempt(params, options = {}) {
4768
4815
  sessionKey: sandboxSessionKey,
4769
4816
  workspaceDir: resolvedWorkspace
4770
4817
  });
4818
+ preDynamicStartupStages.mark("sandbox");
4771
4819
  const effectiveWorkspace = sandbox?.enabled ? sandbox.workspaceAccess === "rw" ? resolvedWorkspace : sandbox.workspaceDir : resolvedWorkspace;
4772
- await fs.mkdir(effectiveWorkspace, { recursive: true });
4820
+ await ensureCodexWorkspaceDirOnce(effectiveWorkspace);
4821
+ preDynamicStartupStages.mark("effective-workspace");
4773
4822
  const appServer = resolveCodexAppServerForOpenClawToolPolicy({
4774
4823
  appServer: configuredAppServer,
4775
4824
  pluginConfig,
@@ -4783,11 +4832,13 @@ async function runCodexAppServerAttempt(params, options = {}) {
4783
4832
  beforeToolCallHook: beforeToolCallPolicy.hasBeforeToolCallHook,
4784
4833
  trustedToolPolicies: beforeToolCallPolicy.trustedToolPolicies
4785
4834
  });
4835
+ preDynamicStartupStages.mark("app-server-policy");
4786
4836
  let pluginAppServer = appServer;
4787
4837
  const nativeHookRelayEvents = resolveCodexNativeHookRelayEvents({
4788
4838
  configuredEvents: options.nativeHookRelay?.events,
4789
4839
  appServer
4790
4840
  });
4841
+ preDynamicStartupStages.mark("native-hook-relay");
4791
4842
  const runAbortController = new AbortController();
4792
4843
  const abortFromUpstream = () => {
4793
4844
  runAbortController.abort(params.abortSignal?.reason ?? "upstream_abort");
@@ -4800,15 +4851,19 @@ async function runCodexAppServerAttempt(params, options = {}) {
4800
4851
  agentId: params.agentId
4801
4852
  });
4802
4853
  const agentDir = params.agentDir ?? resolveAgentDir$1(params.config ?? {}, sessionAgentId);
4854
+ preDynamicStartupStages.mark("session-agent");
4803
4855
  let startupBinding = await readCodexAppServerBinding(params.sessionFile);
4856
+ preDynamicStartupStages.mark("read-binding");
4804
4857
  const startupBindingAuthProfileId = startupBinding?.authProfileId;
4805
4858
  startupBinding = await rotateOversizedCodexAppServerStartupBinding({
4806
4859
  binding: startupBinding,
4807
4860
  sessionFile: params.sessionFile,
4808
4861
  agentDir,
4809
4862
  codexHome: appServer.start.env?.CODEX_HOME,
4810
- config: params.config
4863
+ config: params.config,
4864
+ contextEngineActive: isActiveHarnessContextEngine(params.contextEngine)
4811
4865
  });
4866
+ preDynamicStartupStages.mark("rotate-binding");
4812
4867
  const startupAuthProfileCandidate = params.runtimePlan?.auth.forwardedAuthProfileId ?? params.authProfileId ?? startupBinding?.authProfileId ?? startupBindingAuthProfileId;
4813
4868
  const startupAuthProfileId = params.authProfileStore ? resolveCodexAppServerAuthProfileId({
4814
4869
  authProfileId: startupAuthProfileCandidate,
@@ -4819,6 +4874,7 @@ async function runCodexAppServerAttempt(params, options = {}) {
4819
4874
  agentDir,
4820
4875
  config: params.config
4821
4876
  });
4877
+ preDynamicStartupStages.mark("auth-profile");
4822
4878
  const runtimeParams = {
4823
4879
  ...params,
4824
4880
  sessionKey: contextSessionKey,
@@ -4837,12 +4893,14 @@ async function runCodexAppServerAttempt(params, options = {}) {
4837
4893
  agentDir,
4838
4894
  config: params.config
4839
4895
  });
4840
- const startupEnvApiKeyCacheKey = startupAuthProfileId ? void 0 : resolveCodexAppServerEnvApiKeyCacheKey({ startOptions: appServer.start });
4896
+ const startupEnvApiKeyCacheKey = startupAuthProfileId ? void 0 : resolveCodexAppServerFallbackApiKeyCacheKey({ startOptions: appServer.start });
4897
+ preDynamicStartupStages.mark("auth-cache");
4841
4898
  const nodeExecBlocksNativeExecution = isCodexNativeExecutionBlockedByNodeExecHost(params, {
4842
4899
  agentId: sessionAgentId,
4843
4900
  runtimeSessionKey: sandboxSessionKey,
4844
4901
  sandbox
4845
4902
  });
4903
+ preDynamicStartupStages.mark("native-exec-policy");
4846
4904
  const bundleMcpThreadConfig = await loadCodexBundleMcpThreadConfig({
4847
4905
  workspaceDir: effectiveWorkspace,
4848
4906
  cfg: params.config,
@@ -4850,12 +4908,14 @@ async function runCodexAppServerAttempt(params, options = {}) {
4850
4908
  disableTools: params.disableTools,
4851
4909
  toolsAllow: nodeExecBlocksNativeExecution ? [] : params.toolsAllow
4852
4910
  });
4911
+ preDynamicStartupStages.mark("bundle-mcp");
4853
4912
  const sandboxExecServerEnabled = isCodexSandboxExecServerEnabled(pluginConfig);
4854
4913
  const nativeToolSurfaceEnabled = shouldEnableCodexAppServerNativeToolSurface(params, sandbox, {
4855
4914
  agentId: sessionAgentId,
4856
4915
  runtimeSessionKey: sandboxSessionKey,
4857
4916
  sandboxExecServerEnabled
4858
4917
  });
4918
+ preDynamicStartupStages.mark("native-tool-surface");
4859
4919
  for (const diagnostic of bundleMcpThreadConfig.diagnostics) embeddedAgentLog.warn(`bundle-mcp: ${diagnostic.pluginId}: ${diagnostic.message}`);
4860
4920
  const activeContextEngine = isActiveHarnessContextEngine(params.contextEngine) ? params.contextEngine : void 0;
4861
4921
  if (activeContextEngine) assertContextEngineHostSupport({
@@ -4864,6 +4924,18 @@ async function runCodexAppServerAttempt(params, options = {}) {
4864
4924
  host: CODEX_APP_SERVER_CONTEXT_ENGINE_HOST
4865
4925
  });
4866
4926
  const hookChannelId = resolveCodexAppServerHookChannelId(params, sandboxSessionKey);
4927
+ preDynamicStartupStages.mark("context-engine-support");
4928
+ const preDynamicSummary = preDynamicStartupStages.snapshot();
4929
+ if (shouldWarnCodexDynamicToolBuildStageSummary(preDynamicSummary)) embeddedAgentLog.warn(`codex app-server pre-dynamic startup timings runId=${params.runId} sessionId=${params.sessionId} totalMs=${preDynamicSummary.totalMs} stages=${formatCodexDynamicToolBuildStageSummary(preDynamicSummary)}`, {
4930
+ runId: params.runId,
4931
+ sessionId: params.sessionId,
4932
+ totalMs: preDynamicSummary.totalMs,
4933
+ stages: preDynamicSummary.stages,
4934
+ hasStartupBinding: Boolean(startupBinding?.threadId),
4935
+ startupAuthProfileId: startupAuthProfileId ?? null,
4936
+ bundleMcpDiagnosticCount: bundleMcpThreadConfig.diagnostics.length,
4937
+ nativeToolSurfaceEnabled
4938
+ });
4867
4939
  let yieldDetected = false;
4868
4940
  const tools = await buildDynamicTools({
4869
4941
  params,
@@ -4875,6 +4947,7 @@ async function runCodexAppServerAttempt(params, options = {}) {
4875
4947
  runAbortController,
4876
4948
  sessionAgentId,
4877
4949
  pluginConfig,
4950
+ profilerEnabled,
4878
4951
  onYieldDetected: () => {
4879
4952
  yieldDetected = true;
4880
4953
  }
@@ -4891,6 +4964,7 @@ async function runCodexAppServerAttempt(params, options = {}) {
4891
4964
  runAbortController,
4892
4965
  sessionAgentId,
4893
4966
  pluginConfig,
4967
+ profilerEnabled,
4894
4968
  forceHeartbeatTool: true,
4895
4969
  ignoreRuntimePlan: true,
4896
4970
  onYieldDetected: () => {
@@ -5818,7 +5892,9 @@ async function runCodexAppServerAttempt(params, options = {}) {
5818
5892
  ...turnId ? { turnId } : {}
5819
5893
  });
5820
5894
  embeddedAgentLog.debug("codex app-server raw notification received", correlation);
5821
- if (notification.method === "turn/completed" && correlation.matchesActiveTurn === false) embeddedAgentLog.warn("codex app-server turn/completed did not match active turn", correlation);
5895
+ if (notification.method === "turn/completed" && correlation.matchesActiveTurn === false) if (correlation.matchesActiveThread) embeddedAgentLog.warn("codex app-server turn/completed did not match active turn", correlation);
5896
+ else embeddedAgentLog.debug("codex app-server turn/completed ignored for other subscribed thread", correlation);
5897
+ if (isCodexNotificationOutsideActiveRun(correlation)) return Promise.resolve();
5822
5898
  if (!projector || !turnId) {
5823
5899
  userInputBridge?.handleNotification(notification);
5824
5900
  pendingNotifications.push(notification);
@@ -6375,16 +6451,10 @@ async function runCodexAppServerAttempt(params, options = {}) {
6375
6451
  turnTerminalIdleWatchArmed = true;
6376
6452
  touchTurnCompletionActivity("turn:start", { attemptProgress: true });
6377
6453
  const abortListener = () => {
6378
- const shouldRetireClient = timedOut;
6379
6454
  interruptCodexTurnBestEffort(client, {
6380
6455
  threadId: thread.threadId,
6381
6456
  turnId: activeTurnId,
6382
- timeoutMs: shouldRetireClient ? CODEX_APP_SERVER_INTERRUPT_TIMEOUT_MS : void 0
6383
- });
6384
- if (shouldRetireClient) retireCodexAppServerClientAfterTimedOutTurn(client, {
6385
- threadId: thread.threadId,
6386
- turnId: activeTurnId,
6387
- reason: String(runAbortController.signal.reason ?? "timeout")
6457
+ timeoutMs: timedOut ? CODEX_APP_SERVER_INTERRUPT_TIMEOUT_MS : void 0
6388
6458
  });
6389
6459
  resolveCompletion?.();
6390
6460
  };
@@ -6799,7 +6869,10 @@ function createCodexNativeHookRelay(params) {
6799
6869
  turnStartTimeoutMs: params.turnStartTimeoutMs
6800
6870
  }),
6801
6871
  signal: params.signal,
6802
- command: { timeoutMs: params.options?.gatewayTimeoutMs }
6872
+ command: {
6873
+ nice: 10,
6874
+ timeoutMs: params.options?.gatewayTimeoutMs
6875
+ }
6803
6876
  });
6804
6877
  }
6805
6878
  function resolveCodexNativeHookRelayEvents(params) {
@@ -6867,19 +6940,6 @@ async function unsubscribeCodexThreadBestEffort(client, params) {
6867
6940
  });
6868
6941
  }
6869
6942
  }
6870
- function retireCodexAppServerClientAfterTimedOutTurn(client, params) {
6871
- const clearedSharedClient = clearSharedCodexAppServerClientIfCurrent(client);
6872
- if (!clearedSharedClient) {
6873
- const close = client.close;
6874
- if (typeof close === "function") close.call(client);
6875
- }
6876
- embeddedAgentLog.warn("codex app-server client retired after timed-out turn", {
6877
- threadId: params.threadId,
6878
- turnId: params.turnId,
6879
- reason: params.reason,
6880
- clearedSharedClient
6881
- });
6882
- }
6883
6943
  function resolveOpenClawCodingToolsSessionKeys(params, sandboxSessionKey) {
6884
6944
  return {
6885
6945
  sessionKey: sandboxSessionKey,
@@ -6895,12 +6955,54 @@ function resolveCodexAppServerHookChannelId(params, sandboxSessionKey) {
6895
6955
  messageTo: params.messageTo
6896
6956
  }).channelId;
6897
6957
  }
6958
+ const CODEX_DYNAMIC_TOOL_BUILD_WARN_TOTAL_MS = 1e3;
6959
+ const CODEX_DYNAMIC_TOOL_BUILD_WARN_STAGE_MS = 500;
6960
+ function createCodexDynamicToolBuildStageTracker(options = {}) {
6961
+ if (!options.enabled) return {
6962
+ mark() {},
6963
+ snapshot() {
6964
+ return {
6965
+ totalMs: 0,
6966
+ stages: []
6967
+ };
6968
+ }
6969
+ };
6970
+ const startedAt = Date.now();
6971
+ let previousAt = startedAt;
6972
+ const stages = [];
6973
+ const toMs = (value) => Math.max(0, Math.round(value));
6974
+ return {
6975
+ mark(name) {
6976
+ const currentAt = Date.now();
6977
+ stages.push({
6978
+ name,
6979
+ durationMs: toMs(currentAt - previousAt),
6980
+ elapsedMs: toMs(currentAt - startedAt)
6981
+ });
6982
+ previousAt = currentAt;
6983
+ },
6984
+ snapshot() {
6985
+ return {
6986
+ totalMs: toMs(Date.now() - startedAt),
6987
+ stages: stages.slice()
6988
+ };
6989
+ }
6990
+ };
6991
+ }
6992
+ function shouldWarnCodexDynamicToolBuildStageSummary(summary) {
6993
+ return summary.totalMs >= CODEX_DYNAMIC_TOOL_BUILD_WARN_TOTAL_MS || summary.stages.some((stage) => stage.durationMs >= CODEX_DYNAMIC_TOOL_BUILD_WARN_STAGE_MS);
6994
+ }
6995
+ function formatCodexDynamicToolBuildStageSummary(summary) {
6996
+ return summary.stages.length > 0 ? summary.stages.map((stage) => `${stage.name}:${stage.durationMs}ms@${stage.elapsedMs}ms`).join(",") : "none";
6997
+ }
6898
6998
  async function buildDynamicTools(input) {
6899
6999
  const { params } = input;
6900
7000
  if (params.disableTools || !supportsModelTools(params.model)) return [];
7001
+ const toolBuildStages = createCodexDynamicToolBuildStageTracker({ enabled: input.profilerEnabled });
6901
7002
  const modelHasVision = params.model.input?.includes("image") ?? false;
6902
7003
  const agentDir = params.agentDir ?? resolveAgentDir$1(params.config ?? {}, input.sessionAgentId);
6903
7004
  const createOpenClawCodingTools = (await import("openclaw/plugin-sdk/agent-harness")).createOpenClawCodingTools;
7005
+ toolBuildStages.mark("load-agent-harness-tools");
6904
7006
  const sessionKeys = resolveOpenClawCodingToolsSessionKeys(params, input.sandboxSessionKey);
6905
7007
  const allTools = createOpenClawCodingTools({
6906
7008
  agentId: input.sessionAgentId,
@@ -6965,13 +7067,22 @@ async function buildDynamicTools(input) {
6965
7067
  message
6966
7068
  }
6967
7069
  });
7070
+ },
7071
+ recordToolPrepStage: (name) => {
7072
+ toolBuildStages.mark(name);
6968
7073
  }
6969
7074
  });
6970
- const filteredTools = filterCodexDynamicToolsForAllowlist(filterToolsForVisionInputs(addNodeShellDynamicToolsIfNeeded(addSandboxShellDynamicToolsIfAvailable(isCodexMemoryFlushRun(params) ? filterCodexMemoryFlushDynamicTools(allTools) : filterCodexDynamicTools(allTools, input.pluginConfig), allTools, input), allTools, input), {
7075
+ toolBuildStages.mark("create-openclaw-coding-tools");
7076
+ const codexFilteredTools = addNodeShellDynamicToolsIfNeeded(addSandboxShellDynamicToolsIfAvailable(isCodexMemoryFlushRun(params) ? filterCodexMemoryFlushDynamicTools(allTools) : filterCodexDynamicTools(allTools, input.pluginConfig), allTools, input), allTools, input);
7077
+ toolBuildStages.mark("codex-filtering");
7078
+ const visionFilteredTools = filterToolsForVisionInputs(codexFilteredTools, {
6971
7079
  modelHasVision,
6972
7080
  hasInboundImages: (params.images?.length ?? 0) > 0
6973
- }), includeForcedCodexDynamicToolAllow(params.toolsAllow, params));
6974
- return normalizeAgentRuntimeTools({
7081
+ });
7082
+ toolBuildStages.mark("vision-filtering");
7083
+ const filteredTools = filterCodexDynamicToolsForAllowlist(visionFilteredTools, includeForcedCodexDynamicToolAllow(params.toolsAllow, params));
7084
+ toolBuildStages.mark("allowlist-filter");
7085
+ const normalizedTools = normalizeAgentRuntimeTools({
6975
7086
  runtimePlan: input.ignoreRuntimePlan ? void 0 : params.runtimePlan,
6976
7087
  tools: filteredTools,
6977
7088
  provider: params.provider,
@@ -6982,6 +7093,27 @@ async function buildDynamicTools(input) {
6982
7093
  modelApi: params.model.api,
6983
7094
  model: params.model
6984
7095
  });
7096
+ toolBuildStages.mark("runtime-normalization");
7097
+ const summary = toolBuildStages.snapshot();
7098
+ if (shouldWarnCodexDynamicToolBuildStageSummary(summary)) {
7099
+ const phase = input.forceHeartbeatTool ? "registered-tools" : "runtime-tools";
7100
+ embeddedAgentLog.warn(`codex app-server dynamic tool build timings runId=${params.runId} sessionId=${params.sessionId} phase=${phase} totalMs=${summary.totalMs} stages=${formatCodexDynamicToolBuildStageSummary(summary)}`, {
7101
+ runId: params.runId,
7102
+ sessionId: params.sessionId,
7103
+ phase,
7104
+ totalMs: summary.totalMs,
7105
+ stages: summary.stages,
7106
+ allToolCount: allTools.length,
7107
+ codexFilteredToolCount: codexFilteredTools.length,
7108
+ visionFilteredToolCount: visionFilteredTools.length,
7109
+ filteredToolCount: filteredTools.length,
7110
+ normalizedToolCount: normalizedTools.length,
7111
+ forceHeartbeatTool: input.forceHeartbeatTool === true,
7112
+ ignoreRuntimePlan: input.ignoreRuntimePlan === true,
7113
+ nativeToolSurfaceEnabled: input.nativeToolSurfaceEnabled === true
7114
+ });
7115
+ }
7116
+ return normalizedTools;
6985
7117
  }
6986
7118
  function includeForcedCodexDynamicToolAllow(toolsAllow, params) {
6987
7119
  if (toolsAllow === void 0 || hasWildcardCodexToolsAllow(toolsAllow)) return toolsAllow;
@@ -7151,11 +7283,33 @@ function shouldProjectMirroredHistoryForCodexStart(params) {
7151
7283
  if (!params.historyMessages.some((message) => message.role === "user")) return false;
7152
7284
  if (params.forceProject) return true;
7153
7285
  if (!params.startupBinding?.threadId) return true;
7286
+ if (hasUserVisibleHistoryAfterCodexBinding({
7287
+ startupBinding: params.startupBinding,
7288
+ historyMessages: params.historyMessages
7289
+ })) return true;
7154
7290
  return !areCodexDynamicToolFingerprintsCompatible({
7155
7291
  previous: params.startupBinding.dynamicToolsFingerprint,
7156
7292
  next: params.dynamicToolsFingerprint
7157
7293
  });
7158
7294
  }
7295
+ function hasUserVisibleHistoryAfterCodexBinding(params) {
7296
+ const bindingUpdatedAt = Date.parse(params.startupBinding.updatedAt);
7297
+ if (!Number.isFinite(bindingUpdatedAt)) return false;
7298
+ return params.historyMessages.some((message) => {
7299
+ if (message.role !== "user" && message.role !== "assistant") return false;
7300
+ if (isCodexAppServerMirroredTranscriptMessage(message)) return false;
7301
+ const timestamp = typeof message.timestamp === "number" ? message.timestamp : typeof message.timestamp === "string" ? Date.parse(message.timestamp) : NaN;
7302
+ return Number.isFinite(timestamp) && timestamp > bindingUpdatedAt;
7303
+ });
7304
+ }
7305
+ function isCodexAppServerMirroredTranscriptMessage(message) {
7306
+ const record = message;
7307
+ const idempotencyKey = record.idempotencyKey;
7308
+ if (typeof idempotencyKey === "string" && idempotencyKey.startsWith("codex-app-server:")) return true;
7309
+ const meta = record["__openclaw"];
7310
+ if (!meta || typeof meta !== "object" || Array.isArray(meta)) return false;
7311
+ return typeof meta.mirrorIdentity === "string";
7312
+ }
7159
7313
  function readContextEngineThreadBootstrapProjection(projection) {
7160
7314
  if (projection?.mode !== "thread_bootstrap") return;
7161
7315
  const epoch = projection.epoch?.trim();
@@ -7473,6 +7627,11 @@ function readRawAssistantTextPreview(item) {
7473
7627
  function isTurnNotification(value, threadId, turnId) {
7474
7628
  return isCodexNotificationForTurn(value, threadId, turnId);
7475
7629
  }
7630
+ function isCodexNotificationOutsideActiveRun(correlation) {
7631
+ if (!Boolean(correlation.threadId || correlation.nestedTurnThreadId)) return false;
7632
+ if (!correlation.matchesActiveThread) return true;
7633
+ return Boolean(correlation.turnId || correlation.nestedTurnId) && correlation.matchesActiveTurn === false;
7634
+ }
7476
7635
  function isCurrentThreadTurnRequestParams(value, threadId, turnId) {
7477
7636
  if (!isJsonObject(value)) return false;
7478
7637
  return readString(value, "threadId") === threadId && readString(value, "turnId") === turnId;
@@ -1,5 +1,5 @@
1
1
  import { t as __exportAll } from "./rolldown-runtime-8H4AJuhK.js";
2
- import { s as normalizeCodexServiceTier } from "./config-D6TUuyo2.js";
2
+ import { s as normalizeCodexServiceTier } from "./config-0-UN67Qg.js";
3
3
  import { embeddedAgentLog } from "openclaw/plugin-sdk/agent-harness-runtime";
4
4
  import fs from "node:fs/promises";
5
5
  import { ensureAuthProfileStore, resolveDefaultAgentDir, resolveProviderIdForAuth } from "openclaw/plugin-sdk/agent-runtime";