@openclaw/codex 2026.10.5-beta.4 → 2026.10.10-beta.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (156) hide show
  1. package/README.md +10 -3
  2. package/dist/.setup/{account-usage-runtime-CoVpNIlD.mjs → account-usage-runtime-DDCDkvtl.mjs} +15 -9
  3. package/dist/.setup/{app-server-policy-D_zv8J7V.mjs → app-server-policy-Cog6mm2i.mjs} +1 -1
  4. package/dist/.setup/{apply-BXDMd05l.mjs → apply-BVSXYkTV.mjs} +11 -11
  5. package/dist/.setup/{attempt-client-cleanup-zNuNTKVr.mjs → attempt-client-cleanup-6OcbMH46.mjs} +14 -8
  6. package/dist/.setup/attempt-terminal-sZutF0WY.mjs +1 -0
  7. package/dist/.setup/{attempt-workspace-context-CcwP3DA3.mjs → attempt-workspace-context-GYPLawX6.mjs} +2 -2
  8. package/dist/.setup/{auth-binding-BaxlhaNx.mjs → auth-binding-830RLAJW.mjs} +2 -2
  9. package/dist/.setup/{auth-cache-key-f8ODJ_OX.mjs → auth-cache-key-CVcYw8HD.mjs} +92 -80
  10. package/dist/.setup/{auth-profile-CgHQ8Vot.mjs → auth-profile-auwzSwwy.mjs} +14 -8
  11. package/dist/.setup/{auth-profile-health-oHizqgye.mjs → auth-profile-health-BVPZU9I8.mjs} +15 -8
  12. package/dist/.setup/{auth-profile-selection-hr8ocLtz.mjs → auth-profile-selection-Bp5PDk3W.mjs} +24 -7
  13. package/dist/.setup/{binding-connection-B7HAAZSI.mjs → binding-connection-GTgUj9pi.mjs} +2 -2
  14. package/dist/.setup/{binding-connection.runtime-DAXn7iFl.mjs → binding-connection.runtime-RcWR3vQu.mjs} +4 -3
  15. package/dist/.setup/{bounded-turn-isolation-BfDAo-qZ.mjs → bounded-turn-isolation-D8CDrAVX.mjs} +3 -3
  16. package/dist/.setup/{bounded-turn-DfIJtRlv.mjs → bounded-turn-mN_ekXYW.mjs} +18 -22
  17. package/dist/.setup/{build-state-Ds14X10-.mjs → build-state-VcujMRqP.mjs} +1 -1
  18. package/dist/.setup/{capabilities-DbOzOglY.mjs → capabilities-DAS-JX1z.mjs} +1 -1
  19. package/dist/.setup/{client-D93nbdB8.mjs → client-BS8X7HmG.mjs} +47 -317
  20. package/dist/.setup/{client-catalog-response-CuVLp4I0.mjs → client-catalog-response-jM38o5w1.mjs} +2 -2
  21. package/dist/.setup/client-initialize-CjgZcX61.mjs +165 -0
  22. package/dist/.setup/{command-dispatch-DxdH5a9-.mjs → command-dispatch-DzXbHqCn.mjs} +3 -3
  23. package/dist/.setup/{command-formatters-xW9KpoSZ.mjs → command-formatters-B_7-QZ1c.mjs} +2 -2
  24. package/dist/.setup/{command-handlers-fiYvYYq0.mjs → command-handlers-tfb5Uq-O.mjs} +539 -406
  25. package/dist/.setup/command-rpc-SXqLQukR.mjs +296 -0
  26. package/dist/.setup/compact-M-JxLcbZ.mjs +823 -0
  27. package/dist/.setup/{computer-use-DL2v3Kxq.mjs → computer-use-FqQ-Flbl.mjs} +21 -68
  28. package/dist/.setup/{config-C1YVVLEA.mjs → config-BfrAlTMT.mjs} +3 -3
  29. package/dist/.setup/{config-options-DDzeNQ8m.mjs → config-options-DMFZkd3X.mjs} +1 -1
  30. package/dist/.setup/{config-runtime-DWzK-k0n.mjs → config-runtime-BZRizyuG.mjs} +2 -2
  31. package/dist/.setup/{context-engine-projection-ps-yn_ci.mjs → context-engine-projection-PIeLSnR-.mjs} +16 -30
  32. package/dist/.setup/{conversation-binding-BieJZRRV.mjs → conversation-binding-C7MZy-Cx.mjs} +228 -116
  33. package/dist/.setup/{conversation-binding-data-UgLuTSQT.mjs → conversation-binding-data-khgW0n-o.mjs} +4 -2
  34. package/dist/.setup/{conversation-control-GXM3unE4.mjs → conversation-control-B2EpVZEb.mjs} +53 -23
  35. package/dist/.setup/{cyber-failover-D4dgNfFf.mjs → cyber-failover-CqEZoQsj.mjs} +1 -1
  36. package/dist/.setup/{cyber-failover-notice-ljgGGL0s.mjs → cyber-failover-notice-poL3Advd.mjs} +1 -1
  37. package/dist/.setup/{doctor-start-options-JjTAl-q_.mjs → doctor-start-options-8uIBXIzR.mjs} +8 -5
  38. package/dist/.setup/{dynamic-tool-build-DcaPmBlE.mjs → dynamic-tool-build-BjFAIG-f.mjs} +208 -218
  39. package/dist/.setup/{dynamic-tools-CnQFnNKH.mjs → dynamic-tools-XqWsVjcC.mjs} +344 -118
  40. package/dist/.setup/{effective-mcp-catalog-B5HKFZNK.mjs → effective-mcp-catalog-C3ta5hHc.mjs} +11 -9
  41. package/dist/.setup/{ephemeral-turn-De3qb8EQ.mjs → ephemeral-turn-1ZF17fUR.mjs} +5 -4
  42. package/dist/.setup/{event-projector-assistant-message-CLMKN4x-.mjs → event-projector-assistant-message-ChOAY7rW.mjs} +16 -11
  43. package/dist/.setup/{event-projector-usage-BpKfdoTm.mjs → event-projector-usage-CBY0Hkga.mjs} +2 -2
  44. package/dist/.setup/{event-projector-values-CLvG1Hil.mjs → event-projector-values-yf4us9Pf.mjs} +1 -1
  45. package/dist/.setup/experimental-features-uGnVDtp-.mjs +19 -0
  46. package/dist/.setup/inference-context-mv_dBpAL.mjs +209 -0
  47. package/dist/.setup/{inference-dispatch-CO6tTs4q.mjs → inference-dispatch-C2zVSnrr.mjs} +2 -2
  48. package/dist/.setup/{inference-metadata-DCvcG_N_.mjs → inference-metadata-CYFWLHVk.mjs} +3 -1
  49. package/dist/.setup/{inference-proxy-BDWV0djM.mjs → inference-proxy-yd3hr2dr.mjs} +8 -8
  50. package/dist/.setup/installed-probe-lVC1X5ve.mjs +185 -0
  51. package/dist/.setup/{isolated-completion-BPJdvk5F.mjs → isolated-completion-P-r8NRE4.mjs} +7 -7
  52. package/dist/.setup/managed-binary-DbKvGXKl.mjs +395 -0
  53. package/dist/.setup/{mcp-app-session-preparation-Dz2GOwyE.mjs → mcp-app-session-preparation-fnsnCovu.mjs} +18 -14
  54. package/dist/.setup/{model-catalog-ZNwltCKl.mjs → model-catalog-Y_esgRPY.mjs} +28 -17
  55. package/dist/.setup/{models-BHpbAuz8.mjs → models-BWLEUo2E.mjs} +3 -3
  56. package/dist/.setup/{native-auth-esN5MdIv.mjs → native-auth-DpZIaY8N.mjs} +7 -4
  57. package/dist/.setup/native-execution-policy-D09tLP-u.mjs +152 -0
  58. package/dist/.setup/{native-hook-relay-wq7jrNLk.mjs → native-hook-relay-C7aaLJaP.mjs} +45 -10
  59. package/dist/.setup/{native-mcp-app-DX3nyTtc.mjs → native-mcp-app-CsWj-v_x.mjs} +5 -5
  60. package/dist/.setup/{native-skill-isolation-DSBeF-Yy.mjs → native-skill-isolation-CMimsKYy.mjs} +7 -7
  61. package/dist/.setup/{native-subagent-monitor-DOLEIf9r.mjs → native-subagent-monitor-CFE7b4oC.mjs} +485 -239
  62. package/dist/.setup/{native-subagent-pending-assignments-DmVhedNs.mjs → native-subagent-pending-assignments-CTinVtjo.mjs} +1 -1
  63. package/dist/.setup/{native-task-assignments-DimsQ9Qa.mjs → native-task-assignments-YJopbaVO.mjs} +9 -5
  64. package/dist/.setup/{node-cli-sessions-CzKg2nGq.mjs → node-cli-sessions-BuJnBnEq.mjs} +7 -4
  65. package/dist/.setup/{node-exec-server.runtime-BWkULhBM.mjs → node-exec-server.runtime-CP7RC1Nd.mjs} +3 -3
  66. package/dist/.setup/{plan-41-YOBMq.mjs → plan-B4cHgqNv.mjs} +7 -20
  67. package/dist/.setup/{plugin-activation-D7WkJMvU.mjs → plugin-activation-CXPWe-hl.mjs} +4 -4
  68. package/dist/.setup/{plugin-app-cache-key-Bg9DbDI6.mjs → plugin-app-cache-key-DRb-niJc.mjs} +17 -55
  69. package/dist/.setup/{plugin-approval-roundtrip-CD88q3yx.mjs → plugin-approval-roundtrip-DIZHLbAM.mjs} +1 -1
  70. package/dist/.setup/{plugin-inventory-CYgdo14P.mjs → plugin-inventory-DE9wcaeH.mjs} +2 -2
  71. package/dist/.setup/{plugin-metadata-cache-Bi8TAPwX.mjs → plugin-metadata-cache-BqC-a6Fb.mjs} +2 -15
  72. package/dist/.setup/{project-doc-thread-config-BVcvnps8.mjs → project-doc-thread-config-B0UI3f1D.mjs} +6 -6
  73. package/dist/.setup/protocol-CaPAVwe9.mjs +12 -0
  74. package/dist/.setup/{provider-capabilities-Dn2WwH4P.mjs → provider-capabilities-DjcKunHS.mjs} +1 -1
  75. package/dist/.setup/{provider-LWKll6dV.mjs → provider-wj_LFJH3.mjs} +4 -4
  76. package/dist/.setup/{rate-limits-CI8pTPqL.mjs → rate-limits-BpfURnuy.mjs} +1 -1
  77. package/dist/.setup/{request-Bo0kKABI.mjs → request-ePeNJrOd.mjs} +132 -136
  78. package/dist/.setup/{responses-oauth-twnuTaAa.mjs → responses-oauth-CCV7aVYF.mjs} +6 -6
  79. package/dist/.setup/{rpc-error-C98SHchT.mjs → rpc-error-DemqqaxE.mjs} +7 -3
  80. package/dist/.setup/{run-attempt-ClU8MxhZ.mjs → run-attempt-BcWArowv.mjs} +595 -426
  81. package/dist/.setup/{run-attempt-lifecycle-KN4oh-7O.mjs → run-attempt-lifecycle-DN-ATDp9.mjs} +1 -1
  82. package/dist/.setup/{runtime-artifact-C13pR7tD.mjs → runtime-artifact-CmLWeyJB.mjs} +3 -3
  83. package/dist/.setup/{runtime-artifact-connection-jS5DeCok.mjs → runtime-artifact-connection-DpWlZ02e.mjs} +3 -3
  84. package/dist/.setup/{sandbox-guard-DIImwCy1.mjs → sandbox-guard-DneAfNye.mjs} +70 -30
  85. package/dist/.setup/{session-binding-JEHNMPsr.mjs → session-binding-BgsWcbdY.mjs} +25 -23
  86. package/dist/.setup/{session-binding-record-DU_0biMD.mjs → session-binding-record-C_THntMe.mjs} +27 -12
  87. package/dist/.setup/{session-binding-record-codec-BpH8u_G9.mjs → session-binding-record-codec-DvmOI7g_.mjs} +1 -0
  88. package/dist/.setup/{session-binding-sidecars-DD-enC8w.mjs → session-binding-sidecars-BNSS6WL4.mjs} +55 -63
  89. package/dist/.setup/session-cancellation-DLBSJO5n.mjs +43 -0
  90. package/dist/.setup/{session-catalog-adoption-Ca3OYGYM.mjs → session-catalog-adoption-ppsLlVLB.mjs} +24 -38
  91. package/dist/.setup/{session-catalog-archive-Bv6gV7x9.mjs → session-catalog-archive-CqLRHJ6z.mjs} +11 -13
  92. package/dist/.setup/{session-catalog-events-kR2Ot6nX.mjs → session-catalog-events-DK0opVp3.mjs} +5 -5
  93. package/dist/.setup/{session-catalog-index-CrnfVEnT.mjs → session-catalog-index-BfzfdtH7.mjs} +96 -271
  94. package/dist/.setup/{session-catalog-index-order-CTfoefow.mjs → session-catalog-index-order-0Zqng2u8.mjs} +1 -1
  95. package/dist/.setup/{session-catalog-limits-BynIoOYm.mjs → session-catalog-limits-Dc6E0BZz.mjs} +1 -1
  96. package/dist/.setup/{session-catalog-list-request-D4MYNgDB.mjs → session-catalog-list-request-CAjoWjaH.mjs} +3 -4
  97. package/dist/.setup/{session-catalog-native-projection-CWqCU1I_.mjs → session-catalog-native-projection-G3lSDYYG.mjs} +5 -5
  98. package/dist/.setup/{session-catalog-node-adoption-BdP9Zjqo.mjs → session-catalog-node-adoption-e9v8mGgx.mjs} +5 -5
  99. package/dist/.setup/{session-catalog-node-continue-CNJibO4_.mjs → session-catalog-node-continue-H7nrzcUD.mjs} +5 -5
  100. package/dist/.setup/{session-catalog-node-lookup-BH_DBGa9.mjs → session-catalog-node-lookup-BrZfDkA8.mjs} +2 -2
  101. package/dist/.setup/{session-catalog-parsing-DkeoVn60.mjs → session-catalog-parsing-V6jyFg9g.mjs} +2 -2
  102. package/dist/.setup/{session-catalog-projection-BzHiV818.mjs → session-catalog-projection-BjWE414G.mjs} +8 -7
  103. package/dist/.setup/{session-catalog-provenance-CmsOE5mh.mjs → session-catalog-provenance-Dg9s12z-.mjs} +50 -30
  104. package/dist/.setup/{session-catalog-source-DGuRdGvM.mjs → session-catalog-source-DqyuNxCe.mjs} +2 -6
  105. package/dist/.setup/{session-cli-GwU0izn-.mjs → session-cli-CBGKiqdv.mjs} +1 -1
  106. package/dist/.setup/{session-history-BO6i_pfk.mjs → session-history-7W0cgTXF.mjs} +11 -9
  107. package/dist/.setup/{session-history-import-CaO8s6ta.mjs → session-history-import-BwPKwcNi.mjs} +4 -4
  108. package/dist/.setup/{session-initialization-Bi_2DKhc.mjs → session-initialization-Dn3vveGv.mjs} +2 -2
  109. package/dist/.setup/{session-retirement-B3U5hpGJ.mjs → session-retirement-Ci_JvOfH.mjs} +8 -8
  110. package/dist/.setup/{session-history.worker-DJQfek5p.mjs → settled-turn-evidence--tRW6fSm.mjs} +2 -18
  111. package/dist/.setup/{settled-turn-finalizer-CYCVpTv2.mjs → settled-turn-finalizer-D3-KXsbP.mjs} +8 -8
  112. package/dist/.setup/{shared-client-BCx1wbyA.mjs → shared-client-CE_uY0A1.mjs} +380 -557
  113. package/dist/.setup/side-question-OM18H9WJ.mjs +998 -0
  114. package/dist/.setup/{source-DipMO9hL.mjs → source-uGKgKWm8.mjs} +5 -5
  115. package/dist/.setup/{thread-archive-guard-LKdwQKyr.mjs → thread-archive-guard-BWjSsA92.mjs} +1 -1
  116. package/dist/.setup/{thread-lifecycle-run-C_aYiYqk.mjs → thread-lifecycle-run-mLueY6pH.mjs} +172 -75
  117. package/dist/.setup/{thread-model-selection-DcVebr8N.mjs → thread-model-selection-DxposL4X.mjs} +9 -9
  118. package/dist/.setup/{thread-ownership-BoUd0i6L.mjs → thread-ownership-t6Y9fLQS.mjs} +7 -7
  119. package/dist/.setup/{thread-policy-B3wBRNph.mjs → thread-policy-Cy301Or8.mjs} +6 -6
  120. package/dist/.setup/{thread-requests-BgzJwJtS.mjs → thread-requests-BjawdIVV.mjs} +14 -14
  121. package/dist/.setup/{thread-resume-D-3bsr1j.mjs → thread-resume-BUbsUfgF.mjs} +6 -6
  122. package/dist/.setup/{transcript-history-projection-DfKcoZCB.mjs → transcript-history-projection-i-FVpyha.mjs} +1 -1
  123. package/dist/.setup/{transcript-mirror-Bee2o6jj.mjs → transcript-mirror-CEQJZlF3.mjs} +6 -9
  124. package/dist/.setup/{transport-stdio-CRWTkKOn.mjs → transport-stdio-Bq160Dhv.mjs} +63 -64
  125. package/dist/.setup/{transport-websocket-DIyPfkHo.mjs → transport-websocket-0YqiI_MH.mjs} +1 -1
  126. package/dist/.setup/{turn-router-DBVMToGo.mjs → turn-router-Dbw17k3K.mjs} +2 -2
  127. package/dist/.setup/{upstream-session-fork-p5fwKi7w.mjs → upstream-session-fork-_LYkh0nZ.mjs} +46 -219
  128. package/dist/.setup/{usage-limit-error-BQX8RHAd.mjs → usage-limit-error-DcOSH3J4.mjs} +4 -4
  129. package/dist/.setup/{usage-C2Kq7oej.mjs → usage-w_93wnnR.mjs} +4 -4
  130. package/dist/.setup/{web-search-item-CvokaZOo.mjs → web-search-item-DHVuNSqk.mjs} +1 -1
  131. package/dist/.setup/{web-search-provider.runtime-D89djc7e.mjs → web-search-provider.runtime-DMHxve5v.mjs} +3 -3
  132. package/dist/.setup/{workspace-write-sandbox-probe-BDWO2Qkh.mjs → workspace-write-sandbox-probe-DJxOXcF3.mjs} +2 -2
  133. package/dist/api.js +7 -28
  134. package/dist/catalog-page.worker.js +1 -1
  135. package/dist/cli-metadata.js +1 -1
  136. package/dist/client-version-api.js +25 -0
  137. package/dist/doctor-contract-api.js +5 -5
  138. package/dist/harness.js +59 -36
  139. package/dist/index.js +259 -295
  140. package/dist/media-understanding-provider.js +2 -2
  141. package/dist/migration-provider-api.js +1 -2
  142. package/dist/native-session-binding-api.js +1 -2
  143. package/dist/provider-discovery.js +1 -1
  144. package/dist/session-history-worker-entrypoint.js +12 -0
  145. package/dist/session-history-worker-runtime.js +7 -18
  146. package/dist/session-history.worker.js +18 -2
  147. package/openclaw.plugin.json +1 -1
  148. package/package.json +6 -6
  149. package/dist/.setup/attempt-terminal-jO5IMj9K.mjs +0 -2
  150. package/dist/.setup/command-rpc-HIvsy3wS.mjs +0 -247
  151. package/dist/.setup/compact-ClZ7Ar7L.mjs +0 -808
  152. package/dist/.setup/inference-context-DNlGwzwy.mjs +0 -91
  153. package/dist/.setup/managed-binary-BtIjV7yN.mjs +0 -175
  154. package/dist/.setup/native-execution-policy-MXEe7PB3.mjs +0 -75
  155. package/dist/.setup/protocol-CANUwXJ3.mjs +0 -17
  156. package/dist/.setup/side-question-Bz2UQW0l.mjs +0 -826
@@ -0,0 +1,823 @@
1
+ import { n as readCodexRuntimeModelId } from "./model-runtime-BdqzOMkU.mjs";
2
+ import { r as isJsonObject } from "./protocol-CaPAVwe9.mjs";
3
+ import { g as sessionBindingIdentity } from "./session-binding-record-C_THntMe.mjs";
4
+ import { T as retainSharedCodexAppServerClientByInstanceId, k as waitForCodexAppServerClientExit } from "./auth-cache-key-CVcYw8HD.mjs";
5
+ import { t as CODEX_APP_SERVER_BINDING_GUARDED_REQUEST_TIMEOUT_MS } from "./session-binding-meta-Lkm5Lpf4.mjs";
6
+ import { i as CodexAppServerScopedRequestRejectedError, r as CodexAppServerRpcError } from "./rpc-error-DemqqaxE.mjs";
7
+ import { i as resolveCodexBindingAppServerConnection } from "./binding-connection-GTgUj9pi.mjs";
8
+ import { B as retainCodexAppServerLiveThread, D as consumeCodexAppServerLiveThread, I as protectCodexAppServerLiveThread, V as revertCodexAppServerLiveThreadInstructions, a as createIsolatedCodexAppServerClient, p as retainSharedCodexAppServerClientIfCurrent, w as getCodexInferenceThreadQualification } from "./shared-client-CE_uY0A1.mjs";
9
+ import "./responses-oauth-CCV7aVYF.mjs";
10
+ import { i as isCodexAppServerIndeterminateRequestCancellationError, o as isCodexAppServerPrewriteRequestCancellationError } from "./client-BS8X7HmG.mjs";
11
+ import { c as readCodexNotificationTurnId, s as readCodexNotificationThreadId } from "./turn-router-Dbw17k3K.mjs";
12
+ import { c as isCodexNoActiveTurnInterruptError, f as unsubscribeCodexThreadBestEffort, o as closeCodexStartupClientBestEffort, r as CodexAppServerUnsafeSubscriptionError } from "./attempt-client-cleanup-6OcbMH46.mjs";
13
+ import { n as readCodexThreadContextSnapshot, s as readCodexNotificationItem } from "./event-projector-usage-CBY0Hkga.mjs";
14
+ import { i as resolveCodexSessionBinding } from "./session-binding-BgsWcbdY.mjs";
15
+ import { s as withCodexAppServerThreadMutationHold, t as isSameCodexAppServerThreadOwner } from "./thread-ownership-t6Y9fLQS.mjs";
16
+ import { t as persistCodexContextCompactionActivity } from "./context-compaction-activity-CMla5FPJ.mjs";
17
+ import { t as codexNativeSubagentMonitorRuntime } from "./native-subagent-monitor-CFE7b4oC.mjs";
18
+ import { n as prepareCodexNativeExecutionBlock } from "./sandbox-guard-DneAfNye.mjs";
19
+ import { i as assertCodexSupervisionThreadLineage } from "./thread-policy-Cy301Or8.mjs";
20
+ import { t as resumeCodexAppServerThread } from "./thread-resume-BUbsUfgF.mjs";
21
+ import { asOptionalRecord } from "openclaw/plugin-sdk/string-coerce-runtime";
22
+ import { coerceErrorMessage } from "openclaw/plugin-sdk/error-runtime";
23
+ import { isIncognitoSessionKey } from "openclaw/plugin-sdk/session-key-runtime";
24
+ import { AsyncLocalStorage } from "node:async_hooks";
25
+ import { createDeferred } from "openclaw/plugin-sdk/extension-shared";
26
+ import { resolveAgentDir } from "openclaw/plugin-sdk/agent-runtime";
27
+ import { AgentHarnessSessionSupersededError, embeddedAgentLog, resolveCompactionTimeoutMs } from "openclaw/plugin-sdk/agent-harness-runtime";
28
+ import { runWithAsyncWorkResources } from "openclaw/plugin-sdk/agent-harness-tool-runtime";
29
+ import { createDedupeCache } from "openclaw/plugin-sdk/dedupe-runtime";
30
+ //#region extensions/codex/src/app-server/compact-helpers.ts
31
+ /** Settles the consumed subscription without returning stale ownership to the next turn. */
32
+ async function settleCodexCompactionSubscription(params) {
33
+ let retained = false;
34
+ try {
35
+ if (params.compacted) await params.authority.withCurrent(() => revertCodexAppServerLiveThreadInstructions(params.client, params.binding.threadId));
36
+ const ownership = params.ownership;
37
+ if (ownership) retained = await params.bindingStore.withLease(params.identity, async () => {
38
+ let pendingRetention;
39
+ try {
40
+ await params.authority.withCurrent(() => {
41
+ if (!isSameCodexAppServerThreadOwner(params.bindingStore.read(params.identity), params.binding)) return;
42
+ pendingRetention = retainCodexAppServerLiveThread(params.client, params.binding.threadId, ownership.release, ownership.configFingerprint, ownership.serviceTier, ownership.ephemeralPolicy && params.compacted ? {
43
+ ...ownership.ephemeralPolicy,
44
+ refreshableInstructions: ownership.ephemeralPolicy.nativeRefreshableInstructions
45
+ } : ownership.ephemeralPolicy);
46
+ });
47
+ } catch (error) {
48
+ await pendingRetention;
49
+ throw error;
50
+ }
51
+ return pendingRetention ? await pendingRetention : false;
52
+ }, { authority: params.authority });
53
+ } catch (error) {
54
+ if (!(error instanceof AgentHarnessSessionSupersededError)) throw error;
55
+ } finally {
56
+ if (!retained) await params.release?.();
57
+ }
58
+ }
59
+ async function clearContextEngineProjectionBeforeNativeCompaction(params) {
60
+ const contextEngineBinding = params.binding.contextEngine;
61
+ if (!contextEngineBinding?.projection) return;
62
+ await params.bindingStore.mutate(params.identity, {
63
+ kind: "patch",
64
+ threadId: params.binding.threadId,
65
+ patch: { contextEngine: {
66
+ ...contextEngineBinding,
67
+ projection: void 0
68
+ } }
69
+ }, params.assertCurrent, params.authority);
70
+ embeddedAgentLog.info("cleared codex context-engine projection before native compaction", {
71
+ sessionId: params.sessionId,
72
+ threadId: params.binding.threadId,
73
+ previousEpoch: contextEngineBinding.projection.epoch,
74
+ previousFingerprint: contextEngineBinding.projection.fingerprint
75
+ });
76
+ }
77
+ function isSameNativeCompactionBinding(current, expected) {
78
+ return isSameCodexAppServerThreadOwner(current, expected) && current.authProfileId === expected.authProfileId && current.contextEngine?.engineId === expected.contextEngine?.engineId && current.contextEngine?.policyFingerprint === expected.contextEngine?.policyFingerprint && current.contextEngine?.projection?.mode === expected.contextEngine?.projection?.mode && current.contextEngine?.projection?.epoch === expected.contextEngine?.projection?.epoch && current.contextEngine?.projection?.fingerprint === expected.contextEngine?.projection?.fingerprint;
79
+ }
80
+ function isCodexThreadNotFoundError(error) {
81
+ return coerceErrorMessage(error).toLowerCase().includes("thread not found");
82
+ }
83
+ const warnedIgnoredCompactionOverrides = createDedupeCache({
84
+ ttlMs: 0,
85
+ maxSize: 4096
86
+ });
87
+ function warnIfIgnoringOpenClawCompactionOverrides(params) {
88
+ const compaction = asOptionalRecord(params.config?.agents?.defaults?.compaction);
89
+ const ignoredConfig = [
90
+ "model",
91
+ "thinkingLevel",
92
+ "provider"
93
+ ].flatMap((field) => {
94
+ const value = compaction?.[field];
95
+ return typeof value === "string" && value.trim() ? [`agents.defaults.compaction.${field}`] : [];
96
+ });
97
+ if (ignoredConfig.length === 0) return;
98
+ const warningKey = ignoredConfig.join("\0");
99
+ if (warnedIgnoredCompactionOverrides.check(warningKey)) return;
100
+ embeddedAgentLog.warn("ignoring OpenClaw compaction overrides for Codex app-server compaction; Codex uses native server-side compaction", {
101
+ sessionId: params.sessionId,
102
+ sessionKey: params.sessionKey,
103
+ ignoredConfig
104
+ });
105
+ }
106
+ //#endregion
107
+ //#region extensions/codex/src/app-server/compact-lifecycle.ts
108
+ function watchCodexNativeCompactionCompletion(params) {
109
+ const runOutsideBindingLease = AsyncLocalStorage.snapshot();
110
+ let settled = false;
111
+ let requestStarted = false;
112
+ let abortRequested = false;
113
+ let interruptRequested = false;
114
+ let retirementStarted = false;
115
+ let compactionTurnId;
116
+ let compactionItemId;
117
+ let compactionItemCompleted = false;
118
+ let tokensAfter;
119
+ let admissionFailure;
120
+ const { promise: completion, resolve: resolveCompletion } = createDeferred();
121
+ let removeNotificationHandler = () => {};
122
+ let removeCloseHandler = () => {};
123
+ let removeAbortHandler = () => {};
124
+ let completionTimeout;
125
+ let interruptGraceTimeout;
126
+ const finish = (result) => {
127
+ if (settled) return;
128
+ settled = true;
129
+ removeNotificationHandler();
130
+ removeCloseHandler();
131
+ removeAbortHandler();
132
+ clearTimeout(completionTimeout);
133
+ clearTimeout(interruptGraceTimeout);
134
+ resolveCompletion(result);
135
+ };
136
+ const complete = () => finish({
137
+ completed: true,
138
+ ...compactionTurnId ? { turnId: compactionTurnId } : {},
139
+ ...compactionItemId ? { itemId: compactionItemId } : {},
140
+ ...tokensAfter !== void 0 ? { tokensAfter } : {}
141
+ });
142
+ const fail = (reason) => finish({
143
+ completed: false,
144
+ reason
145
+ });
146
+ const retireUnconfirmed = (reason) => {
147
+ if (settled || retirementStarted) return;
148
+ retirementStarted = true;
149
+ runOutsideBindingLease(() => params.retireUnconfirmed()).then(() => fail(reason)).catch((error) => {
150
+ embeddedAgentLog.error("failed to retire unconfirmed codex app-server compaction", {
151
+ threadId: params.threadId,
152
+ turnId: compactionTurnId,
153
+ reason: coerceErrorMessage(error)
154
+ });
155
+ });
156
+ };
157
+ const requestInterrupt = () => {
158
+ if (settled || !requestStarted || !abortRequested || !compactionTurnId || interruptRequested) return;
159
+ interruptRequested = true;
160
+ params.client.request("turn/interrupt", {
161
+ threadId: params.threadId,
162
+ turnId: compactionTurnId
163
+ }, { timeoutMs: Math.max(1, params.interruptGraceMs) }).catch((error) => {
164
+ if (isCodexNoActiveTurnInterruptError(error)) return;
165
+ embeddedAgentLog.warn("codex app-server compaction interrupt request failed", {
166
+ threadId: params.threadId,
167
+ turnId: compactionTurnId,
168
+ reason: coerceErrorMessage(error)
169
+ });
170
+ });
171
+ };
172
+ const beginInterruptGrace = () => {
173
+ if (settled || !requestStarted || interruptGraceTimeout) return;
174
+ requestInterrupt();
175
+ interruptGraceTimeout = setTimeout(() => {
176
+ embeddedAgentLog.warn("codex app-server compaction did not reach terminal state after interruption", {
177
+ threadId: params.threadId,
178
+ turnId: compactionTurnId,
179
+ interruptGraceMs: params.interruptGraceMs
180
+ });
181
+ retireUnconfirmed("codex app-server compaction did not reach terminal state after interruption");
182
+ }, Math.max(1, params.interruptGraceMs));
183
+ interruptGraceTimeout.unref?.();
184
+ };
185
+ const beginCompletionTimeout = () => {
186
+ completionTimeout = setTimeout(() => {
187
+ abortRequested = true;
188
+ beginInterruptGrace();
189
+ embeddedAgentLog.warn("codex app-server compaction exceeded its completion budget", {
190
+ threadId: params.threadId,
191
+ timeoutMs: params.timeoutMs,
192
+ interruptRequested
193
+ });
194
+ }, Math.max(1, params.timeoutMs));
195
+ completionTimeout.unref?.();
196
+ };
197
+ removeNotificationHandler = params.client.addNotificationHandler((notification) => {
198
+ if (!requestStarted || !isJsonObject(notification.params)) return;
199
+ if (readCodexNotificationThreadId(notification.params) !== params.threadId) return;
200
+ const notificationTurnId = readCodexNotificationTurnId(notification.params);
201
+ if (notification.method === "turn/started") {
202
+ compactionTurnId = notificationTurnId;
203
+ requestInterrupt();
204
+ return;
205
+ }
206
+ if (compactionTurnId && notificationTurnId !== compactionTurnId) return;
207
+ if (notification.method === "thread/tokenUsage/updated") {
208
+ tokensAfter = readCodexThreadContextSnapshot(notification.params).activeContextTokens ?? tokensAfter;
209
+ return;
210
+ }
211
+ const item = readCodexNotificationItem(notification.params);
212
+ if (item?.type === "contextCompaction") {
213
+ if (notification.method === "item/started") {
214
+ compactionTurnId = compactionTurnId ?? notificationTurnId;
215
+ if (!compactionItemId && compactionTurnId) try {
216
+ params.onCompactionTurn?.(compactionTurnId);
217
+ } catch (error) {
218
+ admissionFailure = coerceErrorMessage(error);
219
+ abortRequested = true;
220
+ beginInterruptGrace();
221
+ }
222
+ compactionItemId = item.id;
223
+ requestInterrupt();
224
+ return;
225
+ }
226
+ if (notification.method === "item/completed" && compactionItemId === item.id) {
227
+ compactionItemCompleted = true;
228
+ return;
229
+ }
230
+ }
231
+ if (notification.method !== "turn/completed" || !compactionTurnId || notificationTurnId !== compactionTurnId) return;
232
+ const turn = isJsonObject(notification.params.turn) ? notification.params.turn : void 0;
233
+ const status = typeof turn?.status === "string" ? turn.status : void 0;
234
+ if (admissionFailure) fail(admissionFailure);
235
+ else if (status !== "completed") fail(`codex app-server compaction turn ended with status ${status ?? "unknown"}`);
236
+ else if (!compactionItemId) fail("codex app-server compaction turn completed without a compaction item");
237
+ else if (!compactionItemCompleted) fail("codex app-server compaction turn completed before its compaction item");
238
+ else complete();
239
+ });
240
+ removeCloseHandler = params.client.addCloseHandler(() => {
241
+ retireUnconfirmed("codex app-server closed before native compaction completed");
242
+ });
243
+ if (params.signal) {
244
+ const onAbort = () => {
245
+ abortRequested = true;
246
+ beginInterruptGrace();
247
+ };
248
+ params.signal.addEventListener("abort", onAbort, { once: true });
249
+ removeAbortHandler = () => params.signal?.removeEventListener("abort", onAbort);
250
+ if (params.signal.aborted) onAbort();
251
+ }
252
+ return {
253
+ completion,
254
+ beginRequest: () => {
255
+ requestStarted = true;
256
+ beginCompletionTimeout();
257
+ if (abortRequested) beginInterruptGrace();
258
+ },
259
+ confirmRequestRejected: () => fail("codex app-server rejected the compaction request"),
260
+ retireUnconfirmedRequest: async (reason) => {
261
+ retireUnconfirmed(reason);
262
+ return await completion;
263
+ },
264
+ cancel: () => {
265
+ if (!requestStarted) fail("compaction request did not start");
266
+ }
267
+ };
268
+ }
269
+ //#endregion
270
+ //#region extensions/codex/src/app-server/compact-result.ts
271
+ function codexNativeCompactionResult(params, outcome) {
272
+ return {
273
+ ok: true,
274
+ compacted: outcome.compacted,
275
+ ...outcome.reason ? { reason: outcome.reason } : {},
276
+ result: {
277
+ summary: "",
278
+ firstKeptEntryId: "",
279
+ tokensBefore: params.currentTokenCount ?? 0,
280
+ ...outcome.tokensAfter !== void 0 ? { tokensAfter: outcome.tokensAfter } : {},
281
+ details: outcome.details
282
+ }
283
+ };
284
+ }
285
+ function skippedCodexNativeCompactionResult(params, skipped) {
286
+ return codexNativeCompactionResult(params, {
287
+ compacted: false,
288
+ reason: skipped.reason,
289
+ details: {
290
+ backend: "codex-app-server",
291
+ skipped: true,
292
+ reason: skipped.code,
293
+ request: skipped.request ?? "after_context_engine",
294
+ trigger: params.trigger ?? "unknown",
295
+ ...skipped.expectedThreadId ? { expectedThreadId: skipped.expectedThreadId } : {},
296
+ ...skipped.currentThreadId ? { currentThreadId: skipped.currentThreadId } : {}
297
+ }
298
+ });
299
+ }
300
+ function failedCodexThreadBindingCompactionResult(params, recovery) {
301
+ embeddedAgentLog.warn("codex app-server compaction could not use thread binding", {
302
+ sessionId: params.sessionId,
303
+ sessionKey: params.sessionKey,
304
+ threadId: recovery.threadId,
305
+ reason: recovery.reason,
306
+ recovery: recovery.recovery
307
+ });
308
+ return {
309
+ ok: false,
310
+ compacted: false,
311
+ reason: recovery.reason,
312
+ failure: {
313
+ reason: recovery.recovery,
314
+ rawError: recovery.reason
315
+ }
316
+ };
317
+ }
318
+ //#endregion
319
+ //#region extensions/codex/src/app-server/compact.ts
320
+ const CODEX_NATIVE_COMPACTION_INTERRUPT_GRACE_MS = 3e4;
321
+ /**
322
+ * Starts native Codex compaction for a manually requested bound session, or
323
+ * reports why Codex-owned automatic compaction should handle the trigger.
324
+ */
325
+ async function maybeCompactCodexAppServerSession(params, options) {
326
+ params.hostCapabilities.assertActive();
327
+ warnIfIgnoringOpenClawCompactionOverrides(params);
328
+ if (params.trigger !== "manual" && !options.allowNonManualNativeRequest) {
329
+ embeddedAgentLog.info("skipping codex app-server compaction for non-manual trigger", {
330
+ sessionId: params.sessionId,
331
+ sessionKey: params.sessionKey,
332
+ trigger: params.trigger
333
+ });
334
+ return codexNativeCompactionResult(params, {
335
+ compacted: false,
336
+ reason: "codex app-server owns automatic compaction",
337
+ details: {
338
+ backend: "codex-app-server",
339
+ skipped: true,
340
+ reason: "non_manual_trigger",
341
+ trigger: params.trigger ?? "unknown"
342
+ }
343
+ });
344
+ }
345
+ const nativeExecutionGuard = await prepareCodexNativeExecutionBlock({
346
+ config: params.config,
347
+ sessionKey: params.sandboxSessionKey ?? params.sessionKey,
348
+ sessionId: params.sessionId,
349
+ agentId: params.sandboxAgentId ?? params.agentId,
350
+ storePath: params.sessionTarget?.storePath,
351
+ sessionTarget: params.sessionTarget,
352
+ sandbox: params.sandbox,
353
+ surface: "native compaction"
354
+ });
355
+ try {
356
+ if (nativeExecutionGuard.block) return {
357
+ ok: false,
358
+ compacted: false,
359
+ reason: nativeExecutionGuard.block
360
+ };
361
+ const bindingIdentity = sessionBindingIdentity({
362
+ sessionId: params.sessionId,
363
+ sessionKey: params.sessionKey,
364
+ agentId: params.agentId,
365
+ config: params.config
366
+ });
367
+ const abortedResult = (attempt, expectedThreadId, currentThreadId) => options.allowNonManualNativeRequest ? skippedCodexNativeCompactionResult(attempt, {
368
+ reason: "codex app-server compaction aborted before native compaction",
369
+ code: "aborted_before_native_compaction",
370
+ request: options.nativeCompactionRequest ?? "after_context_engine",
371
+ ...expectedThreadId ? {
372
+ expectedThreadId,
373
+ currentThreadId
374
+ } : {}
375
+ }) : {
376
+ ok: false,
377
+ compacted: false,
378
+ reason: "codex app-server compaction aborted while waiting to start"
379
+ };
380
+ let resolvedBinding;
381
+ try {
382
+ resolvedBinding = await resolveCodexSessionBinding({
383
+ bindingStore: options.bindingStore,
384
+ identity: bindingIdentity,
385
+ config: params.config,
386
+ storePath: params.sessionTarget?.storePath,
387
+ signal: params.abortSignal
388
+ });
389
+ } catch (error) {
390
+ if (!params.abortSignal?.aborted) throw error;
391
+ const threadId = (await options.bindingStore.readAsync(bindingIdentity))?.threadId;
392
+ return abortedResult(params, threadId, threadId);
393
+ }
394
+ using _ = { [Symbol.dispose]: resolvedBinding.release };
395
+ const { binding: initialBinding, authority } = resolvedBinding;
396
+ const assertCurrent = () => {
397
+ authority.assertCurrent();
398
+ };
399
+ const withCurrent = async (write) => {
400
+ await nativeExecutionGuard.assertCurrent();
401
+ await authority.withCurrent(write);
402
+ };
403
+ const settlementAuthority = authority.withLiveness(() => {});
404
+ const assertSettlementCurrent = settlementAuthority.assertCurrent;
405
+ if (!initialBinding?.threadId) return failedCodexThreadBindingCompactionResult(params, {
406
+ reason: "no codex app-server thread binding",
407
+ recovery: "missing_thread_binding"
408
+ });
409
+ if (initialBinding.modelProvider === "openclaw_token_sharing") return {
410
+ ok: false,
411
+ compacted: false,
412
+ reason: "Manual compaction is unavailable with ChatGPT subscription sharing. Automatic compaction runs during normal turns; continue the conversation or start a new session."
413
+ };
414
+ if (params.nativeToolSurface === "host-isolated" || initialBinding.nativeToolPolicyRestricted === true || initialBinding.ringZeroConfigFingerprint !== void 0) return codexNativeCompactionResult(params, {
415
+ compacted: false,
416
+ reason: "native compaction is unavailable for a host-isolated Codex session",
417
+ details: {
418
+ backend: "codex-app-server",
419
+ skipped: true,
420
+ reason: "native_tool_policy_restricted",
421
+ expectedThreadId: initialBinding.threadId
422
+ }
423
+ });
424
+ let binding = initialBinding;
425
+ const requestedAuthProfileId = params.authProfileId?.trim() || void 0;
426
+ let connection;
427
+ try {
428
+ const config = params.config ?? {};
429
+ connection = await resolveCodexBindingAppServerConnection({
430
+ binding,
431
+ authProfileId: requestedAuthProfileId ?? binding.authProfileId,
432
+ pluginConfig: options.pluginConfig,
433
+ config,
434
+ assertCurrent,
435
+ assertCurrentAsync: nativeExecutionGuard.assertCurrent,
436
+ agentDir: resolveAgentDir(config, bindingIdentity.agentId)
437
+ });
438
+ } catch (error) {
439
+ return {
440
+ ok: false,
441
+ compacted: false,
442
+ reason: coerceErrorMessage(error)
443
+ };
444
+ }
445
+ const { appServer, usesSupervisionConnection } = connection;
446
+ if (!usesSupervisionConnection && requestedAuthProfileId && binding.authProfileId && binding.authProfileId !== requestedAuthProfileId) return {
447
+ ok: false,
448
+ compacted: false,
449
+ reason: "auth profile mismatch for session binding"
450
+ };
451
+ const shouldReleaseDefaultLease = !options.clientFactory;
452
+ const clientFactory = options.clientFactory ?? createIsolatedCodexAppServerClient;
453
+ const runtimeAuthPlan = usesSupervisionConnection ? void 0 : params.runtimeAuthPlan ?? params.runtimePlan?.auth;
454
+ const usesPreparedApiKey = appServer.start.homeScope !== "user" && runtimeAuthPlan?.modelRoute?.authRequirement === "api-key";
455
+ const preparedApiKey = usesPreparedApiKey ? params.resolvedApiKey?.trim() : void 0;
456
+ if (usesPreparedApiKey && !preparedApiKey) return {
457
+ ok: false,
458
+ compacted: false,
459
+ reason: "Prepared Codex Platform compaction route is missing its resolved API key."
460
+ };
461
+ return await runWithAsyncWorkResources(async (onAcquired) => {
462
+ const modelSource = params.hostCapabilities.retainSourceAuthority();
463
+ let modelSourceTransferred = false;
464
+ onAcquired({
465
+ release: () => {
466
+ if (!modelSourceTransferred) modelSource?.release();
467
+ },
468
+ releaseBeforeResultWhenIdle: true
469
+ });
470
+ const modelCancellation = new AbortController();
471
+ const signals = [
472
+ params.abortSignal,
473
+ modelSource?.signal,
474
+ modelCancellation.signal
475
+ ].filter((signal) => signal !== void 0);
476
+ const attempt = {
477
+ ...params,
478
+ abortSignal: AbortSignal.any(signals)
479
+ };
480
+ const assertAdmissionCurrent = () => {
481
+ attempt.hostCapabilities.assertActive();
482
+ assertCurrent();
483
+ };
484
+ try {
485
+ return await withCodexAppServerThreadMutationHold(binding.threadId, async (hold, start) => {
486
+ await withCurrent(assertAdmissionCurrent);
487
+ const boundClientLease = await retainSharedCodexAppServerClientByInstanceId(binding.clientId);
488
+ try {
489
+ await withCurrent(assertAdmissionCurrent);
490
+ attempt.abortSignal.throwIfAborted();
491
+ } catch (error) {
492
+ await boundClientLease?.release();
493
+ throw error;
494
+ }
495
+ const client = boundClientLease?.client ?? await clientFactory({
496
+ startOptions: appServer.start,
497
+ ...preparedApiKey ? { preparedAuth: {
498
+ kind: "api-key",
499
+ apiKey: preparedApiKey
500
+ } } : { authProfileId: connection.clientAuthProfileId },
501
+ authRequirement: runtimeAuthPlan?.modelRoute?.authRequirement,
502
+ agentDir: attempt.agentDir,
503
+ config: attempt.config,
504
+ assertCurrent: assertAdmissionCurrent,
505
+ assertCurrentAsync: nativeExecutionGuard.assertCurrent
506
+ });
507
+ start();
508
+ embeddedAgentLog.info("selected codex app-server compaction client", {
509
+ clientId: client.getInstanceId(),
510
+ recordedOwnerReused: Boolean(boundClientLease),
511
+ threadId: binding.threadId
512
+ });
513
+ let releaseThreadSubscription;
514
+ let retainedThreadOwnership;
515
+ let canRetainThreadOwnership = false;
516
+ let compactionSucceeded = false;
517
+ let temporaryClientExited = true;
518
+ let compactionRequestDefinitelyRejected = false;
519
+ let nativeRequestNeedsSettlement = false;
520
+ const leaseAuthority = authority.withLiveness(() => {
521
+ if (!nativeRequestNeedsSettlement && !compactionRequestDefinitelyRejected) assertAdmissionCurrent();
522
+ });
523
+ let tokensAfter;
524
+ let modelOwner;
525
+ const releaseCompactionThread = async (threadId) => {
526
+ if (await unsubscribeCodexThreadBestEffort(client, {
527
+ threadId,
528
+ timeoutMs: 5e3
529
+ })) return;
530
+ await closeCodexStartupClientBestEffort(client);
531
+ throw new CodexAppServerUnsafeSubscriptionError(`Codex compaction thread subscription could not be released: ${threadId}`);
532
+ };
533
+ const completionWatch = watchCodexNativeCompactionCompletion({
534
+ client,
535
+ threadId: binding.threadId,
536
+ signal: attempt.abortSignal,
537
+ timeoutMs: options.nativeCompletionTimeoutMs ?? resolveCompactionTimeoutMs(attempt.config),
538
+ interruptGraceMs: options.nativeInterruptGraceMs ?? CODEX_NATIVE_COMPACTION_INTERRUPT_GRACE_MS,
539
+ onCompactionTurn: (turnId) => {
540
+ assertAdmissionCurrent();
541
+ const runtimeModel = attempt.runtimeModel;
542
+ const mapping = !usesSupervisionConnection && attempt.provider && attempt.model && runtimeModel?.provider === attempt.provider && runtimeModel.id === attempt.model ? {
543
+ nativeModel: {
544
+ provider: attempt.provider,
545
+ model: readCodexRuntimeModelId(runtimeModel, attempt.model)
546
+ },
547
+ authorizedModel: {
548
+ provider: attempt.provider,
549
+ model: attempt.model
550
+ }
551
+ } : void 0;
552
+ modelOwner?.bindTurn(turnId, mapping);
553
+ },
554
+ retireUnconfirmed: async () => {
555
+ releaseThreadSubscription = void 0;
556
+ const transportStopped = await client.closeAndWait({
557
+ exitTimeoutMs: 5e3,
558
+ forceKillDelayMs: 250
559
+ });
560
+ temporaryClientExited = transportStopped.exited;
561
+ if (appServer.start.transport === "stdio") {
562
+ if (transportStopped.exited) return;
563
+ throw new Error("failed to stop unconfirmed codex app-server process");
564
+ }
565
+ if (usesSupervisionConnection) throw new Error("cannot detach an unconfirmed supervised codex thread");
566
+ if (await options.bindingStore.mutate(bindingIdentity, {
567
+ kind: "clear",
568
+ threadId: binding.threadId,
569
+ clientId: binding.clientId
570
+ }, assertSettlementCurrent, settlementAuthority)) return;
571
+ const currentBinding = await options.bindingStore.readAsync(bindingIdentity);
572
+ if (currentBinding?.threadId !== binding.threadId || currentBinding.clientId !== binding.clientId) return;
573
+ throw new Error("failed to detach unconfirmed codex app-server thread binding");
574
+ }
575
+ });
576
+ const acquireThreadSubscription = async (timeoutMs) => {
577
+ if (!isIncognitoSessionKey(attempt.sessionKey)) {
578
+ retainedThreadOwnership = await consumeCodexAppServerLiveThread(client, binding.threadId);
579
+ if (!retainedThreadOwnership) {
580
+ const resumed = await resumeCodexAppServerThread({
581
+ client,
582
+ abandonClient: async () => closeCodexStartupClientBestEffort(client),
583
+ request: {
584
+ threadId: binding.threadId,
585
+ excludeTurns: true
586
+ },
587
+ timeoutMs: timeoutMs ?? appServer.requestTimeoutMs,
588
+ assertCurrent: assertAdmissionCurrent,
589
+ withCurrent,
590
+ signal: attempt.abortSignal
591
+ });
592
+ releaseThreadSubscription = async () => releaseCompactionThread(binding.threadId);
593
+ assertCodexSupervisionThreadLineage(binding, resumed.thread);
594
+ } else if (binding.connectionScope === "supervision") {
595
+ releaseThreadSubscription = async () => retainedThreadOwnership?.release(binding.threadId);
596
+ const { thread } = await client.request("thread/read", {
597
+ threadId: binding.threadId,
598
+ includeTurns: false
599
+ }, {
600
+ assertCurrent: assertAdmissionCurrent,
601
+ withCurrent
602
+ });
603
+ retainedThreadOwnership.assertCurrent();
604
+ assertCodexSupervisionThreadLineage(binding, thread);
605
+ canRetainThreadOwnership = true;
606
+ assertAdmissionCurrent();
607
+ }
608
+ releaseThreadSubscription ??= async () => releaseCompactionThread(binding.threadId);
609
+ }
610
+ };
611
+ try {
612
+ const guardedResult = await options.bindingStore.withLease(bindingIdentity, async () => {
613
+ const currentBinding = await options.bindingStore.readAsync(bindingIdentity);
614
+ if (attempt.abortSignal.aborted) {
615
+ if (!options.allowNonManualNativeRequest) attempt.abortSignal.throwIfAborted();
616
+ return {
617
+ started: false,
618
+ result: abortedResult(attempt, binding.threadId, currentBinding?.threadId)
619
+ };
620
+ }
621
+ assertCurrent();
622
+ if (!currentBinding || !isSameNativeCompactionBinding(currentBinding, binding)) {
623
+ embeddedAgentLog.warn("codex app-server compaction could not use the thread binding because it changed", {
624
+ sessionId: attempt.sessionId,
625
+ sessionKey: attempt.sessionKey,
626
+ expectedThreadId: binding.threadId,
627
+ currentThreadId: currentBinding?.threadId
628
+ });
629
+ const isRequiredPreflight = options.nativeCompactionRequest === "required_preflight";
630
+ return {
631
+ started: false,
632
+ result: options.allowNonManualNativeRequest && !isRequiredPreflight ? skippedCodexNativeCompactionResult(attempt, {
633
+ reason: "codex app-server binding changed before native compaction",
634
+ code: "binding_changed_before_native_compaction",
635
+ request: options.nativeCompactionRequest ?? "after_context_engine",
636
+ expectedThreadId: binding.threadId,
637
+ currentThreadId: currentBinding?.threadId
638
+ }) : failedCodexThreadBindingCompactionResult(attempt, {
639
+ threadId: currentBinding?.threadId ?? binding.threadId,
640
+ reason: "codex app-server binding changed before native compaction",
641
+ recovery: "stale_thread_binding"
642
+ })
643
+ };
644
+ }
645
+ binding = currentBinding;
646
+ const guardedRequestTimeoutMs = options.allowNonManualNativeRequest ? Math.min(appServer.requestTimeoutMs, CODEX_APP_SERVER_BINDING_GUARDED_REQUEST_TIMEOUT_MS) : void 0;
647
+ assertAdmissionCurrent();
648
+ await acquireThreadSubscription(guardedRequestTimeoutMs);
649
+ canRetainThreadOwnership = true;
650
+ attempt.abortSignal.throwIfAborted();
651
+ const configurationQualification = getCodexInferenceThreadQualification(client, binding.threadId);
652
+ modelOwner = await codexNativeSubagentMonitorRuntime.register({
653
+ client,
654
+ parentThreadId: binding.threadId,
655
+ modelSource,
656
+ configurationQualification,
657
+ unqualifiedModelExecution: modelSource && !configurationQualification ? true : void 0,
658
+ onUnqualifiedModelCancelled: (reason) => modelCancellation.abort(reason),
659
+ requesterSessionKey: attempt.sessionKey,
660
+ requesterTurnRunId: attempt.runId,
661
+ agentId: bindingIdentity.agentId,
662
+ assertCurrent: assertAdmissionCurrent,
663
+ retainClient: () => retainSharedCodexAppServerClientIfCurrent(client),
664
+ retainParentThread: (threadId) => protectCodexAppServerLiveThread(client, threadId)
665
+ });
666
+ modelSourceTransferred = true;
667
+ assertAdmissionCurrent();
668
+ attempt.abortSignal.throwIfAborted();
669
+ await clearContextEngineProjectionBeforeNativeCompaction({
670
+ sessionId: attempt.sessionId,
671
+ bindingStore: options.bindingStore,
672
+ identity: bindingIdentity,
673
+ binding,
674
+ assertCurrent: assertAdmissionCurrent,
675
+ authority
676
+ });
677
+ assertAdmissionCurrent();
678
+ try {
679
+ canRetainThreadOwnership = false;
680
+ completionWatch.beginRequest();
681
+ nativeRequestNeedsSettlement = true;
682
+ await client.request("thread/compact/start", { threadId: binding.threadId }, {
683
+ ...guardedRequestTimeoutMs === void 0 ? {} : { timeoutMs: guardedRequestTimeoutMs },
684
+ signal: attempt.abortSignal,
685
+ withCurrent,
686
+ assertCurrent: assertAdmissionCurrent
687
+ });
688
+ return {
689
+ started: true,
690
+ accepted: true
691
+ };
692
+ } catch (error) {
693
+ compactionRequestDefinitelyRejected ||= error instanceof CodexAppServerScopedRequestRejectedError || isCodexAppServerPrewriteRequestCancellationError(error) || error instanceof CodexAppServerRpcError;
694
+ if (compactionRequestDefinitelyRejected) {
695
+ canRetainThreadOwnership = !isCodexThreadNotFoundError(error);
696
+ completionWatch.confirmRequestRejected();
697
+ nativeRequestNeedsSettlement = false;
698
+ if (error instanceof CodexAppServerRpcError || binding.contextEngine?.projection) await options.bindingStore.mutate(bindingIdentity, {
699
+ kind: "set",
700
+ binding
701
+ }, assertSettlementCurrent, settlementAuthority);
702
+ }
703
+ return {
704
+ started: true,
705
+ accepted: false,
706
+ error
707
+ };
708
+ }
709
+ }, {
710
+ assertCurrent: () => nativeRequestNeedsSettlement || compactionRequestDefinitelyRejected ? assertSettlementCurrent() : assertAdmissionCurrent(),
711
+ authority: leaseAuthority
712
+ });
713
+ if (!guardedResult.started) return guardedResult.result;
714
+ if (!guardedResult.accepted) {
715
+ if (compactionRequestDefinitelyRejected) throw guardedResult.error;
716
+ if (!attempt.abortSignal.aborted || !isCodexAppServerIndeterminateRequestCancellationError(guardedResult.error)) {
717
+ await completionWatch.retireUnconfirmedRequest(`codex app-server compaction start was unconfirmed: ${coerceErrorMessage(guardedResult.error)}`);
718
+ nativeRequestNeedsSettlement = false;
719
+ throw guardedResult.error;
720
+ }
721
+ }
722
+ embeddedAgentLog.info("waiting for codex app-server compaction completion", {
723
+ sessionId: attempt.sessionId,
724
+ threadId: binding.threadId
725
+ });
726
+ const completion = await completionWatch.completion;
727
+ nativeRequestNeedsSettlement = false;
728
+ await settlementAuthority.withCurrent(assertSettlementCurrent);
729
+ if (!completion.completed) throw new Error(completion.reason);
730
+ compactionSucceeded = true;
731
+ tokensAfter = completion.tokensAfter;
732
+ if (completion.turnId && completion.itemId) await persistCodexContextCompactionActivity({
733
+ sessionTarget: attempt.sessionTarget,
734
+ config: attempt.config,
735
+ cwd: attempt.workspaceDir,
736
+ runId: attempt.runId,
737
+ threadId: binding.threadId,
738
+ turnId: completion.turnId,
739
+ itemId: completion.itemId,
740
+ timestamp: Date.now()
741
+ });
742
+ await settlementAuthority.withCurrent(assertSettlementCurrent);
743
+ embeddedAgentLog.info("completed codex app-server compaction", {
744
+ sessionId: attempt.sessionId,
745
+ threadId: binding.threadId
746
+ });
747
+ canRetainThreadOwnership = true;
748
+ } catch (error) {
749
+ if (nativeRequestNeedsSettlement) {
750
+ await completionWatch.retireUnconfirmedRequest(`codex app-server compaction ownership failed after request admission: ${coerceErrorMessage(error)}`);
751
+ nativeRequestNeedsSettlement = false;
752
+ }
753
+ if (isCodexThreadNotFoundError(error)) return failedCodexThreadBindingCompactionResult(attempt, {
754
+ threadId: binding.threadId,
755
+ reason: coerceErrorMessage(error),
756
+ recovery: "stale_thread_binding"
757
+ });
758
+ embeddedAgentLog.warn("codex app-server compaction failed", {
759
+ sessionId: attempt.sessionId,
760
+ sessionKey: attempt.sessionKey,
761
+ threadId: binding.threadId,
762
+ reason: coerceErrorMessage(error)
763
+ });
764
+ return {
765
+ ok: false,
766
+ compacted: false,
767
+ reason: coerceErrorMessage(error)
768
+ };
769
+ } finally {
770
+ completionWatch.cancel();
771
+ try {
772
+ await settleCodexCompactionSubscription({
773
+ client,
774
+ bindingStore: options.bindingStore,
775
+ identity: bindingIdentity,
776
+ binding,
777
+ authority: settlementAuthority,
778
+ ownership: canRetainThreadOwnership ? retainedThreadOwnership : void 0,
779
+ compacted: compactionSucceeded,
780
+ release: releaseThreadSubscription
781
+ });
782
+ } finally {
783
+ try {
784
+ await modelOwner?.unregister();
785
+ } finally {
786
+ const ownerExit = boundClientLease?.release();
787
+ if (ownerExit && appServer.start.transport === "stdio") hold(ownerExit);
788
+ else if (!boundClientLease && shouldReleaseDefaultLease) {
789
+ if (appServer.start.transport === "stdio") hold(waitForCodexAppServerClientExit(client));
790
+ temporaryClientExited = temporaryClientExited && (await client.closeAndWait()).exited;
791
+ }
792
+ }
793
+ }
794
+ }
795
+ if (!temporaryClientExited) throw new CodexAppServerUnsafeSubscriptionError(`Codex compaction client did not exit: ${binding.threadId}`);
796
+ const details = {
797
+ backend: "codex-app-server",
798
+ threadId: binding.threadId,
799
+ signal: "thread/compact/start",
800
+ pending: false,
801
+ completed: true,
802
+ ...options.allowNonManualNativeRequest ? {
803
+ request: options.nativeCompactionRequest ?? "after_context_engine",
804
+ trigger: attempt.trigger ?? "unknown"
805
+ } : {}
806
+ };
807
+ return codexNativeCompactionResult(attempt, {
808
+ compacted: true,
809
+ tokensAfter,
810
+ details
811
+ });
812
+ }, attempt.abortSignal);
813
+ } catch (error) {
814
+ if (attempt.abortSignal.aborted) return abortedResult(attempt, initialBinding.threadId, binding.threadId);
815
+ throw error;
816
+ }
817
+ });
818
+ } finally {
819
+ nativeExecutionGuard.release();
820
+ }
821
+ }
822
+ //#endregion
823
+ export { maybeCompactCodexAppServerSession };