@openclaw/codex 2026.10.5 → 2026.10.7

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 (82) hide show
  1. package/dist/.setup/{account-usage-runtime-Dqpnnkst.mjs → account-usage-runtime-gzHf_Qtb.mjs} +3 -3
  2. package/dist/.setup/{app-server-policy-XTIa6h5k.mjs → app-server-policy-V8zuN8q_.mjs} +1 -1
  3. package/dist/.setup/{apply-QyZT5-na.mjs → apply-BaBl0hiG.mjs} +14 -14
  4. package/dist/.setup/{attempt-client-cleanup-TScCVTsk.mjs → attempt-client-cleanup-jWVRH043.mjs} +4 -4
  5. package/dist/.setup/{attempt-workspace-context-Cr3mI4vp.mjs → attempt-workspace-context-BkA0W8Jy.mjs} +1 -1
  6. package/dist/.setup/{auth-cache-key-DvDLHVJe.mjs → auth-cache-key-DrieYJUQ.mjs} +4 -3
  7. package/dist/.setup/{auth-profile-health-oHizqgye.mjs → auth-profile-health-B05o5BAm.mjs} +12 -5
  8. package/dist/.setup/{binding-connection-X1ZeEDz8.mjs → binding-connection-C0t9TBX_.mjs} +1 -1
  9. package/dist/.setup/{binding-connection.runtime-CZSz0g4u.mjs → binding-connection.runtime-Wdm5G_bw.mjs} +1 -1
  10. package/dist/.setup/{bounded-turn-isolation-Brj5qzz6.mjs → bounded-turn-isolation-CIQJykuM.mjs} +3 -3
  11. package/dist/.setup/{bounded-turn-BpjZixcd.mjs → bounded-turn-s9yVsxaM.mjs} +13 -12
  12. package/dist/.setup/{build-state-DfrctLQv.mjs → build-state-B5mKL-in.mjs} +1 -1
  13. package/dist/.setup/{client-BpSxNz4F.mjs → client-BM97zH3z.mjs} +19 -15
  14. package/dist/.setup/{client-catalog-response-DloWE31e.mjs → client-catalog-response-DhB266B_.mjs} +1 -1
  15. package/dist/.setup/{command-dispatch-CIdf7ZvD.mjs → command-dispatch-DsaWfzET.mjs} +1 -1
  16. package/dist/.setup/{command-handlers-C2XNDeHL.mjs → command-handlers-zgDE_J40.mjs} +16 -16
  17. package/dist/.setup/{command-rpc-DpmvEmhc.mjs → command-rpc-CAG1xrqm.mjs} +8 -8
  18. package/dist/.setup/{compact-DpCHUqU5.mjs → compact-BZK-e5zD.mjs} +10 -10
  19. package/dist/.setup/{computer-use-BgGC32hr.mjs → computer-use-CZhx4nNO.mjs} +7 -7
  20. package/dist/.setup/{config-G4IGX6bK.mjs → config-LQemoqTL.mjs} +3 -3
  21. package/dist/.setup/{config-options-nvYwVDyy.mjs → config-options-CZmH25Xq.mjs} +1 -1
  22. package/dist/.setup/{config-runtime-B8agjie6.mjs → config-runtime-DGB1-VbB.mjs} +1 -1
  23. package/dist/.setup/{config-security-D0hAOQRI.mjs → config-security-DpkGNy5T.mjs} +1 -1
  24. package/dist/.setup/{conversation-binding-BCoWi2Kn.mjs → conversation-binding-qGuQR4jw.mjs} +38 -29
  25. package/dist/.setup/{conversation-control--OHH2dHA.mjs → conversation-control-BtPxevoK.mjs} +1 -1
  26. package/dist/.setup/{doctor-start-options-DedLaoqI.mjs → doctor-start-options-C28ek2hD.mjs} +3 -3
  27. package/dist/.setup/{dynamic-tool-build-CoMf7IKx.mjs → dynamic-tool-build-Dp4v52Kl.mjs} +3 -3
  28. package/dist/.setup/{dynamic-tools-CKynHtxM.mjs → dynamic-tools-C1Egdhrx.mjs} +10 -10
  29. package/dist/.setup/{effective-mcp-catalog-DXGsGC1j.mjs → effective-mcp-catalog-BNwgItdW.mjs} +4 -4
  30. package/dist/.setup/{ephemeral-turn-C6aFeGFS.mjs → ephemeral-turn-DeppK8zz.mjs} +2 -2
  31. package/dist/.setup/{inference-proxy-BDWV0djM.mjs → inference-proxy-DSnaS-uS.mjs} +5 -4
  32. package/dist/.setup/{isolated-completion-DVDn5GU5.mjs → isolated-completion-BUS9Mqfm.mjs} +6 -6
  33. package/dist/.setup/{mcp-app-session-preparation-Cnmuh9RT.mjs → mcp-app-session-preparation-D9F1O5si.mjs} +8 -8
  34. package/dist/.setup/{model-catalog-DRbHoUhG.mjs → model-catalog-BBg4thof.mjs} +7 -7
  35. package/dist/.setup/{models-GBLXb27n.mjs → models-B65GHU4g.mjs} +3 -3
  36. package/dist/.setup/{native-auth-DWrRSl4Z.mjs → native-auth-CveRfTpz.mjs} +1 -1
  37. package/dist/.setup/{native-hook-relay-BQ9UkpeG.mjs → native-hook-relay-Ctyky2Qt.mjs} +5 -5
  38. package/dist/.setup/{native-mcp-app-DIheNk35.mjs → native-mcp-app-DprMGBqj.mjs} +4 -4
  39. package/dist/.setup/{native-skill-isolation-CxZRtiWZ.mjs → native-skill-isolation-C4XYLm33.mjs} +3 -3
  40. package/dist/.setup/{native-subagent-monitor-gqu3TQOv.mjs → native-subagent-monitor-CJaIve3h.mjs} +66 -19
  41. package/dist/.setup/{plan-DZWYASAx.mjs → plan-GqWF4XGA.mjs} +4 -4
  42. package/dist/.setup/{plugin-activation-CsW09DWl.mjs → plugin-activation-BgfNFH2L.mjs} +2 -2
  43. package/dist/.setup/{plugin-approval-roundtrip-HbFUm9Pp.mjs → plugin-approval-roundtrip-x7UI_uqk.mjs} +1 -1
  44. package/dist/.setup/{plugin-inventory-kLR7G02h.mjs → plugin-inventory-OhiCoyPH.mjs} +1 -1
  45. package/dist/.setup/{project-doc-thread-config-B2ZD23A_.mjs → project-doc-thread-config-D_sWbxFR.mjs} +5 -5
  46. package/dist/.setup/{provider-BiUzaRth.mjs → provider-Bi9QCsg1.mjs} +4 -4
  47. package/dist/.setup/{provider-capabilities-DOBUBt86.mjs → provider-capabilities-BCZeV7xZ.mjs} +1 -1
  48. package/dist/.setup/{request-DhbisYCc.mjs → request-XC1RG34l.mjs} +2 -2
  49. package/dist/.setup/{run-attempt-WbitbMr6.mjs → run-attempt-8U2CrqjW.mjs} +142 -81
  50. package/dist/.setup/{runtime-artifact-nFHy1R0x.mjs → runtime-artifact-CCPLKFGR.mjs} +1 -1
  51. package/dist/.setup/{runtime-artifact-connection-XSifLLBH.mjs → runtime-artifact-connection-dFoSOKy7.mjs} +3 -3
  52. package/dist/.setup/{session-catalog-events-IoszcO7-.mjs → session-catalog-events-CpEyDv0D.mjs} +4 -4
  53. package/dist/.setup/{session-catalog-index-_4Z5quG3.mjs → session-catalog-index-DpYCf1-8.mjs} +4 -4
  54. package/dist/.setup/{session-catalog-native-projection-imNPfB3q.mjs → session-catalog-native-projection-BYV0ICja.mjs} +1 -1
  55. package/dist/.setup/{session-catalog-projection-BFp1d3bJ.mjs → session-catalog-projection-B0IyXrHt.mjs} +1 -1
  56. package/dist/.setup/{session-catalog-source-CgWkqG43.mjs → session-catalog-source-CfIBVrbT.mjs} +1 -1
  57. package/dist/.setup/{session-permission-policy-BYI6mp5u.mjs → session-permission-policy-C7kYxPGd.mjs} +1 -1
  58. package/dist/.setup/{session-retirement-AhaR7MAp.mjs → session-retirement-CKIS7jFv.mjs} +5 -5
  59. package/dist/.setup/{settled-turn-finalizer-Blsc4VLX.mjs → settled-turn-finalizer-CnIWbqN7.mjs} +4 -4
  60. package/dist/.setup/{shared-client-wb1JBldZ.mjs → shared-client-AdQX0Tdq.mjs} +72 -17
  61. package/dist/.setup/{side-question-DNEeROvz.mjs → side-question-ZVehuPZn.mjs} +17 -17
  62. package/dist/.setup/{source-BjBw-zoV.mjs → source-BszpKEvi.mjs} +3 -3
  63. package/dist/.setup/{thread-lifecycle-run-DdwKMIae.mjs → thread-lifecycle-run-DezS4UNT.mjs} +77 -38
  64. package/dist/.setup/{thread-ownership-CTUs8Eyu.mjs → thread-ownership-OXzPB_RV.mjs} +3 -3
  65. package/dist/.setup/{thread-policy-BMRvlOi-.mjs → thread-policy-Dp4CQjdL.mjs} +3 -3
  66. package/dist/.setup/{thread-requests-BqPhA4Gs.mjs → thread-requests-DjyDmCo4.mjs} +2 -2
  67. package/dist/.setup/{thread-resume-CD48Vab8.mjs → thread-resume-8YKfRoX6.mjs} +4 -4
  68. package/dist/.setup/{transport-websocket-DOY0dJXN.mjs → transport-websocket-CEBjEtFP.mjs} +1 -1
  69. package/dist/.setup/{turn-router-DdlzuFdm.mjs → turn-router-DnfbVPvu.mjs} +1 -1
  70. package/dist/.setup/{upstream-session-fork-BF0c69x6.mjs → upstream-session-fork-BhADVCrb.mjs} +14 -14
  71. package/dist/.setup/{usage-BsMyAOaB.mjs → usage-BoTUkAoJ.mjs} +3 -3
  72. package/dist/.setup/{usage-limit-error-hLIGKewV.mjs → usage-limit-error-EoQ7Vl2A.mjs} +1 -1
  73. package/dist/.setup/{web-search-provider.runtime-BJK0lNpc.mjs → web-search-provider.runtime-Cc6vN-2C.mjs} +2 -2
  74. package/dist/.setup/{workspace-write-sandbox-probe-Cyn6cBsp.mjs → workspace-write-sandbox-probe-DvfWTvuR.mjs} +1 -1
  75. package/dist/api.js +3 -3
  76. package/dist/catalog-page.worker.js +1 -1
  77. package/dist/harness.js +18 -18
  78. package/dist/index.js +33 -33
  79. package/dist/media-understanding-provider.js +2 -2
  80. package/dist/migration-provider-api.js +1 -1
  81. package/dist/provider-discovery.js +1 -1
  82. package/package.json +5 -5
@@ -1,10 +1,10 @@
1
1
  import { i as readMirrorIdentity, n as attachCodexMirrorIdentity } from "./upstream-prompt-provenance-Ccd9MFRJ.mjs";
2
2
  import { l as readCodexMirrorSourceFingerprint, o as fingerprintCodexMirrorSourceMessage } from "./transcript-mirror-attestation-BzUXnrvv.mjs";
3
- import { nt as resolveCodexAppServerPreparedAuthHandoff } from "./shared-client-wb1JBldZ.mjs";
4
- import { f as assertCodexPassiveTurnItems } from "./client-BpSxNz4F.mjs";
5
- import { runBoundedCodexAppServerTurn } from "./bounded-turn-BpjZixcd.mjs";
3
+ import { at as resolveCodexAppServerPreparedAuthHandoff } from "./shared-client-AdQX0Tdq.mjs";
4
+ import { f as assertCodexPassiveTurnItems } from "./client-BM97zH3z.mjs";
5
+ import { runBoundedCodexAppServerTurn } from "./bounded-turn-s9yVsxaM.mjs";
6
6
  import { t as resolveCodexLocalRuntimeAttribution } from "./local-runtime-attribution-CZz2DJ4q.mjs";
7
- import { t as resolveCodexBoundedTurnIsolation } from "./bounded-turn-isolation-Brj5qzz6.mjs";
7
+ import { t as resolveCodexBoundedTurnIsolation } from "./bounded-turn-isolation-CIQJykuM.mjs";
8
8
  import { a as createAttributedCodexAssistantMessage } from "./event-projector-assistant-message-CLMKN4x-.mjs";
9
9
  import { t as codexTranscriptMirrorRuntime } from "./transcript-mirror-DVEzdOs0.mjs";
10
10
  import { t as CodexSettledTurnContext } from "./settled-turn-context-BPL6D3RO.mjs";
@@ -1,22 +1,22 @@
1
1
  import { i as isJsonObject } from "./protocol-CANUwXJ3.mjs";
2
- import { n as defineCodexBuildState, t as codexBuildSymbol } from "./build-state-DfrctLQv.mjs";
2
+ import { n as defineCodexBuildState, t as codexBuildSymbol } from "./build-state-B5mKL-in.mjs";
3
3
  import { t as CODEX_APP_SERVER_AUTH_PROVIDER } from "./auth-profile-selection-hr8ocLtz.mjs";
4
4
  import { n as isCodexAppServerProxyLaunch } from "./launch-args-DbFCehO7.mjs";
5
5
  import { a as withEphemeralCodexAuthStore, i as withClearedEnvironmentVariables, n as resolveCodexAppServerLocalHomeDir, r as resolveCodexAppServerUserHomeDir, t as resolveCodexAppServerHomeDir } from "./auth-start-options-BPIPeEX8.mjs";
6
- import { a as resolveCodexAppServerStartOptionsForAgent, d as readCodexEffectiveConfig, o as resolveCodexComputerUseConfig, t as codexAppServerStartOptionsKey, u as CODEX_SESSION_OVERRIDABLE_LAYER_TYPES } from "./config-options-nvYwVDyy.mjs";
6
+ import { a as resolveCodexAppServerStartOptionsForAgent, d as readCodexEffectiveConfig, o as resolveCodexComputerUseConfig, t as codexAppServerStartOptionsKey, u as CODEX_SESSION_OVERRIDABLE_LAYER_TYPES } from "./config-options-CZmH25Xq.mjs";
7
7
  import { d as resolveMacOSDesktopCodexBundledMarketplaceCandidates, f as resolveMacOSDesktopCodexComputerUseServiceAppCandidates, i as resolveManagedCodexNativeCommand, l as resolveFirstExistingMacOSDesktopCodexBundledMarketplacePath, r as resolveManagedCodexAppServerStartOptions, t as isManagedCodexDesktopCommand, u as resolveMacOSDesktopCodexAppPathCandidates } from "./managed-binary-DwC9wxch.mjs";
8
- import { A as waitForCodexDesktopGeneration, C as retirePendingSharedClientEntryIfUnclaimed, D as waitForUnclaimedSharedClientStartup, _ as observeSharedClientAcquire, a as readCodexCliAuthFileApiKey, b as releaseSharedClientEntry, c as resolveCodexAppServerPreparedApiKeyCacheKey, d as getCurrentSharedClientEntry, f as getOrCreateSharedClientEntry, g as observeAcquire, h as notifyDesktopGenerationDrainChecks, i as fingerprintTokenAuthProfileCacheKey, j as readCodexDesktopArtifactTreeFingerprint, k as isCodexDesktopGenerationCurrent, l as closeSharedClientEntryIfUnclaimed, n as CODEX_AUTH_JSON_FILENAME, o as readFirstNonEmptyEnv, p as getSharedCodexAppServerClientState, r as fingerprintApiKeyAuthProfileCacheKey, s as resolveCodexAppServerFallbackApiKeyCacheKey, t as CODEX_APP_SERVER_API_KEY_ENV_VARS, u as createCodexAppServerStartupLifetime, v as ownCodexStartup, w as retireSharedCodexAppServerClientIfCurrent, x as retainSharedClientEntry, y as recordSharedClientAcquireBoundary } from "./auth-cache-key-DvDLHVJe.mjs";
8
+ import { A as waitForCodexDesktopGeneration, C as retirePendingSharedClientEntryIfUnclaimed, D as waitForUnclaimedSharedClientStartup, _ as observeSharedClientAcquire, a as readCodexCliAuthFileApiKey, b as releaseSharedClientEntry, c as resolveCodexAppServerPreparedApiKeyCacheKey, d as getCurrentSharedClientEntry, f as getOrCreateSharedClientEntry, g as observeAcquire, h as notifyDesktopGenerationDrainChecks, i as fingerprintTokenAuthProfileCacheKey, j as readCodexDesktopArtifactTreeFingerprint, k as isCodexDesktopGenerationCurrent, l as closeSharedClientEntryIfUnclaimed, n as CODEX_AUTH_JSON_FILENAME, o as readFirstNonEmptyEnv, p as getSharedCodexAppServerClientState, r as fingerprintApiKeyAuthProfileCacheKey, s as resolveCodexAppServerFallbackApiKeyCacheKey, t as CODEX_APP_SERVER_API_KEY_ENV_VARS, u as createCodexAppServerStartupLifetime, v as ownCodexStartup, w as retireSharedCodexAppServerClientIfCurrent, x as retainSharedClientEntry, y as recordSharedClientAcquireBoundary } from "./auth-cache-key-DrieYJUQ.mjs";
9
9
  import { n as resolveCodexAppServerSpawnEnv } from "./transport-stdio-lgeKKHyw.mjs";
10
10
  import { n as CodexAppServerAuthProfileUnavailableError, r as formatCodexAuthProfileUnavailableMessage } from "./auth-profile-recovery-BREezV0L.mjs";
11
11
  import { a as codexPrewriteRejectionCause } from "./rpc-error-C98SHchT.mjs";
12
12
  import { i as withTimeout } from "./timeout-D0mEWSGG.mjs";
13
13
  import { n as readCodexSessionMeta } from "./session-catalog-provenance-CmsOE5mh.mjs";
14
- import { n as observeCodexCatalogClient } from "./session-catalog-events-IoszcO7-.mjs";
15
- import { n as resolveCodexAppServerRuntimeOptions } from "./config-runtime-B8agjie6.mjs";
14
+ import { n as observeCodexCatalogClient } from "./session-catalog-events-CpEyDv0D.mjs";
15
+ import { n as resolveCodexAppServerRuntimeOptions } from "./config-runtime-DGB1-VbB.mjs";
16
16
  import { a as resolveCodexAppServerAuthProfileStore, i as resolveCodexAppServerAuthProfileIdForAgent, r as resolveCodexAppServerAuthProfileId, t as isCodexAppServerNativeAuthProfile } from "./auth-profile-CgHQ8Vot.mjs";
17
17
  import { i as isCodexResponsesOAuthCredential, n as createCodexResponsesOAuth, o as resolveCodexResponsesOAuthProfileFingerprint, r as isCodexResponsesOAuth, t as CODEX_RESPONSES_OAUTH_PROVIDER } from "./responses-oauth-twnuTaAa.mjs";
18
- import { N as isUnsupportedCodexAppServerVersionError, t as CodexAppServerClient } from "./client-BpSxNz4F.mjs";
19
- import { n as isCodexWebSocketOpenFailure } from "./transport-websocket-DOY0dJXN.mjs";
18
+ import { N as isUnsupportedCodexAppServerVersionError, t as CodexAppServerClient } from "./client-BM97zH3z.mjs";
19
+ import { n as isCodexWebSocketOpenFailure } from "./transport-websocket-CEBjEtFP.mjs";
20
20
  import { t as __exportAll } from "./session-binding-sidecars-DijNZb31.mjs";
21
21
  import { asOptionalRecord, isRecord } from "openclaw/plugin-sdk/string-coerce-runtime";
22
22
  import { createHash, randomUUID } from "node:crypto";
@@ -1560,7 +1560,55 @@ function resolveExplicitChatgptAccountId(credential) {
1560
1560
  return "accountId" in credential && typeof credential.accountId === "string" ? credential.accountId.trim() || void 0 : void 0;
1561
1561
  }
1562
1562
  //#endregion
1563
+ //#region extensions/codex/src/app-server/client-thread-closure.ts
1564
+ const MAX_CLOSED_THREAD_RECEIPTS = 256;
1565
+ const THREAD_TERMINAL_NOTIFICATION_METHODS = /* @__PURE__ */ new Set([
1566
+ "thread/archived",
1567
+ "thread/deleted",
1568
+ "thread/closed"
1569
+ ]);
1570
+ const closureState = defineCodexBuildState("openclaw.codexAppServerClosedThreads", () => ({
1571
+ closedThreadsByClient: /* @__PURE__ */ new WeakMap(),
1572
+ observedClients: /* @__PURE__ */ new WeakSet()
1573
+ }))();
1574
+ function recordCodexAppServerThreadClosed(client, threadId) {
1575
+ const receipts = closureState.closedThreadsByClient.get(client) ?? /* @__PURE__ */ new Set();
1576
+ receipts.delete(threadId);
1577
+ receipts.add(threadId);
1578
+ while (receipts.size > MAX_CLOSED_THREAD_RECEIPTS) {
1579
+ const oldestThreadId = receipts.values().next().value;
1580
+ if (oldestThreadId === void 0) break;
1581
+ receipts.delete(oldestThreadId);
1582
+ }
1583
+ closureState.closedThreadsByClient.set(client, receipts);
1584
+ }
1585
+ function isCodexAppServerThreadTerminalNotification(method) {
1586
+ return THREAD_TERMINAL_NOTIFICATION_METHODS.has(method);
1587
+ }
1588
+ function ensureCodexAppServerThreadClosureTracking(client) {
1589
+ if (closureState.observedClients.has(client)) return;
1590
+ closureState.observedClients.add(client);
1591
+ client.addNotificationHandler((notification) => {
1592
+ const threadId = notification.params && typeof notification.params === "object" ? Reflect.get(notification.params, "threadId") : void 0;
1593
+ if (isCodexAppServerThreadTerminalNotification(notification.method) && typeof threadId === "string") recordCodexAppServerThreadClosed(client, threadId);
1594
+ });
1595
+ client.addCloseHandler(() => closureState.closedThreadsByClient.delete(client));
1596
+ }
1597
+ function clearCodexAppServerThreadClosed(client, threadId) {
1598
+ closureState.closedThreadsByClient.get(client)?.delete(threadId);
1599
+ }
1600
+ function wasCodexAppServerThreadClosed(client, threadId) {
1601
+ return closureState.closedThreadsByClient.get(client)?.has(threadId) === true;
1602
+ }
1603
+ //#endregion
1563
1604
  //#region extensions/codex/src/app-server/client-thread-owner.ts
1605
+ /** Background custody can survive projection replacement only under its creation policy. */
1606
+ function isThreadBackgroundOnly(runtime, threadId, configFingerprint) {
1607
+ if (!runtime || runtime.closed || !runtime.protectedThreads.has(threadId)) return false;
1608
+ const claim = runtime.claimedThreads.get(threadId);
1609
+ const policy = claim?.configFingerprint ?? runtime.retainedThreads.get(threadId)?.configFingerprint;
1610
+ return (!claim || claim.releaseAfterProtection !== void 0) && (configFingerprint === void 0 || policy === configFingerprint);
1611
+ }
1564
1612
  function createThreadOwnerToken(threadId, onInvalidated) {
1565
1613
  const owner = {
1566
1614
  invalidated: false,
@@ -1853,6 +1901,7 @@ function ensureCodexAppServerClientRuntime(client, context) {
1853
1901
  workspaceReferences: /* @__PURE__ */ new Map()
1854
1902
  };
1855
1903
  configuredClients.set(client, runtime);
1904
+ ensureCodexAppServerThreadClosureTracking(client);
1856
1905
  client.addCloseHandler(() => {
1857
1906
  runtime.closed = true;
1858
1907
  clearTimeout(runtime.evictionTimer);
@@ -1928,7 +1977,7 @@ function scheduleRetainedThreadEviction(client, runtime) {
1928
1977
  evictExpiredRetainedThreads(client, runtime).catch((error) => {
1929
1978
  embeddedAgentLog$1.warn("codex retained thread expiry failed", { reason: formatErrorMessage$1(error) });
1930
1979
  });
1931
- }, Math.max(0, expiresAt - Date.now()));
1980
+ }, Math.max(0, Math.floor(expiresAt - performance.now())));
1932
1981
  runtime.evictionTimer.unref?.();
1933
1982
  }
1934
1983
  async function releaseRetainedThread(client, runtime, threadId, assertCurrent, withCurrent) {
@@ -1962,7 +2011,7 @@ async function releaseRetainedThread(client, runtime, threadId, assertCurrent, w
1962
2011
  return true;
1963
2012
  } catch (error) {
1964
2013
  if (!runtime.closed && !transition.invalidated && runtime.releasingThreads.get(threadId) === transition && !runtime.retainedThreads.has(threadId) && !runtime.claimedThreads.has(threadId)) {
1965
- if (retained.ephemeralPolicy === void 0) retained.expiresAt = Date.now() + CODEX_APP_SERVER_LIVE_THREAD_IDLE_TIMEOUT_MS;
2014
+ if (retained.ephemeralPolicy === void 0) retained.expiresAt = performance.now() + CODEX_APP_SERVER_LIVE_THREAD_IDLE_TIMEOUT_MS;
1966
2015
  const newerThreads = [...runtime.retainedThreads.entries()].filter(([candidateThreadId]) => !olderThreadIds.has(candidateThreadId));
1967
2016
  for (const [candidateThreadId] of newerThreads) runtime.retainedThreads.delete(candidateThreadId);
1968
2017
  runtime.retainedThreads.set(threadId, retained);
@@ -1975,7 +2024,7 @@ async function releaseRetainedThread(client, runtime, threadId, assertCurrent, w
1975
2024
  }
1976
2025
  }
1977
2026
  async function evictExpiredRetainedThreads(client, runtime) {
1978
- const now = Date.now();
2027
+ const now = performance.now();
1979
2028
  for (const [threadId, thread] of runtime.retainedThreads) if (thread.expiresAt <= now && !runtime.protectedThreads.has(threadId)) await releaseRetainedThread(client, runtime, threadId);
1980
2029
  scheduleRetainedThreadEviction(client, runtime);
1981
2030
  }
@@ -2000,13 +2049,14 @@ async function retainCodexAppServerLiveThread(client, threadId, releaseThread, c
2000
2049
  return false;
2001
2050
  }
2002
2051
  const previousOwner = runtime.retainedThreads.get(threadId)?.ownerToken;
2052
+ clearCodexAppServerThreadClosed(client, threadId);
2003
2053
  runtime.retainedThreads.delete(threadId);
2004
2054
  const retained = {
2005
2055
  ownerToken,
2006
2056
  configFingerprint,
2007
2057
  ephemeralPolicy,
2008
2058
  serviceTier,
2009
- expiresAt: ephemeralPolicy === void 0 ? Date.now() + CODEX_APP_SERVER_LIVE_THREAD_IDLE_TIMEOUT_MS : Number.POSITIVE_INFINITY,
2059
+ expiresAt: ephemeralPolicy === void 0 ? performance.now() + CODEX_APP_SERVER_LIVE_THREAD_IDLE_TIMEOUT_MS : Number.POSITIVE_INFINITY,
2010
2060
  release: (releaseThread ? physicalThreadReleases.get(releaseThread) ?? releaseThread : void 0) ?? defaultThreadRelease(client)
2011
2061
  };
2012
2062
  runtime.retainedThreads.set(threadId, retained);
@@ -2050,7 +2100,7 @@ async function claimCodexAppServerLiveThread(client, threadId, onInvalidated) {
2050
2100
  return;
2051
2101
  }
2052
2102
  return claimCodexAppServerThreadOwnership(client, runtime, threadId, runtime.retainedThreads.get(threadId) ?? {
2053
- expiresAt: Date.now() + CODEX_APP_SERVER_LIVE_THREAD_IDLE_TIMEOUT_MS,
2103
+ expiresAt: performance.now() + CODEX_APP_SERVER_LIVE_THREAD_IDLE_TIMEOUT_MS,
2054
2104
  release: defaultThreadRelease(client)
2055
2105
  }, onInvalidated);
2056
2106
  }
@@ -2058,6 +2108,7 @@ function claimCodexAppServerThreadOwnership(client, runtime, threadId, retained,
2058
2108
  const previousClaim = runtime.claimedThreads.get(threadId);
2059
2109
  runtime.retainedThreads.delete(threadId);
2060
2110
  const claimed = createThreadOwnerToken(threadId, onInvalidated);
2111
+ claimed.configFingerprint = retained.configFingerprint;
2061
2112
  runtime.claimedThreads.set(threadId, claimed);
2062
2113
  previousClaim?.invalidate();
2063
2114
  retained.ownerToken?.invalidate();
@@ -2137,6 +2188,10 @@ function isCodexAppServerLiveThreadClaimed(client, threadId) {
2137
2188
  const runtime = configuredClients.get(client);
2138
2189
  return runtime !== void 0 && !runtime.closed && runtime.claimedThreads.has(threadId);
2139
2190
  }
2191
+ /** Completed foreground work may leave cleanup custody with native background work. */
2192
+ function isCodexAppServerLiveThreadBackgroundOnly(client, threadId, configFingerprint) {
2193
+ return isThreadBackgroundOnly(configuredClients.get(client), threadId, configFingerprint);
2194
+ }
2140
2195
  /** Native commands and children can still need an otherwise-idle subscription. */
2141
2196
  function isCodexAppServerLiveThreadProtected(client, threadId) {
2142
2197
  const runtime = configuredClients.get(client);
@@ -2213,7 +2268,7 @@ function protectCodexAppServerLiveThread(client, threadId) {
2213
2268
  if (releaseThreadProtection(runtime, threadId)) {
2214
2269
  const retained = runtime.retainedThreads.get(threadId);
2215
2270
  if (retained) {
2216
- if (retained.ephemeralPolicy === void 0) retained.expiresAt = Date.now() + CODEX_APP_SERVER_LIVE_THREAD_IDLE_TIMEOUT_MS;
2271
+ if (retained.ephemeralPolicy === void 0) retained.expiresAt = performance.now() + CODEX_APP_SERVER_LIVE_THREAD_IDLE_TIMEOUT_MS;
2217
2272
  runtime.retainedThreads.delete(threadId);
2218
2273
  runtime.retainedThreads.set(threadId, retained);
2219
2274
  }
@@ -2485,8 +2540,8 @@ async function prepareCodexInferenceRoute(params) {
2485
2540
  throw new Error("Codex inference route limit reached; start a fresh managed native connection before retrying.");
2486
2541
  }
2487
2542
  pending = Promise.all([
2488
- import("./inference-proxy-BDWV0djM.mjs"),
2489
- import("./native-subagent-monitor-gqu3TQOv.mjs").then((n) => n.n),
2543
+ import("./inference-proxy-DSnaS-uS.mjs"),
2544
+ import("./native-subagent-monitor-CJaIve3h.mjs").then((n) => n.n),
2490
2545
  import("./inference-dispatch-CO6tTs4q.mjs")
2491
2546
  ]).then(([{ createCodexInferenceProxy }, native, { createCodexInferenceModelBinding }]) => {
2492
2547
  assertClient();
@@ -3301,7 +3356,7 @@ async function startInitializedCodexAppServerClientOnce(params) {
3301
3356
  } finally {
3302
3357
  artifactDrain?.cancel();
3303
3358
  }
3304
- const runtimeArtifactModule = params.runtimeArtifactMode ? await import("./runtime-artifact-nFHy1R0x.mjs") : void 0;
3359
+ const runtimeArtifactModule = params.runtimeArtifactMode ? await import("./runtime-artifact-CCPLKFGR.mjs") : void 0;
3305
3360
  const runtimeArtifactBeforeStart = runtimeArtifactModule ? await runtimeArtifactModule.captureCodexAppServerRuntimeArtifactBeforeStart({
3306
3361
  startOptions,
3307
3362
  spawnIdentity: resolveCodexAppServerSpawnIdentity(startOptions),
@@ -3555,4 +3610,4 @@ function clearSharedCodexAppServerClientIfCurrentAndUnclaimed(client) {
3555
3610
  };
3556
3611
  }
3557
3612
  //#endregion
3558
- export { createCodexEphemeralThreadPolicy as $, bindCodexInferenceThread as A, isCodexAppServerClientRuntimeLive as B, CodexThreadBindingConflictError as C, nativeHookRelayUnregisterQueue as D, isCodexContextRestartSelectionChangedError as E, consumeCodexAppServerLiveThread as F, readCodexClientSessionMeta as G, isCodexAppServerLiveThreadProtected as H, ensureCodexAppServerClientRuntime as I, revertCodexAppServerLiveThreadInstructions as J, releaseCodexAppServerLiveThread as K, forgetCodexWorkspaceReferences as L, getCodexInferenceThreadQualification as M, prepareCodexInferenceThreadConfig as N, acquireCodexNativeConfigFence as O, claimCodexAppServerLiveThread as P, rememberCodexRateLimitsRead as Q, hasCodexAppServerLiveThread as R, CodexAdoptedThreadActiveError as S, CodexThreadStartRequestError as T, prepareCodexWorkspaceReferences as U, isCodexAppServerLiveThreadClaimed as V, protectCodexAppServerLiveThread as W, readCodexRateLimitsRevision as X, unsubscribeCodexAppServerLiveThread as Y, readRecentCodexRateLimits as Z, retainSharedCodexAppServerClientIfCurrent as _, clearSharedCodexAppServerClientIfCurrentAndUnclaimed as a, hasLegacyCodexComputerUseMcpPolicy as at, withLeasedCodexAppServerClientStartSelectionRetry as b, getLeasedSharedCodexAppServerClient as c, ensureCodexComputerUseSharedPluginCache as ct, readCodexAppServerClientDesktopGeneration as d, TURN_FINALIZE_DRAIN_ABORT_GRACE_MS as dt, reconcileCodexComputerUseStartArtifacts as et, readCodexAppServerClientDesktopGenerationFingerprint as f, TURN_TERMINAL_SETTLEMENT_TIMEOUT_MS as ft, resolveCodexNativeConfigFenceKey as g, withCodexStartupTimeout as gt, releaseLeasedSharedCodexAppServerClient as h, resolveCodexStartupTimeoutMs as ht, clearSharedCodexAppServerClientIfCurrent as i, resolveClientManagedBundledMarketplacePath as it, getCodexInferenceThread as j, assertCodexInferenceRouteConfig as k, getSharedCodexAppServerClient as l, assertNotSymlink as lt, releaseCodexAppServerClientLease as m, resolveCodexGatewayTimeoutWithGraceMs as mt, captureCodexAppServerClientLifetime as n, resolveCodexAppServerPreparedAuthHandoff as nt, clearSharedCodexAppServerClientIfCurrentAndWait as o, isLegacyCodexComputerUsePluginDisabled as ot, readCodexAppServerClientProcessIdentity as p, isCodexAppServerStartupError as pt, retainCodexAppServerLiveThread as q, captureSharedCodexAppServerCatalogLifetime as r, resolveBundledComputerUseMarketplacePath as rt, createIsolatedCodexAppServerClient as s, resolveManagedCodexComputerUseConfig as st, assertCodexAppServerClientStartSelectionCurrent as t, resolveCodexAppServerAuthAccountCacheKey as tt, isCodexAppServerStartSelectionChangedError as u, CodexAppServerStartupError as ut, shared_client_exports as v, CodexThreadClientReplacementError as w, CODEX_APP_SERVER_CONTEXT_RESTART_SELECTION_CHANGED as x, waitForCodexAppServerClientDesktopGenerationDrain as y, hasCodexAppServerSiblingThreadWork as z };
3613
+ export { rememberCodexRateLimitsRead as $, bindCodexInferenceThread as A, isCodexAppServerClientRuntimeLive as B, CodexThreadBindingConflictError as C, nativeHookRelayUnregisterQueue as D, isCodexContextRestartSelectionChangedError as E, consumeCodexAppServerLiveThread as F, protectCodexAppServerLiveThread as G, isCodexAppServerLiveThreadClaimed as H, ensureCodexAppServerClientRuntime as I, retainCodexAppServerLiveThread as J, readCodexClientSessionMeta as K, forgetCodexWorkspaceReferences as L, getCodexInferenceThreadQualification as M, prepareCodexInferenceThreadConfig as N, acquireCodexNativeConfigFence as O, claimCodexAppServerLiveThread as P, readRecentCodexRateLimits as Q, hasCodexAppServerLiveThread as R, CodexAdoptedThreadActiveError as S, CodexThreadStartRequestError as T, isCodexAppServerLiveThreadProtected as U, isCodexAppServerLiveThreadBackgroundOnly as V, prepareCodexWorkspaceReferences as W, unsubscribeCodexAppServerLiveThread as X, revertCodexAppServerLiveThreadInstructions as Y, readCodexRateLimitsRevision as Z, retainSharedCodexAppServerClientIfCurrent as _, resolveCodexGatewayTimeoutWithGraceMs as _t, clearSharedCodexAppServerClientIfCurrentAndUnclaimed as a, resolveCodexAppServerPreparedAuthHandoff as at, withLeasedCodexAppServerClientStartSelectionRetry as b, getLeasedSharedCodexAppServerClient as c, hasLegacyCodexComputerUseMcpPolicy as ct, readCodexAppServerClientDesktopGeneration as d, ensureCodexComputerUseSharedPluginCache as dt, createCodexEphemeralThreadPolicy as et, readCodexAppServerClientDesktopGenerationFingerprint as f, assertNotSymlink as ft, resolveCodexNativeConfigFenceKey as g, isCodexAppServerStartupError as gt, releaseLeasedSharedCodexAppServerClient as h, TURN_TERMINAL_SETTLEMENT_TIMEOUT_MS as ht, clearSharedCodexAppServerClientIfCurrent as i, resolveCodexAppServerAuthAccountCacheKey as it, getCodexInferenceThread as j, assertCodexInferenceRouteConfig as k, getSharedCodexAppServerClient as l, isLegacyCodexComputerUsePluginDisabled as lt, releaseCodexAppServerClientLease as m, TURN_FINALIZE_DRAIN_ABORT_GRACE_MS as mt, captureCodexAppServerClientLifetime as n, wasCodexAppServerThreadClosed as nt, clearSharedCodexAppServerClientIfCurrentAndWait as o, resolveBundledComputerUseMarketplacePath as ot, readCodexAppServerClientProcessIdentity as p, CodexAppServerStartupError as pt, releaseCodexAppServerLiveThread as q, captureSharedCodexAppServerCatalogLifetime as r, reconcileCodexComputerUseStartArtifacts as rt, createIsolatedCodexAppServerClient as s, resolveClientManagedBundledMarketplacePath as st, assertCodexAppServerClientStartSelectionCurrent as t, isCodexAppServerThreadTerminalNotification as tt, isCodexAppServerStartSelectionChangedError as u, resolveManagedCodexComputerUseConfig as ut, shared_client_exports as v, resolveCodexStartupTimeoutMs as vt, CodexThreadClientReplacementError as w, CODEX_APP_SERVER_CONTEXT_RESTART_SELECTION_CHANGED as x, waitForCodexAppServerClientDesktopGenerationDrain as y, withCodexStartupTimeout as yt, hasCodexAppServerSiblingThreadWork as z };
@@ -1,29 +1,29 @@
1
1
  import { i as isJsonObject } from "./protocol-CANUwXJ3.mjs";
2
2
  import { m as sessionBindingIdentity } from "./session-binding-record-C2kDBZhx.mjs";
3
- import { c as withMcpElicitationsApprovalPolicy, d as readCodexRequirementsToml, n as hasCodexMcpToolApprovalOverrides, s as shouldAutoApproveCodexAppServerApprovals } from "./config-security-D0hAOQRI.mjs";
3
+ import { c as withMcpElicitationsApprovalPolicy, d as readCodexRequirementsToml, n as hasCodexMcpToolApprovalOverrides, s as shouldAutoApproveCodexAppServerApprovals } from "./config-security-DpkGNy5T.mjs";
4
4
  import { c as isCodexPairedNodeRemoteExecPlacementSandbox, d as readCodexPluginConfig, l as isCodexRemoteExecPlacementSandbox, u as isCodexSandboxExecServerEnabled } from "./config-parsing-CVK2Q463.mjs";
5
- import { i as resolveCodexAppServerHomeScope, l as resolveCodexModelBackedReviewerPolicyContext } from "./config-options-nvYwVDyy.mjs";
5
+ import { i as resolveCodexAppServerHomeScope, l as resolveCodexModelBackedReviewerPolicyContext } from "./config-options-CZmH25Xq.mjs";
6
6
  import { n as formatCodexUsageLimitErrorMessage } from "./rate-limits-CI8pTPqL.mjs";
7
- import { i as resolveCodexBindingAppServerConnection, r as requireCodexSupervisionModelSelection } from "./binding-connection-X1ZeEDz8.mjs";
8
- import { n as canUseCodexModelBackedApprovalsReviewerForModel, r as resolveOpenClawExecPolicyForCodexAppServer } from "./config-G4IGX6bK.mjs";
9
- import { Z as readRecentCodexRateLimits, b as withLeasedCodexAppServerClientStartSelectionRetry, c as getLeasedSharedCodexAppServerClient, m as releaseCodexAppServerClientLease, nt as resolveCodexAppServerPreparedAuthHandoff } from "./shared-client-wb1JBldZ.mjs";
10
- import { E as resolveDynamicToolCallTimeoutMs, O as toCodexDynamicToolProtocolResponse, T as handleDynamicToolCallWithTimeout, _ as assertCodexTurnStartResponse, a as isCodexAppServerIndeterminateRequestCancellationError, k as resolveCodexToolAbortTerminalReason, m as assertCodexThreadForkResponse, r as isCodexAppServerApprovalRequest, w as createCodexElicitationResponse, y as readCodexDynamicToolCallParams } from "./client-BpSxNz4F.mjs";
11
- import { d as terminateCodexBackgroundTerminals, f as unsubscribeCodexThreadBestEffort, l as retireUnsafeCodexTurnClientBestEffort, s as interruptCodexTurnAndWaitBestEffort } from "./attempt-client-cleanup-TScCVTsk.mjs";
12
- import { t as CodexEphemeralTurn } from "./ephemeral-turn-C6aFeGFS.mjs";
13
- import { d as mergeCodexThreadConfigs, f as refreshCodexPluginAppApprovalPolicy } from "./project-doc-thread-config-B2ZD23A_.mjs";
7
+ import { i as resolveCodexBindingAppServerConnection, r as requireCodexSupervisionModelSelection } from "./binding-connection-C0t9TBX_.mjs";
8
+ import { n as canUseCodexModelBackedApprovalsReviewerForModel, r as resolveOpenClawExecPolicyForCodexAppServer } from "./config-LQemoqTL.mjs";
9
+ import { Q as readRecentCodexRateLimits, at as resolveCodexAppServerPreparedAuthHandoff, b as withLeasedCodexAppServerClientStartSelectionRetry, c as getLeasedSharedCodexAppServerClient, m as releaseCodexAppServerClientLease } from "./shared-client-AdQX0Tdq.mjs";
10
+ import { E as resolveDynamicToolCallTimeoutMs, O as toCodexDynamicToolProtocolResponse, T as handleDynamicToolCallWithTimeout, _ as assertCodexTurnStartResponse, a as isCodexAppServerIndeterminateRequestCancellationError, k as resolveCodexToolAbortTerminalReason, m as assertCodexThreadForkResponse, r as isCodexAppServerApprovalRequest, w as createCodexElicitationResponse, y as readCodexDynamicToolCallParams } from "./client-BM97zH3z.mjs";
11
+ import { d as terminateCodexBackgroundTerminals, f as unsubscribeCodexThreadBestEffort, l as retireUnsafeCodexTurnClientBestEffort, s as interruptCodexTurnAndWaitBestEffort } from "./attempt-client-cleanup-jWVRH043.mjs";
12
+ import { t as CodexEphemeralTurn } from "./ephemeral-turn-DeppK8zz.mjs";
13
+ import { d as mergeCodexThreadConfigs, f as refreshCodexPluginAppApprovalPolicy } from "./project-doc-thread-config-D_sWbxFR.mjs";
14
14
  import { n as resolveCodexAppServerReasoningEffort, t as readCodexSupportedReasoningEfforts } from "./reasoning-effort-CS9kKWB9.mjs";
15
- import { h as resolveCodexWebSearchPlan, r as buildCodexRuntimeThreadConfig, z as resolveCodexDynamicToolsLoading } from "./thread-requests-BqPhA4Gs.mjs";
15
+ import { h as resolveCodexWebSearchPlan, r as buildCodexRuntimeThreadConfig, z as resolveCodexDynamicToolsLoading } from "./thread-requests-DjyDmCo4.mjs";
16
16
  import { i as resolveCodexSessionBinding } from "./session-binding-BDnNz-Co.mjs";
17
17
  import { i as resolveCodexAppServerThreadModelSelection, t as CODEX_NATIVE_PERSONALITY_NONE } from "./thread-model-selection-DcVebr8N.mjs";
18
18
  import { t as resolveCodexNativeExecutionBlock } from "./sandbox-guard-Cf9XMRrg.mjs";
19
- import { i as assertCodexSupervisionThreadLineage, n as CodexThreadPolicyHandoffError, o as refreshCodexThreadPolicy } from "./thread-policy-BMRvlOi-.mjs";
19
+ import { i as assertCodexSupervisionThreadLineage, n as CodexThreadPolicyHandoffError, o as refreshCodexThreadPolicy } from "./thread-policy-Dp4CQjdL.mjs";
20
20
  import { o as runCodexCleanupStep } from "./run-attempt-lifecycle-DN-ATDp9.mjs";
21
- import { a as resolveCodexExternalSandboxPolicyForOpenClawSandbox, c as shouldEnableCodexAppServerNativeToolSurface, l as shouldRequireCodexSandboxExecServerEnvironment, o as resolveCodexMessageToolProvider, s as resolveCodexSandboxEnvironmentSelection, t as buildDynamicTools } from "./dynamic-tool-build-CoMf7IKx.mjs";
22
- import { a as buildCodexNativeHookRelayDisabledConfig, i as buildCodexNativeHookRelayConfig, l as resolveCodexNativeHookRelayEvents, u as resolveCodexNativeHookRelayTtlMs } from "./native-hook-relay-BQ9UkpeG.mjs";
23
- import { i as resolveCodexSessionPermissionCwd, n as applyCodexSessionPermissionPolicy, r as resolveCodexEffectiveSessionPermissionPolicy, t as CODEX_SESSION_PERMISSION_EXEC_MODES } from "./session-permission-policy-BYI6mp5u.mjs";
24
- import { a as handleCodexAppServerApprovalRequest, c as createCodexNativePreToolUseFailureBuffer, d as buildCodexTemporalAdditionalContext, g as buildCodexUserInput, i as createCodexDynamicToolDiagnostics, o as ensureCodexSandboxExecServerEnvironment, r as routeCodexAppServerElicitationRequest, s as releaseCodexSandboxExecServerEnvironment, t as createCodexDynamicToolBridge, y as CodexNativeToolLifecycleProjector } from "./dynamic-tools-CKynHtxM.mjs";
25
- import { t as resolveCodexAppServerForModelProvider } from "./app-server-policy-XTIa6h5k.mjs";
26
- import { n as resolveCodexProviderWebSearchSupportForClient } from "./provider-capabilities-DOBUBt86.mjs";
21
+ import { a as resolveCodexExternalSandboxPolicyForOpenClawSandbox, c as shouldEnableCodexAppServerNativeToolSurface, l as shouldRequireCodexSandboxExecServerEnvironment, o as resolveCodexMessageToolProvider, s as resolveCodexSandboxEnvironmentSelection, t as buildDynamicTools } from "./dynamic-tool-build-Dp4v52Kl.mjs";
22
+ import { a as buildCodexNativeHookRelayDisabledConfig, i as buildCodexNativeHookRelayConfig, l as resolveCodexNativeHookRelayEvents, u as resolveCodexNativeHookRelayTtlMs } from "./native-hook-relay-Ctyky2Qt.mjs";
23
+ import { i as resolveCodexSessionPermissionCwd, n as applyCodexSessionPermissionPolicy, r as resolveCodexEffectiveSessionPermissionPolicy, t as CODEX_SESSION_PERMISSION_EXEC_MODES } from "./session-permission-policy-C7kYxPGd.mjs";
24
+ import { a as handleCodexAppServerApprovalRequest, c as createCodexNativePreToolUseFailureBuffer, d as buildCodexTemporalAdditionalContext, g as buildCodexUserInput, i as createCodexDynamicToolDiagnostics, o as ensureCodexSandboxExecServerEnvironment, r as routeCodexAppServerElicitationRequest, s as releaseCodexSandboxExecServerEnvironment, t as createCodexDynamicToolBridge, y as CodexNativeToolLifecycleProjector } from "./dynamic-tools-C1Egdhrx.mjs";
25
+ import { t as resolveCodexAppServerForModelProvider } from "./app-server-policy-V8zuN8q_.mjs";
26
+ import { n as resolveCodexProviderWebSearchSupportForClient } from "./provider-capabilities-BCZeV7xZ.mjs";
27
27
  import { readStringField } from "openclaw/plugin-sdk/string-coerce-runtime";
28
28
  import { randomUUID } from "node:crypto";
29
29
  import { isDeepStrictEqual } from "node:util";
@@ -1,7 +1,7 @@
1
1
  import { a as defaultCodexAppInventoryCache, r as buildCodexPluginAppCacheKey } from "./plugin-app-cache-key-Bg9DbDI6.mjs";
2
- import { a as withCodexAppServerJsonClient } from "./request-DhbisYCc.mjs";
3
- import { a as marketplaceRef, o as pluginReadParams, r as isOpenAiCuratedMarketplaceName, u as CODEX_PLUGINS_MARKETPLACE_NAME } from "./plugin-inventory-kLR7G02h.mjs";
4
- import "./config-G4IGX6bK.mjs";
2
+ import { a as withCodexAppServerJsonClient } from "./request-XC1RG34l.mjs";
3
+ import { a as marketplaceRef, o as pluginReadParams, r as isOpenAiCuratedMarketplaceName, u as CODEX_PLUGINS_MARKETPLACE_NAME } from "./plugin-inventory-OhiCoyPH.mjs";
4
+ import "./config-LQemoqTL.mjs";
5
5
  import { t as __exportAll } from "./session-binding-sidecars-DijNZb31.mjs";
6
6
  import { asNonArrayRecord } from "openclaw/plugin-sdk/string-coerce-runtime";
7
7
  import path from "node:path";
@@ -1,11 +1,11 @@
1
1
  import { i as isJsonObject, r as flattenCodexDynamicToolFunctions } from "./protocol-CANUwXJ3.mjs";
2
2
  import { n as matchesPendingSupervisionBranch } from "./session-binding-record-codec-CWQXr9os.mjs";
3
3
  import { m as sessionBindingIdentity, n as assertCodexBindingMayBeReplaced } from "./session-binding-record-C2kDBZhx.mjs";
4
- import { l as fingerprintCodexPolicy } from "./config-security-D0hAOQRI.mjs";
4
+ import { l as fingerprintCodexPolicy } from "./config-security-DpkGNy5T.mjs";
5
5
  import { f as resolveCodexPluginsPolicy } from "./config-parsing-CVK2Q463.mjs";
6
6
  import { n as resolveCodexAppServerLocalHomeDir, t as resolveCodexAppServerHomeDir } from "./auth-start-options-BPIPeEX8.mjs";
7
- import { d as readCodexEffectiveConfig, s as assertCodexModelBackedReviewerEffectiveConfig, u as CODEX_SESSION_OVERRIDABLE_LAYER_TYPES } from "./config-options-nvYwVDyy.mjs";
8
- import { S as retainSharedCodexAppServerClientByInstanceId, d as getCurrentSharedClientEntry } from "./auth-cache-key-DvDLHVJe.mjs";
7
+ import { d as readCodexEffectiveConfig, s as assertCodexModelBackedReviewerEffectiveConfig, u as CODEX_SESSION_OVERRIDABLE_LAYER_TYPES } from "./config-options-CZmH25Xq.mjs";
8
+ import { S as retainSharedCodexAppServerClientByInstanceId, d as getCurrentSharedClientEntry } from "./auth-cache-key-DrieYJUQ.mjs";
9
9
  import { t as withCodexAppServerThreadMutation } from "./thread-ownership-queue-CeyYScUC.mjs";
10
10
  import { o as isCodexAppServerOverloadError, r as CodexAppServerRpcError, s as isCodexThreadReadMissingError } from "./rpc-error-C98SHchT.mjs";
11
11
  import { t as codexCatalogHomeId } from "./session-catalog-home-id-vlih0B_g.mjs";
@@ -13,34 +13,34 @@ import { r as withAbortableTimeout } from "./timeout-D0mEWSGG.mjs";
13
13
  import { t as projectBoundedCodexThreadHistory } from "./transcript-history-projection-DfKcoZCB.mjs";
14
14
  import { a as defaultCodexAppInventoryCache, t as buildCodexAppServerConnectionFingerprint } from "./plugin-app-cache-key-Bg9DbDI6.mjs";
15
15
  import { n as readCodexSessionMeta } from "./session-catalog-provenance-CmsOE5mh.mjs";
16
- import { t as assertCodexSessionRuntimeOwnership } from "./binding-connection-X1ZeEDz8.mjs";
17
- import { c as resolveRecoverableCodexPluginConfigKeys } from "./plugin-inventory-kLR7G02h.mjs";
18
- import "./config-G4IGX6bK.mjs";
16
+ import { t as assertCodexSessionRuntimeOwnership } from "./binding-connection-C0t9TBX_.mjs";
17
+ import { c as resolveRecoverableCodexPluginConfigKeys } from "./plugin-inventory-OhiCoyPH.mjs";
18
+ import "./config-LQemoqTL.mjs";
19
19
  import { c as resolveCodexContextEngineProjectionMaxChars } from "./context-engine-projection-ps-yn_ci.mjs";
20
20
  import { n as normalizeCodexAppServerBindingModelProvider } from "./auth-profile-CgHQ8Vot.mjs";
21
- import { $ as createCodexEphemeralThreadPolicy, A as bindCodexInferenceThread, B as isCodexAppServerClientRuntimeLive, C as CodexThreadBindingConflictError, F as consumeCodexAppServerLiveThread, H as isCodexAppServerLiveThreadProtected, K as releaseCodexAppServerLiveThread, M as getCodexInferenceThreadQualification, N as prepareCodexInferenceThreadConfig, S as CodexAdoptedThreadActiveError, T as CodexThreadStartRequestError, V as isCodexAppServerLiveThreadClaimed, Y as unsubscribeCodexAppServerLiveThread, j as getCodexInferenceThread, k as assertCodexInferenceRouteConfig, n as captureCodexAppServerClientLifetime, w as CodexThreadClientReplacementError, z as hasCodexAppServerSiblingThreadWork } from "./shared-client-wb1JBldZ.mjs";
22
- import { C as resolveCodexThreadRolloutPath, F as getCodexAppServerClientInstanceId, L as resolveCodexAppServerClientInstanceId, S as readSupervisionResponseThreadId, c as isCodexAppServerRequestTimeoutError, g as assertCodexThreadStartResponse, m as assertCodexThreadForkResponse, p as assertCodexThreadAcceptsDirectInput, v as assertExactSupervisionModelSelection } from "./client-BpSxNz4F.mjs";
23
- import { r as hasCodexAppServerSiblingRouteWork } from "./turn-router-DdlzuFdm.mjs";
24
- import { f as unsubscribeCodexThreadBestEffort, l as retireUnsafeCodexTurnClientBestEffort, n as CODEX_APP_SERVER_UNSUBSCRIBE_TIMEOUT_MS, o as closeCodexStartupClientBestEffort, r as CodexAppServerUnsafeSubscriptionError } from "./attempt-client-cleanup-TScCVTsk.mjs";
25
- import { a as buildCodexPluginThreadConfigInputFingerprint, c as buildPluginAppPolicyContext, d as mergeCodexThreadConfigs, i as buildCodexPluginThreadConfig, l as disableUnlistedCodexApps, m as buildCodexAppApprovalOverrides, n as mergeCodexNativeProjectDocThreadConfig, o as buildCodexPluginThreadConfigTimeoutFallback, p as shouldBuildCodexPluginThreadConfig, r as buildCodexPluginAppsConfigPatchFromPolicyContext, u as isCodexPluginThreadBindingStale } from "./project-doc-thread-config-B2ZD23A_.mjs";
26
- import { A as isTransientWebSearchRestriction, C as fingerprintEnvironmentSelection, D as readActiveCodexTurnIdsFromResume, E as legacyFingerprintUserMcpServersConfigPatch, I as isMessageOnlyCodexSourceReply, L as isSystemAgentOnlyCodexDynamicToolAllowlist, M as shouldRotateCodexAppServerBindingForRuntime, N as shouldRotateCodexGpt56MultiAgentBinding, O as shouldStartTransientNoToolThread, S as fingerprintCodexThreadConfig, T as fingerprintUserMcpServersConfigPatch, _ as buildDeveloperInstructions, b as codexDynamicToolsFingerprint, c as codexThreadSandboxOrPermissions, d as readCodexManagedRequirementsFingerprint, f as resolveCodexThreadApprovalsReviewer, g as mergeCodexNativeShellEnvironment, h as resolveCodexWebSearchPlan, i as buildCodexRuntimeThreadConfigForRun, j as shouldRecheckRecoverablePluginBinding, n as buildCodexRingZeroThreadConfigPatch, o as buildThreadResumeParams, p as attestCodexRestrictedToolSurfaceMcpServersDisabled, s as buildThreadStartParams, t as assertCodexManagedRequirementsDoNotOverrideToolPolicy, u as readCodexInheritedMcpServerNames, v as areCodexDynamicToolFingerprintsCompatible, w as fingerprintJsonObject, x as codexLegacyDynamicToolsFingerprint, y as areUserMcpServersFingerprintsCompatible } from "./thread-requests-BqPhA4Gs.mjs";
21
+ import { A as bindCodexInferenceThread, B as isCodexAppServerClientRuntimeLive, C as CodexThreadBindingConflictError, F as consumeCodexAppServerLiveThread, H as isCodexAppServerLiveThreadClaimed, M as getCodexInferenceThreadQualification, N as prepareCodexInferenceThreadConfig, S as CodexAdoptedThreadActiveError, T as CodexThreadStartRequestError, U as isCodexAppServerLiveThreadProtected, V as isCodexAppServerLiveThreadBackgroundOnly, X as unsubscribeCodexAppServerLiveThread, et as createCodexEphemeralThreadPolicy, j as getCodexInferenceThread, k as assertCodexInferenceRouteConfig, n as captureCodexAppServerClientLifetime, nt as wasCodexAppServerThreadClosed, q as releaseCodexAppServerLiveThread, tt as isCodexAppServerThreadTerminalNotification, w as CodexThreadClientReplacementError, z as hasCodexAppServerSiblingThreadWork } from "./shared-client-AdQX0Tdq.mjs";
22
+ import { C as resolveCodexThreadRolloutPath, F as getCodexAppServerClientInstanceId, L as resolveCodexAppServerClientInstanceId, S as readSupervisionResponseThreadId, c as isCodexAppServerRequestTimeoutError, g as assertCodexThreadStartResponse, m as assertCodexThreadForkResponse, p as assertCodexThreadAcceptsDirectInput, v as assertExactSupervisionModelSelection } from "./client-BM97zH3z.mjs";
23
+ import { r as hasCodexAppServerSiblingRouteWork } from "./turn-router-DnfbVPvu.mjs";
24
+ import { f as unsubscribeCodexThreadBestEffort, l as retireUnsafeCodexTurnClientBestEffort, n as CODEX_APP_SERVER_UNSUBSCRIBE_TIMEOUT_MS, o as closeCodexStartupClientBestEffort, r as CodexAppServerUnsafeSubscriptionError } from "./attempt-client-cleanup-jWVRH043.mjs";
25
+ import { a as buildCodexPluginThreadConfigInputFingerprint, c as buildPluginAppPolicyContext, d as mergeCodexThreadConfigs, i as buildCodexPluginThreadConfig, l as disableUnlistedCodexApps, m as buildCodexAppApprovalOverrides, n as mergeCodexNativeProjectDocThreadConfig, o as buildCodexPluginThreadConfigTimeoutFallback, p as shouldBuildCodexPluginThreadConfig, r as buildCodexPluginAppsConfigPatchFromPolicyContext, u as isCodexPluginThreadBindingStale } from "./project-doc-thread-config-D_sWbxFR.mjs";
26
+ import { A as isTransientWebSearchRestriction, C as fingerprintEnvironmentSelection, D as readActiveCodexTurnIdsFromResume, E as legacyFingerprintUserMcpServersConfigPatch, I as isMessageOnlyCodexSourceReply, L as isSystemAgentOnlyCodexDynamicToolAllowlist, M as shouldRotateCodexAppServerBindingForRuntime, N as shouldRotateCodexGpt56MultiAgentBinding, O as shouldStartTransientNoToolThread, S as fingerprintCodexThreadConfig, T as fingerprintUserMcpServersConfigPatch, _ as buildDeveloperInstructions, b as codexDynamicToolsFingerprint, c as codexThreadSandboxOrPermissions, d as readCodexManagedRequirementsFingerprint, f as resolveCodexThreadApprovalsReviewer, g as mergeCodexNativeShellEnvironment, h as resolveCodexWebSearchPlan, i as buildCodexRuntimeThreadConfigForRun, j as shouldRecheckRecoverablePluginBinding, n as buildCodexRingZeroThreadConfigPatch, o as buildThreadResumeParams, p as attestCodexRestrictedToolSurfaceMcpServersDisabled, s as buildThreadStartParams, t as assertCodexManagedRequirementsDoNotOverrideToolPolicy, u as readCodexInheritedMcpServerNames, v as areCodexDynamicToolFingerprintsCompatible, w as fingerprintJsonObject, x as codexLegacyDynamicToolsFingerprint, y as areUserMcpServersFingerprintsCompatible } from "./thread-requests-DjyDmCo4.mjs";
27
27
  import { i as resolveCodexSessionBinding, o as hashCodexAppServerBindingFingerprint } from "./session-binding-BDnNz-Co.mjs";
28
28
  import { i as resolveCodexAppServerThreadModelSelection, n as resolveCodexAppServerModelProvider } from "./thread-model-selection-DcVebr8N.mjs";
29
- import { c as withExclusiveCodexAppServerThread, r as retainCodexAppServerBindingSubscription, t as isSameCodexAppServerThreadOwner } from "./thread-ownership-CTUs8Eyu.mjs";
30
- import { a as refreshCodexThreadInstructions, i as assertCodexSupervisionThreadLineage, n as CodexThreadPolicyHandoffError, o as refreshCodexThreadPolicy, r as assertAdoptedCodexThreadResumeAllowed, t as CodexIncognitoPolicyChangeError } from "./thread-policy-BMRvlOi-.mjs";
31
- import { t as resumeCodexAppServerThread } from "./thread-resume-CD48Vab8.mjs";
29
+ import { c as withExclusiveCodexAppServerThread, r as retainCodexAppServerBindingSubscription, t as isSameCodexAppServerThreadOwner } from "./thread-ownership-OXzPB_RV.mjs";
30
+ import { a as refreshCodexThreadInstructions, i as assertCodexSupervisionThreadLineage, n as CodexThreadPolicyHandoffError, o as refreshCodexThreadPolicy, r as assertAdoptedCodexThreadResumeAllowed, t as CodexIncognitoPolicyChangeError } from "./thread-policy-Dp4CQjdL.mjs";
31
+ import { t as resumeCodexAppServerThread } from "./thread-resume-8YKfRoX6.mjs";
32
32
  import { r as readCodexMcpToolConnectorId } from "./mcp-tool-metadata-_sawBkIh.mjs";
33
- import { n as disableCodexPluginThreadConfig } from "./dynamic-tool-build-CoMf7IKx.mjs";
34
- import { n as CodexManagedHooksOnlyError, r as assertCodexNativeHookRelayAllowed } from "./native-hook-relay-BQ9UkpeG.mjs";
33
+ import { n as disableCodexPluginThreadConfig } from "./dynamic-tool-build-Dp4v52Kl.mjs";
34
+ import { n as CodexManagedHooksOnlyError, r as assertCodexNativeHookRelayAllowed } from "./native-hook-relay-Ctyky2Qt.mjs";
35
35
  import { t as defaultCodexPluginMetadataCache } from "./plugin-metadata-cache-Bi8TAPwX.mjs";
36
- import { a as discardUnattestedCodexPluginThread, i as checkCodexThreadAppAvailability, n as resolveCodexNativeSkillIsolation, o as hasCodexNativeToolCatalog, r as attestCodexThreadToolSurface, s as loadCodexNativeToolCatalog, t as applyCodexNativeSkillIsolation } from "./native-skill-isolation-CxZRtiWZ.mjs";
36
+ import { a as discardUnattestedCodexPluginThread, i as checkCodexThreadAppAvailability, n as resolveCodexNativeSkillIsolation, o as hasCodexNativeToolCatalog, r as attestCodexThreadToolSurface, s as loadCodexNativeToolCatalog, t as applyCodexNativeSkillIsolation } from "./native-skill-isolation-C4XYLm33.mjs";
37
37
  import { asOptionalRecord, normalizeOptionalString } from "openclaw/plugin-sdk/string-coerce-runtime";
38
38
  import crypto from "node:crypto";
39
39
  import { isDeepStrictEqual } from "node:util";
40
40
  import { resolveSessionAgentIdsStrict } from "openclaw/plugin-sdk/agent-scope-runtime";
41
41
  import path from "node:path";
42
- import { isIncognitoSessionKey } from "openclaw/plugin-sdk/session-key-runtime";
43
42
  import { createStageTimingTracker, formatStageTimings, racePromiseWithAbortSignal } from "openclaw/plugin-sdk/time-runtime";
43
+ import { isIncognitoSessionKey } from "openclaw/plugin-sdk/session-key-runtime";
44
44
  import { resolveAgentDir as resolveAgentDir$1 } from "openclaw/plugin-sdk/agent-runtime";
45
45
  import { AgentHarnessPreflightError, embeddedAgentLog, formatErrorMessage, isActiveHarnessContextEngine, isHostScopedAgentToolActive } from "openclaw/plugin-sdk/agent-harness-runtime";
46
46
  import { buildCodexUserMcpServersThreadConfigPatchForRun } from "openclaw/plugin-sdk/codex-mcp-projection";
@@ -1216,9 +1216,23 @@ async function releaseCodexRetainedLiveThread(options) {
1216
1216
  /** Release follows the physical owner across connection rotation, never a copied thread id. */
1217
1217
  async function releaseCodexBoundLiveThread(options) {
1218
1218
  const changedClient = options.ownerClientId && options.ownerClientId !== options.clientId;
1219
- const previous = changedClient ? await retainSharedCodexAppServerClientByInstanceId(options.ownerClientId) : void 0;
1219
+ const previous = changedClient ? await retainSharedCodexAppServerClientByInstanceId(options.ownerClientId, {
1220
+ signal: options.signal,
1221
+ createAbortError: codexThreadLifecycleAbortError
1222
+ }) : void 0;
1220
1223
  if (changedClient && !previous) return false;
1221
1224
  const client = previous?.client ?? options.client;
1225
+ let threadClosed;
1226
+ let stopWatching;
1227
+ if (previous) {
1228
+ threadClosed = new Promise((resolve) => {
1229
+ stopWatching = client.addNotificationHandler((notification) => {
1230
+ const threadId = notification.params && typeof notification.params === "object" ? Reflect.get(notification.params, "threadId") : void 0;
1231
+ if (isCodexAppServerThreadTerminalNotification(notification.method) && threadId === options.threadId) resolve();
1232
+ });
1233
+ });
1234
+ if (wasCodexAppServerThreadClosed(client, options.threadId)) threadClosed = Promise.resolve();
1235
+ }
1222
1236
  try {
1223
1237
  if (isCodexAppServerLiveThreadClaimed(client, options.threadId) || isCodexAppServerLiveThreadProtected(client, options.threadId)) throw new Error(`Codex thread ${options.threadId} is claimed by active work; stop it first.`);
1224
1238
  return await releaseCodexRetainedLiveThread({
@@ -1232,8 +1246,12 @@ async function releaseCodexBoundLiveThread(options) {
1232
1246
  } : void 0
1233
1247
  });
1234
1248
  } finally {
1235
- const retiredExit = previous?.release(!isCodexAppServerLiveThreadClaimed(client, options.threadId) && !isCodexAppServerLiveThreadProtected(client, options.threadId));
1236
- if (retiredExit) await racePromiseWithAbortSignal(retiredExit, options.signal, codexThreadLifecycleAbortError);
1249
+ try {
1250
+ const retiredExit = previous?.release(!isCodexAppServerLiveThreadClaimed(client, options.threadId) && !isCodexAppServerLiveThreadProtected(client, options.threadId));
1251
+ if (retiredExit) await options.lifecycleTiming.measure("retired-thread-runtime-release", () => racePromiseWithAbortSignal(threadClosed ? Promise.race([retiredExit, threadClosed]) : retiredExit, options.signal, codexThreadLifecycleAbortError));
1252
+ } finally {
1253
+ stopWatching?.();
1254
+ }
1237
1255
  }
1238
1256
  }
1239
1257
  /** Reuses one safely owned, fully matching subscription on its original client. */
@@ -1580,6 +1598,16 @@ function observeCodexThreadConfiguration(params, thread, assertCurrent) {
1580
1598
  };
1581
1599
  }
1582
1600
  //#endregion
1601
+ //#region extensions/codex/src/app-server/thread-lifecycle-projection.ts
1602
+ /** Projection identity omits persistent instructions: qualify using warm reuse's full policy. */
1603
+ async function canRetainCodexProjectionBackgroundWork(params, binding, context, pluginThreadConfig) {
1604
+ const finalConfig = await prepareCodexThreadFinalConfigPatch(params, context.nativeModelInputTools, binding);
1605
+ const pluginConfig = pluginThreadConfig?.configPatch ?? (params.pluginThreadConfig?.enabled && binding.pluginAppPolicyContext ? buildCodexPluginAppsConfigPatchFromPolicyContext(binding.pluginAppPolicyContext) : void 0);
1606
+ const authProfileId = binding.connectionScope === "supervision" ? void 0 : params.params.authProfileId ?? binding.authProfileId;
1607
+ const resumeParams = context.buildResumeParams(binding, authProfileId, buildCodexThreadRequestConfig(params, context, pluginConfig, finalConfig.configPatch));
1608
+ return isCodexAppServerLiveThreadBackgroundOnly(params.client, binding.threadId, fingerprintCodexThreadConfig(resumeParams, authProfileId, context.dynamicToolsFingerprint, binding));
1609
+ }
1610
+ //#endregion
1583
1611
  //#region extensions/codex/src/app-server/thread-supervision-cleanup.ts
1584
1612
  function withPendingSupervisionCleanup(pending, cleanupThreadIds) {
1585
1613
  return {
@@ -1917,6 +1945,7 @@ async function startOrResumeThread(input) {
1917
1945
  const preflight = await prepareCodexThreadLifecyclePreflight(params);
1918
1946
  const callerConfig = params.config;
1919
1947
  const { contextEngineBinding, dynamicToolsContainDeferred, dynamicToolsFingerprint, hostSystemAgentActive, legacyDynamicToolsFingerprint, legacyUserMcpServersFingerprint, lifecycleTiming, nativeSkillIsolationFingerprint, networkProxyConfigFingerprint, ringZeroActive, ringZeroClientInstanceId, ringZeroConfigFingerprint, restrictedToolSurface, restrictedToolSurfaceInheritedMcpServerNames, userMcpServersFingerprint, webSearchThreadConfigFingerprint } = preflight;
1948
+ let retainBackgroundPredecessor = false;
1920
1949
  let replacementPredecessor;
1921
1950
  const initialBoundThreadId = binding?.threadId;
1922
1951
  const initialBoundClientId = binding?.clientId;
@@ -2101,21 +2130,6 @@ async function startOrResumeThread(input) {
2101
2130
  embeddedAgentLog.debug("codex app-server delegation restricted for turn; starting transient thread", { threadId: binding.threadId });
2102
2131
  binding = void 0;
2103
2132
  }
2104
- if (binding?.threadId && (binding.contextEngine || contextEngineBinding)) {
2105
- if (!contextEngineBinding || !isContextEngineBindingCompatible(binding.contextEngine, contextEngineBinding)) {
2106
- rotateStaleBinding(binding, "context-engine binding", {
2107
- engineId: contextEngineBinding?.engineId,
2108
- previousEngineId: binding.contextEngine?.engineId,
2109
- epoch: contextEngineBinding?.projection?.epoch,
2110
- previousEpoch: binding.contextEngine?.projection?.epoch,
2111
- fingerprint: contextEngineBinding?.projection?.fingerprint,
2112
- previousFingerprint: binding.contextEngine?.projection?.fingerprint,
2113
- policyFingerprint: contextEngineBinding?.policyFingerprint,
2114
- previousPolicyFingerprint: binding.contextEngine?.policyFingerprint
2115
- });
2116
- rotatedContextEngineBinding = true;
2117
- }
2118
- }
2119
2133
  if (binding?.threadId) {
2120
2134
  if (!areUserMcpServersFingerprintsCompatible({
2121
2135
  previous: binding.userMcpServersFingerprint,
@@ -2132,6 +2146,31 @@ async function startOrResumeThread(input) {
2132
2146
  })) rotateStaleBinding(binding, "plugin app config");
2133
2147
  else if (binding.dynamicToolsFingerprint && params.dynamicTools.length > 0 && binding.dynamicToolsContainDeferred !== dynamicToolsContainDeferred && (binding.dynamicToolsContainDeferred !== void 0 || !dynamicToolsContainDeferred)) rotateStaleBinding(binding, "dynamic tool loading");
2134
2148
  }
2149
+ if (binding?.threadId && (binding.contextEngine || contextEngineBinding)) {
2150
+ if (!contextEngineBinding || !isContextEngineBindingCompatible(binding.contextEngine, contextEngineBinding)) {
2151
+ retainBackgroundPredecessor = initialBoundClientId === clientId && binding.contextEngine?.engineId === contextEngineBinding?.engineId && binding.contextEngine?.policyFingerprint === contextEngineBinding?.policyFingerprint && Boolean(contextEngineBinding) && (!binding.dynamicToolsFingerprint || areCodexDynamicToolFingerprintsCompatible({
2152
+ previous: binding.dynamicToolsFingerprint,
2153
+ next: dynamicToolsFingerprint,
2154
+ nextLegacy: legacyDynamicToolsFingerprint
2155
+ })) && isCodexAppServerLiveThreadBackgroundOnly(params.client, binding.threadId);
2156
+ if (retainBackgroundPredecessor) {
2157
+ const currentPluginConfig = await buildLoadedPluginThreadConfig(binding);
2158
+ if (currentPluginConfig && currentPluginConfig.fingerprint !== binding.pluginAppsFingerprint) retainBackgroundPredecessor = false;
2159
+ }
2160
+ if (retainBackgroundPredecessor) retainBackgroundPredecessor = await canRetainCodexProjectionBackgroundWork(params, binding, await prepareRequestContext(), prebuiltPluginThreadConfig);
2161
+ rotateStaleBinding(binding, "context-engine binding", {
2162
+ engineId: contextEngineBinding?.engineId,
2163
+ previousEngineId: binding.contextEngine?.engineId,
2164
+ epoch: contextEngineBinding?.projection?.epoch,
2165
+ previousEpoch: binding.contextEngine?.projection?.epoch,
2166
+ fingerprint: contextEngineBinding?.projection?.fingerprint,
2167
+ previousFingerprint: binding.contextEngine?.projection?.fingerprint,
2168
+ policyFingerprint: contextEngineBinding?.policyFingerprint,
2169
+ previousPolicyFingerprint: binding.contextEngine?.policyFingerprint
2170
+ });
2171
+ rotatedContextEngineBinding = true;
2172
+ }
2173
+ }
2135
2174
  if (binding?.threadId) {
2136
2175
  if (binding.dynamicToolsFingerprint && !areCodexDynamicToolFingerprintsCompatible({
2137
2176
  previous: binding.dynamicToolsFingerprint,
@@ -2181,7 +2220,7 @@ async function startOrResumeThread(input) {
2181
2220
  }
2182
2221
  assertCodexBindingMayBeReplaced(binding, "starting a fresh native thread", expectedOwnership);
2183
2222
  const requestContext = await prepareRequestContext();
2184
- if (initialBoundThreadId && !preserveExistingBinding && !configuredMcpOwnershipChanged) await releaseRetainedThread(initialBoundThreadId);
2223
+ if (initialBoundThreadId && !preserveExistingBinding && !configuredMcpOwnershipChanged && !(retainBackgroundPredecessor && isCodexAppServerLiveThreadBackgroundOnly(params.client, initialBoundThreadId))) await releaseRetainedThread(initialBoundThreadId);
2185
2224
  const started = await startFreshCodexThread(params, {
2186
2225
  ...requestContext,
2187
2226
  prebuiltPluginThreadConfig,
@@ -1,7 +1,7 @@
1
- import { S as retainSharedCodexAppServerClientByInstanceId } from "./auth-cache-key-DvDLHVJe.mjs";
1
+ import { S as retainSharedCodexAppServerClientByInstanceId } from "./auth-cache-key-DrieYJUQ.mjs";
2
2
  import { t as withCodexAppServerThreadMutation } from "./thread-ownership-queue-CeyYScUC.mjs";
3
- import { K as releaseCodexAppServerLiveThread, V as isCodexAppServerLiveThreadClaimed, q as retainCodexAppServerLiveThread } from "./shared-client-wb1JBldZ.mjs";
4
- import { f as unsubscribeCodexThreadBestEffort, o as closeCodexStartupClientBestEffort, r as CodexAppServerUnsafeSubscriptionError } from "./attempt-client-cleanup-TScCVTsk.mjs";
3
+ import { H as isCodexAppServerLiveThreadClaimed, J as retainCodexAppServerLiveThread, q as releaseCodexAppServerLiveThread } from "./shared-client-AdQX0Tdq.mjs";
4
+ import { f as unsubscribeCodexThreadBestEffort, o as closeCodexStartupClientBestEffort, r as CodexAppServerUnsafeSubscriptionError } from "./attempt-client-cleanup-jWVRH043.mjs";
5
5
  import { t as __exportAll } from "./session-binding-sidecars-DijNZb31.mjs";
6
6
  import { createDeferred } from "openclaw/plugin-sdk/extension-shared";
7
7
  import { runWithAsyncWorkResources } from "openclaw/plugin-sdk/agent-harness-tool-runtime";
@@ -1,7 +1,7 @@
1
1
  import { i as CodexAppServerScopedRequestRejectedError, o as isCodexAppServerOverloadError } from "./rpc-error-C98SHchT.mjs";
2
- import { n as requestCodexAppServerClientJson } from "./request-DhbisYCc.mjs";
3
- import { S as CodexAdoptedThreadActiveError } from "./shared-client-wb1JBldZ.mjs";
4
- import { p as assertCodexThreadAcceptsDirectInput, s as isCodexAppServerPrewriteRequestCancellationError } from "./client-BpSxNz4F.mjs";
2
+ import { n as requestCodexAppServerClientJson } from "./request-XC1RG34l.mjs";
3
+ import { S as CodexAdoptedThreadActiveError } from "./shared-client-AdQX0Tdq.mjs";
4
+ import { p as assertCodexThreadAcceptsDirectInput, s as isCodexAppServerPrewriteRequestCancellationError } from "./client-BM97zH3z.mjs";
5
5
  import { AgentHarnessPreflightError, embeddedAgentLog, formatErrorMessage } from "openclaw/plugin-sdk/agent-harness-runtime";
6
6
  //#region extensions/codex/src/app-server/thread-policy.ts
7
7
  /** A refusal, not a failed native write: the ephemeral conversation must stay alive. */
@@ -1,7 +1,7 @@
1
1
  import { i as isJsonObject } from "./protocol-CANUwXJ3.mjs";
2
- import { d as readCodexEffectiveConfig, u as CODEX_SESSION_OVERRIDABLE_LAYER_TYPES } from "./config-options-nvYwVDyy.mjs";
2
+ import { d as readCodexEffectiveConfig, u as CODEX_SESSION_OVERRIDABLE_LAYER_TYPES } from "./config-options-CZmH25Xq.mjs";
3
3
  import { a as isCodexResponsesOAuthRun } from "./responses-oauth-twnuTaAa.mjs";
4
- import { d as mergeCodexThreadConfigs, t as buildCodexProjectDocThreadConfig } from "./project-doc-thread-config-B2ZD23A_.mjs";
4
+ import { d as mergeCodexThreadConfigs, t as buildCodexProjectDocThreadConfig } from "./project-doc-thread-config-D_sWbxFR.mjs";
5
5
  import { o as hashCodexAppServerBindingFingerprint } from "./session-binding-BDnNz-Co.mjs";
6
6
  import { n as resolveCodexAppServerModelProvider, r as resolveCodexAppServerRequestModelSelection, t as CODEX_NATIVE_PERSONALITY_NONE } from "./thread-model-selection-DcVebr8N.mjs";
7
7
  import { normalizeOptionalString, normalizeUniqueStringEntries, normalizeUniqueTrimmedStringList } from "openclaw/plugin-sdk/string-coerce-runtime";
@@ -1,8 +1,8 @@
1
1
  import { i as CodexAppServerScopedRequestRejectedError, o as isCodexAppServerOverloadError, r as CodexAppServerRpcError } from "./rpc-error-C98SHchT.mjs";
2
- import { r as publishCodexCatalogResume } from "./session-catalog-events-IoszcO7-.mjs";
3
- import { L as forgetCodexWorkspaceReferences, pt as isCodexAppServerStartupError, u as isCodexAppServerStartSelectionChangedError } from "./shared-client-wb1JBldZ.mjs";
4
- import { h as assertCodexThreadResumeResponse, s as isCodexAppServerPrewriteRequestCancellationError } from "./client-BpSxNz4F.mjs";
5
- import { f as unsubscribeCodexThreadBestEffort, i as assertCodexThreadResumeSubscription, r as CodexAppServerUnsafeSubscriptionError } from "./attempt-client-cleanup-TScCVTsk.mjs";
2
+ import { r as publishCodexCatalogResume } from "./session-catalog-events-CpEyDv0D.mjs";
3
+ import { L as forgetCodexWorkspaceReferences, gt as isCodexAppServerStartupError, u as isCodexAppServerStartSelectionChangedError } from "./shared-client-AdQX0Tdq.mjs";
4
+ import { h as assertCodexThreadResumeResponse, s as isCodexAppServerPrewriteRequestCancellationError } from "./client-BM97zH3z.mjs";
5
+ import { f as unsubscribeCodexThreadBestEffort, i as assertCodexThreadResumeSubscription, r as CodexAppServerUnsafeSubscriptionError } from "./attempt-client-cleanup-jWVRH043.mjs";
6
6
  import { sanitizeTerminalText } from "openclaw/plugin-sdk/text-chunking";
7
7
  //#region extensions/codex/src/app-server/thread-resume.ts
8
8
  /** Owns Codex thread/resume subscription safety. */
@@ -1,5 +1,5 @@
1
1
  import { r as resolveCodexAppServerUserHomeDir } from "./auth-start-options-BPIPeEX8.mjs";
2
- import "./config-G4IGX6bK.mjs";
2
+ import "./config-LQemoqTL.mjs";
3
3
  import { t as codexWebSocketDataToBuffer } from "./websocket-data-XlRvt8Ys.mjs";
4
4
  import path from "node:path";
5
5
  import { EventEmitter } from "node:events";
@@ -1,6 +1,6 @@
1
1
  import { i as isJsonObject } from "./protocol-CANUwXJ3.mjs";
2
2
  import { n as waitForPromiseOrAbort, t as abortReason } from "./timeout-D0mEWSGG.mjs";
3
- import { x as readCodexTurnCompletedNotification } from "./client-BpSxNz4F.mjs";
3
+ import { x as readCodexTurnCompletedNotification } from "./client-BM97zH3z.mjs";
4
4
  import { normalizeOptionalString, readStringField } from "openclaw/plugin-sdk/string-coerce-runtime";
5
5
  import { AsyncResource } from "node:async_hooks";
6
6
  import { createDeferred } from "openclaw/plugin-sdk/extension-shared";