@openclaw/codex 2026.9.6 → 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 (158) hide show
  1. package/README.md +2 -0
  2. package/assets/icon.png +0 -0
  3. package/dist/.setup/{account-usage-runtime-Eem_WGqY.mjs → account-usage-runtime-DFhbh1zz.mjs} +5 -5
  4. package/dist/.setup/{apply-DDOi8uNx.mjs → apply-D3GcSoSa.mjs} +22 -36
  5. package/dist/.setup/{attempt-client-cleanup-CEv1cKwF.mjs → attempt-client-cleanup-DOP-cW5j.mjs} +128 -37
  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-B2mpaI9D.mjs → auth-cache-key-Dbvq-QgB.mjs} +36 -34
  9. package/dist/.setup/{auth-profile-WqZtZfXN.mjs → auth-profile-B0okYl2D.mjs} +1 -2
  10. package/dist/.setup/auth-start-options-BPIPeEX8.mjs +44 -0
  11. package/dist/.setup/{binding-connection-ThoatDcb.mjs → binding-connection-DTtN1KrX.mjs} +2 -2
  12. package/dist/.setup/{binding-connection.runtime-yoHrABt-.mjs → binding-connection.runtime-6TpgD1M6.mjs} +4 -4
  13. package/dist/.setup/{bounded-turn-B2HScEgT.mjs → bounded-turn-CbjoN2OW.mjs} +15 -18
  14. package/dist/.setup/bounded-turn-isolation-B8K_ylqk.mjs +14 -0
  15. package/dist/.setup/{build-state-C7EnDVgr.mjs → build-state-Da1_z0kd.mjs} +1 -1
  16. package/dist/.setup/{capabilities-CDXOOFdZ.mjs → capabilities-B3WEZl4e.mjs} +2 -10
  17. package/dist/.setup/{client-Cs08OXVQ.mjs → client-N0JpgSzF.mjs} +138 -399
  18. package/dist/.setup/{client-catalog-response-BMgt_4q4.mjs → client-catalog-response-5HHLdcde.mjs} +1 -1
  19. package/dist/.setup/{command-dispatch-B4JuOsOk.mjs → command-dispatch-BeAoaovI.mjs} +5 -8
  20. package/dist/.setup/{command-formatters-Bmqvr9tO.mjs → command-formatters-R3ckE3Co.mjs} +29 -61
  21. package/dist/.setup/{command-handlers-DW7Lx9oH.mjs → command-handlers-ylTMS00z.mjs} +222 -343
  22. package/dist/.setup/{command-rpc-DixIj3HW.mjs → command-rpc-CGJGUQ6Y.mjs} +15 -18
  23. package/dist/.setup/compact-C2WamavS.mjs +776 -0
  24. package/dist/.setup/{config-BoTP_mrL.mjs → config-DKhXquav.mjs} +26 -28
  25. package/dist/.setup/{config-options-BvaRs51b.mjs → config-options-CzyWLTJt.mjs} +24 -37
  26. package/dist/.setup/{config-parsing-CcB9iPoq.mjs → config-parsing-b088LyhT.mjs} +57 -60
  27. package/dist/.setup/{config-runtime-C8Rw1m1m.mjs → config-runtime-C0NbLms1.mjs} +2 -2
  28. package/dist/.setup/{config-security-BEReZ6go.mjs → config-security-CE-FcGw9.mjs} +32 -111
  29. package/dist/.setup/{config-utils-DujwEnhg.mjs → config-utils-D0CXecki.mjs} +3 -13
  30. package/dist/.setup/context-engine-projection-PezSESth.mjs +387 -0
  31. package/dist/.setup/{conversation-binding-DP-gMrBP.mjs → conversation-binding-3Min8qvP.mjs} +67 -90
  32. package/dist/.setup/{conversation-binding-data-CrcyZk6O.mjs → conversation-binding-data-C746z5Pn.mjs} +8 -12
  33. package/dist/.setup/{conversation-control-uK9Jomlc.mjs → conversation-control-CEP8X5JC.mjs} +8 -8
  34. package/dist/.setup/{cyber-failover-DYwbmf1o.mjs → cyber-failover-XV0nNRZu.mjs} +1 -1
  35. package/dist/.setup/{cyber-failover-notice-e9G3J9-e.mjs → cyber-failover-notice-RNpGpTyP.mjs} +1 -1
  36. package/dist/.setup/{dynamic-tools-BDXl-8Cw.mjs → dynamic-tools-DzlsLUuS.mjs} +2305 -2606
  37. package/dist/.setup/{effective-mcp-catalog-CvnvnGIe.mjs → effective-mcp-catalog-CxUtC-xG.mjs} +8 -17
  38. package/dist/.setup/{ephemeral-turn-poidXgek.mjs → ephemeral-turn-CDsPJOa2.mjs} +3 -3
  39. package/dist/.setup/event-projector-assistant-message-CigreO4K.mjs +69 -0
  40. package/dist/.setup/{event-projector-usage-CnBS8Wa3.mjs → event-projector-usage-03R0I2dM.mjs} +3 -25
  41. package/dist/.setup/event-projector-values-DJSz8BTk.mjs +106 -0
  42. package/dist/.setup/incognito-session-DWYapfwf.mjs +2 -0
  43. package/dist/.setup/{inference-context-D96l9-ew.mjs → inference-context-D-9gWlTR.mjs} +16 -18
  44. package/dist/.setup/inference-dispatch-CMZtjQyz.mjs +359 -0
  45. package/dist/.setup/inference-metadata-CgIf7sOx.mjs +81 -0
  46. package/dist/.setup/{inference-proxy-b-aJMSxm.mjs → inference-proxy-DhcXOgUE.mjs} +174 -214
  47. package/dist/.setup/{isolated-completion-BIZFhTNG.mjs → isolated-completion-Dm3PzxJk.mjs} +9 -12
  48. package/dist/.setup/{managed-binary-BnshlFag.mjs → managed-binary-kiWRhNRE.mjs} +8 -12
  49. package/dist/.setup/{model-catalog-CfXJf9Ay.mjs → model-catalog-PAuZgJC6.mjs} +11 -10
  50. package/dist/.setup/model-runtime-BdqzOMkU.mjs +11 -0
  51. package/dist/.setup/{models-KnqBv0hE.mjs → models-DHXZtVVk.mjs} +9 -18
  52. package/dist/.setup/{native-auth-rWbGbMn3.mjs → native-auth-CuG53tu4.mjs} +4 -4
  53. package/dist/.setup/{native-execution-policy-umd0tgh4.mjs → native-execution-policy-BxZJy5mP.mjs} +5 -30
  54. package/dist/.setup/{native-subagent-monitor-D3filLY2.mjs → native-subagent-monitor-Dpsmf2wz.mjs} +4395 -3609
  55. package/dist/.setup/native-subagent-pending-assignments-DwkCzLvD.mjs +203 -0
  56. package/dist/.setup/native-task-assignments-DMQ0g3hu.mjs +194 -0
  57. package/dist/.setup/{node-cli-sessions-r3avj02l.mjs → node-cli-sessions-HC4W6FLI.mjs} +19 -49
  58. package/dist/.setup/{node-exec-server.runtime-BDwWXVpK.mjs → node-exec-server.runtime-BgBfWQqo.mjs} +3 -6
  59. package/dist/.setup/{plan-CN3VwfNU.mjs → plan-Y-QIvrKB.mjs} +49 -92
  60. package/dist/.setup/{plugin-activation-DT3MNtqj.mjs → plugin-activation-cNHRfaxU.mjs} +8 -36
  61. package/dist/.setup/{plugin-app-cache-key-B2CsSdnV.mjs → plugin-app-cache-key-BL9B5H0L.mjs} +6 -23
  62. package/dist/.setup/{plugin-inventory-BoRei8Z4.mjs → plugin-inventory-Cky2XJUw.mjs} +21 -21
  63. package/dist/.setup/{plugin-marketplace-discovery-CDOi8IFs.mjs → plugin-marketplace-discovery-D_dV9FXa.mjs} +18 -24
  64. package/dist/.setup/{plugin-metadata-cache-Ctmo83k_.mjs → plugin-metadata-cache-DsjsL1dr.mjs} +115 -175
  65. package/dist/.setup/{provider-BOsxQHOM.mjs → provider-DH8NSzGt.mjs} +11 -14
  66. package/dist/.setup/{provider-capabilities-BfE88FZ5.mjs → provider-capabilities-CAxoF-X1.mjs} +13 -18
  67. package/dist/.setup/{rate-limits-CMU3DUD0.mjs → rate-limits-B7-X2TgG.mjs} +9 -31
  68. package/dist/.setup/{request-D2L0zMrq.mjs → request-BHZ1nz8d.mjs} +7 -6
  69. package/dist/.setup/responses-oauth-twnuTaAa.mjs +93 -0
  70. package/dist/.setup/rpc-error-BlD2vuzn.mjs +31 -0
  71. package/dist/.setup/{run-attempt-BHu11r7h.mjs → run-attempt-D8RZUOzY.mjs} +1035 -1023
  72. package/dist/.setup/{run-attempt-lifecycle-B7JbY4-F.mjs → run-attempt-lifecycle-C-6O3Exn.mjs} +10 -24
  73. package/dist/.setup/{runtime-artifact-CLZ8udh-.mjs → runtime-artifact-DDQ-HGXf.mjs} +16 -4
  74. package/dist/.setup/runtime-artifact-connection-D68qQn1m.mjs +78 -0
  75. package/dist/.setup/sandbox-guard-DjCz2eOw.mjs +126 -0
  76. package/dist/.setup/scope-DOC1Xjc8.mjs +6 -0
  77. package/dist/.setup/session-binding-DGCYAfvD.mjs +443 -0
  78. package/dist/.setup/{session-binding-record-BGoz8wOK.mjs → session-binding-record-Oe9L-CNY.mjs} +52 -130
  79. package/dist/.setup/{session-binding-sidecars-BlB5EvIS.mjs → session-binding-sidecars-jo6H8dFr.mjs} +196 -17
  80. package/dist/.setup/{session-catalog-Pno1xGcl.mjs → session-catalog-4sCdv5qx.mjs} +170 -324
  81. package/dist/.setup/{session-catalog-adoption-BI6UTDZT.mjs → session-catalog-adoption-BU_pHWG7.mjs} +7 -6
  82. package/dist/.setup/{session-catalog-archive-lHBqzhaO.mjs → session-catalog-archive-spHfihri.mjs} +6 -6
  83. package/dist/.setup/session-catalog-events-DePDzzjc.mjs +139 -0
  84. package/dist/.setup/session-catalog-home-id-vlih0B_g.mjs +22 -0
  85. package/dist/.setup/{session-catalog-index-B9_VQIUz.mjs → session-catalog-index-CZvDzC6z.mjs} +126 -122
  86. package/dist/.setup/{session-catalog-index-order-hcdz07yN.mjs → session-catalog-index-order-BcQpHks3.mjs} +1 -1
  87. package/dist/.setup/{session-catalog-index-state-Dgh8ORJm.mjs → session-catalog-index-state-TeO7EyO-.mjs} +3 -2
  88. package/dist/.setup/session-catalog-limits-DDxOsQeC.mjs +14 -0
  89. package/dist/.setup/session-catalog-list-request-CvtxrYSe.mjs +170 -0
  90. package/dist/.setup/session-catalog-native-projection-DjhwGL6x.mjs +178 -0
  91. package/dist/.setup/{session-catalog-node-adoption-ITddWx_X.mjs → session-catalog-node-adoption-DgXvSGu0.mjs} +10 -27
  92. package/dist/.setup/{session-catalog-node-continue-6g6qi4A9.mjs → session-catalog-node-continue-DjKXHBbi.mjs} +8 -10
  93. package/dist/.setup/session-catalog-node-lookup-CtAXI5W5.mjs +56 -0
  94. package/dist/.setup/{session-catalog-native-projection-DowriLid.mjs → session-catalog-parsing-CPGaPYr-.mjs} +11 -194
  95. package/dist/.setup/{session-catalog-projection-zK_PUsiE.mjs → session-catalog-projection-Cr5qP5Dj.mjs} +6 -4
  96. package/dist/.setup/session-catalog-provenance-DoAvktcj.mjs +95 -0
  97. package/dist/.setup/{session-cli-irrD-uo7.mjs → session-cli-Cn_nCqfq.mjs} +9 -22
  98. package/dist/.setup/{session-history-BrqhSCf9.mjs → session-history-D83lJWHG.mjs} +4 -6
  99. package/dist/.setup/{session-history-import-D-3wAgOP.mjs → session-history-import-WhX-X33a.mjs} +7 -10
  100. package/dist/.setup/session-history-read-Ov3StuL4.mjs +133 -0
  101. package/dist/.setup/{session-history.worker-CaCh0xF_.mjs → session-history.worker-MnPKncqP.mjs} +9 -5
  102. package/dist/.setup/session-initialization-6aveB9qb.mjs +22 -0
  103. package/dist/.setup/{session-permission-policy-BI1QK_98.mjs → session-permission-policy-Ci_fVX6y.mjs} +4 -8
  104. package/dist/.setup/{session-retirement-BH-S6qkJ.mjs → session-retirement-qMTxkNx2.mjs} +17 -17
  105. package/dist/.setup/{settled-turn-context-fmwouT5I.mjs → settled-turn-context-D4yj4rxf.mjs} +1 -1
  106. package/dist/.setup/{settled-turn-finalizer-DiAi6Kx6.mjs → settled-turn-finalizer-BsvEabkw.mjs} +14 -10
  107. package/dist/.setup/{shared-client-DA4VR4Eb.mjs → shared-client-DqyTMYug.mjs} +783 -412
  108. package/dist/.setup/shared-client-lifecycle-DJIgqgMw.mjs +153 -0
  109. package/dist/.setup/{side-question-BJ1wSDcB.mjs → side-question-C4kCmQy1.mjs} +79 -143
  110. package/dist/.setup/{source-CUzJq5WN.mjs → source-CS_7GFJZ.mjs} +80 -137
  111. package/dist/.setup/{thread-lifecycle-B3mfz1TG.mjs → thread-lifecycle-DPflntEJ.mjs} +294 -737
  112. package/dist/.setup/{incognito-session-uhrBF6wJ.mjs → thread-ownership-queue-Dp24d7-F.mjs} +1 -2
  113. package/dist/.setup/{thread-ownership-DcTtAcXj.mjs → thread-ownership-roNP0l1c.mjs} +45 -10
  114. package/dist/.setup/{thread-policy-DGuQsuFC.mjs → thread-policy-DTd-DtkX.mjs} +46 -7
  115. package/dist/.setup/{thread-requests-BLvGkP2R.mjs → thread-requests-B_bRnMGN.mjs} +199 -302
  116. package/dist/.setup/{thread-resume-DIBXwOpE.mjs → thread-resume-CdDaoc7T.mjs} +6 -6
  117. package/dist/.setup/{timeout-C910MdAB.mjs → timeout-CXOfNoaX.mjs} +1 -35
  118. package/dist/.setup/{transcript-history-projection-ZZpkFkJ_.mjs → transcript-history-projection-DRSifI-1.mjs} +17 -89
  119. package/dist/.setup/{transcript-mirror-attestation-CzM-94NC.mjs → transcript-mirror-attestation-YSegaktH.mjs} +3 -4
  120. package/dist/.setup/{transcript-mirror-BtHDBp1G.mjs → transcript-mirror-kxmCYsuF.mjs} +7 -9
  121. package/dist/.setup/{transport-stdio-h2VHOskC.mjs → transport-stdio-Bdegpn2V.mjs} +5 -22
  122. package/dist/.setup/transport-websocket-BTBE-LD9.mjs +211 -0
  123. package/dist/.setup/{upstream-prompt-provenance-LphB8slG.mjs → upstream-prompt-provenance-fXkKbPVC.mjs} +3 -9
  124. package/dist/.setup/{upstream-session-fork-BUr4OUbC.mjs → upstream-session-fork-CBeVjBpT.mjs} +23 -23
  125. package/dist/.setup/{usage-BML0r-ua.mjs → usage-BMzNxeR_.mjs} +4 -4
  126. package/dist/.setup/{usage-limit-error-DUMbefVY.mjs → usage-limit-error-QXerDo3i.mjs} +4 -19
  127. package/dist/.setup/{web-search-provider.runtime-CDKlN-Rv.mjs → web-search-provider.runtime-P77OUeoo.mjs} +8 -19
  128. package/dist/api.js +9 -11
  129. package/dist/catalog-page.worker.js +1 -1
  130. package/dist/cli-metadata.js +1 -1
  131. package/dist/doctor-contract-api.js +50 -8
  132. package/dist/harness.js +344 -1
  133. package/dist/index.js +193 -245
  134. package/dist/media-understanding-provider.js +9 -22
  135. package/dist/migration-provider-api.js +1 -1
  136. package/dist/provider-discovery.js +1 -1
  137. package/dist/session-history-worker-runtime.js +3 -3
  138. package/dist/session-history.worker.js +1 -1
  139. package/openclaw.plugin.json +14 -2
  140. package/package.json +7 -6
  141. package/dist/.setup/attempt-workspace-context-DUVEn_CS.mjs +0 -331
  142. package/dist/.setup/compact-Du5UvtxA.mjs +0 -680
  143. package/dist/.setup/event-projector-assistant-message-BsruvNrH.mjs +0 -103
  144. package/dist/.setup/event-projector-items-C6L_5ZiT.mjs +0 -234
  145. package/dist/.setup/harness-a_MsE4-_.mjs +0 -355
  146. package/dist/.setup/history-rejection-B4nOXNXF.mjs +0 -13
  147. package/dist/.setup/image-payload-sanitizer-tupAr-2o.mjs +0 -79
  148. package/dist/.setup/local-runtime-attribution-B_2mnqhb.mjs +0 -19
  149. package/dist/.setup/native-subagent-history-0nYYgo0k.mjs +0 -148
  150. package/dist/.setup/native-subagent-task-ids-wb8CKZGN.mjs +0 -441
  151. package/dist/.setup/plugin-approval-roundtrip-C0MZzCuP.mjs +0 -122
  152. package/dist/.setup/rolldown-runtime-8H4AJuhK.mjs +0 -14
  153. package/dist/.setup/sandbox-guard-C2sRMOEY.mjs +0 -166
  154. package/dist/.setup/session-binding-Cm0apEbd.mjs +0 -692
  155. package/dist/.setup/session-catalog-events-Bj6j94E_.mjs +0 -347
  156. package/dist/.setup/session-history-read-B3ZfSUbF.mjs +0 -50
  157. package/dist/.setup/session-initialization-rcgbZiid.mjs +0 -75
  158. package/dist/.setup/thread-history-page-DoVpnHim.mjs +0 -83
@@ -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 };