@openclaw/codex 2026.8.1 → 2026.8.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (54) hide show
  1. package/dist/api.js +2 -2
  2. package/dist/{attempt-client-cleanup-CVPvp9dL.js → attempt-client-cleanup-CpVfwctT.js} +1 -1
  3. package/dist/{binding-connection-CCQFs8lf.js → binding-connection-CF7BmrDk.js} +2 -2
  4. package/dist/{bounded-turn-rq5tiSXk.js → bounded-turn-DRC3hcjm.js} +10 -9
  5. package/dist/{capabilities-CGm_94eL.js → capabilities-D6m_TdVy.js} +1 -1
  6. package/dist/cli-metadata.js +1 -1
  7. package/dist/{command-formatters-C54Yg3eA.js → command-formatters--UToCokS.js} +4 -3
  8. package/dist/{command-handlers-BvOAHTrA.js → command-handlers-CLFx2Ypa.js} +41 -33
  9. package/dist/{compact-Hd7SAc0N.js → compact-5xqW1oCh.js} +13 -11
  10. package/dist/{config-Cxw3Cl3k.js → config-CcYL77O6.js} +6 -4
  11. package/dist/{conversation-binding-data-CW2GuupV.js → conversation-binding-data-BiodpIzq.js} +2 -1
  12. package/dist/doctor-contract-api.js +8 -4
  13. package/dist/{dynamic-tools-BFoUcRdx.js → dynamic-tools-BmeXjwNZ.js} +103 -106
  14. package/dist/{effective-mcp-catalog-BTJHnDSx.js → effective-mcp-catalog-XXQKgK1U.js} +2 -2
  15. package/dist/{event-projector-usage-D3PHFFXh.js → event-projector-usage-B2r5vhWH.js} +7 -12
  16. package/dist/{harness-DVfUQBlQ.js → harness-BgeB7LnD.js} +13 -13
  17. package/dist/harness.js +1 -1
  18. package/dist/index.js +56 -37
  19. package/dist/{isolated-completion-Cbbx_5Ed.js → isolated-completion-CxTus3vZ.js} +3 -3
  20. package/dist/media-understanding-provider.js +1 -1
  21. package/dist/{model-catalog-o6Cgjoss.js → model-catalog-DULBcniB.js} +5 -5
  22. package/dist/{models-DgFWSuxA.js → models-DaWfETQk.js} +4 -3
  23. package/dist/{native-subagent-monitor-CwFyoylz.js → native-subagent-monitor-vXYUZH37.js} +24 -104
  24. package/dist/{node-exec-server.runtime-DXrqpw1c.js → node-exec-server.runtime-DirKVZ5h.js} +2 -2
  25. package/dist/{plugin-approval-roundtrip-D80UZiJ_.js → plugin-approval-roundtrip-CCWQGlAI.js} +2 -1
  26. package/dist/{plugin-marketplace-discovery-mdmScYOj.js → plugin-marketplace-discovery-BXjIFEiw.js} +14 -13
  27. package/dist/{plugin-metadata-cache-CulOABwu.js → plugin-metadata-cache-DQQm4gWT.js} +5 -5
  28. package/dist/{rate-limits-hFtzt2Up.js → rate-limits-BqHEHXQJ.js} +3 -2
  29. package/dist/{request-CCm4LaED.js → request-BWxweEdK.js} +2 -2
  30. package/dist/{run-attempt-BwNQDH2u.js → run-attempt-BVLE4Gbi.js} +133 -182
  31. package/dist/{runtime-artifact-DeBvleJw.js → runtime-artifact-D9pYp4zL.js} +3 -3
  32. package/dist/{session-binding-q2WSTVmC.js → session-binding-D0zinCP1.js} +1 -1
  33. package/dist/{session-catalog-C2Tae4rI.js → session-catalog-eMhVm0Ql.js} +232 -204
  34. package/dist/{session-catalog-home-id-DAKUrm3C.js → session-catalog-home-id-Dt2GiG5o.js} +3 -3
  35. package/dist/{session-cli-BuDjm5Ou.js → session-cli-B2lyjJA0.js} +1 -1
  36. package/dist/session-history-C5J1AKzG.js +87 -0
  37. package/dist/{session-permission-policy-gLm40Vtq.js → session-permission-policy-ScnAyG90.js} +1 -1
  38. package/dist/{session-retirement-CdkI0bvb.js → session-retirement-CtUtUTr9.js} +4 -4
  39. package/dist/{session-upstream-marker-Bcy33kam.js → session-upstream-marker-gqrYIRHk.js} +1 -1
  40. package/dist/settled-turn-context-Bk3IUwod.js +290 -0
  41. package/dist/settled-turn-finalizer-BXLN9PfJ.js +104 -0
  42. package/dist/{shared-client-kNkljY-R.js → shared-client-B1tT5U6r.js} +33 -35
  43. package/dist/{side-question-GwD73tX6.js → side-question-CZ-mCw-t.js} +18 -15
  44. package/dist/{thread-lifecycle-Ss-uwnC4.js → thread-lifecycle-CGGKP720.js} +206 -163
  45. package/dist/{thread-ownership-CeYBqg_4.js → thread-ownership-RkaoZCmQ.js} +2 -2
  46. package/dist/{thread-resume-DF54hagX.js → thread-resume-BFt1-ZDa.js} +7 -6
  47. package/dist/{transcript-mirror-CkEQIna-.js → transcript-mirror-1ep4XjzF.js} +14 -7
  48. package/dist/{transport-stdio-C7-s9TLG.js → transport-stdio-NT_Dpd9V.js} +40 -24
  49. package/dist/{upstream-prompt-provenance-CFmsKwr9.js → upstream-prompt-provenance-LphB8slG.js} +8 -4
  50. package/dist/{upstream-session-fork-BACGlOFa.js → upstream-session-fork-Dc8BFExw.js} +13 -19
  51. package/dist/{usage-C2l8Mils.js → usage-DUhd58gI.js} +3 -3
  52. package/dist/{web-search-provider.runtime-B2XgRdFv.js → web-search-provider.runtime-BEmlE7ov.js} +3 -3
  53. package/package.json +5 -5
  54. package/dist/settled-turn-finalizer-B8JJcxCi.js +0 -329
@@ -1,12 +1,12 @@
1
- import { E as resolveCodexPluginsPolicy, F as resolveCodexAppServerLocalHomeDir, M as CODEX_PLUGINS_WORKSPACE_MARKETPLACE_NAME, P as resolveCodexAppServerHomeDir, f as assertCodexModelBackedReviewerEffectiveConfig, j as CODEX_PLUGINS_MARKETPLACE_NAME, n as codexSandboxPolicyForTurn } from "./config-Cxw3Cl3k.js";
2
- import { $ as CodexAppServerRpcError, D as CodexThreadStartRequestError, E as CodexThreadBindingConflictError, H as getCodexAppServerClientInstanceId, Ht as isJsonObject, J as isCodexAppServerOverloadError, Q as resolveCodexAppServerClientInstanceId, St as releaseCodexAppServerLiveThread, T as CodexRestrictedToolSurfaceAttestationError, Vt as flattenCodexDynamicToolFunctions, _ as retainSharedCodexAppServerClientByInstanceId, bt as isCodexAppServerLiveThreadClaimed, dt as resolveCodexToolAbortTerminalReason, gt as consumeCodexAppServerLiveThread, n as captureExclusiveSharedCodexAppServerClient, w as CodexAdoptedThreadActiveError, wt as unsubscribeCodexAppServerLiveThread } from "./shared-client-kNkljY-R.js";
3
- import { a as hashCodexAppServerBindingFingerprint, c as reclaimCurrentCodexSessionGeneration, d as sessionBindingIdentity, i as createCodexSessionGenerationSupersededError, n as assertCodexBindingMayBeReplaced, o as isCodexAppServerNativeAuthProfile, s as normalizeCodexAppServerBindingModelProvider } from "./session-binding-q2WSTVmC.js";
1
+ import { E as resolveCodexPluginsPolicy, F as resolveCodexAppServerLocalHomeDir, M as CODEX_PLUGINS_WORKSPACE_MARKETPLACE_NAME, P as resolveCodexAppServerHomeDir, f as assertCodexModelBackedReviewerEffectiveConfig, j as CODEX_PLUGINS_MARKETPLACE_NAME, n as codexSandboxPolicyForTurn } from "./config-CcYL77O6.js";
2
+ import { $ as CodexAppServerRpcError, D as CodexThreadStartRequestError, E as CodexThreadBindingConflictError, H as getCodexAppServerClientInstanceId, Ht as isJsonObject, J as isCodexAppServerOverloadError, Q as resolveCodexAppServerClientInstanceId, St as releaseCodexAppServerLiveThread, T as CodexRestrictedToolSurfaceAttestationError, Vt as flattenCodexDynamicToolFunctions, _ as retainSharedCodexAppServerClientByInstanceId, bt as isCodexAppServerLiveThreadClaimed, dt as resolveCodexToolAbortTerminalReason, gt as consumeCodexAppServerLiveThread, n as captureExclusiveSharedCodexAppServerClient, w as CodexAdoptedThreadActiveError, wt as unsubscribeCodexAppServerLiveThread, yt as isCodexAppServerClientRuntimeLive } from "./shared-client-B1tT5U6r.js";
3
+ import { a as hashCodexAppServerBindingFingerprint, c as reclaimCurrentCodexSessionGeneration, d as sessionBindingIdentity, i as createCodexSessionGenerationSupersededError, n as assertCodexBindingMayBeReplaced, o as isCodexAppServerNativeAuthProfile, s as normalizeCodexAppServerBindingModelProvider } from "./session-binding-D0zinCP1.js";
4
4
  import { a as assertCodexThreadForkResponse, r as assertCodexThreadAcceptsDirectInput, s as assertCodexThreadStartResponse, t as CodexThreadDirectInputError } from "./protocol-validators-Bg5rpNxk.js";
5
- import { a as closeCodexStartupClientBestEffort, c as isCodexAppServerUnsafeSubscriptionError, f as unsubscribeCodexThreadBestEffort, n as CODEX_APP_SERVER_UNSUBSCRIBE_TIMEOUT_MS, r as CodexAppServerUnsafeSubscriptionError } from "./attempt-client-cleanup-CVPvp9dL.js";
6
- import { c as serializeCodexAppInventoryError, n as buildCodexAppServerConnectionFingerprint, s as defaultCodexAppInventoryCache, t as resumeCodexAppServerThread } from "./thread-resume-DF54hagX.js";
7
- import { c as withExclusiveCodexAppServerThread, l as isIncognitoSessionKey } from "./thread-ownership-CeYBqg_4.js";
8
- import { i as readCodexSessionMeta, n as codexCatalogHomeId } from "./session-catalog-home-id-DAKUrm3C.js";
9
- import { d as projectBoundedCodexThreadHistory } from "./transcript-mirror-CkEQIna-.js";
5
+ import { a as closeCodexStartupClientBestEffort, c as isCodexAppServerUnsafeSubscriptionError, f as unsubscribeCodexThreadBestEffort, n as CODEX_APP_SERVER_UNSUBSCRIBE_TIMEOUT_MS, r as CodexAppServerUnsafeSubscriptionError } from "./attempt-client-cleanup-CpVfwctT.js";
6
+ import { c as serializeCodexAppInventoryError, n as buildCodexAppServerConnectionFingerprint, s as defaultCodexAppInventoryCache, t as resumeCodexAppServerThread } from "./thread-resume-BFt1-ZDa.js";
7
+ import { c as withExclusiveCodexAppServerThread, l as isIncognitoSessionKey } from "./thread-ownership-RkaoZCmQ.js";
8
+ import { i as readCodexSessionMeta, n as codexCatalogHomeId } from "./session-catalog-home-id-Dt2GiG5o.js";
9
+ import { f as projectBoundedCodexThreadHistory } from "./transcript-mirror-1ep4XjzF.js";
10
10
  import { r as sanitizeInlineImageDataUrl, t as invalidInlineImageText } from "./image-payload-sanitizer-CnfoUPCE.js";
11
11
  import { asOptionalRecord, isRecord, normalizeOptionalString } from "openclaw/plugin-sdk/string-coerce-runtime";
12
12
  import fs from "node:fs/promises";
@@ -1198,6 +1198,7 @@ function renderMessagesForCodexContext(messages, options) {
1198
1198
  }).filter((value) => Boolean(value)).join("\n\n");
1199
1199
  }
1200
1200
  function renderMessageBody(message, options) {
1201
+ if (message.role === "compactionSummary" || message.role === "branchSummary") return truncateText(message.summary.trim(), options.maxTextPartChars);
1201
1202
  if (!hasMessageContent(message)) return "";
1202
1203
  if (typeof message.content === "string") return truncateText(message.content.trim(), options.maxTextPartChars);
1203
1204
  if (!Array.isArray(message.content)) return "[non-text content omitted]";
@@ -1666,7 +1667,8 @@ async function collectPersonalSkillRealPaths(homes, codexHome) {
1666
1667
  }
1667
1668
  const configuredCodexHome = codexHome?.trim() || process.env.CODEX_HOME?.trim();
1668
1669
  if (configuredCodexHome) {
1669
- const stateOwned = isPathInside(realStateDir, await canonicalizeExistingPath(configuredCodexHome));
1670
+ const realCodexHome = await canonicalizeExistingPath(configuredCodexHome);
1671
+ const stateOwned = isPathInside(realStateDir, realCodexHome);
1670
1672
  roots.push({
1671
1673
  dir: path.join(configuredCodexHome, "skills"),
1672
1674
  onlyEscapedStateTargets: stateOwned
@@ -1729,12 +1731,14 @@ async function collectPersonalSkillRealPaths(homes, codexHome) {
1729
1731
  try {
1730
1732
  const stat = await fs.stat(entryPath);
1731
1733
  if (entry.name === "SKILL.md" && stat.isFile()) await recordSkillFile(entryPath, current.onlyEscapedStateTargets);
1732
- else if (stat.isDirectory()) if (current.depth < MAX_PERSONAL_SKILL_DEPTH) queue.push({
1733
- dir: entryPath,
1734
- depth: current.depth + 1,
1735
- onlyEscapedStateTargets: current.onlyEscapedStateTargets
1736
- });
1737
- else complete = false;
1734
+ else if (stat.isDirectory()) {
1735
+ if (current.depth < MAX_PERSONAL_SKILL_DEPTH) queue.push({
1736
+ dir: entryPath,
1737
+ depth: current.depth + 1,
1738
+ onlyEscapedStateTargets: current.onlyEscapedStateTargets
1739
+ });
1740
+ else complete = false;
1741
+ }
1738
1742
  } catch (error) {
1739
1743
  if (!isMissingPathError(error)) complete = false;
1740
1744
  }
@@ -1852,6 +1856,10 @@ function managedThreadStoreKey(sourceHomeId, threadId) {
1852
1856
  /** Durable ownership index for Codex threads created by OpenClaw. */
1853
1857
  function createCodexManagedThreadStore(state) {
1854
1858
  return {
1859
+ async has(sourceHomeId, threadId) {
1860
+ const parsed = managedThreadSchema.safeParse(state.lookup(managedThreadStoreKey(sourceHomeId, threadId)));
1861
+ return parsed.success && parsed.data.sourceHomeId === sourceHomeId && parsed.data.threadId === threadId;
1862
+ },
1855
1863
  async mark(params) {
1856
1864
  try {
1857
1865
  const value = managedThreadSchema.parse({
@@ -2107,7 +2115,7 @@ function resolveReasoningEffort(thinkLevel, modelId, supportedReasoningEfforts)
2107
2115
  }
2108
2116
  //#endregion
2109
2117
  //#region extensions/codex/src/app-server/project-doc-thread-config.ts
2110
- const CODEX_NATIVE_PROJECT_DOC_MAX_BYTES = 128 * 1024;
2118
+ const CODEX_NATIVE_PROJECT_DOC_MAX_BYTES = 131072;
2111
2119
  function buildCodexProjectDocThreadConfig(config) {
2112
2120
  const defaults = { project_doc_max_bytes: CODEX_NATIVE_PROJECT_DOC_MAX_BYTES };
2113
2121
  return mergeCodexThreadConfigs(defaults, config) ?? defaults;
@@ -2634,6 +2642,7 @@ async function resumeExistingCodexThread(params, context) {
2634
2642
  const { binding: resumeBinding, bindingIdentity, startModelSelection, startModelProvider, userMcpServersConfigPatch, dynamicToolsFingerprint, dynamicToolsContainDeferred, webSearchThreadConfigFingerprint, nativeSkillIsolationFingerprint, userMcpServersFingerprint, ringZeroConfigFingerprint, ringZeroClientInstanceId, networkProxyConfigFingerprint, contextEngineBinding, environmentSelectionFingerprint, hostSystemAgentActive, ringZeroActive, restrictedToolSurface, restrictedToolSurfaceInheritedMcpServerNames, nativeSkillIsolation, lifecycleTiming, normalizeBindingModelProvider, throwIfAborted, clearCurrentBinding } = context;
2635
2643
  let resumeReservation;
2636
2644
  let resumeResponseAccepted = false;
2645
+ let checkingLoadedPluginThreadConfig = false;
2637
2646
  const abandonClient = params.abandonClient ?? (() => closeCodexStartupClientBestEffort(params.client));
2638
2647
  try {
2639
2648
  const authProfileId = resumeBinding.connectionScope === "supervision" ? void 0 : params.params.authProfileId ?? resumeBinding.authProfileId;
@@ -2644,7 +2653,8 @@ async function resumeExistingCodexThread(params, context) {
2644
2653
  configPatch: params.finalConfigPatch,
2645
2654
  nativeHookRelayGeneration: params.nativeHookRelayGeneration
2646
2655
  };
2647
- const pluginAppsConfigPatch = context.prebuiltPluginThreadConfig?.configPatch ?? (params.pluginThreadConfig?.enabled && resumeBinding.pluginAppPolicyContext ? buildCodexPluginAppsConfigPatchFromPolicyContext(resumeBinding.pluginAppPolicyContext) : void 0);
2656
+ const pluginThreadConfig = context.prebuiltPluginThreadConfig ?? (params.pluginThreadConfig?.requiresCurrentPolicyCheck ? await lifecycleTiming.measure("plugin-config-build", () => params.pluginThreadConfig?.build()) : void 0);
2657
+ const pluginAppsConfigPatch = pluginThreadConfig?.configPatch ?? (params.pluginThreadConfig?.enabled && resumeBinding.pluginAppPolicyContext ? buildCodexPluginAppsConfigPatchFromPolicyContext(resumeBinding.pluginAppPolicyContext) : void 0);
2648
2658
  const resumeConfig = applyCodexNativeSkillIsolation(mergeCodexThreadConfigs(params.config, userMcpServersConfigPatch, pluginAppsConfigPatch, finalConfigPatch.configPatch), nativeSkillIsolation);
2649
2659
  const resumeParams = lifecycleTiming.measureSync("thread-resume-params", () => buildThreadResumeParams(params.params, {
2650
2660
  threadId: resumeBinding.threadId,
@@ -2680,12 +2690,19 @@ async function resumeExistingCodexThread(params, context) {
2680
2690
  resumeResponseAccepted = true;
2681
2691
  assertCodexThreadAcceptsDirectInput(response.thread);
2682
2692
  context.assertResumeConfiguration?.();
2683
- if (resumeBinding.pendingResumeConfiguration) await attestCodexPluginThreadApps({
2693
+ checkingLoadedPluginThreadConfig = true;
2694
+ const loadedPluginThreadConfig = await context.buildLoadedPluginThreadConfig?.(resumeBinding);
2695
+ if (loadedPluginThreadConfig && loadedPluginThreadConfig.fingerprint !== (pluginThreadConfig?.fingerprint ?? resumeBinding.pluginAppsFingerprint)) {
2696
+ checkingLoadedPluginThreadConfig = false;
2697
+ throw new Error("Codex thread app policy changed; a fresh thread configuration is required");
2698
+ }
2699
+ await attestCodexPluginThreadApps({
2684
2700
  client: params.client,
2685
2701
  threadId: response.thread.id,
2686
- appIds: context.prebuiltPluginThreadConfig?.provisionalAppIds ?? [],
2702
+ appIds: loadedPluginThreadConfig?.provisionalAppIds ?? pluginThreadConfig?.provisionalAppIds ?? [],
2687
2703
  signal: params.signal
2688
2704
  });
2705
+ checkingLoadedPluginThreadConfig = false;
2689
2706
  if (ringZeroActive || isMessageOnlyCodexSourceReply(params.params) || params.params.pluginHarnessToolPolicyRestricted === true) try {
2690
2707
  await lifecycleTiming.measure("restricted-tool-surface-mcp-attestation", () => attestCodexRestrictedToolSurfaceMcpServersDisabled(params.client, response.thread.id, resumeParams.config, params.signal));
2691
2708
  } catch (error) {
@@ -2719,9 +2736,9 @@ async function resumeExistingCodexThread(params, context) {
2719
2736
  networkProxyConfigFingerprint,
2720
2737
  nativeHookRelayGeneration: finalConfigPatch.nativeHookRelayGeneration ?? resumeBinding.nativeHookRelayGeneration,
2721
2738
  appServerRuntimeFingerprint: resumeBinding.connectionScope === "supervision" ? buildCodexAppServerConnectionFingerprint(params.appServer, params.params.agentDir) : params.appServerRuntimeFingerprint,
2722
- pluginAppsFingerprint: context.prebuiltPluginThreadConfig?.fingerprint ?? resumeBinding.pluginAppsFingerprint,
2723
- pluginAppsInputFingerprint: context.prebuiltPluginThreadConfig?.inputFingerprint ?? resumeBinding.pluginAppsInputFingerprint,
2724
- pluginAppPolicyContext: context.prebuiltPluginThreadConfig?.policyContext ?? resumeBinding.pluginAppPolicyContext,
2739
+ pluginAppsFingerprint: pluginThreadConfig?.fingerprint ?? resumeBinding.pluginAppsFingerprint,
2740
+ pluginAppsInputFingerprint: pluginThreadConfig?.inputFingerprint ?? resumeBinding.pluginAppsInputFingerprint,
2741
+ pluginAppPolicyContext: pluginThreadConfig?.policyContext ?? resumeBinding.pluginAppPolicyContext,
2725
2742
  contextEngine: contextEngineBinding,
2726
2743
  environmentSelectionFingerprint
2727
2744
  };
@@ -2785,7 +2802,7 @@ async function resumeExistingCodexThread(params, context) {
2785
2802
  throw new CodexAppServerUnsafeSubscriptionError("Codex thread/resume subscription cleanup failed", { cause: error });
2786
2803
  }
2787
2804
  }
2788
- if (resumeBinding.pendingResumeConfiguration || error instanceof CodexThreadDirectInputError || params.signal?.aborted) throw error;
2805
+ if (checkingLoadedPluginThreadConfig || resumeBinding.pendingResumeConfiguration || error instanceof CodexThreadDirectInputError || params.signal?.aborted) throw error;
2789
2806
  embeddedAgentLog.warn("codex app-server thread resume failed; starting a new thread", { error });
2790
2807
  await clearCurrentBinding("rotating a stale thread binding");
2791
2808
  }
@@ -2818,14 +2835,15 @@ async function startFreshCodexThread(params, context) {
2818
2835
  disableLoginShell: params.disableLoginShell
2819
2836
  }));
2820
2837
  const requestModelProvider = typeof startParams.modelProvider === "string" && startParams.modelProvider.trim() ? startParams.modelProvider : void 0;
2821
- const response = assertCodexThreadStartResponse(await lifecycleTiming.measure("thread-start-request", async () => {
2838
+ const threadStartResponse = await lifecycleTiming.measure("thread-start-request", async () => {
2822
2839
  try {
2823
2840
  return await params.client.request("thread/start", startParams, { signal: params.signal });
2824
2841
  } catch (error) {
2825
2842
  if (error instanceof CodexAppServerRpcError) throw new CodexThreadStartRequestError(error);
2826
2843
  throw error;
2827
2844
  }
2828
- }));
2845
+ });
2846
+ const response = assertCodexThreadStartResponse(threadStartResponse);
2829
2847
  const provisionalAppIds = pluginThreadConfig?.provisionalAppIds;
2830
2848
  if (provisionalAppIds?.length) try {
2831
2849
  await lifecycleTiming.measure("plugin-app-attestation", () => attestCodexPluginThreadApps({
@@ -3010,52 +3028,67 @@ async function releaseCodexRetainedLiveThread(options) {
3010
3028
  }
3011
3029
  /** Reuses one safely owned, fully matching subscription on its original client. */
3012
3030
  async function tryReuseCodexLiveThread(options) {
3013
- const { params, binding, bindingIdentity, clientId, dynamicToolsFingerprint, environmentSelectionFingerprint, hostSystemAgentActive, lifecycleTiming, nativeSkillIsolation, releaseConsumedThread, ringZeroActive, restrictedToolSurfaceInheritedMcpServerNames, startModelProvider, startModelSelection, throwIfAborted, userMcpServersConfigPatch } = options;
3014
- if (!binding.clientId || binding.clientId !== clientId || binding.preserveNativeModel === true || binding.connectionScope === "supervision" || ringZeroActive) return {};
3015
- const prebuiltFinalConfigPatch = params.buildFinalConfigPatch?.({
3016
- action: "resume",
3017
- binding
3018
- }) ?? {
3019
- configPatch: params.finalConfigPatch,
3020
- nativeHookRelayGeneration: params.nativeHookRelayGeneration
3031
+ const { params, binding, bindingIdentity, clientId, dynamicToolsFingerprint, environmentSelectionFingerprint, hostSystemAgentActive, lifecycleTiming, nativeSkillIsolation, ringZeroActive, restrictedToolSurfaceInheritedMcpServerNames, startModelProvider, startModelSelection, throwIfAborted, userMcpServersConfigPatch } = options;
3032
+ if (!binding.clientId || binding.clientId !== clientId || binding.preserveNativeModel === true || binding.connectionScope === "supervision" || ringZeroActive) return { kind: "resume" };
3033
+ const retainedThread = await consumeCodexAppServerLiveThread(params.client, binding.threadId);
3034
+ if (!retainedThread) return { kind: "resume" };
3035
+ const assertCurrentClient = () => {
3036
+ throwIfAborted();
3037
+ if (!isCodexAppServerClientRuntimeLive(params.client)) throw params.client.getCloseError() ?? /* @__PURE__ */ new Error("codex app-server client is closed");
3021
3038
  };
3022
- const pluginAppsConfigPatch = params.pluginThreadConfig?.enabled && binding.pluginAppPolicyContext ? buildCodexPluginAppsConfigPatchFromPolicyContext(binding.pluginAppPolicyContext) : void 0;
3023
- const resumeAuthProfileId = params.params.authProfileId ?? binding.authProfileId;
3024
- const resumeConfig = mergeCodexThreadConfigs(params.config, userMcpServersConfigPatch, pluginAppsConfigPatch, prebuiltFinalConfigPatch.configPatch);
3025
- const resumeParams = lifecycleTiming.measureSync("warm-thread-resume-params", () => buildThreadResumeParams(params.params, {
3026
- threadId: binding.threadId,
3027
- cwd: params.cwd,
3028
- authProfileId: resumeAuthProfileId,
3029
- model: startModelSelection.model,
3030
- modelProvider: startModelProvider,
3031
- preserveNativeModel: false,
3032
- appServer: params.appServer,
3033
- dynamicTools: params.dynamicTools,
3034
- developerInstructions: params.developerInstructions,
3035
- config: applyCodexNativeSkillIsolation(resumeConfig, nativeSkillIsolation),
3036
- nativeCodeModeEnabled: params.nativeCodeModeEnabled,
3037
- nativeProviderWebSearchSupport: params.nativeProviderWebSearchSupport,
3038
- nativeCodeModeOnlyEnabled: params.nativeCodeModeOnlyEnabled,
3039
- webSearchAllowed: params.webSearchAllowed,
3040
- hostSystemAgentActive,
3041
- restrictedToolSurfaceInheritedMcpServerNames,
3042
- shellEnvironment: params.shellEnvironment,
3043
- disableLoginShell: params.disableLoginShell
3044
- }));
3045
- const liveThreadConfigFingerprint = fingerprintCodexThreadConfig({
3046
- ...resumeParams,
3047
- model: binding.model ?? resumeParams.model ?? null,
3048
- requestedModel: resumeParams.model ?? null,
3049
- modelProvider: binding.modelProvider ?? resumeParams.modelProvider ?? null,
3050
- requestedModelProvider: resumeParams.modelProvider ?? binding.modelProvider ?? null
3051
- }, resumeAuthProfileId, dynamicToolsFingerprint);
3052
- const retainedThread = await consumeCodexAppServerLiveThread(params.client, binding.threadId, liveThreadConfigFingerprint);
3053
- if (!retainedThread) {
3054
- const incompatibleOwnership = await consumeCodexAppServerLiveThread(params.client, binding.threadId);
3055
- if (incompatibleOwnership) await incompatibleOwnership.release(binding.threadId);
3056
- return { prebuiltFinalConfigPatch };
3057
- }
3039
+ let ownershipTransferred = false;
3058
3040
  try {
3041
+ const pluginThreadConfig = await options.buildLoadedPluginThreadConfig(binding);
3042
+ assertCurrentClient();
3043
+ if (pluginThreadConfig && pluginThreadConfig.fingerprint !== binding.pluginAppsFingerprint) return { kind: "rotate" };
3044
+ const prebuiltFinalConfigPatch = params.buildFinalConfigPatch?.({
3045
+ action: "resume",
3046
+ binding
3047
+ }) ?? {
3048
+ configPatch: params.finalConfigPatch,
3049
+ nativeHookRelayGeneration: params.nativeHookRelayGeneration
3050
+ };
3051
+ const pluginAppsConfigPatch = pluginThreadConfig?.configPatch ?? (params.pluginThreadConfig?.enabled && binding.pluginAppPolicyContext ? buildCodexPluginAppsConfigPatchFromPolicyContext(binding.pluginAppPolicyContext) : void 0);
3052
+ const resumeAuthProfileId = params.params.authProfileId ?? binding.authProfileId;
3053
+ const resumeConfig = mergeCodexThreadConfigs(params.config, userMcpServersConfigPatch, pluginAppsConfigPatch, prebuiltFinalConfigPatch.configPatch);
3054
+ const resumeParams = lifecycleTiming.measureSync("warm-thread-resume-params", () => buildThreadResumeParams(params.params, {
3055
+ threadId: binding.threadId,
3056
+ cwd: params.cwd,
3057
+ authProfileId: resumeAuthProfileId,
3058
+ model: startModelSelection.model,
3059
+ modelProvider: startModelProvider,
3060
+ preserveNativeModel: false,
3061
+ appServer: params.appServer,
3062
+ dynamicTools: params.dynamicTools,
3063
+ developerInstructions: params.developerInstructions,
3064
+ config: applyCodexNativeSkillIsolation(resumeConfig, nativeSkillIsolation),
3065
+ nativeCodeModeEnabled: params.nativeCodeModeEnabled,
3066
+ nativeProviderWebSearchSupport: params.nativeProviderWebSearchSupport,
3067
+ nativeCodeModeOnlyEnabled: params.nativeCodeModeOnlyEnabled,
3068
+ webSearchAllowed: params.webSearchAllowed,
3069
+ hostSystemAgentActive,
3070
+ restrictedToolSurfaceInheritedMcpServerNames,
3071
+ shellEnvironment: params.shellEnvironment,
3072
+ disableLoginShell: params.disableLoginShell
3073
+ }));
3074
+ const liveThreadConfigFingerprint = fingerprintCodexThreadConfig({
3075
+ ...resumeParams,
3076
+ model: binding.model ?? resumeParams.model ?? null,
3077
+ requestedModel: resumeParams.model ?? null,
3078
+ modelProvider: binding.modelProvider ?? resumeParams.modelProvider ?? null,
3079
+ requestedModelProvider: resumeParams.modelProvider ?? binding.modelProvider ?? null
3080
+ }, resumeAuthProfileId, dynamicToolsFingerprint);
3081
+ if (retainedThread.configFingerprint !== liveThreadConfigFingerprint) return {
3082
+ kind: "resume",
3083
+ prebuiltFinalConfigPatch
3084
+ };
3085
+ await attestCodexPluginThreadApps({
3086
+ client: params.client,
3087
+ threadId: binding.threadId,
3088
+ appIds: pluginThreadConfig?.provisionalAppIds ?? [],
3089
+ signal: params.signal
3090
+ });
3091
+ assertCurrentClient();
3059
3092
  const nativeHookRelayGeneration = prebuiltFinalConfigPatch.nativeHookRelayGeneration ?? binding.nativeHookRelayGeneration;
3060
3093
  const model = startModelSelection.model;
3061
3094
  if (!await lifecycleTiming.measure("warm-thread-write-binding", () => params.bindingStore.mutate(bindingIdentity, {
@@ -3067,8 +3100,8 @@ async function tryReuseCodexLiveThread(options) {
3067
3100
  nativeHookRelayGeneration,
3068
3101
  environmentSelectionFingerprint
3069
3102
  }
3070
- }))) throw new CodexThreadBindingConflictError(binding.threadId, "committing a reused thread");
3071
- throwIfAborted();
3103
+ }, assertCurrentClient))) throw new CodexThreadBindingConflictError(binding.threadId, "committing a reused thread");
3104
+ assertCurrentClient();
3072
3105
  lifecycleTiming.mark("thread-ready");
3073
3106
  lifecycleTiming.logSummary({
3074
3107
  runId: params.params.runId,
@@ -3077,7 +3110,9 @@ async function tryReuseCodexLiveThread(options) {
3077
3110
  threadId: binding.threadId,
3078
3111
  action: "resumed"
3079
3112
  });
3113
+ ownershipTransferred = true;
3080
3114
  return {
3115
+ kind: "ready",
3081
3116
  binding: {
3082
3117
  ...binding,
3083
3118
  cwd: params.cwd,
@@ -3088,12 +3123,19 @@ async function tryReuseCodexLiveThread(options) {
3088
3123
  liveThreadOwnership: retainedThread,
3089
3124
  ...retainedThread.serviceTier && resumeParams.serviceTier === void 0 ? { clearInheritedServiceTier: true } : {},
3090
3125
  lifecycle: { action: "resumed" }
3091
- },
3092
- prebuiltFinalConfigPatch
3126
+ }
3093
3127
  };
3094
- } catch (error) {
3095
- await releaseConsumedThread(binding.threadId, error);
3096
- throw error;
3128
+ } finally {
3129
+ if (!ownershipTransferred) try {
3130
+ await retainedThread.release(binding.threadId);
3131
+ } catch (error) {
3132
+ await abandonCodexLiveThreadRelease({
3133
+ client: params.client,
3134
+ abandonClient: params.abandonClient,
3135
+ lifecycleTiming,
3136
+ threadId: binding.threadId
3137
+ }, error);
3138
+ }
3097
3139
  }
3098
3140
  }
3099
3141
  //#endregion
@@ -3244,9 +3286,9 @@ const CODEX_NATIVE_HOOK_RELAY_EVENTS = [
3244
3286
  "before_agent_finalize"
3245
3287
  ];
3246
3288
  const CODEX_NATIVE_HOOK_RELAY_EVENTS_WITH_APP_SERVER_APPROVALS = CODEX_NATIVE_HOOK_RELAY_EVENTS.filter((event) => event !== "permission_request");
3247
- const CODEX_NATIVE_HOOK_RELAY_MIN_TTL_MS = 30 * 6e4;
3289
+ const CODEX_NATIVE_HOOK_RELAY_MIN_TTL_MS = 18e5;
3248
3290
  /** Extra relay lifetime after the expected turn budget, preventing late hook drops. */
3249
- const CODEX_NATIVE_HOOK_RELAY_TTL_GRACE_MS = 5 * 6e4;
3291
+ const CODEX_NATIVE_HOOK_RELAY_TTL_GRACE_MS = 3e5;
3250
3292
  const CODEX_NATIVE_HOOK_RELAY_COMMAND_MIN_PARENT_MARGIN_MS = 250;
3251
3293
  const CODEX_NATIVE_HOOK_RELAY_COMMAND_MAX_PARENT_MARGIN_MS = 1e3;
3252
3294
  const CODEX_NATIVE_HOOK_RELAY_DEFAULT_TIMEOUT_SEC = 10;
@@ -4311,10 +4353,28 @@ async function startOrResumeThread(params) {
4311
4353
  binding = void 0;
4312
4354
  }
4313
4355
  const requestContext = resolveRequestContext();
4314
- const { startModelSelection, startModelProvider } = requestContext;
4315
4356
  let preserveExistingBinding = transientDelegationRestriction || !ringZeroActive && params.nativeProviderWebSearchSupport === "unknown" && !binding?.threadId;
4316
4357
  let rotatedContextEngineBinding = false;
4317
4358
  let prebuiltPluginThreadConfig;
4359
+ const buildLoadedPluginThreadConfig = async (current) => {
4360
+ if (!params.pluginThreadConfig?.requiresCurrentPolicyCheck && !shouldRecheckRecoverablePluginBinding({
4361
+ binding: current,
4362
+ pluginThreadConfig: params.pluginThreadConfig
4363
+ })) return;
4364
+ try {
4365
+ prebuiltPluginThreadConfig = await lifecycleTiming.measure("plugin-config-recovery", () => params.pluginThreadConfig?.build({ threadId: current.threadId }));
4366
+ } catch (error) {
4367
+ throwIfAborted();
4368
+ if (params.pluginThreadConfig?.requiresCurrentPolicyCheck) throw error;
4369
+ embeddedAgentLog.warn("codex app-server plugin app config recovery check failed", {
4370
+ error,
4371
+ threadId: current.threadId
4372
+ });
4373
+ return;
4374
+ }
4375
+ throwIfAborted();
4376
+ return prebuiltPluginThreadConfig;
4377
+ };
4318
4378
  const webSearchBindingChanged = binding?.threadId && binding.webSearchThreadConfigFingerprint !== webSearchThreadConfigFingerprint;
4319
4379
  const explicitTransientWebSearchRestriction = params.webSearchAllowed === false && params.persistentWebSearchAllowed !== false && transientWebSearchRestriction;
4320
4380
  const unknownProviderWebSearchSupport = params.nativeProviderWebSearchSupport === "unknown";
@@ -4393,28 +4453,13 @@ async function startOrResumeThread(params) {
4393
4453
  binding = void 0;
4394
4454
  }
4395
4455
  if (binding?.threadId) {
4396
- let pluginBindingStale = isCodexPluginThreadBindingStale({
4456
+ if (isCodexPluginThreadBindingStale({
4397
4457
  codexPluginsEnabled: params.pluginThreadConfig?.enabled ?? false,
4398
4458
  bindingFingerprint: binding.pluginAppsFingerprint,
4399
4459
  bindingInputFingerprint: binding.pluginAppsInputFingerprint,
4400
4460
  currentInputFingerprint: params.pluginThreadConfig?.inputFingerprint,
4401
4461
  hasBindingPolicyContext: Boolean(binding.pluginAppPolicyContext)
4402
- });
4403
- if (!pluginBindingStale && (params.pluginThreadConfig?.requiresCurrentPolicyCheck || shouldRecheckRecoverablePluginBinding({
4404
- binding,
4405
- pluginThreadConfig: params.pluginThreadConfig
4406
- }))) try {
4407
- const bindingThreadId = binding.threadId;
4408
- prebuiltPluginThreadConfig = await lifecycleTiming.measure("plugin-config-recovery", () => params.pluginThreadConfig?.build({ threadId: bindingThreadId }));
4409
- pluginBindingStale = prebuiltPluginThreadConfig?.fingerprint !== binding.pluginAppsFingerprint;
4410
- } catch (error) {
4411
- if (params.pluginThreadConfig?.requiresCurrentPolicyCheck) throw error;
4412
- embeddedAgentLog.warn("codex app-server plugin app config recovery check failed", {
4413
- error,
4414
- threadId: binding.threadId
4415
- });
4416
- }
4417
- if (pluginBindingStale) {
4462
+ })) {
4418
4463
  embeddedAgentLog.debug("codex app-server plugin app config changed; starting a new thread", { threadId: binding.threadId });
4419
4464
  await clearCurrentBinding("rotating a stale thread binding");
4420
4465
  binding = void 0;
@@ -4427,75 +4472,66 @@ async function startOrResumeThread(params) {
4427
4472
  binding = void 0;
4428
4473
  }
4429
4474
  }
4430
- if (binding?.threadId) if (binding.dynamicToolsFingerprint && !areDynamicToolFingerprintsCompatible(binding.dynamicToolsFingerprint, dynamicToolsFingerprint, legacyDynamicToolsFingerprint)) {
4431
- assertCodexBindingMayBeReplaced(binding, "changing the dynamic tool catalog");
4432
- preserveExistingBinding = shouldStartTransientNoToolThread({
4433
- previous: binding.dynamicToolsFingerprint,
4434
- nextHasDynamicTools: params.dynamicTools.length > 0
4435
- });
4436
- if (preserveExistingBinding) embeddedAgentLog.debug("codex app-server dynamic tools unavailable for turn; starting transient thread", { threadId: binding.threadId });
4437
- else {
4438
- embeddedAgentLog.debug("codex app-server dynamic tool catalog changed; starting a new thread", { threadId: binding.threadId });
4439
- await clearCurrentBinding("rotating a stale thread binding");
4440
- }
4441
- } else if (incognito) {
4442
- if (binding.clientId && binding.clientId === clientId) {
4443
- params.buildFinalConfigPatch?.({
4444
- action: "resume",
4445
- binding
4475
+ if (binding?.threadId) {
4476
+ if (binding.dynamicToolsFingerprint && !areDynamicToolFingerprintsCompatible(binding.dynamicToolsFingerprint, dynamicToolsFingerprint, legacyDynamicToolsFingerprint)) {
4477
+ assertCodexBindingMayBeReplaced(binding, "changing the dynamic tool catalog");
4478
+ preserveExistingBinding = shouldStartTransientNoToolThread({
4479
+ previous: binding.dynamicToolsFingerprint,
4480
+ nextHasDynamicTools: params.dynamicTools.length > 0
4446
4481
  });
4447
- throwIfAborted();
4448
- lifecycleTiming.mark("thread-ready");
4449
- lifecycleTiming.logSummary({
4450
- runId: params.params.runId,
4451
- sessionId: params.params.sessionId,
4452
- sessionKey: params.params.sessionKey,
4453
- threadId: binding.threadId,
4454
- action: "resumed"
4482
+ if (preserveExistingBinding) embeddedAgentLog.debug("codex app-server dynamic tools unavailable for turn; starting transient thread", { threadId: binding.threadId });
4483
+ else {
4484
+ embeddedAgentLog.debug("codex app-server dynamic tool catalog changed; starting a new thread", { threadId: binding.threadId });
4485
+ await clearCurrentBinding("rotating a stale thread binding");
4486
+ }
4487
+ } else if (incognito) {
4488
+ if (binding.clientId && binding.clientId === clientId && ((await buildLoadedPluginThreadConfig(binding))?.fingerprint ?? binding.pluginAppsFingerprint) === binding.pluginAppsFingerprint) {
4489
+ params.buildFinalConfigPatch?.({
4490
+ action: "resume",
4491
+ binding
4492
+ });
4493
+ throwIfAborted();
4494
+ lifecycleTiming.mark("thread-ready");
4495
+ lifecycleTiming.logSummary({
4496
+ runId: params.params.runId,
4497
+ sessionId: params.params.sessionId,
4498
+ sessionKey: params.params.sessionKey,
4499
+ threadId: binding.threadId,
4500
+ action: "resumed"
4501
+ });
4502
+ return {
4503
+ ...binding,
4504
+ lifecycle: { action: "resumed" }
4505
+ };
4506
+ }
4507
+ await clearCurrentBinding("rotating an unavailable ephemeral thread binding");
4508
+ binding = void 0;
4509
+ } else {
4510
+ const warmReuse = await tryReuseCodexLiveThread({
4511
+ ...requestContext,
4512
+ params,
4513
+ binding,
4514
+ clientId,
4515
+ buildLoadedPluginThreadConfig
4455
4516
  });
4456
- return {
4457
- ...binding,
4458
- lifecycle: { action: "resumed" }
4459
- };
4517
+ if (warmReuse.kind === "ready") return warmReuse.binding;
4518
+ if (warmReuse.kind === "rotate") {
4519
+ throwIfAborted();
4520
+ await clearCurrentBinding("rotating a stale plugin app binding");
4521
+ } else {
4522
+ if (binding.preserveNativeModel === true) await assertAdoptedCodexThreadResumeAllowed(params, binding.threadId, requestContext);
4523
+ await releaseRetainedThread(binding.threadId);
4524
+ const resumed = await resumeExistingCodexThread(params, {
4525
+ ...requestContext,
4526
+ binding,
4527
+ clearCurrentBinding,
4528
+ prebuiltFinalConfigPatch: warmReuse.prebuiltFinalConfigPatch,
4529
+ prebuiltPluginThreadConfig,
4530
+ buildLoadedPluginThreadConfig
4531
+ });
4532
+ if (resumed) return resumed;
4533
+ }
4460
4534
  }
4461
- await clearCurrentBinding("rotating an unavailable ephemeral thread binding");
4462
- binding = void 0;
4463
- } else {
4464
- const warmReuse = await tryReuseCodexLiveThread({
4465
- params,
4466
- binding,
4467
- bindingIdentity,
4468
- clientId,
4469
- dynamicToolsFingerprint,
4470
- environmentSelectionFingerprint,
4471
- hostSystemAgentActive,
4472
- lifecycleTiming,
4473
- nativeSkillIsolation,
4474
- releaseConsumedThread: (threadId, cause) => releaseCodexConsumedLiveThread({
4475
- client: params.client,
4476
- abandonClient: params.abandonClient,
4477
- lifecycleTiming,
4478
- threadId,
4479
- cause
4480
- }),
4481
- ringZeroActive,
4482
- restrictedToolSurfaceInheritedMcpServerNames,
4483
- startModelProvider,
4484
- startModelSelection,
4485
- throwIfAborted,
4486
- userMcpServersConfigPatch
4487
- });
4488
- if (warmReuse.binding) return warmReuse.binding;
4489
- if (binding.preserveNativeModel === true) await assertAdoptedCodexThreadResumeAllowed(params, binding.threadId, requestContext);
4490
- await releaseRetainedThread(binding.threadId);
4491
- const resumed = await resumeExistingCodexThread(params, {
4492
- ...requestContext,
4493
- binding,
4494
- clearCurrentBinding,
4495
- prebuiltFinalConfigPatch: warmReuse.prebuiltFinalConfigPatch,
4496
- prebuiltPluginThreadConfig
4497
- });
4498
- if (resumed) return resumed;
4499
4535
  }
4500
4536
  if (initialBoundThreadId && !preserveExistingBinding && !replacementPredecessor) await releaseRetainedThread(initialBoundThreadId);
4501
4537
  const started = await startFreshCodexThread(params, {
@@ -4564,10 +4600,17 @@ function buildTurnStartParams(params, options) {
4564
4600
  });
4565
4601
  const useThreadPermissionProfile = options.appServer.networkProxy && !options.sandboxPolicy;
4566
4602
  const currentSenderContext = params.trigger === "user" ? buildCodexCurrentSenderContextValue(params) : void 0;
4567
- const additionalContext = currentSenderContext ? { openclaw_current_sender: {
4603
+ let additionalContext = currentSenderContext ? { openclaw_current_sender: {
4568
4604
  kind: "untrusted",
4569
4605
  value: currentSenderContext
4570
4606
  } } : void 0;
4607
+ if (params.permissionChange?.notice) additionalContext = {
4608
+ ...additionalContext,
4609
+ openclaw_permission_change: {
4610
+ kind: "application",
4611
+ value: params.permissionChange.notice
4612
+ }
4613
+ };
4571
4614
  return {
4572
4615
  threadId: options.threadId,
4573
4616
  input: [...buildCodexUserInput(options.promptText ?? params.prompt, params.images), ...options.explicitSkillInputs ?? []],
@@ -1,5 +1,5 @@
1
- import { Ct as retainCodexAppServerLiveThread, St as releaseCodexAppServerLiveThread, _ as retainSharedCodexAppServerClientByInstanceId, bt as isCodexAppServerLiveThreadClaimed } from "./shared-client-kNkljY-R.js";
2
- import { a as closeCodexStartupClientBestEffort, f as unsubscribeCodexThreadBestEffort, r as CodexAppServerUnsafeSubscriptionError } from "./attempt-client-cleanup-CVPvp9dL.js";
1
+ import { Ct as retainCodexAppServerLiveThread, St as releaseCodexAppServerLiveThread, _ as retainSharedCodexAppServerClientByInstanceId, bt as isCodexAppServerLiveThreadClaimed } from "./shared-client-B1tT5U6r.js";
2
+ import { a as closeCodexStartupClientBestEffort, f as unsubscribeCodexThreadBestEffort, r as CodexAppServerUnsafeSubscriptionError } from "./attempt-client-cleanup-CpVfwctT.js";
3
3
  import { isIncognitoSessionKey } from "openclaw/plugin-sdk/routing";
4
4
  import { KeyedAsyncQueue } from "openclaw/plugin-sdk/keyed-async-queue";
5
5
  //#region extensions/codex/src/app-server/thread-ownership.ts
@@ -1,8 +1,8 @@
1
- import { F as resolveCodexAppServerLocalHomeDir, I as resolveCodexAppServerUserHomeDir, P as resolveCodexAppServerHomeDir } from "./config-Cxw3Cl3k.js";
2
- import { $ as CodexAppServerRpcError, J as isCodexAppServerOverloadError, P as isCodexAppServerStartupError, Y as isCodexAppServerPrewriteRequestCancellationError, u as isCodexAppServerStartSelectionChangedError } from "./shared-client-kNkljY-R.js";
1
+ import { F as resolveCodexAppServerLocalHomeDir, I as resolveCodexAppServerUserHomeDir, P as resolveCodexAppServerHomeDir } from "./config-CcYL77O6.js";
2
+ import { $ as CodexAppServerRpcError, J as isCodexAppServerOverloadError, P as isCodexAppServerStartupError, Y as isCodexAppServerPrewriteRequestCancellationError, u as isCodexAppServerStartSelectionChangedError } from "./shared-client-B1tT5U6r.js";
3
3
  import { o as assertCodexThreadResumeResponse } from "./protocol-validators-Bg5rpNxk.js";
4
- import { f as unsubscribeCodexThreadBestEffort, i as assertCodexThreadResumeSubscription, r as CodexAppServerUnsafeSubscriptionError } from "./attempt-client-cleanup-CVPvp9dL.js";
5
- import { t as CodexAppServerScopedRequestRejectedError } from "./request-CCm4LaED.js";
4
+ import { f as unsubscribeCodexThreadBestEffort, i as assertCodexThreadResumeSubscription, r as CodexAppServerUnsafeSubscriptionError } from "./attempt-client-cleanup-CpVfwctT.js";
5
+ import { t as CodexAppServerScopedRequestRejectedError } from "./request-BWxweEdK.js";
6
6
  import { createRequire } from "node:module";
7
7
  import { isRecord } from "openclaw/plugin-sdk/string-coerce-runtime";
8
8
  import { readPluginPackageVersion } from "openclaw/plugin-sdk/extension-shared";
@@ -16,7 +16,7 @@ import { truncateUtf16Safe } from "openclaw/plugin-sdk/text-utility-runtime";
16
16
  * identity and safe to refresh in the background.
17
17
  */
18
18
  /** Default app inventory cache freshness window. */
19
- const CODEX_APP_INVENTORY_CACHE_TTL_MS = 3600 * 1e3;
19
+ const CODEX_APP_INVENTORY_CACHE_TTL_MS = 36e5;
20
20
  const CODEX_APP_READ_BATCH_LIMIT = 100;
21
21
  const MAX_SERIALIZED_ERROR_MESSAGE_LENGTH = 500;
22
22
  /** In-memory app inventory cache with coalesced refreshes per key. */
@@ -337,7 +337,8 @@ function isSensitiveErrorDataKey(key) {
337
337
  * Builds stable Codex plugin/app inventory cache keys from app-server startup,
338
338
  * auth, account, and version inputs without storing secret material.
339
339
  */
340
- const CODEX_PLUGIN_VERSION = readPluginPackageVersion({ require: createRequire(import.meta.url) });
340
+ const require = createRequire(import.meta.url);
341
+ const CODEX_PLUGIN_VERSION = readPluginPackageVersion({ require });
341
342
  let catalogConnectionHomes = /* @__PURE__ */ new Map();
342
343
  function catalogConnectionHomeKey(fingerprint, agentDir) {
343
344
  return `${agentDir ?? ""}\0${fingerprint}`;
@@ -1,4 +1,4 @@
1
- import { i as readUpstreamUserText, n as attachUpstreamUserText, r as readMirrorIdentity, t as attachCodexMirrorIdentity } from "./upstream-prompt-provenance-CFmsKwr9.js";
1
+ import { i as readUpstreamUserText, n as attachUpstreamUserText, r as readMirrorIdentity, t as attachCodexMirrorIdentity } from "./upstream-prompt-provenance-LphB8slG.js";
2
2
  import { asOptionalRecord, normalizeOptionalString } from "openclaw/plugin-sdk/string-coerce-runtime";
3
3
  import { deliverAgentHarnessUserInputPrompt, embeddedAgentLog, formatErrorMessage, projectAgentHarnessTranscriptMessageForDisplay, runAgentHarnessBeforeMessageWriteHook } from "openclaw/plugin-sdk/agent-harness-runtime";
4
4
  import { createHash } from "node:crypto";
@@ -8,8 +8,8 @@ import { publishSessionTranscriptUpdateByIdentity } from "openclaw/plugin-sdk/se
8
8
  import { Buffer } from "node:buffer";
9
9
  //#region extensions/codex/src/app-server/transcript-history-projection.ts
10
10
  const CODEX_HISTORY_IMPORT_MAX_MESSAGES = 200;
11
- const CODEX_HISTORY_IMPORT_MAX_BYTES = 512 * 1024;
12
- const CODEX_HISTORY_IMPORT_MAX_MESSAGE_BYTES = 64 * 1024;
11
+ const CODEX_HISTORY_IMPORT_MAX_BYTES = 524288;
12
+ const CODEX_HISTORY_IMPORT_MAX_MESSAGE_BYTES = 65536;
13
13
  const CODEX_HISTORY_TRUNCATION_SUFFIX = "\n\n[Message truncated during Codex history import.]";
14
14
  const CODEX_HISTORY_ASSISTANT_API = "openai-chatgpt-responses";
15
15
  const CODEX_HISTORY_ASSISTANT_PROVIDER = "openai";
@@ -34,7 +34,8 @@ function normalizeImportedHistoryText(value) {
34
34
  if (!text) return;
35
35
  if (Buffer.byteLength(text, "utf8") <= CODEX_HISTORY_IMPORT_MAX_MESSAGE_BYTES) return text;
36
36
  const suffixBytes = Buffer.byteLength(CODEX_HISTORY_TRUNCATION_SUFFIX, "utf8");
37
- return `${truncateUtf8Prefix(text, Math.max(0, CODEX_HISTORY_IMPORT_MAX_MESSAGE_BYTES - suffixBytes))}${CODEX_HISTORY_TRUNCATION_SUFFIX}`;
37
+ const contentLimitBytes = Math.max(0, CODEX_HISTORY_IMPORT_MAX_MESSAGE_BYTES - suffixBytes);
38
+ return `${truncateUtf8Prefix(text, contentLimitBytes)}${CODEX_HISTORY_TRUNCATION_SUFFIX}`;
38
39
  }
39
40
  function projectCodexUserItemText(item) {
40
41
  if (!Array.isArray(item.content)) return;
@@ -183,7 +184,8 @@ function applyCodexTranscriptTaint(message, state) {
183
184
  state.tainted = false;
184
185
  return message;
185
186
  }
186
- const metadata = asOptionalRecord(CODEX_META_KEY in message ? message[CODEX_META_KEY] : void 0);
187
+ const existing = CODEX_META_KEY in message ? message[CODEX_META_KEY] : void 0;
188
+ const metadata = asOptionalRecord(existing);
187
189
  state.tainted ||= metadata?.turnTainted === true || metadata?.resultContentSource === "network";
188
190
  return message.role === "assistant" && state.tainted ? {
189
191
  ...message,
@@ -206,7 +208,8 @@ function attachCodexMirrorAttestation(message, sourceFingerprint) {
206
208
  };
207
209
  }
208
210
  function attachCodexMirrorRunId(message, runId, terminal = false) {
209
- const { runTerminal: _staleTerminal, ...current } = asOptionalRecord(CODEX_META_KEY in message ? message[CODEX_META_KEY] : void 0) ?? {};
211
+ const existing = CODEX_META_KEY in message ? message[CODEX_META_KEY] : void 0;
212
+ const { runTerminal: _staleTerminal, ...current } = asOptionalRecord(existing) ?? {};
210
213
  return {
211
214
  ...message,
212
215
  [CODEX_META_KEY]: {
@@ -216,6 +219,10 @@ function attachCodexMirrorRunId(message, runId, terminal = false) {
216
219
  }
217
220
  };
218
221
  }
222
+ function hasCodexMirrorOrigin(message) {
223
+ const meta = CODEX_META_KEY in message ? message[CODEX_META_KEY] : void 0;
224
+ return asOptionalRecord(meta)?.[MIRROR_ORIGIN_META_KEY] === CODEX_APP_SERVER_MIRROR_ORIGIN;
225
+ }
219
226
  function readCodexMirrorSourceFingerprint(message) {
220
227
  const meta = CODEX_META_KEY in message ? message[CODEX_META_KEY] : void 0;
221
228
  if (!meta || typeof meta !== "object" || Array.isArray(meta)) return;
@@ -684,4 +691,4 @@ function resolveCodexMirrorTranscriptTarget(params) {
684
691
  };
685
692
  }
686
693
  //#endregion
687
- export { buildCodexUserPromptMessage as a, fingerprintCodexMirrorSourceMessage as c, projectBoundedCodexThreadHistory as d, projectBoundedCodexVisibleSessionHistory as f, mirrorPromptAtTurnStartBestEffort as i, readCodexMirrorSourceFingerprint as l, createCodexAppServerUserMessagePersistenceNotifier as n, promptSnapshot as o, projectCodexUserItemText as p, importCodexThreadHistoryToTranscript as r, applyCodexTranscriptTaint as s, codexTranscriptMirrorRuntime as t, serializeCodexMirrorSourceEvidence as u };
694
+ export { buildCodexUserPromptMessage as a, fingerprintCodexMirrorSourceMessage as c, serializeCodexMirrorSourceEvidence as d, projectBoundedCodexThreadHistory as f, mirrorPromptAtTurnStartBestEffort as i, hasCodexMirrorOrigin as l, projectCodexUserItemText as m, createCodexAppServerUserMessagePersistenceNotifier as n, promptSnapshot as o, projectBoundedCodexVisibleSessionHistory as p, importCodexThreadHistoryToTranscript as r, applyCodexTranscriptTaint as s, codexTranscriptMirrorRuntime as t, readCodexMirrorSourceFingerprint as u };