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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (156) hide show
  1. package/README.md +10 -3
  2. package/dist/.setup/{account-usage-runtime-CoVpNIlD.mjs → account-usage-runtime-BVO-lpvn.mjs} +15 -9
  3. package/dist/.setup/{app-server-policy-D_zv8J7V.mjs → app-server-policy-Cog6mm2i.mjs} +1 -1
  4. package/dist/.setup/{apply-BXDMd05l.mjs → apply-tJl5mopa.mjs} +11 -11
  5. package/dist/.setup/{attempt-client-cleanup-zNuNTKVr.mjs → attempt-client-cleanup-DMJWXGxM.mjs} +14 -8
  6. package/dist/.setup/attempt-terminal-sZutF0WY.mjs +1 -0
  7. package/dist/.setup/{attempt-workspace-context-CcwP3DA3.mjs → attempt-workspace-context-GYPLawX6.mjs} +2 -2
  8. package/dist/.setup/{auth-binding-BaxlhaNx.mjs → auth-binding-830RLAJW.mjs} +2 -2
  9. package/dist/.setup/{auth-cache-key-f8ODJ_OX.mjs → auth-cache-key-BW1YeaIk.mjs} +92 -80
  10. package/dist/.setup/{auth-profile-CgHQ8Vot.mjs → auth-profile-auwzSwwy.mjs} +14 -8
  11. package/dist/.setup/{auth-profile-health-oHizqgye.mjs → auth-profile-health-BVPZU9I8.mjs} +15 -8
  12. package/dist/.setup/{auth-profile-selection-hr8ocLtz.mjs → auth-profile-selection-Bp5PDk3W.mjs} +24 -7
  13. package/dist/.setup/{binding-connection-B7HAAZSI.mjs → binding-connection-GTgUj9pi.mjs} +2 -2
  14. package/dist/.setup/{binding-connection.runtime-DAXn7iFl.mjs → binding-connection.runtime-RcWR3vQu.mjs} +4 -3
  15. package/dist/.setup/{bounded-turn-DfIJtRlv.mjs → bounded-turn-BQkmyyjB.mjs} +18 -22
  16. package/dist/.setup/{bounded-turn-isolation-BfDAo-qZ.mjs → bounded-turn-isolation-D8CDrAVX.mjs} +3 -3
  17. package/dist/.setup/{build-state-Ds14X10-.mjs → build-state-CjLCC0wm.mjs} +1 -1
  18. package/dist/.setup/{capabilities-DbOzOglY.mjs → capabilities-DAS-JX1z.mjs} +1 -1
  19. package/dist/.setup/{client-D93nbdB8.mjs → client--P8jwXvA.mjs} +47 -317
  20. package/dist/.setup/{client-catalog-response-CuVLp4I0.mjs → client-catalog-response-CsDxVVOZ.mjs} +2 -2
  21. package/dist/.setup/client-initialize-CjgZcX61.mjs +165 -0
  22. package/dist/.setup/{command-dispatch-DxdH5a9-.mjs → command-dispatch-DqaVBeR3.mjs} +3 -3
  23. package/dist/.setup/{command-formatters-xW9KpoSZ.mjs → command-formatters-B_7-QZ1c.mjs} +2 -2
  24. package/dist/.setup/{command-handlers-fiYvYYq0.mjs → command-handlers-i6mEjvfo.mjs} +539 -406
  25. package/dist/.setup/command-rpc-B65jEc0r.mjs +296 -0
  26. package/dist/.setup/compact-AO2H4RJe.mjs +823 -0
  27. package/dist/.setup/{computer-use-DL2v3Kxq.mjs → computer-use-YUnu0JVx.mjs} +21 -68
  28. package/dist/.setup/{config-C1YVVLEA.mjs → config-BfrAlTMT.mjs} +3 -3
  29. package/dist/.setup/{config-options-DDzeNQ8m.mjs → config-options-DMFZkd3X.mjs} +1 -1
  30. package/dist/.setup/{config-runtime-DWzK-k0n.mjs → config-runtime-BZRizyuG.mjs} +2 -2
  31. package/dist/.setup/{context-engine-projection-ps-yn_ci.mjs → context-engine-projection-PIeLSnR-.mjs} +16 -30
  32. package/dist/.setup/{conversation-binding-BieJZRRV.mjs → conversation-binding-CfnUR-IM.mjs} +228 -116
  33. package/dist/.setup/{conversation-binding-data-UgLuTSQT.mjs → conversation-binding-data-khgW0n-o.mjs} +4 -2
  34. package/dist/.setup/{conversation-control-GXM3unE4.mjs → conversation-control-B2EpVZEb.mjs} +53 -23
  35. package/dist/.setup/{cyber-failover-D4dgNfFf.mjs → cyber-failover-CqEZoQsj.mjs} +1 -1
  36. package/dist/.setup/{cyber-failover-notice-ljgGGL0s.mjs → cyber-failover-notice-poL3Advd.mjs} +1 -1
  37. package/dist/.setup/{doctor-start-options-JjTAl-q_.mjs → doctor-start-options-8uIBXIzR.mjs} +8 -5
  38. package/dist/.setup/{dynamic-tool-build-DcaPmBlE.mjs → dynamic-tool-build-DOub3CB5.mjs} +208 -218
  39. package/dist/.setup/{dynamic-tools-CnQFnNKH.mjs → dynamic-tools-Us5mvq_N.mjs} +344 -118
  40. package/dist/.setup/{effective-mcp-catalog-B5HKFZNK.mjs → effective-mcp-catalog-DfUUoeeM.mjs} +11 -9
  41. package/dist/.setup/{ephemeral-turn-De3qb8EQ.mjs → ephemeral-turn-B2z0RIeF.mjs} +5 -4
  42. package/dist/.setup/{event-projector-assistant-message-CLMKN4x-.mjs → event-projector-assistant-message-ChOAY7rW.mjs} +16 -11
  43. package/dist/.setup/{event-projector-usage-BpKfdoTm.mjs → event-projector-usage-CBY0Hkga.mjs} +2 -2
  44. package/dist/.setup/{event-projector-values-CLvG1Hil.mjs → event-projector-values-yf4us9Pf.mjs} +1 -1
  45. package/dist/.setup/experimental-features-uGnVDtp-.mjs +19 -0
  46. package/dist/.setup/inference-context-HRw3PDwn.mjs +209 -0
  47. package/dist/.setup/{inference-dispatch-CO6tTs4q.mjs → inference-dispatch-C2zVSnrr.mjs} +2 -2
  48. package/dist/.setup/{inference-metadata-DCvcG_N_.mjs → inference-metadata-CYFWLHVk.mjs} +3 -1
  49. package/dist/.setup/{inference-proxy-BDWV0djM.mjs → inference-proxy-CiLbHMLf.mjs} +8 -8
  50. package/dist/.setup/installed-probe-lVC1X5ve.mjs +185 -0
  51. package/dist/.setup/{isolated-completion-BPJdvk5F.mjs → isolated-completion-CybgD6uU.mjs} +7 -7
  52. package/dist/.setup/managed-binary-DbKvGXKl.mjs +395 -0
  53. package/dist/.setup/{mcp-app-session-preparation-Dz2GOwyE.mjs → mcp-app-session-preparation-zUgpDLWR.mjs} +18 -14
  54. package/dist/.setup/{model-catalog-ZNwltCKl.mjs → model-catalog-CWY3wo0B.mjs} +28 -17
  55. package/dist/.setup/{models-BHpbAuz8.mjs → models-CmOBxsKF.mjs} +3 -3
  56. package/dist/.setup/{native-auth-esN5MdIv.mjs → native-auth-DpZIaY8N.mjs} +7 -4
  57. package/dist/.setup/native-execution-policy-D09tLP-u.mjs +152 -0
  58. package/dist/.setup/{native-hook-relay-wq7jrNLk.mjs → native-hook-relay-CocOW9YS.mjs} +45 -10
  59. package/dist/.setup/{native-mcp-app-DX3nyTtc.mjs → native-mcp-app-DrQeLxXj.mjs} +5 -5
  60. package/dist/.setup/{native-skill-isolation-DSBeF-Yy.mjs → native-skill-isolation-DL4-PQa4.mjs} +7 -7
  61. package/dist/.setup/{native-subagent-monitor-DOLEIf9r.mjs → native-subagent-monitor-C3CIIaZG.mjs} +485 -239
  62. package/dist/.setup/{native-subagent-pending-assignments-DmVhedNs.mjs → native-subagent-pending-assignments-CTinVtjo.mjs} +1 -1
  63. package/dist/.setup/{native-task-assignments-DimsQ9Qa.mjs → native-task-assignments-YJopbaVO.mjs} +9 -5
  64. package/dist/.setup/{node-cli-sessions-CzKg2nGq.mjs → node-cli-sessions-BuJnBnEq.mjs} +7 -4
  65. package/dist/.setup/{node-exec-server.runtime-BWkULhBM.mjs → node-exec-server.runtime-CP7RC1Nd.mjs} +3 -3
  66. package/dist/.setup/{plan-41-YOBMq.mjs → plan-Bqj6VQvQ.mjs} +7 -20
  67. package/dist/.setup/{plugin-activation-D7WkJMvU.mjs → plugin-activation-CXPWe-hl.mjs} +4 -4
  68. package/dist/.setup/{plugin-app-cache-key-Bg9DbDI6.mjs → plugin-app-cache-key-DRb-niJc.mjs} +17 -55
  69. package/dist/.setup/{plugin-approval-roundtrip-CD88q3yx.mjs → plugin-approval-roundtrip-CGEiG7hG.mjs} +1 -1
  70. package/dist/.setup/{plugin-inventory-CYgdo14P.mjs → plugin-inventory-DE9wcaeH.mjs} +2 -2
  71. package/dist/.setup/{plugin-metadata-cache-Bi8TAPwX.mjs → plugin-metadata-cache-BqC-a6Fb.mjs} +2 -15
  72. package/dist/.setup/{project-doc-thread-config-BVcvnps8.mjs → project-doc-thread-config-B0UI3f1D.mjs} +6 -6
  73. package/dist/.setup/protocol-CaPAVwe9.mjs +12 -0
  74. package/dist/.setup/{provider-LWKll6dV.mjs → provider-C_1fMsyD.mjs} +4 -4
  75. package/dist/.setup/{provider-capabilities-Dn2WwH4P.mjs → provider-capabilities-C7pYYpvh.mjs} +1 -1
  76. package/dist/.setup/{rate-limits-CI8pTPqL.mjs → rate-limits-BpfURnuy.mjs} +1 -1
  77. package/dist/.setup/{request-Bo0kKABI.mjs → request-C6U8q2uz.mjs} +132 -136
  78. package/dist/.setup/{responses-oauth-twnuTaAa.mjs → responses-oauth-CCV7aVYF.mjs} +6 -6
  79. package/dist/.setup/{rpc-error-C98SHchT.mjs → rpc-error-DemqqaxE.mjs} +7 -3
  80. package/dist/.setup/{run-attempt-ClU8MxhZ.mjs → run-attempt-BhuXanLv.mjs} +595 -426
  81. package/dist/.setup/{run-attempt-lifecycle-KN4oh-7O.mjs → run-attempt-lifecycle-DN-ATDp9.mjs} +1 -1
  82. package/dist/.setup/{runtime-artifact-C13pR7tD.mjs → runtime-artifact-CmLWeyJB.mjs} +3 -3
  83. package/dist/.setup/{runtime-artifact-connection-jS5DeCok.mjs → runtime-artifact-connection-DpWlZ02e.mjs} +3 -3
  84. package/dist/.setup/{sandbox-guard-DIImwCy1.mjs → sandbox-guard-DneAfNye.mjs} +70 -30
  85. package/dist/.setup/{session-binding-JEHNMPsr.mjs → session-binding-BgsWcbdY.mjs} +25 -23
  86. package/dist/.setup/{session-binding-record-DU_0biMD.mjs → session-binding-record-C_THntMe.mjs} +27 -12
  87. package/dist/.setup/{session-binding-record-codec-BpH8u_G9.mjs → session-binding-record-codec-DvmOI7g_.mjs} +1 -0
  88. package/dist/.setup/{session-binding-sidecars-DD-enC8w.mjs → session-binding-sidecars-BNSS6WL4.mjs} +55 -63
  89. package/dist/.setup/session-cancellation-DCN1FcBZ.mjs +43 -0
  90. package/dist/.setup/{session-catalog-adoption-Ca3OYGYM.mjs → session-catalog-adoption-ppsLlVLB.mjs} +24 -38
  91. package/dist/.setup/{session-catalog-archive-Bv6gV7x9.mjs → session-catalog-archive-CqLRHJ6z.mjs} +11 -13
  92. package/dist/.setup/{session-catalog-events-kR2Ot6nX.mjs → session-catalog-events-CEi6SuLQ.mjs} +5 -5
  93. package/dist/.setup/{session-catalog-index-order-CTfoefow.mjs → session-catalog-index-order-0Zqng2u8.mjs} +1 -1
  94. package/dist/.setup/{session-catalog-index-CrnfVEnT.mjs → session-catalog-index-qt4UWBua.mjs} +96 -271
  95. package/dist/.setup/{session-catalog-limits-BynIoOYm.mjs → session-catalog-limits-Dc6E0BZz.mjs} +1 -1
  96. package/dist/.setup/{session-catalog-list-request-D4MYNgDB.mjs → session-catalog-list-request-CAjoWjaH.mjs} +3 -4
  97. package/dist/.setup/{session-catalog-native-projection-CWqCU1I_.mjs → session-catalog-native-projection-BqBYi6kV.mjs} +5 -5
  98. package/dist/.setup/{session-catalog-node-adoption-BdP9Zjqo.mjs → session-catalog-node-adoption-e9v8mGgx.mjs} +5 -5
  99. package/dist/.setup/{session-catalog-node-continue-CNJibO4_.mjs → session-catalog-node-continue-H7nrzcUD.mjs} +5 -5
  100. package/dist/.setup/{session-catalog-node-lookup-BH_DBGa9.mjs → session-catalog-node-lookup-BrZfDkA8.mjs} +2 -2
  101. package/dist/.setup/{session-catalog-parsing-DkeoVn60.mjs → session-catalog-parsing-V6jyFg9g.mjs} +2 -2
  102. package/dist/.setup/{session-catalog-projection-BzHiV818.mjs → session-catalog-projection-CNyhjZze.mjs} +8 -7
  103. package/dist/.setup/{session-catalog-provenance-CmsOE5mh.mjs → session-catalog-provenance-Dg9s12z-.mjs} +50 -30
  104. package/dist/.setup/{session-catalog-source-DGuRdGvM.mjs → session-catalog-source-z_mNyQdX.mjs} +2 -6
  105. package/dist/.setup/{session-cli-GwU0izn-.mjs → session-cli-CBGKiqdv.mjs} +1 -1
  106. package/dist/.setup/{session-history-BO6i_pfk.mjs → session-history-7W0cgTXF.mjs} +11 -9
  107. package/dist/.setup/{session-history-import-CaO8s6ta.mjs → session-history-import-BwPKwcNi.mjs} +4 -4
  108. package/dist/.setup/{session-initialization-Bi_2DKhc.mjs → session-initialization-Dn3vveGv.mjs} +2 -2
  109. package/dist/.setup/{session-retirement-B3U5hpGJ.mjs → session-retirement-RZStisKb.mjs} +8 -8
  110. package/dist/.setup/{session-history.worker-DJQfek5p.mjs → settled-turn-evidence--tRW6fSm.mjs} +2 -18
  111. package/dist/.setup/{settled-turn-finalizer-CYCVpTv2.mjs → settled-turn-finalizer-gioXygEX.mjs} +8 -8
  112. package/dist/.setup/{shared-client-BCx1wbyA.mjs → shared-client-CkyTrNB8.mjs} +380 -557
  113. package/dist/.setup/side-question-DHPWKgO3.mjs +998 -0
  114. package/dist/.setup/{source-DipMO9hL.mjs → source-63MLSmLJ.mjs} +5 -5
  115. package/dist/.setup/{thread-archive-guard-LKdwQKyr.mjs → thread-archive-guard-BWjSsA92.mjs} +1 -1
  116. package/dist/.setup/{thread-lifecycle-run-C_aYiYqk.mjs → thread-lifecycle-run-zCXYFW8W.mjs} +172 -75
  117. package/dist/.setup/{thread-model-selection-DcVebr8N.mjs → thread-model-selection-DxposL4X.mjs} +9 -9
  118. package/dist/.setup/{thread-ownership-BoUd0i6L.mjs → thread-ownership-Bmk5a2Gu.mjs} +7 -7
  119. package/dist/.setup/{thread-policy-B3wBRNph.mjs → thread-policy-DYtvZ5Ay.mjs} +6 -6
  120. package/dist/.setup/{thread-requests-BgzJwJtS.mjs → thread-requests-BjawdIVV.mjs} +14 -14
  121. package/dist/.setup/{thread-resume-D-3bsr1j.mjs → thread-resume-vBShG3-o.mjs} +6 -6
  122. package/dist/.setup/{transcript-history-projection-DfKcoZCB.mjs → transcript-history-projection-i-FVpyha.mjs} +1 -1
  123. package/dist/.setup/{transcript-mirror-Bee2o6jj.mjs → transcript-mirror-CEQJZlF3.mjs} +6 -9
  124. package/dist/.setup/{transport-stdio-CRWTkKOn.mjs → transport-stdio-Bq160Dhv.mjs} +63 -64
  125. package/dist/.setup/{transport-websocket-DIyPfkHo.mjs → transport-websocket-0YqiI_MH.mjs} +1 -1
  126. package/dist/.setup/{turn-router-DBVMToGo.mjs → turn-router-BGj67FMK.mjs} +2 -2
  127. package/dist/.setup/{upstream-session-fork-p5fwKi7w.mjs → upstream-session-fork-CWKjpdtW.mjs} +46 -219
  128. package/dist/.setup/{usage-C2Kq7oej.mjs → usage-AhrLFxZP.mjs} +4 -4
  129. package/dist/.setup/{usage-limit-error-BQX8RHAd.mjs → usage-limit-error-BdNbGJC3.mjs} +4 -4
  130. package/dist/.setup/{web-search-item-CvokaZOo.mjs → web-search-item-DHVuNSqk.mjs} +1 -1
  131. package/dist/.setup/{web-search-provider.runtime-D89djc7e.mjs → web-search-provider.runtime-Yk6lnJBG.mjs} +3 -3
  132. package/dist/.setup/{workspace-write-sandbox-probe-BDWO2Qkh.mjs → workspace-write-sandbox-probe-DJxOXcF3.mjs} +2 -2
  133. package/dist/api.js +7 -28
  134. package/dist/catalog-page.worker.js +1 -1
  135. package/dist/cli-metadata.js +1 -1
  136. package/dist/client-version-api.js +25 -0
  137. package/dist/doctor-contract-api.js +5 -5
  138. package/dist/harness.js +59 -36
  139. package/dist/index.js +259 -295
  140. package/dist/media-understanding-provider.js +2 -2
  141. package/dist/migration-provider-api.js +1 -2
  142. package/dist/native-session-binding-api.js +1 -2
  143. package/dist/provider-discovery.js +1 -1
  144. package/dist/session-history-worker-entrypoint.js +12 -0
  145. package/dist/session-history-worker-runtime.js +7 -18
  146. package/dist/session-history.worker.js +18 -2
  147. package/openclaw.plugin.json +1 -1
  148. package/package.json +6 -6
  149. package/dist/.setup/attempt-terminal-jO5IMj9K.mjs +0 -2
  150. package/dist/.setup/command-rpc-HIvsy3wS.mjs +0 -247
  151. package/dist/.setup/compact-ClZ7Ar7L.mjs +0 -808
  152. package/dist/.setup/inference-context-DNlGwzwy.mjs +0 -91
  153. package/dist/.setup/managed-binary-BtIjV7yN.mjs +0 -175
  154. package/dist/.setup/native-execution-policy-MXEe7PB3.mjs +0 -75
  155. package/dist/.setup/protocol-CANUwXJ3.mjs +0 -17
  156. package/dist/.setup/side-question-Bz2UQW0l.mjs +0 -826
@@ -1,17 +1,17 @@
1
- import { c as codexNativeSubagentRunId, d as readNativeSubagentThreadIds, f as readThreadParentThreadId, l as normalizeIdentifier, m as assertHistoryOwnerMatchesRegistration, p as readThreadSpawnSource, t as matchesNativeAssignmentLifecycle, u as readCodexNativeSubagentRunId } from "./native-subagent-pending-assignments-DmVhedNs.mjs";
2
- import { i as isJsonObject } from "./protocol-CANUwXJ3.mjs";
3
- import { n as defineCodexBuildState } from "./build-state-Ds14X10-.mjs";
4
- import { a as readHookOutputEntries, o as readItem, s as readNullableString } from "./event-projector-values-CLvG1Hil.mjs";
1
+ import { c as codexNativeSubagentRunId, d as readNativeSubagentThreadIds, f as readThreadParentThreadId, l as normalizeIdentifier, m as assertHistoryOwnerMatchesRegistration, p as readThreadSpawnSource, t as matchesNativeAssignmentLifecycle, u as readCodexNativeSubagentRunId } from "./native-subagent-pending-assignments-CTinVtjo.mjs";
2
+ import { r as isJsonObject } from "./protocol-CaPAVwe9.mjs";
3
+ import { n as defineCodexBuildState } from "./build-state-CjLCC0wm.mjs";
4
+ import { a as readHookOutputEntries, o as readItem, s as readNullableString } from "./event-projector-values-yf4us9Pf.mjs";
5
5
  import { n as attachCodexMirrorIdentity } from "./upstream-prompt-provenance-Ccd9MFRJ.mjs";
6
- import { t as readCodexMirroredSessionHistoryMessages } from "./session-history-BO6i_pfk.mjs";
7
- import { P as claimCodexAppServerLiveThread, R as hasCodexAppServerLiveThread, q as retainCodexAppServerLiveThread } from "./shared-client-BCx1wbyA.mjs";
8
- import { M as readCodexAppServerWarningMessage } from "./client-D93nbdB8.mjs";
9
- import { C as unknownItemStatus, _ as itemName, b as matchesCodexSnapshotTurn, f as isMutatingNativeToolItem, g as itemKind, h as isSideEffectingNativeToolItem, l as auditNativeToolName, m as isProjectedNativeToolItem, p as isNonSuccessItemStatus, u as auditNativeToolTerminalStatus, v as itemStatus, y as itemTitle } from "./turn-router-DBVMToGo.mjs";
10
- import { s as interruptCodexTurnAndWaitBestEffort } from "./attempt-client-cleanup-zNuNTKVr.mjs";
11
- import { t as projectCodexWebSearchItem } from "./web-search-item-CvokaZOo.mjs";
12
- import { n as codexApprovalTimeoutText } from "./plugin-approval-roundtrip-CD88q3yx.mjs";
6
+ import { t as readCodexMirroredSessionHistoryMessages } from "./session-history-7W0cgTXF.mjs";
7
+ import { A as hasCodexAppServerLiveThread, B as retainCodexAppServerLiveThread, E as claimCodexAppServerLiveThread } from "./shared-client-CkyTrNB8.mjs";
8
+ import { j as readCodexAppServerWarningMessage } from "./client--P8jwXvA.mjs";
9
+ import { C as unknownItemStatus, _ as itemName, b as matchesCodexSnapshotTurn, f as isMutatingNativeToolItem, g as itemKind, h as isSideEffectingNativeToolItem, l as auditNativeToolName, m as isProjectedNativeToolItem, p as isNonSuccessItemStatus, u as auditNativeToolTerminalStatus, v as itemStatus, y as itemTitle } from "./turn-router-BGj67FMK.mjs";
10
+ import { s as interruptCodexTurnAndWaitBestEffort, t as CODEX_APP_SERVER_INTERRUPT_TIMEOUT_MS } from "./attempt-client-cleanup-DMJWXGxM.mjs";
11
+ import { t as projectCodexWebSearchItem } from "./web-search-item-DHVuNSqk.mjs";
12
+ import { n as codexApprovalTimeoutText } from "./plugin-approval-roundtrip-CGEiG7hG.mjs";
13
13
  import { t as resolveCodexLocalRuntimeAttribution } from "./local-runtime-attribution-CZz2DJ4q.mjs";
14
- import { t as __exportAll } from "./session-binding-sidecars-DD-enC8w.mjs";
14
+ import { t as __exportAll } from "./session-binding-sidecars-BNSS6WL4.mjs";
15
15
  import { asFiniteNumber, asNonArrayRecord, normalizeOptionalString, readStringField } from "openclaw/plugin-sdk/string-coerce-runtime";
16
16
  import { randomUUID } from "node:crypto";
17
17
  import { asDateTimestampMs } from "openclaw/plugin-sdk/number-runtime";
@@ -19,7 +19,8 @@ import { truncateUtf16Safe } from "openclaw/plugin-sdk/text-utility-runtime";
19
19
  import path from "node:path";
20
20
  import { toErrorObject } from "openclaw/plugin-sdk/error-runtime";
21
21
  import { KeyedAsyncQueue } from "openclaw/plugin-sdk/keyed-async-queue";
22
- import { TOOL_PROGRESS_OUTPUT_MAX_CHARS, embeddedAgentLog, emitAgentEvent, formatErrorMessage as formatErrorMessage$1, inferToolMetaFromArgs, projectAgentActivityItem, projectAgentToolActivity, runAgentHarnessAfterToolCallHook, sanitizeToolArgs } from "openclaw/plugin-sdk/agent-harness-runtime";
22
+ import { createDeferred } from "openclaw/plugin-sdk/extension-shared";
23
+ import { TOOL_PROGRESS_OUTPUT_MAX_CHARS, embeddedAgentLog, emitAgentEvent, formatErrorMessage as formatErrorMessage$1, inferToolMetaFromArgs, projectAgentActivityItem, projectAgentToolActivity, runAgentHarnessAfterToolCallHook } from "openclaw/plugin-sdk/agent-harness-runtime";
23
24
  import { MAX_TOOL_OUTPUT_DELTA_MESSAGES_PER_ITEM, NativeToolOutputAccumulator, TOOL_TRANSCRIPT_OUTPUT_MAX_CHARS, createAgentHarnessToolCallMessage, createAgentHarnessToolResultMessage, formatNativeToolOutput, formatNativeToolSummary, truncateNativeToolTranscriptText } from "openclaw/plugin-sdk/agent-harness-attempt-runtime";
24
25
  import { captureAgentHarnessCompletionCustody, createAgentHarnessCompletionEventSink, deliverAgentHarnessCompletion, isDurableAgentHarnessCompletionDelivery } from "openclaw/plugin-sdk/agent-harness-completion";
25
26
  import { compileFunction } from "node:vm";
@@ -184,6 +185,12 @@ function retainNativeModelExecution(owner, turnId, threadId, completionCustody =
184
185
  const capture = owner?.modelSource?.capture();
185
186
  if (!owner || !capture) return;
186
187
  const nativeOwner = {
188
+ requestCustody: owner.requestCustody,
189
+ requesterTurnRunId: owner.requesterTurnRunId,
190
+ requesterAgentId: owner.requesterAgentId,
191
+ requesterSessionKey: owner.requesterSessionKey,
192
+ requesterSessionId: owner.requesterSessionId,
193
+ requesterLifecycleRevision: owner.requesterLifecycleRevision,
187
194
  modelSource: owner.modelSource,
188
195
  modelMapping: owner.modelMapping,
189
196
  configurationQualification: owner.configurationQualification,
@@ -266,6 +273,10 @@ function releaseNativeDirectChild(child) {
266
273
  }
267
274
  function admitNativeChildModelExecution(child, owner, known) {
268
275
  if (known) known.configurationQualification = owner.configurationQualification;
276
+ if (!child.modelExecution) {
277
+ child.requesterTurnRunId = owner.requesterTurnRunId;
278
+ child.requestCustody = owner.requestCustody;
279
+ }
269
280
  child.modelExecution ??= retainNativeModelExecution(owner, child.nativeTurnId, child.childThreadId, child.completionCustody);
270
281
  owner.onDirectChildAccepted?.();
271
282
  }
@@ -563,6 +574,7 @@ var CodexNativeSubagentAssignmentInventory = class {
563
574
  this.dependencies = dependencies;
564
575
  this.writes = /* @__PURE__ */ new Map();
565
576
  this.snapshots = /* @__PURE__ */ new WeakMap();
577
+ this.cancelled = /* @__PURE__ */ new WeakSet();
566
578
  }
567
579
  hasWrites(state) {
568
580
  return this.writes.has(state);
@@ -620,18 +632,33 @@ var CodexNativeSubagentAssignmentInventory = class {
620
632
  await state.assignmentStore?.consume(assignment, () => this.dependencies.assertCurrent(state));
621
633
  });
622
634
  }
635
+ settleCancelled(state, child, assertCurrent) {
636
+ return this.enqueue(state, async () => {
637
+ const assertAdmission = () => {
638
+ this.dependencies.assertCurrent(state);
639
+ assertCurrent();
640
+ };
641
+ assertAdmission();
642
+ const assignment = this.fact(child);
643
+ if (!assignment || !state.assignmentStore || this.cancelled.has(child)) return;
644
+ if (!await state.assignmentStore.consume(assignment, assertAdmission)) throw new Error("Cancelled native assignment was not acknowledged.");
645
+ this.cancelled.add(child);
646
+ assertAdmission();
647
+ });
648
+ }
623
649
  async restore(state, owner) {
624
650
  const store = state.assignmentStore;
625
651
  const current = state.historyOwner;
626
652
  if (!store || !current || !owner.completionCustody?.isCurrent()) return;
627
653
  const custody = owner.completionCustody.retain();
628
654
  try {
629
- store.assertCurrent();
630
- for (const assignment of store.read()) {
655
+ const assignments = await store.read();
656
+ if (!this.dependencies.isCurrent(state) || !custody.isCurrent()) return;
657
+ for (const assignment of assignments) {
631
658
  if (!matchesNativeAssignmentLifecycle(assignment.owner, current)) continue;
632
659
  const recovery = await this.dependencies.readHistory(assignment);
660
+ await store.assertCurrentAsync();
633
661
  if (!this.dependencies.isCurrent(state) || !custody.isCurrent()) return;
634
- store.assertCurrent();
635
662
  if (!recovery || recovery.parentThreadId !== assignment.nativeParentThreadId) continue;
636
663
  await this.dependencies.restore(state, assignment, recovery, custody);
637
664
  }
@@ -664,6 +691,22 @@ var CodexNativeSubagentAssignmentInventory = class {
664
691
  }
665
692
  };
666
693
  //#endregion
694
+ //#region extensions/codex/src/app-server/native-subagent-cancellation-wait.ts
695
+ /** Bound pending registration and turn discovery by Stop's shared native deadline. */
696
+ async function waitForNativeCancellationWork(client, work, deadline) {
697
+ const remaining = deadline - performance.now();
698
+ if (remaining <= 0) throw new Error("Codex descendant cancellation did not settle before its deadline");
699
+ const interrupted = createDeferred();
700
+ const timer = setTimeout(() => interrupted.reject(/* @__PURE__ */ new Error("Codex descendant cancellation did not settle before its deadline")), remaining);
701
+ const releaseClose = client.addCloseHandler(() => interrupted.reject(/* @__PURE__ */ new Error("Codex client closed during descendant cancellation")));
702
+ try {
703
+ return await Promise.race([work, interrupted.promise]);
704
+ } finally {
705
+ clearTimeout(timer);
706
+ releaseClose();
707
+ }
708
+ }
709
+ //#endregion
667
710
  //#region extensions/codex/src/app-server/native-subagent-retry.ts
668
711
  function delayForAttempt(delays, attempt) {
669
712
  return Math.max(1, delays[Math.min(attempt, delays.length - 1)] ?? 1);
@@ -683,29 +726,14 @@ const DEFAULT_RECOVERY_POLL_DELAYS_MS = [
683
726
  var CodexNativeSubagentRecoveryCoordinator = class {
684
727
  constructor(dependencies) {
685
728
  this.dependencies = dependencies;
686
- this.threadStatusRevisions = /* @__PURE__ */ new Map();
729
+ this.terminalThreads = /* @__PURE__ */ new Map();
687
730
  this.recoveryPollDelaysMs = dependencies.recoveryPollDelaysMs ?? DEFAULT_RECOVERY_POLL_DELAYS_MS;
688
731
  }
689
- hasRevision(threadId) {
690
- return this.threadStatusRevisions.has(threadId);
732
+ isTerminalThread(threadId) {
733
+ return this.terminalThreads.has(threadId);
691
734
  }
692
- observeRevision(threadId) {
693
- const revision = this.threadStatusRevisions.get(threadId);
694
- if (revision) revision.value += 1;
695
- }
696
- isTerminalRevision(threadId) {
697
- return this.threadStatusRevisions.get(threadId)?.terminal === true;
698
- }
699
- markTerminalRevision(threadId) {
700
- const revision = this.threadStatusRevisions.get(threadId);
701
- if (revision) revision.terminal = true;
702
- }
703
- seedRevision(threadId, parentThreadId) {
704
- this.threadStatusRevisions.set(threadId, this.threadStatusRevisions.get(threadId) ?? {
705
- value: 0,
706
- readers: 0,
707
- parentThreadId
708
- });
735
+ markTerminalThread(threadId, parentThreadId) {
736
+ this.terminalThreads.set(threadId, parentThreadId);
709
737
  }
710
738
  async reconcileRegisteredChild(childState) {
711
739
  if (childState.terminal || this.dependencies.isDisposed() || !this.dependencies.isRegisteredChild(childState)) return false;
@@ -715,16 +743,11 @@ var CodexNativeSubagentRecoveryCoordinator = class {
715
743
  try {
716
744
  return await recovery;
717
745
  } finally {
718
- if (childState.recoveryInFlight === recovery) childState.recoveryInFlight = void 0;
746
+ childState.recoveryInFlight = void 0;
719
747
  }
720
748
  }
721
- clearTerminalRevisionsForParent(parentThreadId) {
722
- for (const [threadId, revision] of this.threadStatusRevisions) if (revision.parentThreadId === parentThreadId) this.collectThreadStatusRevision(threadId, revision);
723
- }
724
- collectThreadStatusRevision(threadId, revision = this.threadStatusRevisions.get(threadId)) {
725
- if (!revision || revision.readers > 0 || Boolean(this.dependencies.currentChild(threadId))) return;
726
- if ((revision.parentThreadId ? this.dependencies.parentState(revision.parentThreadId) : void 0)?.owners.size) return;
727
- if (this.threadStatusRevisions.get(threadId) === revision) this.threadStatusRevisions.delete(threadId);
749
+ clearTerminalThreadsForParent(parentThreadId) {
750
+ for (const [threadId, parent] of this.terminalThreads) if (parent === parentThreadId) this.terminalThreads.delete(threadId);
728
751
  }
729
752
  scheduleRecoveryPoll(childState) {
730
753
  if (childState.terminal || childState.settledWithoutCompletion || childState.recoveryTimer || this.dependencies.isDisposed() || this.recoveryPollDelaysMs.length === 0) return;
@@ -763,25 +786,6 @@ var CodexNativeSubagentRecoveryCoordinator = class {
763
786
  if (childState.fallbackCompletion?.statusLabel !== "system_error") return;
764
787
  childState.fallbackCompletion = void 0;
765
788
  }
766
- retainThreadStatusRevision(threadId) {
767
- const revision = this.threadStatusRevisions.get(threadId) ?? {
768
- value: 0,
769
- readers: 0
770
- };
771
- this.threadStatusRevisions.set(threadId, revision);
772
- revision.readers += 1;
773
- const capturedValue = revision.value;
774
- let retained = true;
775
- return {
776
- isCurrent: () => this.threadStatusRevisions.get(threadId) === revision && revision.value === capturedValue,
777
- release: () => {
778
- if (!retained) return;
779
- retained = false;
780
- revision.readers -= 1;
781
- this.collectThreadStatusRevision(threadId, revision);
782
- }
783
- };
784
- }
785
789
  clearRecoveryTimers(childState) {
786
790
  clearTimeout(childState.recoveryTimer);
787
791
  childState.recoveryTimer = void 0;
@@ -809,7 +813,7 @@ var CodexNativeSubagentCloseOwner = class {
809
813
  this.calls.delete(state);
810
814
  }
811
815
  hasPending(state) {
812
- return [...this.calls.get(state)?.values() ?? []].some((call) => call.completing && !call.settled);
816
+ return [...this.calls.get(state)?.values() ?? []].some((call) => call.settlement !== void 0);
813
817
  }
814
818
  settlements(state) {
815
819
  return [...this.calls.get(state)?.values() ?? []].flatMap((call) => call.settlement ? [call.settlement] : []);
@@ -862,7 +866,7 @@ var CodexNativeSubagentCloseOwner = class {
862
866
  const calls = this.calls.get(state);
863
867
  if (!calls) return;
864
868
  for (const [key, call] of calls) {
865
- if (call.completing && !call.settled) continue;
869
+ if (call.settlement) continue;
866
870
  if (!this.hasCallOwner(state, call, true)) calls.delete(key);
867
871
  }
868
872
  }
@@ -883,7 +887,7 @@ var CodexNativeSubagentCloseOwner = class {
883
887
  known.assignment.terminal = true;
884
888
  known.assignment.nativeTurnId = childState.nativeTurnId;
885
889
  }
886
- this.callbacks.markTerminalRevision(childState.childThreadId);
890
+ this.callbacks.markTerminalThread(childState.childThreadId, state.parentThreadId);
887
891
  }
888
892
  childState.pendingCompletion = void 0;
889
893
  childState.subscriptionClosed = true;
@@ -899,9 +903,9 @@ var CodexNativeSubagentCloseOwner = class {
899
903
  }
900
904
  completeChildClose(state, key, call) {
901
905
  if (call.settlement) return call.settlement;
902
- const settlement = this.confirmChildClose(state, key, call);
903
- if (call.completing) call.settlement = settlement;
904
- return settlement;
906
+ if (!this.callbacks.isParentCurrent(state) || !this.hasCallOwner(state, call, false)) return Promise.resolve();
907
+ call.settlement = this.confirmChildClose(state, key, call);
908
+ return call.settlement;
905
909
  }
906
910
  async confirmChildClose(state, key, call) {
907
911
  const isCurrent = () => this.callbacks.isParentCurrent(state) && this.calls.get(state)?.get(key) === call;
@@ -910,19 +914,13 @@ var CodexNativeSubagentCloseOwner = class {
910
914
  const childState = this.callbacks.currentChild(target.childThreadId);
911
915
  return known?.parent === state && known.assignment.runId === target.runId && known.turnId === target.nativeTurnId && known.pendingTurns.length === 0 && (childState === void 0 || childState === target.childState);
912
916
  };
913
- if (call.completing || !isCurrent() || !this.hasCallOwner(state, call, false)) return;
914
- call.completing = true;
915
- let settled = false;
916
917
  let retiring = false;
917
918
  try {
918
919
  const forgetters = await Promise.all(call.targets.map((target) => Promise.resolve(target.forget)));
919
920
  if (!isCurrent()) return;
920
921
  const loaded = await this.client.request("thread/loaded/list", {}, { timeoutMs: 1e4 });
921
922
  if (!isCurrent()) return;
922
- if (!isJsonObject(loaded) || loaded.nextCursor !== null || !Array.isArray(loaded.data) || !loaded.data.every((id) => typeof id === "string" && id.trim() !== "")) {
923
- settled = true;
924
- return;
925
- }
923
+ if (!isJsonObject(loaded) || loaded.nextCursor !== null || !Array.isArray(loaded.data) || !loaded.data.every((id) => typeof id === "string" && id.trim() !== "")) return;
926
924
  for (const [index, target] of call.targets.entries()) {
927
925
  const childState = this.callbacks.currentChild(target.childThreadId);
928
926
  if (loaded.data.includes(target.childThreadId) || !isTargetCurrent(target)) continue;
@@ -933,21 +931,14 @@ var CodexNativeSubagentCloseOwner = class {
933
931
  if (!isCurrent()) return;
934
932
  } else forget?.();
935
933
  }
936
- settled = true;
937
934
  } catch (error) {
938
935
  embeddedAgentLog.warn("Failed to confirm Codex native subagent close", {
939
936
  parentThreadId: state.parentThreadId,
940
937
  error: formatErrorMessage$1(error)
941
938
  });
942
939
  if (retiring) throw error;
943
- settled = true;
944
940
  } finally {
945
- if (settled || !isCurrent()) call.settled = true;
946
- else {
947
- call.completing = void 0;
948
- call.settlement = void 0;
949
- }
950
- if (call.settled && this.calls.get(state)?.get(key) === call) call.targets = [];
941
+ if (this.calls.get(state)?.get(key) === call) this.calls.get(state)?.delete(key);
951
942
  this.prune(state);
952
943
  this.callbacks.pruneParent(state);
953
944
  }
@@ -980,21 +971,24 @@ var CodexNativeSubagentCompletionDelivery = class {
980
971
  deliverPending(state, childState) {
981
972
  const existing = this.attempts.get(childState);
982
973
  if (existing) return existing;
983
- const attempt = this.deliverAttempt(state, childState);
974
+ const attempt = Promise.resolve().then(() => this.deliverAttempt(state, childState));
984
975
  this.attempts.set(childState, attempt);
985
976
  const release = () => {
986
- if (this.attempts.get(childState) === attempt) this.attempts.delete(childState);
977
+ this.attempts.delete(childState);
987
978
  };
988
979
  attempt.then(release, release);
989
980
  return attempt;
990
981
  }
982
+ async join(child) {
983
+ await this.attempts.get(child);
984
+ }
991
985
  async deliverAttempt(state, childState) {
992
986
  const completion = childState.pendingCompletion;
993
987
  if (!completion || !this.isCurrent(state, childState)) return;
994
- if (childState.deliveringCompletion || childState.completionDeliveryTimer) return;
995
- childState.deliveringCompletion = true;
988
+ if (childState.completionDeliveryTimer) return;
996
989
  let deferredToForeground = false;
997
990
  try {
991
+ if (childState.cancellationRequested && completion.status === "cancelled") return;
998
992
  if (!this.prepareDelivery(state, childState)) return;
999
993
  if (state.owners.size > 0 || !state.completionScope) {
1000
994
  deferredToForeground = state.owners.size > 0;
@@ -1047,7 +1041,6 @@ var CodexNativeSubagentCompletionDelivery = class {
1047
1041
  });
1048
1042
  } finally {
1049
1043
  if (!deferredToForeground) childState.completionCustody?.settleExecution();
1050
- childState.deliveringCompletion = false;
1051
1044
  }
1052
1045
  }
1053
1046
  finish(state, child) {
@@ -1070,7 +1063,7 @@ var CodexNativeSubagentCompletionDelivery = class {
1070
1063
  if (!this.claim(deliveryParent, child)) continue;
1071
1064
  }
1072
1065
  child.nativeCompletionDelivered = true;
1073
- if (child.pendingCompletion && !child.deliveringCompletion) this.finish(deliveryParent, child);
1066
+ if (child.pendingCompletion && !this.attempts.has(child)) this.finish(deliveryParent, child);
1074
1067
  }
1075
1068
  }
1076
1069
  deliverDetached(state) {
@@ -1155,12 +1148,6 @@ const NATIVE_SUBAGENT_NOTIFICATION_METHODS = /* @__PURE__ */ new Set([
1155
1148
  "item/completed",
1156
1149
  "rawResponseItem/completed"
1157
1150
  ]);
1158
- const RECOVERY_REVISION_NOTIFICATION_METHODS = /* @__PURE__ */ new Set([
1159
- "thread/started",
1160
- "thread/status/changed",
1161
- "turn/started",
1162
- "turn/completed"
1163
- ]);
1164
1151
  const CODEX_SUBAGENT_NOTIFICATION_START = "<subagent_notification>";
1165
1152
  const CODEX_SUBAGENT_NOTIFICATION_END = "</subagent_notification>";
1166
1153
  function extractCodexNativeSubagentCompletions(notification) {
@@ -1618,7 +1605,6 @@ async function prepareNativeModelToolInput(request, dependencies) {
1618
1605
  }
1619
1606
  let preparedSource;
1620
1607
  let pendingBinding;
1621
- let targetRevision;
1622
1608
  let assertTargetCurrent;
1623
1609
  const assertCurrent = () => {
1624
1610
  request.signal?.throwIfAborted();
@@ -1631,16 +1617,16 @@ async function prepareNativeModelToolInput(request, dependencies) {
1631
1617
  try {
1632
1618
  assertCurrent();
1633
1619
  const targetThreadId = resolveInputTarget(request, dependencies);
1634
- targetRevision = dependencies.retainTargetRevision(targetThreadId);
1635
1620
  const targetParent = dependencies.parents.get(targetThreadId);
1636
1621
  const targetChild = dependencies.knownChildren.get(targetThreadId);
1622
+ const targetLoad = (targetParent ?? targetChild)?.nativeLoad;
1637
1623
  const targetConfiguration = targetChild?.configurationQualification;
1638
1624
  const targetRouting = request.readQualification(targetThreadId);
1639
1625
  let metadataRead = false;
1640
1626
  assertTargetCurrent = () => {
1641
1627
  const nativeRoot = nativeRootThreadId(request.threadId, dependencies.knownChildren, state);
1642
1628
  if (!(targetParent ? (targetParent === state || nativeRoot === targetThreadId) && dependencies.canPrepareReceiver(state, targetThreadId) : targetChild ? dependencies.canPrepareReceiver(state, targetThreadId) : !metadataRead || nativeRoot === targetThreadId || nativeParentThreadId === state.parentThreadId || nativeParentThreadId !== void 0 && dependencies.knownChildren.get(nativeParentThreadId)?.parent === state)) throw new Error("Codex native input target is outside the sender's admitted tree");
1643
- if (!targetRevision?.isCurrent() || dependencies.parents.get(targetThreadId) !== targetParent || dependencies.knownChildren.get(targetThreadId) !== targetChild || targetChild?.configurationQualification !== targetConfiguration || request.readQualification(targetThreadId) !== targetRouting) throw new Error("Codex native receiver changed during input preparation; retry with its current thread");
1629
+ if (dependencies.parents.get(targetThreadId) !== targetParent || dependencies.knownChildren.get(targetThreadId) !== targetChild || (targetParent ?? targetChild)?.nativeLoad !== targetLoad || targetChild?.configurationQualification !== targetConfiguration || request.readQualification(targetThreadId) !== targetRouting) throw new Error("Codex native receiver changed during input preparation; retry with its current thread");
1644
1630
  targetConfiguration?.assertCurrent();
1645
1631
  targetRouting?.assertCurrent();
1646
1632
  };
@@ -1722,7 +1708,6 @@ async function prepareNativeModelToolInput(request, dependencies) {
1722
1708
  targetThreadId
1723
1709
  }, pendingModelSources, preparedOwner);
1724
1710
  } finally {
1725
- targetRevision?.release();
1726
1711
  preparedSource?.release();
1727
1712
  if (!preparedSource) capture.release();
1728
1713
  }
@@ -1813,6 +1798,12 @@ function createCodexNativeSubagentMonitorRuntime(Monitor) {
1813
1798
  };
1814
1799
  monitor = new Monitor(client, runtime ?? defaultNativeSubagentMonitorRuntime, {
1815
1800
  retainClient,
1801
+ interruptChildAndWait: (threadId, turnId, assertCurrent, timeoutMs) => interruptCodexTurnAndWaitBestEffort(client, {
1802
+ threadId,
1803
+ turnId,
1804
+ assertCurrent,
1805
+ timeoutMs
1806
+ }),
1816
1807
  interruptModelExecution: (threadId, turnId) => {
1817
1808
  interruptCodexTurnAndWaitBestEffort(client, {
1818
1809
  threadId,
@@ -1870,6 +1861,10 @@ function createCodexNativeSubagentMonitorRuntime(Monitor) {
1870
1861
  if (!monitor) return Promise.reject(/* @__PURE__ */ new Error("Codex native input has no admitted model source"));
1871
1862
  return monitor.prepareModelInput(request);
1872
1863
  },
1864
+ withDescendantCancellation: (client, params, run) => monitors.get(client)?.withDescendantCancellation(params, run) ?? run(async () => ({
1865
+ killed: 0,
1866
+ cancelledRequesters: []
1867
+ })),
1873
1868
  retireParent: (client, parentThreadId) => monitors.get(client)?.retireParent(parentThreadId) ?? Promise.resolve()
1874
1869
  };
1875
1870
  }
@@ -1976,6 +1971,7 @@ async function registerNativeSubagentParent(input, dependencies) {
1976
1971
  const parentThreadId = params.parentThreadId.trim();
1977
1972
  if (!parentThreadId) throw new Error("Codex native subagent monitor requires a parent thread id");
1978
1973
  if (dependencies.isClosed()) throw new Error("Codex native subagent monitor is closed");
1974
+ dependencies.assertAdmissionCurrent?.(params);
1979
1975
  let state = dependencies.states.get(parentThreadId);
1980
1976
  if (state?.requesterSessionKey && params.requesterSessionKey && state.requesterSessionKey !== params.requesterSessionKey) throw new Error(`Codex thread ${parentThreadId} is already bound to another session`);
1981
1977
  if (!state) {
@@ -1990,11 +1986,18 @@ async function registerNativeSubagentParent(input, dependencies) {
1990
1986
  }
1991
1987
  state.requesterSessionKey ??= params.requesterSessionKey;
1992
1988
  const requesterSessionKey = state.requesterSessionKey;
1993
- state.pendingRegistrations = (state.pendingRegistrations ?? 0) + 1;
1994
1989
  const registeredState = state;
1995
1990
  const isCurrent = () => !dependencies.isClosed() && !dependencies.isRetired(registeredState) && dependencies.states.get(parentThreadId) === registeredState;
1996
1991
  const ownerKey = Symbol("codex-native-subagent-owner");
1992
+ const registrationSettled = createDeferred();
1997
1993
  let owner = {
1994
+ requestCustody: params.requestCustody,
1995
+ requesterAgentId: params.agentId,
1996
+ requesterSessionKey: params.requesterSessionKey,
1997
+ requesterTurnRunId: params.requesterTurnRunId,
1998
+ requesterSessionId: params.historyOwner?.sessionId,
1999
+ requesterLifecycleRevision: params.historyOwner?.lifecycleRevision,
2000
+ registrationSettled: registrationSettled.promise,
1998
2001
  configurationQualification: params.configurationQualification,
1999
2002
  unqualifiedModelExecution: params.modelSource ? params.unqualifiedModelExecution : void 0,
2000
2003
  interruptModelExecution: dependencies.interruptModelExecution,
@@ -2003,6 +2006,7 @@ async function registerNativeSubagentParent(input, dependencies) {
2003
2006
  onDirectChildAccepted: params.onDirectChildAccepted,
2004
2007
  isTurnYielded: params.isTurnYielded
2005
2008
  };
2009
+ (state.pendingRegistrations ??= /* @__PURE__ */ new Set()).add(owner);
2006
2010
  let rootModelBinding;
2007
2011
  let cancellationReported = false;
2008
2012
  let interruptedTurnId;
@@ -2025,11 +2029,12 @@ async function registerNativeSubagentParent(input, dependencies) {
2025
2029
  };
2026
2030
  try {
2027
2031
  owner.completionCustody = params.completionScope ? await dependencies.runtime.captureAgentHarnessCompletionCustody(params.completionScope) : void 0;
2032
+ await params.assertCurrentAsync?.();
2028
2033
  if (!isCurrent() || state.requesterSessionKey !== requesterSessionKey || owner.completionCustody && !owner.completionCustody.isCurrent()) throw new Error("Codex native subagent parent registration is no longer current");
2029
2034
  params.assertCurrent?.();
2030
2035
  params.modelSource?.assertCurrent();
2031
2036
  if (Object.hasOwn(params, "modelSource")) owner.modelSource = createNativeModelSourceOwner(params.modelSource, state, () => {
2032
- if (!isCurrent()) throw new Error("Codex native model source owner is no longer current");
2037
+ if (owner.descendantsCancelled || !isCurrent()) throw new Error("Codex native model source owner is no longer current");
2033
2038
  }, () => dependencies.prune(registeredState));
2034
2039
  if (owner.unqualifiedModelExecution && params.modelSource) {
2035
2040
  rootModelBinding = params.modelSource.bindModelExecution?.(void 0);
@@ -2038,6 +2043,8 @@ async function registerNativeSubagentParent(input, dependencies) {
2038
2043
  if (rootModelBinding.signal.aborted) cancelUnqualifiedRoot();
2039
2044
  }
2040
2045
  params.assertCurrent?.();
2046
+ if (owner.descendantsCancelled) throw new Error("Codex parent registration was cancelled before admission");
2047
+ dependencies.assertAdmissionCurrent?.(params);
2041
2048
  state.completionScope ??= params.completionScope;
2042
2049
  state.historyOwner ??= params.historyOwner;
2043
2050
  state.submissionStore ??= params.submissionStore;
@@ -2046,7 +2053,6 @@ async function registerNativeSubagentParent(input, dependencies) {
2046
2053
  state.owners.set(ownerKey, owner);
2047
2054
  state.preparing = void 0;
2048
2055
  dependencies.deliverDetached(state);
2049
- dependencies.submissions.restore(state, owner);
2050
2056
  } catch (error) {
2051
2057
  releaseRootModelBinding();
2052
2058
  state.owners.delete(ownerKey);
@@ -2055,10 +2061,11 @@ async function registerNativeSubagentParent(input, dependencies) {
2055
2061
  else params.modelSource?.release();
2056
2062
  throw error;
2057
2063
  } finally {
2058
- state.pendingRegistrations -= 1;
2064
+ state.pendingRegistrations?.delete(owner);
2059
2065
  dependencies.prune(registeredState);
2066
+ registrationSettled.resolve();
2060
2067
  }
2061
- const ready = dependencies.assignments.restore(state, owner);
2068
+ const ready = dependencies.submissions.restore(state, owner).then(() => dependencies.assignments.restore(state, owner));
2062
2069
  let registered = true;
2063
2070
  let settlement;
2064
2071
  return {
@@ -2095,6 +2102,7 @@ async function registerNativeSubagentParent(input, dependencies) {
2095
2102
  dependencies.clearAdmissions();
2096
2103
  notifyNativeModelSourceWaiters(registeredState);
2097
2104
  },
2105
+ listPendingChildren: () => registered && dependencies.states.get(parentThreadId) === registeredState ? dependencies.pendingChildren(registeredState) : [],
2098
2106
  unregister: () => {
2099
2107
  if (!registered) return settlement ?? Promise.resolve();
2100
2108
  registered = false;
@@ -2122,6 +2130,7 @@ async function registerNativeSubagentParent(input, dependencies) {
2122
2130
  await Promise.allSettled([dependencies.submissions.drain(registeredState)]);
2123
2131
  await Promise.allSettled([dependencies.assignments.drain(registeredState)]);
2124
2132
  dependencies.prune(registeredState);
2133
+ if (params.submissionStore !== registeredState.submissionStore) params.submissionStore?.release?.();
2125
2134
  })();
2126
2135
  return settlement;
2127
2136
  }
@@ -2391,25 +2400,20 @@ function captureSubmissionPredecessor(params) {
2391
2400
  //#region extensions/codex/src/app-server/native-subagent-submission-history.ts
2392
2401
  async function readCodexNativeSubmissionTurn(receipt, dependencies) {
2393
2402
  if (!dependencies.prepareReceiver()) return;
2394
- const revision = dependencies.recovery.retainThreadStatusRevision(receipt.childThreadId);
2395
- try {
2396
- const response = await dependencies.client.request("thread/read", {
2397
- threadId: receipt.childThreadId,
2398
- includeTurns: true
2399
- }, { timeoutMs: 3e4 });
2400
- if (!revision.isCurrent() || !dependencies.isCurrent()) return;
2401
- const thread = isJsonObject(response.thread) ? response.thread : void 0;
2402
- if (readStringField(thread, "id") !== receipt.childThreadId || readThreadParentThreadId(thread) !== dependencies.parentThreadId()) return;
2403
- const turns = (Array.isArray(thread?.turns) ? thread.turns : []).flatMap((turn) => isJsonObject(turn) ? [turn] : []);
2404
- const predecessorIndex = turns.findIndex((turn) => readStringField(turn, "id") === receipt.predecessorNativeTurnId);
2405
- const turnIndex = turns.findIndex((turn) => readStringField(turn, "id") === receipt.submissionId);
2406
- if (predecessorIndex < 0 || turnIndex <= predecessorIndex || !["completed", "failed"].includes(readStringField(turns[predecessorIndex], "status") ?? "")) return;
2407
- const previous = dependencies.currentChild();
2408
- if (previous && !previous.terminal && previous.nativeTurnId !== receipt.submissionId) await dependencies.recovery.reconcileRegisteredChild(previous);
2409
- return dependencies.isCurrent() ? turns[turnIndex] : void 0;
2410
- } finally {
2411
- revision.release();
2412
- }
2403
+ const response = await dependencies.client.request("thread/read", {
2404
+ threadId: receipt.childThreadId,
2405
+ includeTurns: true
2406
+ }, { timeoutMs: 3e4 });
2407
+ if (!dependencies.isCurrent()) return;
2408
+ const thread = isJsonObject(response.thread) ? response.thread : void 0;
2409
+ if (readStringField(thread, "id") !== receipt.childThreadId || readThreadParentThreadId(thread) !== dependencies.parentThreadId()) return;
2410
+ const turns = (Array.isArray(thread?.turns) ? thread.turns : []).flatMap((turn) => isJsonObject(turn) ? [turn] : []);
2411
+ const predecessorIndex = turns.findIndex((turn) => readStringField(turn, "id") === receipt.predecessorNativeTurnId);
2412
+ const turnIndex = turns.findIndex((turn) => readStringField(turn, "id") === receipt.submissionId);
2413
+ if (predecessorIndex < 0 || turnIndex <= predecessorIndex || !["completed", "failed"].includes(readStringField(turns[predecessorIndex], "status") ?? "")) return;
2414
+ const previous = dependencies.currentChild();
2415
+ if (previous && !previous.terminal && previous.nativeTurnId !== receipt.submissionId) await dependencies.recovery.reconcileRegisteredChild(previous);
2416
+ return dependencies.isCurrent() ? turns[turnIndex] : void 0;
2413
2417
  }
2414
2418
  //#endregion
2415
2419
  //#region extensions/codex/src/app-server/native-subagent-submission-owner.ts
@@ -2467,11 +2471,17 @@ var CodexNativeSubagentSubmissionOwner = class {
2467
2471
  bind(state, turnId) {
2468
2472
  for (const call of this.calls.get(state)?.values() ?? []) if (call.parentTurnId === turnId && call.submissionId) this.modelInputs.acceptNativeSubmission(state, call);
2469
2473
  }
2470
- restore(state, owner) {
2474
+ async restore(state, owner) {
2475
+ const custody = owner.completionCustody?.retain();
2471
2476
  try {
2472
- for (const receipt of state.submissionStore?.read() ?? []) this.capture(state, receipt, void 0, false, owner.completionCustody);
2477
+ const receipts = await state.submissionStore?.read() ?? [];
2478
+ await state.submissionStore?.assertCurrentAsync();
2479
+ if (this.disposed || !this.isCurrent(state) || custody && !custody.isCurrent()) return;
2480
+ for (const receipt of receipts) this.capture(state, receipt, void 0, false, custody);
2473
2481
  } catch (error) {
2474
2482
  embeddedAgentLog.warn("Cannot recover native follow-up submission receipts", { error: formatErrorMessage$1(error) });
2483
+ } finally {
2484
+ custody?.release();
2475
2485
  }
2476
2486
  }
2477
2487
  observeTurn(threadId, turn) {
@@ -2546,13 +2556,14 @@ var CodexNativeSubagentSubmissionOwner = class {
2546
2556
  entries.set(key, custody);
2547
2557
  this.pending.set(state, entries);
2548
2558
  if (persist) this.dependencies.recordPendingAssignment(state, receipt, this.nativeParentThreadId(state, receipt.childThreadId));
2549
- if (persist && state.submissionStore) custody.recorded = this.track(state, (async () => {
2550
- try {
2559
+ if (persist && state.submissionStore) {
2560
+ custody.recorded = this.track(state, (async () => {
2551
2561
  if (!await state.submissionStore.record(receipt, () => this.dependencies.assertPersistenceCurrent(state))) throw new Error("Native submission binding changed before receipt persistence.");
2552
- } catch (error) {
2562
+ })());
2563
+ custody.recorded.catch((error) => {
2553
2564
  embeddedAgentLog.warn("Accepted native follow-up lost restart protection; retaining local observation", { error: formatErrorMessage$1(error) });
2554
- }
2555
- })());
2565
+ });
2566
+ }
2556
2567
  const observed = this.modelInputs.readObservedSubmissionTurn(state, receipt.childThreadId, receipt.submissionId);
2557
2568
  if (observed) this.promote(state, custody, observed);
2558
2569
  if (custody.phase !== "promoting") this.reconcile(state, custody);
@@ -2567,7 +2578,7 @@ var CodexNativeSubagentSubmissionOwner = class {
2567
2578
  if (custody.phase === "settled" || codexNativeSubagentRunId(custody.receipt.childThreadId, custody.receipt.submissionId) !== child.runId) continue;
2568
2579
  custody.phase = "settled";
2569
2580
  const settlement = (async () => {
2570
- await custody.recorded;
2581
+ await custody.recorded.catch(() => {});
2571
2582
  try {
2572
2583
  if ((child.nativeCompletionDelivered || child.subscriptionClosed && !child.pendingCompletion) && state.submissionStore) await state.submissionStore.consume(custody.receipt, () => this.dependencies.assertPersistenceCurrent(state));
2573
2584
  } catch (error) {
@@ -2579,6 +2590,24 @@ var CodexNativeSubagentSubmissionOwner = class {
2579
2590
  this.track(state, settlement);
2580
2591
  }
2581
2592
  }
2593
+ settleCancelled(state, child, assertCurrent) {
2594
+ const settlement = async () => {
2595
+ const assertAdmission = () => {
2596
+ this.dependencies.assertPersistenceCurrent(state);
2597
+ assertCurrent();
2598
+ };
2599
+ assertAdmission();
2600
+ for (const custody of this.pending.get(state)?.values() ?? []) {
2601
+ if (codexNativeSubagentRunId(custody.receipt.childThreadId, custody.receipt.submissionId) !== child.runId) continue;
2602
+ await custody.recorded;
2603
+ assertAdmission();
2604
+ if (state.submissionStore && !await state.submissionStore.consume(custody.receipt, assertAdmission)) throw new Error("Cancelled native follow-up receipt was not acknowledged.");
2605
+ this.finishCustody(state, custody);
2606
+ assertAdmission();
2607
+ }
2608
+ };
2609
+ return this.track(state, settlement());
2610
+ }
2582
2611
  async reconcile(state, custody) {
2583
2612
  if (!this.isObserving(state, custody)) return;
2584
2613
  try {
@@ -2726,11 +2755,8 @@ function isCodexCommandBearingToolCall(name, args) {
2726
2755
  const normalizedName = name?.trim().toLowerCase();
2727
2756
  return normalizedName === "exec" || normalizedName === "bash" || normalizedName === "shell" || typeof args?.command === "string" && args.command.trim().length > 0;
2728
2757
  }
2729
- function sanitizeCodexAgentEventRecord(value) {
2730
- return sanitizeToolArgs(value);
2731
- }
2732
- function sanitizeCodexToolArguments(value) {
2733
- return isJsonObject(value) ? sanitizeCodexAgentEventRecord(value) : void 0;
2758
+ function asCodexToolArguments(value) {
2759
+ return isJsonObject(value) ? value : void 0;
2734
2760
  }
2735
2761
  //#endregion
2736
2762
  //#region extensions/codex/src/app-server/event-projector-tool-items.ts
@@ -2773,13 +2799,13 @@ function shouldSuppressChannelProgressForItem(item) {
2773
2799
  return isProjectedNativeToolItem(item) || item.type === "dynamicToolCall";
2774
2800
  }
2775
2801
  function itemToolArgs(item) {
2776
- if (item.type === "commandExecution") return sanitizeCodexAgentEventRecord({
2802
+ if (item.type === "commandExecution") return {
2777
2803
  command: item.command,
2778
2804
  ...typeof item.cwd === "string" ? { cwd: item.cwd } : {}
2779
- });
2780
- if (item.type === "fileChange") return sanitizeCodexAgentEventRecord({ changes: itemFileChanges(item, true) });
2805
+ };
2806
+ if (item.type === "fileChange") return { changes: itemFileChanges(item, true) };
2781
2807
  if (item.type === "webSearch") return webSearchToolArgs(item);
2782
- if (item.type === "dynamicToolCall" || item.type === "mcpToolCall") return sanitizeCodexToolArguments(item.arguments);
2808
+ if (item.type === "dynamicToolCall" || item.type === "mcpToolCall") return asCodexToolArguments(item.arguments);
2783
2809
  }
2784
2810
  function isCommandBearingToolItem(item, args) {
2785
2811
  if (item.type === "commandExecution") return true;
@@ -2788,29 +2814,29 @@ function isCommandBearingToolItem(item, args) {
2788
2814
  function webSearchToolArgs(item) {
2789
2815
  const args = projectCodexWebSearchItem(item);
2790
2816
  if (!args.query && !args.url && !args.pattern) args.queryUnavailable = true;
2791
- return sanitizeCodexAgentEventRecord(args);
2817
+ return args;
2792
2818
  }
2793
2819
  function itemToolResult(item) {
2794
- if (item.type === "commandExecution") return sanitizeCodexAgentEventRecord({
2820
+ if (item.type === "commandExecution") return {
2795
2821
  status: item.status,
2796
2822
  exitCode: item.exitCode,
2797
2823
  durationMs: item.durationMs
2798
- });
2799
- if (item.type === "fileChange") return sanitizeCodexAgentEventRecord({
2824
+ };
2825
+ if (item.type === "fileChange") return {
2800
2826
  status: item.status,
2801
2827
  changes: itemFileChanges(item)
2802
- });
2803
- if (item.type === "mcpToolCall") return sanitizeCodexAgentEventRecord({
2828
+ };
2829
+ if (item.type === "mcpToolCall") return {
2804
2830
  status: item.status,
2805
2831
  durationMs: item.durationMs,
2806
2832
  ...item.error ? { error: item.error } : {},
2807
2833
  ...item.result ? { result: item.result } : {}
2808
- });
2809
- if (item.type === "webSearch") return sanitizeCodexAgentEventRecord({
2834
+ };
2835
+ if (item.type === "webSearch") return {
2810
2836
  status: itemStatus(item),
2811
2837
  ...typeof item.durationMs === "number" ? { durationMs: item.durationMs } : {},
2812
2838
  ...webSearchToolArgs(item)
2813
- });
2839
+ };
2814
2840
  }
2815
2841
  function itemFileChangeRecords(item) {
2816
2842
  const changes = item.changes;
@@ -3359,7 +3385,7 @@ var CodexToolTranscriptProjection = class {
3359
3385
  this.recordToolCall({
3360
3386
  id: params.callId,
3361
3387
  name: params.tool,
3362
- arguments: sanitizeCodexToolArguments(params.arguments)
3388
+ arguments: asCodexToolArguments(params.arguments)
3363
3389
  });
3364
3390
  }
3365
3391
  recordDynamicToolResult(params, resultContentSource) {
@@ -4344,9 +4370,12 @@ var Monitor = class {
4344
4370
  this.childStates = /* @__PURE__ */ new Map();
4345
4371
  this.knownChildren = /* @__PURE__ */ new Map();
4346
4372
  this.childThreadIdsByAgentPath = /* @__PURE__ */ new Map();
4373
+ this.cancellationReservations = /* @__PURE__ */ new Map();
4374
+ this.cancellationTurnWaiters = /* @__PURE__ */ new Map();
4347
4375
  this.parentThreadRetentions = /* @__PURE__ */ new Map();
4348
4376
  this.disposed = false;
4349
4377
  this.interruptModelExecution = options.interruptModelExecution;
4378
+ this.interruptChildAndWait = options.interruptChildAndWait;
4350
4379
  this.admissionCustody = new CodexNativeSubagentAdmissionCustody({
4351
4380
  parentState: (id) => this.parentStates.get(id),
4352
4381
  knownChild: (id) => this.knownChildren.get(id),
@@ -4367,7 +4396,7 @@ var Monitor = class {
4367
4396
  captureForget: options.captureChildThreadForget,
4368
4397
  releaseDirectChild: releaseNativeDirectChild,
4369
4398
  clearRecoveryTimers: (child) => this.recovery.clearRecoveryTimers(child),
4370
- markTerminalRevision: (id) => this.recovery.markTerminalRevision(id),
4399
+ markTerminalThread: (id, parentId) => this.recovery.markTerminalThread(id, parentId),
4371
4400
  unregisterChild: (child) => this.unregisterChild(child, { retainSubscription: false }),
4372
4401
  releaseClientRetentionIfIdle: () => this.releaseClientRetentionIfIdle(),
4373
4402
  pruneParent: (state) => this.pruneParentIfUnused(state)
@@ -4402,7 +4431,6 @@ var Monitor = class {
4402
4431
  this.recovery = new CodexNativeSubagentRecoveryCoordinator({
4403
4432
  isDisposed: () => this.disposed,
4404
4433
  isRegisteredChild: (child) => this.childStates.get(child.runId) === child,
4405
- currentChild: (id) => this.currentChild(id),
4406
4434
  parentState: (id) => this.parentStates.get(id),
4407
4435
  reconcileChildState: (child) => this.reconcileChildState(child),
4408
4436
  processCompletion: (state, child, completion, eventAt) => this.processCompletion(state, child, completion, eventAt),
@@ -4474,23 +4502,15 @@ var Monitor = class {
4474
4502
  state.assignmentStore?.assertCurrent();
4475
4503
  },
4476
4504
  isCurrent: (state) => this.isCurrentParent(state),
4477
- readHistory: async (assignment) => {
4478
- const revision = this.recovery.retainThreadStatusRevision(assignment.childThreadId);
4479
- try {
4480
- const history = await this.historyRecovery.read({
4481
- ...assignment,
4482
- nativeTurnId: assignment.nativeTurnId
4483
- }, {
4484
- resumeInterrupted: assignment.recordedCompletion === void 0,
4485
- predecessorNativeTurnId: assignment.submission?.predecessorNativeTurnId,
4486
- recordedCompletion: assignment.recordedCompletion,
4487
- initialAssignment: !readCodexNativeSubagentRunId(assignment.runId)?.turnId
4488
- });
4489
- return revision.isCurrent() ? history : void 0;
4490
- } finally {
4491
- revision.release();
4492
- }
4493
- },
4505
+ readHistory: (assignment) => this.historyRecovery.read({
4506
+ ...assignment,
4507
+ nativeTurnId: assignment.nativeTurnId
4508
+ }, {
4509
+ resumeInterrupted: assignment.recordedCompletion === void 0,
4510
+ predecessorNativeTurnId: assignment.submission?.predecessorNativeTurnId,
4511
+ recordedCompletion: assignment.recordedCompletion,
4512
+ initialAssignment: !readCodexNativeSubagentRunId(assignment.runId)?.turnId
4513
+ }),
4494
4514
  restore: async (state, assignment, recovery, custody) => {
4495
4515
  const existing = this.childStates.get(assignment.runId);
4496
4516
  if (existing) {
@@ -4551,14 +4571,15 @@ var Monitor = class {
4551
4571
  }
4552
4572
  const parents = [...this.parentStates.values()];
4553
4573
  for (const state of parents) notifyNativeModelSourceWaiters(state);
4554
- if (!parents.some((state) => this.assignments.hasWrites(state) || this.submissions.hasCustody(state))) {
4555
- this.finishDisposal();
4556
- return this.disposal = Promise.resolve();
4557
- }
4574
+ const pending = parents.some((state) => this.assignments.hasWrites(state) || this.submissions.hasCustody(state));
4575
+ if (!pending) this.finishDisposal();
4558
4576
  this.disposal = (async () => {
4559
4577
  await Promise.allSettled(parents.flatMap((state) => [this.submissions.drain(state), this.assignments.drain(state)]));
4560
- this.finishDisposal();
4561
- await Promise.allSettled(parents.flatMap((state) => [this.submissions.drain(state), this.assignments.drain(state)]));
4578
+ if (pending) {
4579
+ this.finishDisposal();
4580
+ await Promise.allSettled(parents.flatMap((state) => [this.submissions.drain(state), this.assignments.drain(state)]));
4581
+ }
4582
+ for (const state of parents) if (this.parentStates.get(state.parentThreadId) !== state) state.submissionStore?.release?.();
4562
4583
  })();
4563
4584
  return this.disposal;
4564
4585
  }
@@ -4596,6 +4617,9 @@ var Monitor = class {
4596
4617
  states: this.parentStates,
4597
4618
  isClosed: () => this.disposed,
4598
4619
  isRetired: (state) => this.retiredParentStates.has(state),
4620
+ assertAdmissionCurrent: (input) => {
4621
+ for (const { params: request } of this.cancellationReservations.values()) if (input.agentId === request.agentId && input.requesterSessionKey === request.sessionKey && input.historyOwner?.sessionId === request.sessionId && input.historyOwner?.lifecycleRevision === request.lifecycleRevision && request.acceptsRequest(input.requestCustody)) throw new Error("Codex descendant cancellation is still settling");
4622
+ },
4599
4623
  runtime: this.runtime,
4600
4624
  submissions: this.submissions,
4601
4625
  assignments: this.assignments,
@@ -4604,9 +4628,170 @@ var Monitor = class {
4604
4628
  drainAdmissions: (state, owner, turnId) => this.drainPendingChildAdmissionEvidence(state, owner, turnId, true),
4605
4629
  clearAdmissions: () => this.clearUnconsumablePendingChildAdmissionEvidence(),
4606
4630
  prune: (state) => this.pruneParentIfUnused(state),
4631
+ pendingChildren: (state) => this.listPendingChildren(state),
4607
4632
  interruptModelExecution: this.interruptModelExecution
4608
4633
  });
4609
4634
  }
4635
+ async withDescendantCancellation(params, run) {
4636
+ params.assertCurrent();
4637
+ const parent = this.parentStates.get(params.parentThreadId);
4638
+ if (!parent) return run(async () => ({
4639
+ killed: 0,
4640
+ cancelledRequesters: []
4641
+ }));
4642
+ const matchesOwner = (owner) => owner.requesterAgentId === params.agentId && owner.requesterSessionKey === params.sessionKey && owner.requesterSessionId === params.sessionId && owner.requesterLifecycleRevision === params.lifecycleRevision && params.acceptsRequest(owner.requestCustody);
4643
+ const preparingOwners = /* @__PURE__ */ new Map();
4644
+ for (const state of this.parentStates.values()) if (state.preparing && !state.agentId && !state.historyOwner) {
4645
+ const owner = [...state.pendingRegistrations ?? []].find(matchesOwner);
4646
+ if (owner) preparingOwners.set(state, owner);
4647
+ }
4648
+ const matches = (state) => {
4649
+ if (state.agentId || state.historyOwner) return state.agentId === params.agentId && state.requesterSessionKey === params.sessionKey && state.historyOwner?.sessionId === params.sessionId && state.historyOwner?.lifecycleRevision === params.lifecycleRevision;
4650
+ const owner = preparingOwners.get(state);
4651
+ return Boolean(state.preparing && owner && matchesOwner(owner) && (state.pendingRegistrations?.has(owner) || owner.descendantsCancelled));
4652
+ };
4653
+ if (!matches(parent)) throw new Error("Codex descendant cancellation requester generation changed");
4654
+ const states = [...this.parentStates.values()].filter(matches);
4655
+ const assertCurrent = () => {
4656
+ params.assertCurrent();
4657
+ if (this.disposed || states.some((state) => !this.isCurrentParent(state) || !matches(state) || !this.cancellationReservations.has(state))) throw new Error("Codex descendant cancellation reservation changed");
4658
+ for (const state of states) state.assignmentStore?.assertCurrent();
4659
+ };
4660
+ if (states.some((state) => this.cancellationReservations.has(state))) throw new Error("Codex descendants already have a cancellation owner");
4661
+ const reservation = {
4662
+ params,
4663
+ accepted: false,
4664
+ lateAdmission: false
4665
+ };
4666
+ for (const state of states) this.cancellationReservations.set(state, reservation);
4667
+ let consumed = false;
4668
+ try {
4669
+ const cancellationResult = await run(async () => {
4670
+ assertCurrent();
4671
+ if (consumed) throw new Error("Codex descendant cancellation was already consumed");
4672
+ consumed = true;
4673
+ reservation.accepted = true;
4674
+ const deadline = performance.now() + CODEX_APP_SERVER_INTERRUPT_TIMEOUT_MS;
4675
+ const registrations = states.flatMap((state) => [...state.pendingRegistrations ?? []].filter(matchesOwner));
4676
+ const registrationResults = Promise.allSettled(registrations.map((owner) => waitForNativeCancellationWork(this.client, owner.registrationSettled ?? Promise.reject(/* @__PURE__ */ new Error("Codex pending registration has no settlement owner")), deadline)));
4677
+ const selected = [...this.childStates.values()].filter((child) => child.historyOwner?.sessionId === params.sessionId && child.historyOwner?.lifecycleRevision === params.lifecycleRevision && states.some((state) => state.parentThreadId === child.parentThreadId) && params.acceptsRequest(child.requestCustody));
4678
+ const owners = new Set(states.flatMap((state) => [...state.owners.values(), ...state.pendingRegistrations ?? []]));
4679
+ for (const known of this.knownChildren.values()) if (states.includes(known.parent)) for (const pending of known.pendingTurns) {
4680
+ if (pending.admittedOwner) owners.add(pending.admittedOwner);
4681
+ if (pending.modelSource) owners.add(pending.modelSource.owner);
4682
+ }
4683
+ for (const entries of this.admissionCustody.entries.values()) for (const evidence of entries) if (evidence.kind === "interaction" && states.some((state) => state.parentThreadId === evidence.parentThreadId)) {
4684
+ if (evidence.owner) owners.add(evidence.owner);
4685
+ if (evidence.modelOwner) owners.add(evidence.modelOwner);
4686
+ if (evidence.modelSource) owners.add(evidence.modelSource.owner);
4687
+ }
4688
+ for (const child of selected) {
4689
+ if (child.modelExecution) owners.add(child.modelExecution.owner);
4690
+ if (child.directOwner) owners.add(child.directOwner);
4691
+ }
4692
+ for (const owner of owners) if (matchesOwner(owner)) owner.descendantsCancelled = true;
4693
+ const results = await Promise.allSettled(selected.map(async (child) => {
4694
+ const state = states.find((candidate) => candidate.parentThreadId === child.parentThreadId);
4695
+ if (!state) throw new Error("Codex descendant requester owner changed");
4696
+ let turnId = child.nativeTurnId;
4697
+ const requesterTurnRunId = child.requesterTurnRunId;
4698
+ const requestCustody = child.requestCustody;
4699
+ const assertChild = () => {
4700
+ assertCurrent();
4701
+ if (this.childStates.get(child.runId) !== child || this.currentChild(child.childThreadId) !== child || turnId !== void 0 && child.nativeTurnId !== turnId || child.requesterTurnRunId !== requesterTurnRunId || child.requestCustody !== requestCustody || !params.acceptsRequest(requestCustody) || child.historyOwner?.sessionId !== params.sessionId || child.historyOwner?.lifecycleRevision !== params.lifecycleRevision || child.completionCustody && !child.completionCustody.isCurrent()) throw new Error("Codex descendant assignment changed before cancellation");
4702
+ };
4703
+ assertChild();
4704
+ if (!child.terminal) {
4705
+ child.cancellationRequested = true;
4706
+ if (!turnId) {
4707
+ const observed = createDeferred();
4708
+ this.cancellationTurnWaiters.set(child, () => observed.resolve());
4709
+ try {
4710
+ if (!child.nativeTurnId && !child.terminalHandling) await waitForNativeCancellationWork(this.client, observed.promise, deadline);
4711
+ } finally {
4712
+ this.cancellationTurnWaiters.delete(child);
4713
+ }
4714
+ assertCurrent();
4715
+ if (child.requesterTurnRunId !== requesterTurnRunId) throw new Error("Codex descendant requester changed while awaiting its native turn");
4716
+ turnId = child.nativeTurnId;
4717
+ }
4718
+ if (!child.terminalHandling) {
4719
+ assertChild();
4720
+ if (child.nativeTurnState === "interrupted") child.terminalHandling = this.cancelInterruptedChild(state, child);
4721
+ else {
4722
+ const remaining = deadline - performance.now();
4723
+ if (!turnId || !this.interruptChildAndWait || remaining <= 0) throw new Error("Codex descendant has no exact cancellable native turn");
4724
+ const terminal = await this.interruptChildAndWait(child.childThreadId, turnId, assertChild, remaining);
4725
+ assertCurrent();
4726
+ if (!terminal) throw new Error("Codex descendant interruption did not reach its native terminal");
4727
+ }
4728
+ }
4729
+ const terminalHandling = child.terminalHandling;
4730
+ if (!terminalHandling && !child.terminal) throw new Error("Codex descendant terminal has not reached its completion owner");
4731
+ await terminalHandling;
4732
+ assertCurrent();
4733
+ }
4734
+ await this.completionDelivery.join(child);
4735
+ assertCurrent();
4736
+ const cancelled = child.cancellationRequested && child.pendingCompletion?.status === "cancelled";
4737
+ if (cancelled && this.childStates.get(child.runId) === child) {
4738
+ assertChild();
4739
+ await this.submissions.settleCancelled(state, child, assertChild);
4740
+ assertChild();
4741
+ await this.assignments.settleCancelled(state, child, assertChild);
4742
+ assertChild();
4743
+ this.unregisterChild(child);
4744
+ }
4745
+ if (this.childStates.get(child.runId) === child) throw new Error("Codex descendant completion delivery remains unsettled");
4746
+ if (!cancelled) {
4747
+ await this.assignments.drain(state);
4748
+ await this.submissions.drain(state);
4749
+ assertCurrent();
4750
+ }
4751
+ if (child.requesterTurnRunId !== requesterTurnRunId || child.requestCustody !== requestCustody || child.historyOwner?.sessionId !== params.sessionId || child.historyOwner?.lifecycleRevision !== params.lifecycleRevision) throw new Error("Codex descendant requester changed during settlement");
4752
+ return {
4753
+ killed: cancelled ? 1 : 0,
4754
+ cancelledRequesters: cancelled && requesterTurnRunId ? [{
4755
+ agentId: params.agentId,
4756
+ sessionKey: params.sessionKey,
4757
+ sessionId: params.sessionId,
4758
+ lifecycleRevision: params.lifecycleRevision,
4759
+ requesterTurnRunId
4760
+ }] : []
4761
+ };
4762
+ }));
4763
+ const completedRegistrations = await registrationResults;
4764
+ const failed = [...results, ...completedRegistrations].flatMap((result) => result.status === "rejected" ? [result.reason] : []);
4765
+ try {
4766
+ assertCurrent();
4767
+ } catch (error) {
4768
+ failed.push(error);
4769
+ }
4770
+ const pending = [...this.knownChildren.values()].some((known) => states.includes(known.parent) && known.pendingTurns.some((turn) => {
4771
+ return (turn.modelSource?.owner ?? turn.admittedOwner)?.descendantsCancelled && turn.state !== "completed" && turn.state !== "failed";
4772
+ }));
4773
+ if (reservation.lateAdmission || pending) failed.push(/* @__PURE__ */ new Error("Codex descendant admission remains unsettled after cancellation"));
4774
+ return results.reduce((total, result) => {
4775
+ if (result.status === "fulfilled") {
4776
+ total.killed += result.value.killed;
4777
+ total.cancelledRequesters.push(...result.value.cancelledRequesters);
4778
+ }
4779
+ return total;
4780
+ }, {
4781
+ killed: 0,
4782
+ cancelledRequesters: [],
4783
+ ...failed.length ? { errors: failed } : {}
4784
+ });
4785
+ });
4786
+ assertCurrent();
4787
+ return cancellationResult;
4788
+ } finally {
4789
+ for (const state of states) {
4790
+ this.cancellationReservations.delete(state);
4791
+ this.pruneParentIfUnused(state);
4792
+ }
4793
+ }
4794
+ }
4610
4795
  async captureModelSource(request) {
4611
4796
  const capture = await captureNativeModelSource(request, {
4612
4797
  parents: this.parentStates,
@@ -4648,7 +4833,8 @@ var Monitor = class {
4648
4833
  }
4649
4834
  async persistModelAssignment(request, capture) {
4650
4835
  const known = this.knownChildren.get(request.threadId);
4651
- if (!known?.parent.assignmentStore) return;
4836
+ const store = known?.parent.assignmentStore;
4837
+ if (!known || !store) return;
4652
4838
  const state = known.parent;
4653
4839
  const child = this.currentChild(request.threadId);
4654
4840
  const current = child?.nativeTurnId === request.turnId ? child : void 0;
@@ -4668,6 +4854,7 @@ var Monitor = class {
4668
4854
  nativeParentThreadId: known.nativeParentThreadId,
4669
4855
  owner
4670
4856
  }, assertCurrent);
4857
+ await store.assertCurrentAsync();
4671
4858
  assertCurrent();
4672
4859
  }
4673
4860
  resolveModelThreadId(turnId) {
@@ -4681,7 +4868,6 @@ var Monitor = class {
4681
4868
  knownChildren: this.knownChildren,
4682
4869
  isCurrent: (state) => this.isCurrentParent(state),
4683
4870
  interruptModelExecution: this.interruptModelExecution,
4684
- retainTargetRevision: (threadId) => this.recovery.retainThreadStatusRevision(threadId),
4685
4871
  currentModelExecution: (threadId) => currentNativeModelExecution(threadId, this.parentStates, this.knownChildren, this.childStates),
4686
4872
  admissions: this.admissionCustody.entries,
4687
4873
  canPrepareReceiver: (state, threadId) => this.canPrepareReceiverChild(state, threadId),
@@ -4727,8 +4913,14 @@ var Monitor = class {
4727
4913
  async handleNotification(notification) {
4728
4914
  if (this.disposed) return;
4729
4915
  const params = isJsonObject(notification.params) ? notification.params : void 0;
4730
- const revisedThreadId = readStringField(params, "threadId") ?? (isJsonObject(params?.thread) ? readStringField(params.thread, "id") : void 0);
4731
- if (revisedThreadId && (RECOVERY_REVISION_NOTIFICATION_METHODS.has(notification.method) || notification.method === "thread/closed")) this.recovery.observeRevision(revisedThreadId);
4916
+ const startedThread = isJsonObject(params?.thread) ? params.thread : void 0;
4917
+ const threadId = readStringField(params, "threadId")?.trim() ?? readStringField(startedThread, "id")?.trim();
4918
+ const threadStatus = isJsonObject(params?.status) ? normalizeIdentifier(readStringField(params.status, "type")) : void 0;
4919
+ const loadOwner = threadId ? this.parentStates.get(threadId) ?? this.knownChildren.get(threadId) : void 0;
4920
+ if (loadOwner && (notification.method === "thread/started" || notification.method === "thread/closed" || notification.method === "thread/status/changed" && threadStatus)) {
4921
+ const loaded = notification.method !== "thread/closed" && threadStatus !== "notloaded";
4922
+ if (loadOwner.nativeLoad?.loaded !== loaded) loadOwner.nativeLoad = { loaded };
4923
+ }
4732
4924
  if (notification.method === "thread/closed") {
4733
4925
  const closedThreadId = readStringField(params, "threadId");
4734
4926
  if (closedThreadId) this.releasePendingModelInputs(closedThreadId);
@@ -4753,13 +4945,9 @@ var Monitor = class {
4753
4945
  }
4754
4946
  }
4755
4947
  const notificationState = this.resolveNotificationState(notification);
4756
- const startedThread = isJsonObject(params?.thread) ? params.thread : void 0;
4757
- const threadId = readStringField(params, "threadId")?.trim() ?? readStringField(startedThread, "id")?.trim();
4758
- const threadStatus = isJsonObject(params?.status) ? normalizeIdentifier(readStringField(params.status, "type")) : void 0;
4759
4948
  const parent = threadId ? this.parentStates.get(threadId) : void 0;
4760
4949
  if (parent) observeNativeParentTurn(parent, notification);
4761
- const tracksRecoveryRevision = Boolean(threadId && this.recovery.hasRevision(threadId));
4762
- if (!notificationState && (!threadId || !this.parentStates.has(threadId) && !this.currentChild(threadId) && !tracksRecoveryRevision)) return;
4950
+ if (!notificationState && (!threadId || !this.parentStates.has(threadId) && !this.currentChild(threadId))) return;
4763
4951
  const notificationTurnId = readStringField(params, "turnId") ?? (isJsonObject(params?.turn) ? readStringField(params.turn, "id") : void 0);
4764
4952
  const pendingTurns = threadId ? this.knownChildren.get(threadId)?.pendingTurns : void 0;
4765
4953
  const pendingNativeTurn = pendingTurns?.some((pending) => !notificationTurnId || pending.turnId === notificationTurnId);
@@ -4823,26 +5011,38 @@ var Monitor = class {
4823
5011
  this.recovery.clearRecoveryTimers(childState);
4824
5012
  this.releaseClientRetentionIfIdle();
4825
5013
  }
4826
- async handleChildTurnCompletion(notification, childState) {
4827
- if (notification.method !== "turn/completed") return;
5014
+ handleChildTurnCompletion(notification, childState) {
5015
+ if (notification.method !== "turn/completed") return Promise.resolve();
4828
5016
  const params = isJsonObject(notification.params) ? notification.params : void 0;
4829
5017
  const childThreadId = readStringField(params, "threadId")?.trim();
4830
5018
  const state = childState ? this.parentStates.get(childState.parentThreadId) : void 0;
4831
5019
  const turn = isJsonObject(params?.turn) ? params.turn : void 0;
4832
- if (!state || !childState || childState.childThreadId !== childThreadId || !turn || childState.terminal) return;
5020
+ if (!state || !childState || childState.childThreadId !== childThreadId || !turn || childState.terminal) return Promise.resolve();
5021
+ const turnId = readStringField(turn, "id");
5022
+ if (childState.nativeTurnId && turnId !== childState.nativeTurnId) return Promise.resolve();
5023
+ if (childState.terminalHandling) return childState.terminalHandling;
5024
+ const handling = this.completeChildTurn(state, childState, turn);
5025
+ childState.terminalHandling = handling;
5026
+ this.cancellationTurnWaiters.get(childState)?.();
5027
+ handling.finally(() => {
5028
+ if (childState.terminalHandling === handling && !childState.cancellationRequested) childState.terminalHandling = void 0;
5029
+ }).catch(() => {});
5030
+ return handling;
5031
+ }
5032
+ async completeChildTurn(state, childState, turn) {
4833
5033
  const turnId = readStringField(turn, "id");
4834
- if (childState.nativeTurnId && turnId !== childState.nativeTurnId) return;
4835
5034
  const status = normalizeIdentifier(readStringField(turn, "status"));
4836
5035
  if (status === "interrupted") {
4837
5036
  this.removePendingSpawnAdmissionEvidenceForChild(childState.childThreadId);
4838
5037
  this.rejectPendingDirectChild(state, childState.childThreadId, "Codex child turn interrupted");
4839
- this.settleResumableChild(childState);
5038
+ if (childState.cancellationRequested) await this.cancelInterruptedChild(state, childState);
5039
+ else this.settleResumableChild(childState);
4840
5040
  return;
4841
5041
  }
4842
5042
  if (status === "completed" || status === "failed") {
4843
5043
  const latestTurnId = this.knownChildren.get(childState.childThreadId)?.turnId;
4844
5044
  if (!latestTurnId || latestTurnId === turnId) {
4845
- this.recovery.markTerminalRevision(childState.childThreadId);
5045
+ this.recovery.markTerminalThread(childState.childThreadId, state.parentThreadId);
4846
5046
  this.rejectPendingDirectChild(state, childState.childThreadId, "Codex child turn completed");
4847
5047
  this.removePendingSpawnAdmissionEvidenceForChild(childState.childThreadId);
4848
5048
  }
@@ -4853,6 +5053,14 @@ var Monitor = class {
4853
5053
  if (!completion) return;
4854
5054
  await this.processObservedCompletion(state, childState, completion);
4855
5055
  }
5056
+ cancelInterruptedChild(state, child) {
5057
+ return this.processCompletion(state, child, {
5058
+ childThreadId: child.childThreadId,
5059
+ status: "cancelled",
5060
+ statusLabel: "interrupted",
5061
+ result: "Cancelled by the requester."
5062
+ });
5063
+ }
4856
5064
  async reconcileChildThread(childThreadIdInput) {
4857
5065
  const childState = this.currentChild(childThreadIdInput.trim());
4858
5066
  return childState ? this.recovery.reconcileRegisteredChild(childState) : false;
@@ -4896,45 +5104,40 @@ var Monitor = class {
4896
5104
  async reconcileChildState(childState) {
4897
5105
  const state = this.parentStates.get(childState.parentThreadId);
4898
5106
  if (!state) return false;
4899
- const statusRead = this.recovery.retainThreadStatusRevision(childState.childThreadId);
4900
- try {
4901
- const recovery = await this.historyRecovery.read(childState, {
4902
- resumeInterrupted: !childState.terminal,
4903
- initialAssignment: childState.recoverInitialAssignment,
4904
- recordedCompletion: childState.pendingCompletion
5107
+ const recovery = await this.historyRecovery.read(childState, {
5108
+ resumeInterrupted: !childState.terminal,
5109
+ initialAssignment: childState.recoverInitialAssignment,
5110
+ recordedCompletion: childState.pendingCompletion
5111
+ });
5112
+ if (this.childStates.get(childState.runId) !== childState || !this.isCurrentParent(state)) return false;
5113
+ if (childState.completionCustody && !childState.completionCustody.isCurrent()) {
5114
+ this.unregisterChild(childState);
5115
+ return false;
5116
+ }
5117
+ if (recovery.parentThreadId && recovery.parentThreadId !== childState.nativeParentThreadId) {
5118
+ embeddedAgentLog.warn("Codex native subagent parent did not match monitor state", {
5119
+ childThreadId: childState.childThreadId,
5120
+ expectedParentThreadId: childState.nativeParentThreadId,
5121
+ actualParentThreadId: recovery.parentThreadId
4905
5122
  });
4906
- if (!statusRead.isCurrent() || this.childStates.get(childState.runId) !== childState || !this.isCurrentParent(state)) return false;
4907
- if (childState.completionCustody && !childState.completionCustody.isCurrent()) {
4908
- this.unregisterChild(childState);
4909
- return false;
4910
- }
4911
- if (recovery.parentThreadId && recovery.parentThreadId !== childState.nativeParentThreadId) {
4912
- embeddedAgentLog.warn("Codex native subagent parent did not match monitor state", {
4913
- childThreadId: childState.childThreadId,
4914
- expectedParentThreadId: childState.nativeParentThreadId,
4915
- actualParentThreadId: recovery.parentThreadId
4916
- });
4917
- this.unregisterChild(childState);
4918
- return false;
4919
- }
4920
- if (recovery.agentPath) this.registerAgentPath(state, childState.childThreadId, recovery.agentPath);
4921
- this.recordRecoveredChildTurn(state, childState, recovery);
4922
- if (recovery.threadState === "active") {
4923
- this.observeActiveChild(childState);
4924
- return false;
4925
- }
4926
- if (recovery.threadState === "other") this.recovery.clearSystemErrorFallback(childState);
4927
- if (recovery.resumable) {
4928
- this.settleResumableChild(childState);
4929
- return false;
4930
- }
4931
- const completion = this.processRecoveredCompletion(state, childState, recovery);
4932
- if (!completion) return false;
4933
- await completion;
4934
- return true;
4935
- } finally {
4936
- statusRead.release();
5123
+ this.unregisterChild(childState);
5124
+ return false;
5125
+ }
5126
+ if (recovery.agentPath) this.registerAgentPath(state, childState.childThreadId, recovery.agentPath);
5127
+ this.recordRecoveredChildTurn(state, childState, recovery);
5128
+ if (recovery.threadState === "active") {
5129
+ this.observeActiveChild(childState);
5130
+ return false;
4937
5131
  }
5132
+ if (recovery.threadState === "other") this.recovery.clearSystemErrorFallback(childState);
5133
+ if (recovery.resumable) {
5134
+ this.settleResumableChild(childState);
5135
+ return false;
5136
+ }
5137
+ const completion = this.processRecoveredCompletion(state, childState, recovery);
5138
+ if (!completion) return false;
5139
+ await completion;
5140
+ return true;
4938
5141
  }
4939
5142
  processRecoveredCompletion(state, child, recovery) {
4940
5143
  const completion = recovery.completion;
@@ -4990,7 +5193,7 @@ var Monitor = class {
4990
5193
  ...acceptedCompletion,
4991
5194
  completedAt: eventAt
4992
5195
  };
4993
- this.recovery.markTerminalRevision(childState.childThreadId);
5196
+ this.recovery.markTerminalThread(childState.childThreadId, state.parentThreadId);
4994
5197
  releaseNativeDirectChild(childState);
4995
5198
  this.recovery.clearRecoveryTimers(childState);
4996
5199
  this.completionDelivery.applyReceipts(state, childState.deliveryReceipts.record(childState.runId, this.knownChildren.get(childState.childThreadId)?.agentPaths ?? [childState.childThreadId], acceptedCompletion.result));
@@ -5017,13 +5220,24 @@ var Monitor = class {
5017
5220
  for (const agentPath of known.agentPaths) this.registerAgentPath(state, threadId, agentPath);
5018
5221
  return true;
5019
5222
  }
5223
+ childAdmissionCancelled(state, owner, history = state.historyOwner) {
5224
+ const reservation = this.cancellationReservations.get(state);
5225
+ const requestMatches = reservation?.params.acceptsRequest(owner?.requestCustody) === true;
5226
+ const generationMatches = (owner ? owner.requesterSessionId : history?.sessionId) === reservation?.params.sessionId && (owner ? owner.requesterLifecycleRevision : history?.lifecycleRevision) === reservation?.params.lifecycleRevision;
5227
+ if (owner?.descendantsCancelled || reservation?.accepted && generationMatches && requestMatches) {
5228
+ if (reservation) reservation.lateAdmission = true;
5229
+ return true;
5230
+ }
5231
+ return false;
5232
+ }
5020
5233
  registerChildThread(state, childInput, options = {}) {
5021
5234
  const parentThreadId = state.parentThreadId;
5022
5235
  const preparedAssignment = typeof childInput === "string" ? void 0 : childInput;
5023
5236
  const childThreadId = typeof childInput === "string" ? childInput.trim() : childInput.childThreadId;
5024
5237
  if (!parentThreadId || !childThreadId || this.disposed || state.preparing) return;
5238
+ if (this.childAdmissionCancelled(state, options.directOwner, options.historyOwner)) return;
5025
5239
  const claimDirectChild = options.directOwner?.claimDirectChild;
5026
- if (claimDirectChild && this.recovery.isTerminalRevision(childThreadId)) return;
5240
+ if (claimDirectChild && this.recovery.isTerminalThread(childThreadId)) return;
5027
5241
  if (!preparedAssignment && !this.prepareReceiverChild(state, childThreadId)) return;
5028
5242
  const known = this.knownChildren.get(childThreadId);
5029
5243
  const observedTurns = options.observedTurns ?? [];
@@ -5053,6 +5267,7 @@ var Monitor = class {
5053
5267
  }
5054
5268
  childState = {
5055
5269
  runId,
5270
+ requestCustody: options.directOwner?.requestCustody,
5056
5271
  nativeTurnId: assignment.nativeTurnId,
5057
5272
  nativeTurnState: observedTurns.find((turn) => turn.turnId === assignment.nativeTurnId)?.state,
5058
5273
  deliveryReceipts: this.resolveChildReceiptOwner(state, childThreadId),
@@ -5065,12 +5280,10 @@ var Monitor = class {
5065
5280
  terminal: false,
5066
5281
  nativeCompletionDelivered: false,
5067
5282
  settledWithoutCompletion: false,
5068
- completionDeliveryAttempt: 0,
5069
- deliveringCompletion: false
5283
+ completionDeliveryAttempt: 0
5070
5284
  };
5071
5285
  this.childStates.set(runId, childState);
5072
5286
  if (!known || !known.assignment.nativeTurnId && assignment.nativeTurnId && observedTurns.length > 0) this.restoreKnownChild(state, assignment, observedTurns);
5073
- this.recovery.seedRevision(childThreadId, parentThreadId);
5074
5287
  }
5075
5288
  if (known && options.admitAssignment) {
5076
5289
  const previousRunId = known.assignment.runId;
@@ -5082,6 +5295,8 @@ var Monitor = class {
5082
5295
  }
5083
5296
  if (claimDirectChild && !childState.terminal && !childState.settledWithoutCompletion && !childState.releaseDirectChild) {
5084
5297
  childState.directOwner = options.directOwner;
5298
+ childState.requesterTurnRunId = options.directOwner?.requesterTurnRunId;
5299
+ childState.requestCustody = options.directOwner?.requestCustody;
5085
5300
  childState.releaseDirectChild = claimDirectChild(childThreadId);
5086
5301
  }
5087
5302
  childState.completionCustody ??= (options.completionCustody ?? options.directOwner?.completionCustody)?.retain();
@@ -5133,7 +5348,7 @@ var Monitor = class {
5133
5348
  if (pending) pending.state = "active";
5134
5349
  if (known.observedTurns.has(turnId) && (known.turnId !== turnId || known.assignment.terminal || pending || previous?.nativeTurnState !== void 0)) return false;
5135
5350
  const observedTurn = !known.observedTurns.has(turnId);
5136
- const startsPendingTurn = !pending && (known.pendingTurns.length > 0 || known.assignment.unanchored || !previous || known.assignment.terminal || previous.terminal || previous.nativeTurnState === "completed" || previous.nativeTurnState === "failed" || previous.nativeTurnId && previous.nativeTurnId !== turnId);
5351
+ const startsPendingTurn = !pending && !(previous?.cancellationRequested && !previous.nativeTurnId && !previous.terminal && known.pendingTurns.length === 0) && (known.pendingTurns.length > 0 || known.assignment.unanchored || !previous || known.assignment.terminal || previous.terminal || previous.nativeTurnState === "completed" || previous.nativeTurnState === "failed" || previous.nativeTurnId && previous.nativeTurnId !== turnId);
5137
5352
  if (observedTurn) known.observedTurns.set(turnId, startsPendingTurn ? { awaitingInteraction: true } : {});
5138
5353
  if (startsPendingTurn) {
5139
5354
  const previousPending = known.pendingTurns.at(-1);
@@ -5158,6 +5373,7 @@ var Monitor = class {
5158
5373
  previous.nativeTurnState = "active";
5159
5374
  this.assignments.record(known.parent, previous);
5160
5375
  if (previous.modelExecution && !previous.modelExecution.executionOwner.turnId) previous.modelExecution.bindTurn(turnId);
5376
+ this.cancellationTurnWaiters.get(previous)?.();
5161
5377
  }
5162
5378
  if (observedTurn) this.associatePendingChildInteraction(known, turnId);
5163
5379
  this.admitFollowupChild(known);
@@ -5207,8 +5423,14 @@ var Monitor = class {
5207
5423
  if (child && !child.terminal && !known.assignment.terminal && (recoveredIndex >= 0 || child.nativeTurnState === "interrupted")) {
5208
5424
  let continuationCount = Math.max(1, recoveredIndex + 1);
5209
5425
  if (recoveredIndex < 0) while (continuationCount < known.pendingTurns.length && known.pendingTurns[continuationCount - 1]?.state === "interrupted") continuationCount += 1;
5426
+ const resumed = known.pendingTurns[continuationCount - 1];
5427
+ const resumedOwner = resumed.modelSource?.owner ?? resumed.admittedOwner;
5428
+ if (this.childAdmissionCancelled(known.parent, resumedOwner)) return;
5210
5429
  const continuations = known.pendingTurns.splice(0, continuationCount);
5211
- const resumed = continuations.at(-1);
5430
+ child.requesterTurnRunId = resumedOwner?.requesterTurnRunId;
5431
+ child.requestCustody = resumedOwner?.requestCustody;
5432
+ child.cancellationRequested = void 0;
5433
+ child.terminalHandling = void 0;
5212
5434
  child.completionCustody ??= resumed.completionCustody?.retain();
5213
5435
  continuations.forEach(releaseCompletionCustody);
5214
5436
  if (recoveredIndex < 0) {
@@ -5232,6 +5454,8 @@ var Monitor = class {
5232
5454
  return;
5233
5455
  }
5234
5456
  if (!pending.admittedOwner && !pending.admittedSubmission && !pending.modelSource) return;
5457
+ const pendingOwner = pending.modelSource?.owner ?? pending.admittedOwner;
5458
+ if (this.childAdmissionCancelled(known.parent, pendingOwner)) return;
5235
5459
  const runId = codexNativeSubagentRunId(threadId, pending.turnId);
5236
5460
  child = this.registerChildThread(known.parent, {
5237
5461
  runId,
@@ -5244,6 +5468,8 @@ var Monitor = class {
5244
5468
  if (!child) return;
5245
5469
  child.nativeTurnId = pending.turnId;
5246
5470
  child.nativeTurnState = pending.state;
5471
+ child.requesterTurnRunId = pendingOwner?.requesterTurnRunId;
5472
+ child.requestCustody = pendingOwner?.requestCustody;
5247
5473
  if (pending.modelSource) {
5248
5474
  releaseNativeModelExecution(child);
5249
5475
  child.modelExecution = pending.modelSource;
@@ -5262,6 +5488,9 @@ var Monitor = class {
5262
5488
  const currentInteraction = [...this.admissionCustody.entries.values()].flat().findLast((evidence) => evidence.kind === "interaction" && evidence.parentThreadId === known.parent.parentThreadId && evidence.childThreadId === threadId && !evidence.nativeTurnId && evidence.owner && [...known.parent.owners.values()].includes(evidence.owner));
5263
5489
  if (currentInteraction?.kind === "interaction" && currentInteraction.owner) claimOwner = currentInteraction.owner;
5264
5490
  if (claimOwner && [...known.parent.owners.values()].includes(claimOwner)) {
5491
+ if (this.childAdmissionCancelled(known.parent, claimOwner)) return;
5492
+ child.requesterTurnRunId = claimOwner.requesterTurnRunId;
5493
+ child.requestCustody = claimOwner.requestCustody;
5265
5494
  child.completionCustody ??= claimOwner.completionCustody?.retain();
5266
5495
  if (child.directOwner !== claimOwner) {
5267
5496
  releaseNativeDirectChild(child);
@@ -5326,7 +5555,6 @@ var Monitor = class {
5326
5555
  this.parentThreadRetentions.delete(childState.parentThreadId);
5327
5556
  releaseParentThread?.();
5328
5557
  }
5329
- this.recovery.collectThreadStatusRevision(childState.childThreadId);
5330
5558
  this.releaseClientRetentionIfIdle();
5331
5559
  const state = this.parentStates.get(childState.parentThreadId);
5332
5560
  if (state) {
@@ -5362,8 +5590,25 @@ var Monitor = class {
5362
5590
  requesterParents(source) {
5363
5591
  return [...this.parentStates.values()].filter((state) => state === source || Boolean(source.requesterSessionKey && state.requesterSessionKey === source.requesterSessionKey && state.agentId === source.agentId && source.historyOwner && state.historyOwner && matchesNativeAssignmentLifecycle(source.historyOwner, state.historyOwner)));
5364
5592
  }
5593
+ listPendingChildren(source) {
5594
+ const parentThreadIds = new Set(this.requesterParents(source).filter((state) => state.requesterSessionKey && state.completionScope).map((state) => state.parentThreadId));
5595
+ const pending = [];
5596
+ for (const child of this.childStates.values()) {
5597
+ if (!parentThreadIds.has(child.parentThreadId) || child.settledWithoutCompletion || child.nativeCompletionDelivered || child.terminal && !child.pendingCompletion) continue;
5598
+ const label = [...this.knownChildren.get(child.childThreadId)?.agentPaths ?? []].find((path) => path !== child.childThreadId);
5599
+ pending.push({
5600
+ runId: child.runId,
5601
+ childSessionKey: child.runId,
5602
+ ...label ? { label } : {},
5603
+ state: child.terminal ? "completing" : "running",
5604
+ wakeArmed: false
5605
+ });
5606
+ }
5607
+ return pending;
5608
+ }
5365
5609
  hasParentWork(state) {
5366
- if (state.modelSourceReferences || state.pendingRegistrations && !this.disposed && !this.retiredParentStates.has(state) || this.assignments.hasWrites(state) || this.submissions.hasCustody(state) || state.owners.size > 0 || this.childCloses.hasPending(state) || this.hasChildrenForParent(state.parentThreadId)) return true;
5610
+ if (this.cancellationReservations.has(state)) return true;
5611
+ if (state.modelSourceReferences || state.pendingRegistrations?.size && !this.disposed && !this.retiredParentStates.has(state) || this.assignments.hasWrites(state) || this.submissions.hasCustody(state) || state.owners.size > 0 || this.childCloses.hasPending(state) || this.hasChildrenForParent(state.parentThreadId)) return true;
5367
5612
  for (const known of this.knownChildren.values()) if (known.parent === state && this.currentChild(known.assignment.childThreadId)) return true;
5368
5613
  return false;
5369
5614
  }
@@ -5378,8 +5623,9 @@ var Monitor = class {
5378
5623
  for (const state of states) {
5379
5624
  this.submissions.retire(state);
5380
5625
  this.childCloses.clear(state);
5381
- this.recovery.clearTerminalRevisionsForParent(state.parentThreadId);
5626
+ this.recovery.clearTerminalThreadsForParent(state.parentThreadId);
5382
5627
  this.parentStates.delete(state.parentThreadId);
5628
+ state.submissionStore?.release?.();
5383
5629
  for (const [threadId, known] of this.knownChildren) if (known.parent === state) {
5384
5630
  this.childCloses.retireReceiver(known, () => this.updateChildThreadOwnership("release", threadId, this.releaseChildThread));
5385
5631
  for (const path of known.agentPaths) this.childThreadIdsByAgentPath.delete(buildCodexNativeSubagentAgentPathKey(state.parentThreadId, path));
@@ -5425,4 +5671,4 @@ var Monitor = class {
5425
5671
  };
5426
5672
  const codexNativeSubagentMonitorRuntime = createCodexNativeSubagentMonitorRuntime(Monitor);
5427
5673
  //#endregion
5428
- export { CodexToolTranscriptProjection as a, isCodexCommandBearingToolCall as c, sanitizeCodexToolArguments as d, emitCodexAgentEvent as i, resolveCodexToolProgressDetailMode as l, native_subagent_monitor_exports as n, CodexToolProgressProjection as o, CodexEventProjection as r, shouldEmitTranscriptToolProgress as s, codexNativeSubagentMonitorRuntime as t, sanitizeCodexAgentEventRecord as u };
5674
+ export { CodexToolTranscriptProjection as a, asCodexToolArguments as c, emitCodexAgentEvent as i, isCodexCommandBearingToolCall as l, native_subagent_monitor_exports as n, CodexToolProgressProjection as o, CodexEventProjection as r, shouldEmitTranscriptToolProgress as s, codexNativeSubagentMonitorRuntime as t, resolveCodexToolProgressDetailMode as u };