@openclaw/codex 2026.9.5 → 2026.9.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 (174) hide show
  1. package/README.md +2 -0
  2. package/assets/icon.png +0 -0
  3. package/dist/.setup/{account-usage-runtime-C2MOIvfq.mjs → account-usage-runtime-DFhbh1zz.mjs} +6 -6
  4. package/dist/.setup/{apply-CJ0ZfmBG.mjs → apply-D3GcSoSa.mjs} +35 -55
  5. package/dist/.setup/{attempt-client-cleanup-BpYKdTA0.mjs → attempt-client-cleanup-DOP-cW5j.mjs} +179 -73
  6. package/dist/.setup/attempt-workspace-context-C5HigshI.mjs +164 -0
  7. package/dist/.setup/{auth-binding-DhLWa_7K.mjs → auth-binding-BLWz7stm.mjs} +14 -1
  8. package/dist/.setup/{auth-cache-key-QirmgiCo.mjs → auth-cache-key-Dbvq-QgB.mjs} +41 -111
  9. package/dist/.setup/{auth-profile-WqZtZfXN.mjs → auth-profile-B0okYl2D.mjs} +1 -2
  10. package/dist/.setup/auth-profile-health-oHizqgye.mjs +53 -0
  11. package/dist/.setup/auth-profile-recovery-BREezV0L.mjs +14 -0
  12. package/dist/.setup/auth-start-options-BPIPeEX8.mjs +44 -0
  13. package/dist/.setup/{binding-connection-Bm38niE8.mjs → binding-connection-DTtN1KrX.mjs} +2 -2
  14. package/dist/.setup/{binding-connection.runtime-CnRMC0ta.mjs → binding-connection.runtime-6TpgD1M6.mjs} +5 -5
  15. package/dist/.setup/{bounded-turn-BtlZcivC.mjs → bounded-turn-CbjoN2OW.mjs} +140 -37
  16. package/dist/.setup/bounded-turn-isolation-B8K_ylqk.mjs +14 -0
  17. package/dist/.setup/{build-state-Xx9ybZqa.mjs → build-state-Da1_z0kd.mjs} +1 -1
  18. package/dist/.setup/{capabilities-_vXcZGSx.mjs → capabilities-B3WEZl4e.mjs} +2 -10
  19. package/dist/.setup/{client-vXs2929Q.mjs → client-N0JpgSzF.mjs} +635 -872
  20. package/dist/.setup/client-catalog-response-5HHLdcde.mjs +285 -0
  21. package/dist/.setup/{command-dispatch-naHIZwwF.mjs → command-dispatch-BeAoaovI.mjs} +9 -8
  22. package/dist/.setup/{command-formatters-CGEkdawF.mjs → command-formatters-R3ckE3Co.mjs} +36 -64
  23. package/dist/.setup/{command-handlers-BtAJEW1X.mjs → command-handlers-ylTMS00z.mjs} +301 -488
  24. package/dist/.setup/{command-rpc-DHFpn4le.mjs → command-rpc-CGJGUQ6Y.mjs} +40 -28
  25. package/dist/.setup/compact-C2WamavS.mjs +776 -0
  26. package/dist/.setup/{config-CedDWjM-.mjs → config-DKhXquav.mjs} +26 -28
  27. package/dist/.setup/{config-options-BsanJ8QG.mjs → config-options-CzyWLTJt.mjs} +68 -65
  28. package/dist/.setup/{config-parsing-CcB9iPoq.mjs → config-parsing-b088LyhT.mjs} +57 -60
  29. package/dist/.setup/{config-runtime-CeAhl_h4.mjs → config-runtime-C0NbLms1.mjs} +2 -2
  30. package/dist/.setup/{config-security-BRQ2mgW9.mjs → config-security-CE-FcGw9.mjs} +51 -215
  31. package/dist/.setup/{config-utils-DujwEnhg.mjs → config-utils-D0CXecki.mjs} +3 -13
  32. package/dist/.setup/context-engine-projection-PezSESth.mjs +387 -0
  33. package/dist/.setup/{conversation-binding-DhzrpTM6.mjs → conversation-binding-3Min8qvP.mjs} +71 -105
  34. package/dist/.setup/{conversation-binding-data-CrcyZk6O.mjs → conversation-binding-data-C746z5Pn.mjs} +8 -12
  35. package/dist/.setup/{conversation-control-DN53ns41.mjs → conversation-control-CEP8X5JC.mjs} +30 -69
  36. package/dist/.setup/{cyber-failover-DYwbmf1o.mjs → cyber-failover-XV0nNRZu.mjs} +1 -1
  37. package/dist/.setup/{cyber-failover-notice-e9G3J9-e.mjs → cyber-failover-notice-RNpGpTyP.mjs} +1 -1
  38. package/dist/.setup/{dynamic-tools-D16lOp67.mjs → dynamic-tools-DzlsLUuS.mjs} +3136 -3167
  39. package/dist/.setup/{effective-mcp-catalog-K6kLCN8X.mjs → effective-mcp-catalog-CxUtC-xG.mjs} +8 -17
  40. package/dist/.setup/{ephemeral-turn-R1gA8Sn6.mjs → ephemeral-turn-CDsPJOa2.mjs} +9 -6
  41. package/dist/.setup/event-projector-assistant-message-CigreO4K.mjs +69 -0
  42. package/dist/.setup/{event-projector-usage-C7Ntzs-f.mjs → event-projector-usage-03R0I2dM.mjs} +4 -26
  43. package/dist/.setup/event-projector-values-DJSz8BTk.mjs +106 -0
  44. package/dist/.setup/incognito-session-DWYapfwf.mjs +2 -0
  45. package/dist/.setup/{inference-context-fulhZuz8.mjs → inference-context-D-9gWlTR.mjs} +16 -18
  46. package/dist/.setup/inference-dispatch-CMZtjQyz.mjs +359 -0
  47. package/dist/.setup/inference-metadata-CgIf7sOx.mjs +81 -0
  48. package/dist/.setup/inference-proxy-DhcXOgUE.mjs +561 -0
  49. package/dist/.setup/{isolated-completion-B6srt48J.mjs → isolated-completion-Dm3PzxJk.mjs} +15 -11
  50. package/dist/.setup/launch-args-DbFCehO7.mjs +196 -0
  51. package/dist/.setup/{managed-binary-DP6Rib3P.mjs → managed-binary-kiWRhNRE.mjs} +16 -9
  52. package/dist/.setup/{model-catalog-DkvUuBey.mjs → model-catalog-PAuZgJC6.mjs} +14 -14
  53. package/dist/.setup/model-runtime-BdqzOMkU.mjs +11 -0
  54. package/dist/.setup/{models-BDFgm_G-.mjs → models-DHXZtVVk.mjs} +9 -18
  55. package/dist/.setup/{native-auth-BLZGqFjw.mjs → native-auth-CuG53tu4.mjs} +5 -5
  56. package/dist/.setup/{native-execution-policy-YBMHSzC4.mjs → native-execution-policy-BxZJy5mP.mjs} +6 -31
  57. package/dist/.setup/{native-subagent-monitor-B1hxzIOy.mjs → native-subagent-monitor-Dpsmf2wz.mjs} +4422 -3808
  58. package/dist/.setup/native-subagent-pending-assignments-DwkCzLvD.mjs +203 -0
  59. package/dist/.setup/native-task-assignments-DMQ0g3hu.mjs +194 -0
  60. package/dist/.setup/{node-cli-sessions-Cl8b2ZF3.mjs → node-cli-sessions-HC4W6FLI.mjs} +99 -111
  61. package/dist/.setup/node-exec-server.runtime-BgBfWQqo.mjs +244 -0
  62. package/dist/.setup/{plan-xD7WKYTM.mjs → plan-Y-QIvrKB.mjs} +118 -163
  63. package/dist/.setup/{plugin-activation-r8nq5Jzp.mjs → plugin-activation-cNHRfaxU.mjs} +10 -47
  64. package/dist/.setup/{plugin-app-cache-key-BOxKP7db.mjs → plugin-app-cache-key-BL9B5H0L.mjs} +9 -42
  65. package/dist/.setup/{plugin-inventory-DUle8DLz.mjs → plugin-inventory-Cky2XJUw.mjs} +32 -23
  66. package/dist/.setup/{plugin-marketplace-discovery-P-Vndfqq.mjs → plugin-marketplace-discovery-D_dV9FXa.mjs} +22 -25
  67. package/dist/.setup/{plugin-metadata-cache-DsS5buNa.mjs → plugin-metadata-cache-DsjsL1dr.mjs} +328 -318
  68. package/dist/.setup/protocol-CANUwXJ3.mjs +17 -0
  69. package/dist/.setup/provider-DH8NSzGt.mjs +51 -0
  70. package/dist/.setup/{provider-capabilities-B8J4Dy-O.mjs → provider-capabilities-CAxoF-X1.mjs} +35 -12
  71. package/dist/.setup/{rate-limits-DOEGYRNs.mjs → rate-limits-B7-X2TgG.mjs} +123 -166
  72. package/dist/.setup/{request-BioXJLYa.mjs → request-BHZ1nz8d.mjs} +25 -16
  73. package/dist/.setup/responses-oauth-twnuTaAa.mjs +93 -0
  74. package/dist/.setup/rpc-error-BlD2vuzn.mjs +31 -0
  75. package/dist/.setup/{run-attempt-rlA07pUv.mjs → run-attempt-D8RZUOzY.mjs} +2046 -1454
  76. package/dist/.setup/{run-attempt-lifecycle-B7JbY4-F.mjs → run-attempt-lifecycle-C-6O3Exn.mjs} +10 -24
  77. package/dist/.setup/{runtime-artifact-Dy38Z5iU.mjs → runtime-artifact-DDQ-HGXf.mjs} +43 -47
  78. package/dist/.setup/runtime-artifact-connection-D68qQn1m.mjs +78 -0
  79. package/dist/.setup/sandbox-guard-DjCz2eOw.mjs +126 -0
  80. package/dist/.setup/scope-DOC1Xjc8.mjs +6 -0
  81. package/dist/.setup/session-binding-DGCYAfvD.mjs +443 -0
  82. package/dist/.setup/{session-binding-record-TH3xA0zj.mjs → session-binding-record-Oe9L-CNY.mjs} +73 -132
  83. package/dist/.setup/{session-binding-sidecars-CKYEcfNn.mjs → session-binding-sidecars-jo6H8dFr.mjs} +242 -60
  84. package/dist/.setup/{session-catalog-fUdWDx-U.mjs → session-catalog-4sCdv5qx.mjs} +598 -452
  85. package/dist/.setup/{session-catalog-adoption-CR_whkEW.mjs → session-catalog-adoption-BU_pHWG7.mjs} +59 -26
  86. package/dist/.setup/{session-catalog-archive-CwZaPacf.mjs → session-catalog-archive-spHfihri.mjs} +7 -7
  87. package/dist/.setup/session-catalog-events-DePDzzjc.mjs +139 -0
  88. package/dist/.setup/session-catalog-home-id-vlih0B_g.mjs +22 -0
  89. package/dist/.setup/{session-catalog-index-B141u15s.mjs → session-catalog-index-CZvDzC6z.mjs} +286 -182
  90. package/dist/.setup/{session-catalog-index-order-Cc5BzlQr.mjs → session-catalog-index-order-BcQpHks3.mjs} +2 -2
  91. package/dist/.setup/{session-catalog-index-state-BAuDztHN.mjs → session-catalog-index-state-TeO7EyO-.mjs} +6 -2
  92. package/dist/.setup/session-catalog-limits-DDxOsQeC.mjs +14 -0
  93. package/dist/.setup/session-catalog-list-request-CvtxrYSe.mjs +170 -0
  94. package/dist/.setup/session-catalog-native-projection-DjhwGL6x.mjs +178 -0
  95. package/dist/.setup/{session-catalog-node-adoption-BVRsYOSh.mjs → session-catalog-node-adoption-DgXvSGu0.mjs} +30 -35
  96. package/dist/.setup/{session-catalog-node-continue-Dowv8osw.mjs → session-catalog-node-continue-DjKXHBbi.mjs} +25 -18
  97. package/dist/.setup/session-catalog-node-lookup-CtAXI5W5.mjs +56 -0
  98. package/dist/.setup/{session-catalog-native-projection-ChV3cCtm.mjs → session-catalog-parsing-CPGaPYr-.mjs} +14 -180
  99. package/dist/.setup/{session-catalog-projection-C1Bj9Jl-.mjs → session-catalog-projection-Cr5qP5Dj.mjs} +15 -5
  100. package/dist/.setup/session-catalog-provenance-DoAvktcj.mjs +95 -0
  101. package/dist/.setup/{session-cli-DIj-IE-E.mjs → session-cli-Cn_nCqfq.mjs} +11 -24
  102. package/dist/.setup/{session-history-C--SrLI8.mjs → session-history-D83lJWHG.mjs} +16 -23
  103. package/dist/.setup/{session-history-import-JHXT5Xfi.mjs → session-history-import-WhX-X33a.mjs} +7 -10
  104. package/dist/.setup/session-history-read-Ov3StuL4.mjs +133 -0
  105. package/dist/.setup/{session-history.worker-CpNj7H_P.mjs → session-history.worker-MnPKncqP.mjs} +14 -23
  106. package/dist/.setup/session-initialization-6aveB9qb.mjs +22 -0
  107. package/dist/.setup/{session-permission-policy-DhurXY0l.mjs → session-permission-policy-Ci_fVX6y.mjs} +4 -8
  108. package/dist/.setup/{session-retirement-CU87AOg9.mjs → session-retirement-qMTxkNx2.mjs} +31 -12
  109. package/dist/.setup/{settled-turn-context-fmwouT5I.mjs → settled-turn-context-D4yj4rxf.mjs} +1 -1
  110. package/dist/.setup/{settled-turn-finalizer-CiY2bLFK.mjs → settled-turn-finalizer-BsvEabkw.mjs} +17 -13
  111. package/dist/.setup/{shared-client-BpTtuLQ5.mjs → shared-client-DqyTMYug.mjs} +826 -485
  112. package/dist/.setup/shared-client-lifecycle-DJIgqgMw.mjs +153 -0
  113. package/dist/.setup/{side-question-DSCZyoBD.mjs → side-question-C4kCmQy1.mjs} +206 -334
  114. package/dist/.setup/{source-Bjp4UQij.mjs → source-CS_7GFJZ.mjs} +82 -139
  115. package/dist/.setup/spawn-error-CL3n6MAa.mjs +57 -0
  116. package/dist/.setup/{thread-archive-guard-jmecf6OJ.mjs → thread-archive-guard-C9frICzX.mjs} +10 -3
  117. package/dist/.setup/thread-lifecycle-DPflntEJ.mjs +2362 -0
  118. package/dist/.setup/{incognito-session-uhrBF6wJ.mjs → thread-ownership-queue-Dp24d7-F.mjs} +1 -2
  119. package/dist/.setup/{thread-ownership-skomxnIt.mjs → thread-ownership-roNP0l1c.mjs} +47 -10
  120. package/dist/.setup/thread-policy-DTd-DtkX.mjs +109 -0
  121. package/dist/.setup/thread-requests-B_bRnMGN.mjs +2102 -0
  122. package/dist/.setup/{thread-resume-BkNpj9Pz.mjs → thread-resume-CdDaoc7T.mjs} +6 -6
  123. package/dist/.setup/timeout-CXOfNoaX.mjs +46 -0
  124. package/dist/.setup/transcript-history-projection-DRSifI-1.mjs +201 -0
  125. package/dist/.setup/{transcript-mirror-attestation-CzM-94NC.mjs → transcript-mirror-attestation-YSegaktH.mjs} +3 -4
  126. package/dist/.setup/{transcript-mirror-D4qp_leP.mjs → transcript-mirror-kxmCYsuF.mjs} +224 -206
  127. package/dist/.setup/{transport-stdio-Cmx94Oiy.mjs → transport-stdio-Bdegpn2V.mjs} +138 -75
  128. package/dist/.setup/transport-websocket-BTBE-LD9.mjs +211 -0
  129. package/dist/.setup/{upstream-prompt-provenance-LphB8slG.mjs → upstream-prompt-provenance-fXkKbPVC.mjs} +3 -9
  130. package/dist/.setup/{upstream-session-fork-D3UKxgVD.mjs → upstream-session-fork-CBeVjBpT.mjs} +48 -40
  131. package/dist/.setup/{usage-BOgBEKso.mjs → usage-BMzNxeR_.mjs} +5 -4
  132. package/dist/.setup/{usage-limit-error-C0ow7DOc.mjs → usage-limit-error-QXerDo3i.mjs} +5 -20
  133. package/dist/.setup/{web-search-provider.runtime-CTGuJt6i.mjs → web-search-provider.runtime-P77OUeoo.mjs} +10 -20
  134. package/dist/api.js +25 -16
  135. package/dist/catalog-page-worker-entrypoint.js +12 -0
  136. package/dist/catalog-page.worker.js +9 -0
  137. package/dist/cli-metadata.js +1 -1
  138. package/dist/doctor-contract-api.js +50 -8
  139. package/dist/harness.js +344 -1
  140. package/dist/index.js +345 -346
  141. package/dist/media-understanding-provider.js +9 -22
  142. package/dist/migration-provider-api.js +1 -1
  143. package/dist/provider-discovery.js +1 -1
  144. package/dist/session-history-worker-runtime.js +16 -33
  145. package/dist/session-history.worker.js +1 -1
  146. package/openclaw.plugin.json +14 -2
  147. package/package.json +11 -7
  148. package/dist/.setup/attempt-context-VXVwTCfS.mjs +0 -636
  149. package/dist/.setup/compact-C3i3qlzj.mjs +0 -687
  150. package/dist/.setup/event-projector-assistant-message-DNUR1s0A.mjs +0 -105
  151. package/dist/.setup/event-projector-items-DyTQ_XqL.mjs +0 -200
  152. package/dist/.setup/harness-rxaaoN-o.mjs +0 -349
  153. package/dist/.setup/history-rejection-B4nOXNXF.mjs +0 -13
  154. package/dist/.setup/image-payload-sanitizer-tupAr-2o.mjs +0 -79
  155. package/dist/.setup/inference-proxy-CC15HuSi.mjs +0 -311
  156. package/dist/.setup/launch-args-DnMak49W.mjs +0 -111
  157. package/dist/.setup/local-runtime-attribution-B_2mnqhb.mjs +0 -19
  158. package/dist/.setup/native-subagent-history-YXaL6dMd.mjs +0 -135
  159. package/dist/.setup/native-subagent-task-ids-DsuOonKv.mjs +0 -411
  160. package/dist/.setup/node-exec-server.runtime-BaViBKNz.mjs +0 -226
  161. package/dist/.setup/plugin-approval-roundtrip-CjfzafAZ.mjs +0 -122
  162. package/dist/.setup/provider-fFh_-VR3.mjs +0 -50
  163. package/dist/.setup/rolldown-runtime-8H4AJuhK.mjs +0 -14
  164. package/dist/.setup/sandbox-guard-BBP-RbTf.mjs +0 -166
  165. package/dist/.setup/session-binding-_0W_fHRr.mjs +0 -721
  166. package/dist/.setup/session-catalog-events-jMcYfQyd.mjs +0 -250
  167. package/dist/.setup/session-history-read-B3ZfSUbF.mjs +0 -50
  168. package/dist/.setup/session-initialization-DH1z6fXn.mjs +0 -75
  169. package/dist/.setup/thread-history-page-BTx-4xsg.mjs +0 -83
  170. package/dist/.setup/thread-lifecycle-Cik28qWn.mjs +0 -4904
  171. package/dist/.setup/thread-policy-Cjs4B8xf.mjs +0 -54
  172. package/dist/.setup/timeout-DZF05XrR.mjs +0 -63
  173. package/dist/.setup/transcript-history-projection-DHNBDhCU.mjs +0 -243
  174. package/dist/.setup/version-CoqzXPgK.mjs +0 -12
@@ -0,0 +1,776 @@
1
+ import { n as readCodexRuntimeModelId } from "./model-runtime-BdqzOMkU.mjs";
2
+ import { i as isJsonObject } from "./protocol-CANUwXJ3.mjs";
3
+ import { v as sessionBindingIdentity } from "./session-binding-record-Oe9L-CNY.mjs";
4
+ import { l as retainSharedCodexAppServerClientByInstanceId, p as waitForCodexAppServerClientExit } from "./shared-client-lifecycle-DJIgqgMw.mjs";
5
+ import { t as isIncognitoSessionKey } from "./incognito-session-DWYapfwf.mjs";
6
+ import { n as CodexAppServerRpcError } from "./rpc-error-BlD2vuzn.mjs";
7
+ import { i as resolveCodexBindingAppServerConnection } from "./binding-connection-DTtN1KrX.mjs";
8
+ import { F as consumeCodexAppServerLiveThread, K as retainCodexAppServerLiveThread, M as getCodexInferenceThreadQualification, U as protectCodexAppServerLiveThread, _ as retainSharedCodexAppServerClientIfCurrent, q as revertCodexAppServerLiveThreadSkillsCatalog, s as createIsolatedCodexAppServerClient } from "./shared-client-DqyTMYug.mjs";
9
+ import "./responses-oauth-twnuTaAa.mjs";
10
+ import { s as isCodexAppServerIndeterminateRequestCancellationError, u as isCodexAppServerPrewriteRequestCancellationError } from "./client-N0JpgSzF.mjs";
11
+ import { b as readCodexNotificationTurnId, l as isCodexNoActiveTurnInterruptError, o as closeCodexStartupClientBestEffort, p as unsubscribeCodexThreadBestEffort, r as CodexAppServerUnsafeSubscriptionError, y as readCodexNotificationThreadId } from "./attempt-client-cleanup-DOP-cW5j.mjs";
12
+ import { n as readCodexThreadContextSnapshot, s as readCodexNotificationItem } from "./event-projector-usage-03R0I2dM.mjs";
13
+ import { o as resolveCodexSessionBinding, t as CODEX_APP_SERVER_BINDING_GUARDED_REQUEST_TIMEOUT_MS } from "./session-binding-DGCYAfvD.mjs";
14
+ import { t as codexNativeSubagentMonitorRuntime } from "./native-subagent-monitor-Dpsmf2wz.mjs";
15
+ import { i as assertCodexSupervisionThreadLineage } from "./thread-policy-DTd-DtkX.mjs";
16
+ import { t as resumeCodexAppServerThread } from "./thread-resume-CdDaoc7T.mjs";
17
+ import { s as withCodexAppServerThreadMutationHold, t as isSameCodexAppServerThreadOwner } from "./thread-ownership-roNP0l1c.mjs";
18
+ import { t as persistCodexContextCompactionActivity } from "./context-compaction-activity-CMla5FPJ.mjs";
19
+ import { t as resolveCodexNativeExecutionBlock } from "./sandbox-guard-DjCz2eOw.mjs";
20
+ import { asOptionalRecord } from "openclaw/plugin-sdk/string-coerce-runtime";
21
+ import { coerceErrorMessage } from "openclaw/plugin-sdk/error-runtime";
22
+ import { AsyncLocalStorage } from "node:async_hooks";
23
+ import { createDeferred } from "openclaw/plugin-sdk/extension-shared";
24
+ import { resolveAgentDir } from "openclaw/plugin-sdk/agent-runtime";
25
+ import { embeddedAgentLog, resolveCompactionTimeoutMs } from "openclaw/plugin-sdk/agent-harness-runtime";
26
+ import { runWithAsyncWorkResources } from "openclaw/plugin-sdk/agent-harness-tool-runtime";
27
+ import { createDedupeCache } from "openclaw/plugin-sdk/dedupe-runtime";
28
+ //#region extensions/codex/src/app-server/compact-helpers.ts
29
+ async function clearContextEngineProjectionBeforeNativeCompaction(params) {
30
+ const contextEngineBinding = params.binding.contextEngine;
31
+ if (!contextEngineBinding?.projection) return;
32
+ await params.bindingStore.mutate(params.identity, {
33
+ kind: "patch",
34
+ threadId: params.binding.threadId,
35
+ patch: { contextEngine: {
36
+ ...contextEngineBinding,
37
+ projection: void 0
38
+ } }
39
+ }, params.assertCurrent);
40
+ embeddedAgentLog.info("cleared codex context-engine projection before native compaction", {
41
+ sessionId: params.sessionId,
42
+ threadId: params.binding.threadId,
43
+ previousEpoch: contextEngineBinding.projection.epoch,
44
+ previousFingerprint: contextEngineBinding.projection.fingerprint
45
+ });
46
+ }
47
+ function isSameNativeCompactionBinding(current, expected) {
48
+ 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;
49
+ }
50
+ function isCodexThreadNotFoundError(error) {
51
+ return coerceErrorMessage(error).toLowerCase().includes("thread not found");
52
+ }
53
+ const warnedIgnoredCompactionOverrides = createDedupeCache({
54
+ ttlMs: 0,
55
+ maxSize: 4096
56
+ });
57
+ function warnIfIgnoringOpenClawCompactionOverrides(params) {
58
+ const ignoredConfig = readIgnoredCompactionOverridePaths(params);
59
+ if (ignoredConfig.length === 0) return;
60
+ const warningKey = ignoredConfig.join("\0");
61
+ if (warnedIgnoredCompactionOverrides.check(warningKey)) return;
62
+ embeddedAgentLog.warn("ignoring OpenClaw compaction overrides for Codex app-server compaction; Codex uses native server-side compaction", {
63
+ sessionId: params.sessionId,
64
+ sessionKey: params.sessionKey,
65
+ ignoredConfig
66
+ });
67
+ }
68
+ function readIgnoredCompactionOverridePaths(params) {
69
+ const compaction = asOptionalRecord(params.config?.agents?.defaults?.compaction);
70
+ return [
71
+ "model",
72
+ "thinkingLevel",
73
+ "provider"
74
+ ].flatMap((field) => {
75
+ const value = compaction?.[field];
76
+ return typeof value === "string" && value.trim() ? [`agents.defaults.compaction.${field}`] : [];
77
+ });
78
+ }
79
+ //#endregion
80
+ //#region extensions/codex/src/app-server/compact-lifecycle.ts
81
+ function watchCodexNativeCompactionCompletion(params) {
82
+ const runOutsideBindingLease = AsyncLocalStorage.snapshot();
83
+ let settled = false;
84
+ let requestStarted = false;
85
+ let abortRequested = false;
86
+ let interruptRequested = false;
87
+ let retirementStarted = false;
88
+ let compactionTurnId;
89
+ let compactionItemId;
90
+ let compactionItemCompleted = false;
91
+ let tokensAfter;
92
+ let admissionFailure;
93
+ const { promise: completion, resolve: resolveCompletion } = createDeferred();
94
+ let removeNotificationHandler = () => {};
95
+ let removeCloseHandler = () => {};
96
+ let removeAbortHandler = () => {};
97
+ let completionTimeout;
98
+ let interruptGraceTimeout;
99
+ const finish = (result) => {
100
+ if (settled) return;
101
+ settled = true;
102
+ removeNotificationHandler();
103
+ removeCloseHandler();
104
+ removeAbortHandler();
105
+ clearTimeout(completionTimeout);
106
+ clearTimeout(interruptGraceTimeout);
107
+ resolveCompletion(result);
108
+ };
109
+ const complete = () => finish({
110
+ completed: true,
111
+ ...compactionTurnId ? { turnId: compactionTurnId } : {},
112
+ ...compactionItemId ? { itemId: compactionItemId } : {},
113
+ ...tokensAfter !== void 0 ? { tokensAfter } : {}
114
+ });
115
+ const fail = (reason) => finish({
116
+ completed: false,
117
+ reason
118
+ });
119
+ const retireUnconfirmed = (reason) => {
120
+ if (settled || retirementStarted) return;
121
+ retirementStarted = true;
122
+ runOutsideBindingLease(() => params.retireUnconfirmed()).then(() => fail(reason)).catch((error) => {
123
+ embeddedAgentLog.error("failed to retire unconfirmed codex app-server compaction", {
124
+ threadId: params.threadId,
125
+ turnId: compactionTurnId,
126
+ reason: coerceErrorMessage(error)
127
+ });
128
+ });
129
+ };
130
+ const requestInterrupt = () => {
131
+ if (settled || !requestStarted || !abortRequested || !compactionTurnId || interruptRequested) return;
132
+ interruptRequested = true;
133
+ params.client.request("turn/interrupt", {
134
+ threadId: params.threadId,
135
+ turnId: compactionTurnId
136
+ }, { timeoutMs: Math.max(1, params.interruptGraceMs) }).catch((error) => {
137
+ if (isCodexNoActiveTurnInterruptError(error)) return;
138
+ embeddedAgentLog.warn("codex app-server compaction interrupt request failed", {
139
+ threadId: params.threadId,
140
+ turnId: compactionTurnId,
141
+ reason: coerceErrorMessage(error)
142
+ });
143
+ });
144
+ };
145
+ const beginInterruptGrace = () => {
146
+ if (settled || !requestStarted || interruptGraceTimeout) return;
147
+ requestInterrupt();
148
+ interruptGraceTimeout = setTimeout(() => {
149
+ embeddedAgentLog.warn("codex app-server compaction did not reach terminal state after interruption", {
150
+ threadId: params.threadId,
151
+ turnId: compactionTurnId,
152
+ interruptGraceMs: params.interruptGraceMs
153
+ });
154
+ retireUnconfirmed("codex app-server compaction did not reach terminal state after interruption");
155
+ }, Math.max(1, params.interruptGraceMs));
156
+ interruptGraceTimeout.unref?.();
157
+ };
158
+ const beginCompletionTimeout = () => {
159
+ completionTimeout = setTimeout(() => {
160
+ abortRequested = true;
161
+ beginInterruptGrace();
162
+ embeddedAgentLog.warn("codex app-server compaction exceeded its completion budget", {
163
+ threadId: params.threadId,
164
+ timeoutMs: params.timeoutMs,
165
+ interruptRequested
166
+ });
167
+ }, Math.max(1, params.timeoutMs));
168
+ completionTimeout.unref?.();
169
+ };
170
+ removeNotificationHandler = params.client.addNotificationHandler((notification) => {
171
+ if (!requestStarted) return;
172
+ if (!isJsonObject(notification.params)) return;
173
+ if (readCodexNotificationThreadId(notification.params) !== params.threadId) return;
174
+ const notificationTurnId = readCodexNotificationTurnId(notification.params);
175
+ if (notification.method === "turn/started") {
176
+ compactionTurnId = notificationTurnId;
177
+ requestInterrupt();
178
+ return;
179
+ }
180
+ if (compactionTurnId && notificationTurnId !== compactionTurnId) return;
181
+ if (notification.method === "thread/tokenUsage/updated") {
182
+ tokensAfter = readCodexThreadContextSnapshot(notification.params).activeContextTokens ?? tokensAfter;
183
+ return;
184
+ }
185
+ const item = readCodexNotificationItem(notification.params);
186
+ if (item?.type === "contextCompaction") {
187
+ if (notification.method === "item/started") {
188
+ compactionTurnId = compactionTurnId ?? notificationTurnId;
189
+ if (!compactionItemId && compactionTurnId) try {
190
+ params.onCompactionTurn?.(compactionTurnId);
191
+ } catch (error) {
192
+ admissionFailure = coerceErrorMessage(error);
193
+ abortRequested = true;
194
+ beginInterruptGrace();
195
+ }
196
+ compactionItemId = item.id;
197
+ requestInterrupt();
198
+ return;
199
+ }
200
+ if (notification.method === "item/completed" && compactionItemId === item.id) {
201
+ compactionItemCompleted = true;
202
+ return;
203
+ }
204
+ }
205
+ if (notification.method !== "turn/completed" || !compactionTurnId || notificationTurnId !== compactionTurnId) return;
206
+ const turn = isJsonObject(notification.params.turn) ? notification.params.turn : void 0;
207
+ const status = typeof turn?.status === "string" ? turn.status : void 0;
208
+ if (admissionFailure) {
209
+ fail(admissionFailure);
210
+ return;
211
+ }
212
+ if (status !== "completed") {
213
+ fail(`codex app-server compaction turn ended with status ${status ?? "unknown"}`);
214
+ return;
215
+ }
216
+ const incompleteReason = !compactionItemId ? "codex app-server compaction turn completed without a compaction item" : !compactionItemCompleted ? "codex app-server compaction turn completed before its compaction item" : void 0;
217
+ if (incompleteReason) {
218
+ fail(incompleteReason);
219
+ return;
220
+ }
221
+ complete();
222
+ });
223
+ removeCloseHandler = params.client.addCloseHandler(() => {
224
+ retireUnconfirmed("codex app-server closed before native compaction completed");
225
+ });
226
+ if (params.signal) {
227
+ const onAbort = () => {
228
+ abortRequested = true;
229
+ beginInterruptGrace();
230
+ };
231
+ params.signal.addEventListener("abort", onAbort, { once: true });
232
+ removeAbortHandler = () => params.signal?.removeEventListener("abort", onAbort);
233
+ if (params.signal.aborted) onAbort();
234
+ }
235
+ return {
236
+ completion,
237
+ beginRequest: () => {
238
+ requestStarted = true;
239
+ beginCompletionTimeout();
240
+ if (abortRequested) beginInterruptGrace();
241
+ },
242
+ confirmRequestRejected: () => fail("codex app-server rejected the compaction request"),
243
+ retireUnconfirmedRequest: async (reason) => {
244
+ retireUnconfirmed(reason);
245
+ return await completion;
246
+ },
247
+ cancel: () => {
248
+ if (!requestStarted) fail("compaction request did not start");
249
+ }
250
+ };
251
+ }
252
+ //#endregion
253
+ //#region extensions/codex/src/app-server/compact-result.ts
254
+ function codexNativeCompactionResult(params, outcome) {
255
+ return {
256
+ ok: true,
257
+ compacted: outcome.compacted,
258
+ ...outcome.reason ? { reason: outcome.reason } : {},
259
+ result: {
260
+ summary: "",
261
+ firstKeptEntryId: "",
262
+ tokensBefore: params.currentTokenCount ?? 0,
263
+ ...outcome.tokensAfter !== void 0 ? { tokensAfter: outcome.tokensAfter } : {},
264
+ details: outcome.details
265
+ }
266
+ };
267
+ }
268
+ function skippedCodexNativeCompactionResult(params, skipped) {
269
+ return codexNativeCompactionResult(params, {
270
+ compacted: false,
271
+ reason: skipped.reason,
272
+ details: {
273
+ backend: "codex-app-server",
274
+ skipped: true,
275
+ reason: skipped.code,
276
+ request: skipped.request ?? "after_context_engine",
277
+ trigger: params.trigger ?? "unknown",
278
+ ...skipped.expectedThreadId ? { expectedThreadId: skipped.expectedThreadId } : {},
279
+ ...skipped.currentThreadId ? { currentThreadId: skipped.currentThreadId } : {}
280
+ }
281
+ });
282
+ }
283
+ function failedCodexThreadBindingCompactionResult(params, recovery) {
284
+ embeddedAgentLog.warn("codex app-server compaction could not use thread binding", {
285
+ sessionId: params.sessionId,
286
+ sessionKey: params.sessionKey,
287
+ threadId: recovery.threadId,
288
+ reason: recovery.reason,
289
+ recovery: recovery.recovery
290
+ });
291
+ return {
292
+ ok: false,
293
+ compacted: false,
294
+ reason: recovery.reason,
295
+ failure: {
296
+ reason: recovery.recovery,
297
+ rawError: recovery.reason
298
+ }
299
+ };
300
+ }
301
+ //#endregion
302
+ //#region extensions/codex/src/app-server/compact.ts
303
+ const CODEX_NATIVE_COMPACTION_INTERRUPT_GRACE_MS = 3e4;
304
+ /**
305
+ * Starts native Codex compaction for a manually requested bound session, or
306
+ * reports why Codex-owned automatic compaction should handle the trigger.
307
+ */
308
+ async function maybeCompactCodexAppServerSession(params, options) {
309
+ params.hostCapabilities.assertActive();
310
+ warnIfIgnoringOpenClawCompactionOverrides(params);
311
+ if (params.trigger !== "manual" && !options.allowNonManualNativeRequest) {
312
+ embeddedAgentLog.info("skipping codex app-server compaction for non-manual trigger", {
313
+ sessionId: params.sessionId,
314
+ sessionKey: params.sessionKey,
315
+ trigger: params.trigger
316
+ });
317
+ return codexNativeCompactionResult(params, {
318
+ compacted: false,
319
+ reason: "codex app-server owns automatic compaction",
320
+ details: {
321
+ backend: "codex-app-server",
322
+ skipped: true,
323
+ reason: "non_manual_trigger",
324
+ trigger: params.trigger ?? "unknown"
325
+ }
326
+ });
327
+ }
328
+ const sandbox = params.sandbox;
329
+ const nativeExecutionBlock = resolveCodexNativeExecutionBlock({
330
+ config: params.config,
331
+ sessionKey: params.sandboxSessionKey ?? params.sessionKey,
332
+ sessionId: params.sessionId,
333
+ agentId: params.sandboxAgentId ?? params.agentId,
334
+ sandbox,
335
+ surface: "native compaction"
336
+ });
337
+ if (nativeExecutionBlock) return {
338
+ ok: false,
339
+ compacted: false,
340
+ reason: nativeExecutionBlock
341
+ };
342
+ const bindingIdentity = sessionBindingIdentity({
343
+ sessionId: params.sessionId,
344
+ sessionKey: params.sessionKey,
345
+ agentId: params.agentId,
346
+ config: params.config
347
+ });
348
+ const abortedResult = (attempt, expectedThreadId, currentThreadId = expectedThreadId) => options.allowNonManualNativeRequest ? skippedCodexNativeCompactionResult(attempt, {
349
+ reason: "codex app-server compaction aborted before native compaction",
350
+ code: "aborted_before_native_compaction",
351
+ request: options.nativeCompactionRequest ?? "after_context_engine",
352
+ ...expectedThreadId ? {
353
+ expectedThreadId,
354
+ currentThreadId
355
+ } : {}
356
+ }) : {
357
+ ok: false,
358
+ compacted: false,
359
+ reason: "codex app-server compaction aborted while waiting to start"
360
+ };
361
+ let resolvedBinding;
362
+ try {
363
+ resolvedBinding = await resolveCodexSessionBinding({
364
+ bindingStore: options.bindingStore,
365
+ identity: bindingIdentity,
366
+ config: params.config,
367
+ storePath: params.sessionTarget?.storePath,
368
+ signal: params.abortSignal
369
+ });
370
+ } catch (error) {
371
+ if (!params.abortSignal?.aborted) throw error;
372
+ return abortedResult(params, options.bindingStore.read(bindingIdentity)?.threadId);
373
+ }
374
+ const { binding: initialBinding, assertCurrent } = resolvedBinding;
375
+ if (!initialBinding?.threadId) return failedCodexThreadBindingCompactionResult(params, {
376
+ reason: "no codex app-server thread binding",
377
+ recovery: "missing_thread_binding"
378
+ });
379
+ if (initialBinding.modelProvider === "openclaw_token_sharing") return {
380
+ ok: false,
381
+ compacted: false,
382
+ reason: "Manual compaction is unavailable with ChatGPT subscription sharing. Automatic compaction runs during normal turns; continue the conversation or start a new session."
383
+ };
384
+ if (params.nativeToolSurface === "host-isolated" || initialBinding.nativeToolPolicyRestricted === true || initialBinding.ringZeroConfigFingerprint !== void 0) return codexNativeCompactionResult(params, {
385
+ compacted: false,
386
+ reason: "native compaction is unavailable for a host-isolated Codex session",
387
+ details: {
388
+ backend: "codex-app-server",
389
+ skipped: true,
390
+ reason: "native_tool_policy_restricted",
391
+ expectedThreadId: initialBinding.threadId
392
+ }
393
+ });
394
+ let binding = initialBinding;
395
+ const requestedAuthProfileId = params.authProfileId?.trim() || void 0;
396
+ let connection;
397
+ try {
398
+ const config = params.config ?? {};
399
+ connection = await resolveCodexBindingAppServerConnection({
400
+ binding,
401
+ authProfileId: requestedAuthProfileId ?? binding.authProfileId,
402
+ pluginConfig: options.pluginConfig,
403
+ config,
404
+ assertCurrent,
405
+ agentDir: resolveAgentDir(config, bindingIdentity.agentId)
406
+ });
407
+ } catch (error) {
408
+ return {
409
+ ok: false,
410
+ compacted: false,
411
+ reason: coerceErrorMessage(error)
412
+ };
413
+ }
414
+ const { appServer, usesSupervisionConnection } = connection;
415
+ if (!usesSupervisionConnection && requestedAuthProfileId && binding.authProfileId && binding.authProfileId !== requestedAuthProfileId) return {
416
+ ok: false,
417
+ compacted: false,
418
+ reason: "auth profile mismatch for session binding"
419
+ };
420
+ const shouldReleaseDefaultLease = !options.clientFactory;
421
+ const clientFactory = options.clientFactory ?? createIsolatedCodexAppServerClient;
422
+ const runtimeAuthPlan = usesSupervisionConnection ? void 0 : params.runtimeAuthPlan ?? params.runtimePlan?.auth;
423
+ const usesPreparedApiKey = appServer.start.homeScope !== "user" && runtimeAuthPlan?.modelRoute?.authRequirement === "api-key";
424
+ const preparedApiKey = usesPreparedApiKey ? params.resolvedApiKey?.trim() : void 0;
425
+ if (usesPreparedApiKey && !preparedApiKey) return {
426
+ ok: false,
427
+ compacted: false,
428
+ reason: "Prepared Codex Platform compaction route is missing its resolved API key."
429
+ };
430
+ return await runWithAsyncWorkResources(async (onAcquired) => {
431
+ const modelSource = params.hostCapabilities.retainSourceAuthority();
432
+ let modelSourceTransferred = false;
433
+ onAcquired({
434
+ release: () => {
435
+ if (!modelSourceTransferred) modelSource?.release();
436
+ },
437
+ releaseBeforeResultWhenIdle: true
438
+ });
439
+ const modelCancellation = new AbortController();
440
+ const signals = [
441
+ params.abortSignal,
442
+ modelSource?.signal,
443
+ modelCancellation.signal
444
+ ].filter((signal) => signal !== void 0);
445
+ const attempt = {
446
+ ...params,
447
+ abortSignal: AbortSignal.any(signals)
448
+ };
449
+ const assertAdmissionCurrent = () => {
450
+ attempt.hostCapabilities.assertActive();
451
+ assertCurrent();
452
+ };
453
+ try {
454
+ return await withCodexAppServerThreadMutationHold(binding.threadId, async (hold, start) => {
455
+ assertAdmissionCurrent();
456
+ const boundClientLease = await retainSharedCodexAppServerClientByInstanceId(binding.clientId);
457
+ if (attempt.abortSignal.aborted) {
458
+ await boundClientLease?.release();
459
+ attempt.abortSignal.throwIfAborted();
460
+ }
461
+ const client = boundClientLease?.client ?? await clientFactory({
462
+ startOptions: appServer.start,
463
+ ...preparedApiKey ? { preparedAuth: {
464
+ kind: "api-key",
465
+ apiKey: preparedApiKey
466
+ } } : { authProfileId: connection.clientAuthProfileId },
467
+ authRequirement: runtimeAuthPlan?.modelRoute?.authRequirement,
468
+ agentDir: attempt.agentDir,
469
+ config: attempt.config,
470
+ assertCurrent: assertAdmissionCurrent
471
+ });
472
+ start();
473
+ embeddedAgentLog.info("selected codex app-server compaction client", {
474
+ clientId: client.getInstanceId(),
475
+ recordedOwnerReused: Boolean(boundClientLease),
476
+ threadId: binding.threadId
477
+ });
478
+ let releaseThreadSubscription;
479
+ let retainedThreadOwnership;
480
+ let canRetainThreadOwnership = false;
481
+ let compactionSucceeded = false;
482
+ let temporaryClientExited = true;
483
+ let compactionRequestDefinitelyRejected = false;
484
+ let tokensAfter;
485
+ let modelOwner;
486
+ const releaseCompactionThread = async (threadId) => {
487
+ if (await unsubscribeCodexThreadBestEffort(client, {
488
+ threadId,
489
+ timeoutMs: 5e3
490
+ })) return;
491
+ await closeCodexStartupClientBestEffort(client);
492
+ throw new CodexAppServerUnsafeSubscriptionError(`Codex compaction thread subscription could not be released: ${threadId}`);
493
+ };
494
+ const completionWatch = watchCodexNativeCompactionCompletion({
495
+ client,
496
+ threadId: binding.threadId,
497
+ signal: attempt.abortSignal,
498
+ timeoutMs: options.nativeCompletionTimeoutMs ?? resolveCompactionTimeoutMs(attempt.config),
499
+ interruptGraceMs: options.nativeInterruptGraceMs ?? CODEX_NATIVE_COMPACTION_INTERRUPT_GRACE_MS,
500
+ onCompactionTurn: (turnId) => {
501
+ assertAdmissionCurrent();
502
+ const runtimeModel = attempt.runtimeModel;
503
+ const mapping = !usesSupervisionConnection && attempt.provider && attempt.model && runtimeModel?.provider === attempt.provider && runtimeModel.id === attempt.model ? {
504
+ nativeModel: {
505
+ provider: attempt.provider,
506
+ model: readCodexRuntimeModelId(runtimeModel, attempt.model)
507
+ },
508
+ authorizedModel: {
509
+ provider: attempt.provider,
510
+ model: attempt.model
511
+ }
512
+ } : void 0;
513
+ modelOwner?.bindTurn(turnId, mapping);
514
+ },
515
+ retireUnconfirmed: async () => {
516
+ releaseThreadSubscription = void 0;
517
+ const transportStopped = await client.closeAndWait({
518
+ exitTimeoutMs: 5e3,
519
+ forceKillDelayMs: 250
520
+ });
521
+ temporaryClientExited = transportStopped.exited;
522
+ if (appServer.start.transport === "stdio") {
523
+ if (transportStopped.exited) return;
524
+ throw new Error("failed to stop unconfirmed codex app-server process");
525
+ }
526
+ if (usesSupervisionConnection) throw new Error("cannot detach an unconfirmed supervised codex thread");
527
+ if (await options.bindingStore.mutate(bindingIdentity, {
528
+ kind: "clear",
529
+ threadId: binding.threadId
530
+ }, assertCurrent)) return;
531
+ if (options.bindingStore.read(bindingIdentity)?.threadId !== binding.threadId) return;
532
+ throw new Error("failed to detach unconfirmed codex app-server thread binding");
533
+ }
534
+ });
535
+ const acquireThreadSubscription = async (timeoutMs) => {
536
+ if (!isIncognitoSessionKey(attempt.sessionKey)) {
537
+ retainedThreadOwnership = await consumeCodexAppServerLiveThread(client, binding.threadId);
538
+ if (!retainedThreadOwnership) {
539
+ const resumed = await resumeCodexAppServerThread({
540
+ client,
541
+ abandonClient: async () => closeCodexStartupClientBestEffort(client),
542
+ request: {
543
+ threadId: binding.threadId,
544
+ excludeTurns: true
545
+ },
546
+ timeoutMs: timeoutMs ?? appServer.requestTimeoutMs,
547
+ assertCurrent,
548
+ signal: attempt.abortSignal
549
+ });
550
+ releaseThreadSubscription = async () => releaseCompactionThread(binding.threadId);
551
+ assertCodexSupervisionThreadLineage(binding, resumed.thread);
552
+ } else if (binding.connectionScope === "supervision") {
553
+ releaseThreadSubscription = async () => retainedThreadOwnership?.release(binding.threadId);
554
+ const { thread } = await client.request("thread/read", {
555
+ threadId: binding.threadId,
556
+ includeTurns: false
557
+ }, { assertCurrent });
558
+ assertCurrent();
559
+ retainedThreadOwnership.assertCurrent();
560
+ assertCodexSupervisionThreadLineage(binding, thread);
561
+ }
562
+ releaseThreadSubscription ??= async () => releaseCompactionThread(binding.threadId);
563
+ }
564
+ };
565
+ try {
566
+ const guardedResult = await options.bindingStore.withLease(bindingIdentity, async () => {
567
+ const currentBinding = options.bindingStore.read(bindingIdentity);
568
+ if (attempt.abortSignal.aborted) {
569
+ if (!options.allowNonManualNativeRequest) attempt.abortSignal.throwIfAborted();
570
+ return {
571
+ started: false,
572
+ result: skippedCodexNativeCompactionResult(attempt, {
573
+ reason: "codex app-server compaction aborted before native compaction",
574
+ code: "aborted_before_native_compaction",
575
+ request: options.nativeCompactionRequest ?? "after_context_engine",
576
+ expectedThreadId: binding.threadId,
577
+ currentThreadId: currentBinding?.threadId
578
+ })
579
+ };
580
+ }
581
+ assertCurrent();
582
+ if (!currentBinding || !isSameNativeCompactionBinding(currentBinding, binding)) {
583
+ embeddedAgentLog.warn("codex app-server compaction could not use the thread binding because it changed", {
584
+ sessionId: attempt.sessionId,
585
+ sessionKey: attempt.sessionKey,
586
+ expectedThreadId: binding.threadId,
587
+ currentThreadId: currentBinding?.threadId
588
+ });
589
+ const isRequiredPreflight = options.nativeCompactionRequest === "required_preflight";
590
+ return {
591
+ started: false,
592
+ result: options.allowNonManualNativeRequest && !isRequiredPreflight ? skippedCodexNativeCompactionResult(attempt, {
593
+ reason: "codex app-server binding changed before native compaction",
594
+ code: "binding_changed_before_native_compaction",
595
+ request: options.nativeCompactionRequest ?? "after_context_engine",
596
+ expectedThreadId: binding.threadId,
597
+ currentThreadId: currentBinding?.threadId
598
+ }) : failedCodexThreadBindingCompactionResult(attempt, {
599
+ threadId: currentBinding?.threadId ?? binding.threadId,
600
+ reason: "codex app-server binding changed before native compaction",
601
+ recovery: "stale_thread_binding"
602
+ })
603
+ };
604
+ }
605
+ binding = currentBinding;
606
+ const guardedRequestTimeoutMs = options.allowNonManualNativeRequest ? Math.min(appServer.requestTimeoutMs, CODEX_APP_SERVER_BINDING_GUARDED_REQUEST_TIMEOUT_MS) : void 0;
607
+ assertAdmissionCurrent();
608
+ await acquireThreadSubscription(guardedRequestTimeoutMs);
609
+ canRetainThreadOwnership = true;
610
+ attempt.abortSignal.throwIfAborted();
611
+ const configurationQualification = getCodexInferenceThreadQualification(client, binding.threadId);
612
+ modelOwner = await codexNativeSubagentMonitorRuntime.register({
613
+ client,
614
+ parentThreadId: binding.threadId,
615
+ modelSource,
616
+ configurationQualification,
617
+ unqualifiedModelExecution: modelSource && !configurationQualification ? true : void 0,
618
+ onUnqualifiedModelCancelled: (reason) => modelCancellation.abort(reason),
619
+ requesterSessionKey: attempt.sessionKey,
620
+ agentId: bindingIdentity.agentId,
621
+ assertCurrent: assertAdmissionCurrent,
622
+ retainClient: () => retainSharedCodexAppServerClientIfCurrent(client),
623
+ retainParentThread: (threadId) => protectCodexAppServerLiveThread(client, threadId)
624
+ });
625
+ modelSourceTransferred = true;
626
+ assertAdmissionCurrent();
627
+ attempt.abortSignal.throwIfAborted();
628
+ await clearContextEngineProjectionBeforeNativeCompaction({
629
+ sessionId: attempt.sessionId,
630
+ bindingStore: options.bindingStore,
631
+ identity: bindingIdentity,
632
+ binding,
633
+ assertCurrent: assertAdmissionCurrent
634
+ });
635
+ assertAdmissionCurrent();
636
+ try {
637
+ canRetainThreadOwnership = false;
638
+ completionWatch.beginRequest();
639
+ await client.request("thread/compact/start", { threadId: binding.threadId }, {
640
+ ...guardedRequestTimeoutMs === void 0 ? {} : { timeoutMs: guardedRequestTimeoutMs },
641
+ signal: attempt.abortSignal,
642
+ assertCurrent: () => {
643
+ try {
644
+ assertAdmissionCurrent();
645
+ } catch (error) {
646
+ compactionRequestDefinitelyRejected = true;
647
+ throw error;
648
+ }
649
+ }
650
+ });
651
+ return {
652
+ started: true,
653
+ accepted: true
654
+ };
655
+ } catch (error) {
656
+ compactionRequestDefinitelyRejected ||= isCodexAppServerPrewriteRequestCancellationError(error) || error instanceof CodexAppServerRpcError;
657
+ if (compactionRequestDefinitelyRejected) {
658
+ canRetainThreadOwnership = !isCodexThreadNotFoundError(error);
659
+ completionWatch.confirmRequestRejected();
660
+ if (error instanceof CodexAppServerRpcError || binding.contextEngine?.projection) await options.bindingStore.mutate(bindingIdentity, {
661
+ kind: "set",
662
+ binding
663
+ }, assertCurrent);
664
+ }
665
+ return {
666
+ started: true,
667
+ accepted: false,
668
+ error
669
+ };
670
+ }
671
+ });
672
+ if (!guardedResult.started) return guardedResult.result;
673
+ if (!guardedResult.accepted) {
674
+ if (compactionRequestDefinitelyRejected) throw guardedResult.error;
675
+ if (!attempt.abortSignal.aborted || !isCodexAppServerIndeterminateRequestCancellationError(guardedResult.error)) {
676
+ await completionWatch.retireUnconfirmedRequest(`codex app-server compaction start was unconfirmed: ${coerceErrorMessage(guardedResult.error)}`);
677
+ throw guardedResult.error;
678
+ }
679
+ }
680
+ embeddedAgentLog.info("waiting for codex app-server compaction completion", {
681
+ sessionId: attempt.sessionId,
682
+ threadId: binding.threadId
683
+ });
684
+ const completion = await completionWatch.completion;
685
+ assertCurrent();
686
+ if (!completion.completed) throw new Error(completion.reason);
687
+ compactionSucceeded = true;
688
+ tokensAfter = completion.tokensAfter;
689
+ if (completion.turnId && completion.itemId) await persistCodexContextCompactionActivity({
690
+ sessionTarget: attempt.sessionTarget,
691
+ config: attempt.config,
692
+ cwd: attempt.workspaceDir,
693
+ runId: attempt.runId,
694
+ threadId: binding.threadId,
695
+ turnId: completion.turnId,
696
+ itemId: completion.itemId,
697
+ timestamp: Date.now()
698
+ });
699
+ assertCurrent();
700
+ embeddedAgentLog.info("completed codex app-server compaction", {
701
+ sessionId: attempt.sessionId,
702
+ threadId: binding.threadId
703
+ });
704
+ canRetainThreadOwnership = true;
705
+ } catch (error) {
706
+ if (isCodexThreadNotFoundError(error)) return failedCodexThreadBindingCompactionResult(attempt, {
707
+ threadId: binding.threadId,
708
+ reason: coerceErrorMessage(error),
709
+ recovery: "stale_thread_binding"
710
+ });
711
+ embeddedAgentLog.warn("codex app-server compaction failed", {
712
+ sessionId: attempt.sessionId,
713
+ sessionKey: attempt.sessionKey,
714
+ threadId: binding.threadId,
715
+ reason: coerceErrorMessage(error)
716
+ });
717
+ return {
718
+ ok: false,
719
+ compacted: false,
720
+ reason: coerceErrorMessage(error)
721
+ };
722
+ } finally {
723
+ completionWatch.cancel();
724
+ try {
725
+ if (compactionSucceeded) revertCodexAppServerLiveThreadSkillsCatalog(client, binding.threadId);
726
+ if (canRetainThreadOwnership && retainedThreadOwnership) {
727
+ const ownership = retainedThreadOwnership;
728
+ const currentBinding = options.bindingStore.read(bindingIdentity);
729
+ if (!(isSameCodexAppServerThreadOwner(currentBinding, binding) && await options.bindingStore.withLease(bindingIdentity, async () => {
730
+ const leasedBinding = options.bindingStore.read(bindingIdentity);
731
+ if (!isSameCodexAppServerThreadOwner(leasedBinding, binding)) return false;
732
+ return await retainCodexAppServerLiveThread(client, binding.threadId, ownership.release, ownership.configFingerprint, ownership.serviceTier, ownership.ephemeralPolicy && compactionSucceeded ? {
733
+ ...ownership.ephemeralPolicy,
734
+ skillsInstructions: ownership.ephemeralPolicy.nativeSkillsInstructions
735
+ } : ownership.ephemeralPolicy);
736
+ }))) await releaseThreadSubscription?.();
737
+ } else await releaseThreadSubscription?.();
738
+ } finally {
739
+ try {
740
+ await modelOwner?.unregister();
741
+ } finally {
742
+ const ownerExit = boundClientLease?.release();
743
+ if (ownerExit && appServer.start.transport === "stdio") hold(ownerExit);
744
+ else if (!boundClientLease && shouldReleaseDefaultLease) {
745
+ if (appServer.start.transport === "stdio") hold(waitForCodexAppServerClientExit(client));
746
+ temporaryClientExited = temporaryClientExited && (await client.closeAndWait()).exited;
747
+ }
748
+ }
749
+ }
750
+ }
751
+ if (!temporaryClientExited) throw new CodexAppServerUnsafeSubscriptionError(`Codex compaction client did not exit: ${binding.threadId}`);
752
+ const details = {
753
+ backend: "codex-app-server",
754
+ threadId: binding.threadId,
755
+ signal: "thread/compact/start",
756
+ pending: false,
757
+ completed: true,
758
+ ...options.allowNonManualNativeRequest ? {
759
+ request: options.nativeCompactionRequest ?? "after_context_engine",
760
+ trigger: attempt.trigger ?? "unknown"
761
+ } : {}
762
+ };
763
+ return codexNativeCompactionResult(attempt, {
764
+ compacted: true,
765
+ tokensAfter,
766
+ details
767
+ });
768
+ }, attempt.abortSignal);
769
+ } catch (error) {
770
+ if (attempt.abortSignal.aborted) return abortedResult(attempt, initialBinding.threadId, binding.threadId);
771
+ throw error;
772
+ }
773
+ });
774
+ }
775
+ //#endregion
776
+ export { maybeCompactCodexAppServerSession };