@openclaw/codex 2026.10.5-beta.4 → 2026.10.10-beta.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +10 -3
- package/dist/.setup/{account-usage-runtime-CoVpNIlD.mjs → account-usage-runtime-DDCDkvtl.mjs} +15 -9
- package/dist/.setup/{app-server-policy-D_zv8J7V.mjs → app-server-policy-Cog6mm2i.mjs} +1 -1
- package/dist/.setup/{apply-BXDMd05l.mjs → apply-BVSXYkTV.mjs} +11 -11
- package/dist/.setup/{attempt-client-cleanup-zNuNTKVr.mjs → attempt-client-cleanup-6OcbMH46.mjs} +14 -8
- package/dist/.setup/attempt-terminal-sZutF0WY.mjs +1 -0
- package/dist/.setup/{attempt-workspace-context-CcwP3DA3.mjs → attempt-workspace-context-GYPLawX6.mjs} +2 -2
- package/dist/.setup/{auth-binding-BaxlhaNx.mjs → auth-binding-830RLAJW.mjs} +2 -2
- package/dist/.setup/{auth-cache-key-f8ODJ_OX.mjs → auth-cache-key-CVcYw8HD.mjs} +92 -80
- package/dist/.setup/{auth-profile-CgHQ8Vot.mjs → auth-profile-auwzSwwy.mjs} +14 -8
- package/dist/.setup/{auth-profile-health-oHizqgye.mjs → auth-profile-health-BVPZU9I8.mjs} +15 -8
- package/dist/.setup/{auth-profile-selection-hr8ocLtz.mjs → auth-profile-selection-Bp5PDk3W.mjs} +24 -7
- package/dist/.setup/{binding-connection-B7HAAZSI.mjs → binding-connection-GTgUj9pi.mjs} +2 -2
- package/dist/.setup/{binding-connection.runtime-DAXn7iFl.mjs → binding-connection.runtime-RcWR3vQu.mjs} +4 -3
- package/dist/.setup/{bounded-turn-isolation-BfDAo-qZ.mjs → bounded-turn-isolation-D8CDrAVX.mjs} +3 -3
- package/dist/.setup/{bounded-turn-DfIJtRlv.mjs → bounded-turn-mN_ekXYW.mjs} +18 -22
- package/dist/.setup/{build-state-Ds14X10-.mjs → build-state-VcujMRqP.mjs} +1 -1
- package/dist/.setup/{capabilities-DbOzOglY.mjs → capabilities-DAS-JX1z.mjs} +1 -1
- package/dist/.setup/{client-D93nbdB8.mjs → client-BS8X7HmG.mjs} +47 -317
- package/dist/.setup/{client-catalog-response-CuVLp4I0.mjs → client-catalog-response-jM38o5w1.mjs} +2 -2
- package/dist/.setup/client-initialize-CjgZcX61.mjs +165 -0
- package/dist/.setup/{command-dispatch-DxdH5a9-.mjs → command-dispatch-DzXbHqCn.mjs} +3 -3
- package/dist/.setup/{command-formatters-xW9KpoSZ.mjs → command-formatters-B_7-QZ1c.mjs} +2 -2
- package/dist/.setup/{command-handlers-fiYvYYq0.mjs → command-handlers-tfb5Uq-O.mjs} +539 -406
- package/dist/.setup/command-rpc-SXqLQukR.mjs +296 -0
- package/dist/.setup/compact-M-JxLcbZ.mjs +823 -0
- package/dist/.setup/{computer-use-DL2v3Kxq.mjs → computer-use-FqQ-Flbl.mjs} +21 -68
- package/dist/.setup/{config-C1YVVLEA.mjs → config-BfrAlTMT.mjs} +3 -3
- package/dist/.setup/{config-options-DDzeNQ8m.mjs → config-options-DMFZkd3X.mjs} +1 -1
- package/dist/.setup/{config-runtime-DWzK-k0n.mjs → config-runtime-BZRizyuG.mjs} +2 -2
- package/dist/.setup/{context-engine-projection-ps-yn_ci.mjs → context-engine-projection-PIeLSnR-.mjs} +16 -30
- package/dist/.setup/{conversation-binding-BieJZRRV.mjs → conversation-binding-C7MZy-Cx.mjs} +228 -116
- package/dist/.setup/{conversation-binding-data-UgLuTSQT.mjs → conversation-binding-data-khgW0n-o.mjs} +4 -2
- package/dist/.setup/{conversation-control-GXM3unE4.mjs → conversation-control-B2EpVZEb.mjs} +53 -23
- package/dist/.setup/{cyber-failover-D4dgNfFf.mjs → cyber-failover-CqEZoQsj.mjs} +1 -1
- package/dist/.setup/{cyber-failover-notice-ljgGGL0s.mjs → cyber-failover-notice-poL3Advd.mjs} +1 -1
- package/dist/.setup/{doctor-start-options-JjTAl-q_.mjs → doctor-start-options-8uIBXIzR.mjs} +8 -5
- package/dist/.setup/{dynamic-tool-build-DcaPmBlE.mjs → dynamic-tool-build-BjFAIG-f.mjs} +208 -218
- package/dist/.setup/{dynamic-tools-CnQFnNKH.mjs → dynamic-tools-XqWsVjcC.mjs} +344 -118
- package/dist/.setup/{effective-mcp-catalog-B5HKFZNK.mjs → effective-mcp-catalog-C3ta5hHc.mjs} +11 -9
- package/dist/.setup/{ephemeral-turn-De3qb8EQ.mjs → ephemeral-turn-1ZF17fUR.mjs} +5 -4
- package/dist/.setup/{event-projector-assistant-message-CLMKN4x-.mjs → event-projector-assistant-message-ChOAY7rW.mjs} +16 -11
- package/dist/.setup/{event-projector-usage-BpKfdoTm.mjs → event-projector-usage-CBY0Hkga.mjs} +2 -2
- package/dist/.setup/{event-projector-values-CLvG1Hil.mjs → event-projector-values-yf4us9Pf.mjs} +1 -1
- package/dist/.setup/experimental-features-uGnVDtp-.mjs +19 -0
- package/dist/.setup/inference-context-mv_dBpAL.mjs +209 -0
- package/dist/.setup/{inference-dispatch-CO6tTs4q.mjs → inference-dispatch-C2zVSnrr.mjs} +2 -2
- package/dist/.setup/{inference-metadata-DCvcG_N_.mjs → inference-metadata-CYFWLHVk.mjs} +3 -1
- package/dist/.setup/{inference-proxy-BDWV0djM.mjs → inference-proxy-yd3hr2dr.mjs} +8 -8
- package/dist/.setup/installed-probe-lVC1X5ve.mjs +185 -0
- package/dist/.setup/{isolated-completion-BPJdvk5F.mjs → isolated-completion-P-r8NRE4.mjs} +7 -7
- package/dist/.setup/managed-binary-DbKvGXKl.mjs +395 -0
- package/dist/.setup/{mcp-app-session-preparation-Dz2GOwyE.mjs → mcp-app-session-preparation-fnsnCovu.mjs} +18 -14
- package/dist/.setup/{model-catalog-ZNwltCKl.mjs → model-catalog-Y_esgRPY.mjs} +28 -17
- package/dist/.setup/{models-BHpbAuz8.mjs → models-BWLEUo2E.mjs} +3 -3
- package/dist/.setup/{native-auth-esN5MdIv.mjs → native-auth-DpZIaY8N.mjs} +7 -4
- package/dist/.setup/native-execution-policy-D09tLP-u.mjs +152 -0
- package/dist/.setup/{native-hook-relay-wq7jrNLk.mjs → native-hook-relay-C7aaLJaP.mjs} +45 -10
- package/dist/.setup/{native-mcp-app-DX3nyTtc.mjs → native-mcp-app-CsWj-v_x.mjs} +5 -5
- package/dist/.setup/{native-skill-isolation-DSBeF-Yy.mjs → native-skill-isolation-CMimsKYy.mjs} +7 -7
- package/dist/.setup/{native-subagent-monitor-DOLEIf9r.mjs → native-subagent-monitor-CFE7b4oC.mjs} +485 -239
- package/dist/.setup/{native-subagent-pending-assignments-DmVhedNs.mjs → native-subagent-pending-assignments-CTinVtjo.mjs} +1 -1
- package/dist/.setup/{native-task-assignments-DimsQ9Qa.mjs → native-task-assignments-YJopbaVO.mjs} +9 -5
- package/dist/.setup/{node-cli-sessions-CzKg2nGq.mjs → node-cli-sessions-BuJnBnEq.mjs} +7 -4
- package/dist/.setup/{node-exec-server.runtime-BWkULhBM.mjs → node-exec-server.runtime-CP7RC1Nd.mjs} +3 -3
- package/dist/.setup/{plan-41-YOBMq.mjs → plan-B4cHgqNv.mjs} +7 -20
- package/dist/.setup/{plugin-activation-D7WkJMvU.mjs → plugin-activation-CXPWe-hl.mjs} +4 -4
- package/dist/.setup/{plugin-app-cache-key-Bg9DbDI6.mjs → plugin-app-cache-key-DRb-niJc.mjs} +17 -55
- package/dist/.setup/{plugin-approval-roundtrip-CD88q3yx.mjs → plugin-approval-roundtrip-DIZHLbAM.mjs} +1 -1
- package/dist/.setup/{plugin-inventory-CYgdo14P.mjs → plugin-inventory-DE9wcaeH.mjs} +2 -2
- package/dist/.setup/{plugin-metadata-cache-Bi8TAPwX.mjs → plugin-metadata-cache-BqC-a6Fb.mjs} +2 -15
- package/dist/.setup/{project-doc-thread-config-BVcvnps8.mjs → project-doc-thread-config-B0UI3f1D.mjs} +6 -6
- package/dist/.setup/protocol-CaPAVwe9.mjs +12 -0
- package/dist/.setup/{provider-capabilities-Dn2WwH4P.mjs → provider-capabilities-DjcKunHS.mjs} +1 -1
- package/dist/.setup/{provider-LWKll6dV.mjs → provider-wj_LFJH3.mjs} +4 -4
- package/dist/.setup/{rate-limits-CI8pTPqL.mjs → rate-limits-BpfURnuy.mjs} +1 -1
- package/dist/.setup/{request-Bo0kKABI.mjs → request-ePeNJrOd.mjs} +132 -136
- package/dist/.setup/{responses-oauth-twnuTaAa.mjs → responses-oauth-CCV7aVYF.mjs} +6 -6
- package/dist/.setup/{rpc-error-C98SHchT.mjs → rpc-error-DemqqaxE.mjs} +7 -3
- package/dist/.setup/{run-attempt-ClU8MxhZ.mjs → run-attempt-BcWArowv.mjs} +595 -426
- package/dist/.setup/{run-attempt-lifecycle-KN4oh-7O.mjs → run-attempt-lifecycle-DN-ATDp9.mjs} +1 -1
- package/dist/.setup/{runtime-artifact-C13pR7tD.mjs → runtime-artifact-CmLWeyJB.mjs} +3 -3
- package/dist/.setup/{runtime-artifact-connection-jS5DeCok.mjs → runtime-artifact-connection-DpWlZ02e.mjs} +3 -3
- package/dist/.setup/{sandbox-guard-DIImwCy1.mjs → sandbox-guard-DneAfNye.mjs} +70 -30
- package/dist/.setup/{session-binding-JEHNMPsr.mjs → session-binding-BgsWcbdY.mjs} +25 -23
- package/dist/.setup/{session-binding-record-DU_0biMD.mjs → session-binding-record-C_THntMe.mjs} +27 -12
- package/dist/.setup/{session-binding-record-codec-BpH8u_G9.mjs → session-binding-record-codec-DvmOI7g_.mjs} +1 -0
- package/dist/.setup/{session-binding-sidecars-DD-enC8w.mjs → session-binding-sidecars-BNSS6WL4.mjs} +55 -63
- package/dist/.setup/session-cancellation-DLBSJO5n.mjs +43 -0
- package/dist/.setup/{session-catalog-adoption-Ca3OYGYM.mjs → session-catalog-adoption-ppsLlVLB.mjs} +24 -38
- package/dist/.setup/{session-catalog-archive-Bv6gV7x9.mjs → session-catalog-archive-CqLRHJ6z.mjs} +11 -13
- package/dist/.setup/{session-catalog-events-kR2Ot6nX.mjs → session-catalog-events-DK0opVp3.mjs} +5 -5
- package/dist/.setup/{session-catalog-index-CrnfVEnT.mjs → session-catalog-index-BfzfdtH7.mjs} +96 -271
- package/dist/.setup/{session-catalog-index-order-CTfoefow.mjs → session-catalog-index-order-0Zqng2u8.mjs} +1 -1
- package/dist/.setup/{session-catalog-limits-BynIoOYm.mjs → session-catalog-limits-Dc6E0BZz.mjs} +1 -1
- package/dist/.setup/{session-catalog-list-request-D4MYNgDB.mjs → session-catalog-list-request-CAjoWjaH.mjs} +3 -4
- package/dist/.setup/{session-catalog-native-projection-CWqCU1I_.mjs → session-catalog-native-projection-G3lSDYYG.mjs} +5 -5
- package/dist/.setup/{session-catalog-node-adoption-BdP9Zjqo.mjs → session-catalog-node-adoption-e9v8mGgx.mjs} +5 -5
- package/dist/.setup/{session-catalog-node-continue-CNJibO4_.mjs → session-catalog-node-continue-H7nrzcUD.mjs} +5 -5
- package/dist/.setup/{session-catalog-node-lookup-BH_DBGa9.mjs → session-catalog-node-lookup-BrZfDkA8.mjs} +2 -2
- package/dist/.setup/{session-catalog-parsing-DkeoVn60.mjs → session-catalog-parsing-V6jyFg9g.mjs} +2 -2
- package/dist/.setup/{session-catalog-projection-BzHiV818.mjs → session-catalog-projection-BjWE414G.mjs} +8 -7
- package/dist/.setup/{session-catalog-provenance-CmsOE5mh.mjs → session-catalog-provenance-Dg9s12z-.mjs} +50 -30
- package/dist/.setup/{session-catalog-source-DGuRdGvM.mjs → session-catalog-source-DqyuNxCe.mjs} +2 -6
- package/dist/.setup/{session-cli-GwU0izn-.mjs → session-cli-CBGKiqdv.mjs} +1 -1
- package/dist/.setup/{session-history-BO6i_pfk.mjs → session-history-7W0cgTXF.mjs} +11 -9
- package/dist/.setup/{session-history-import-CaO8s6ta.mjs → session-history-import-BwPKwcNi.mjs} +4 -4
- package/dist/.setup/{session-initialization-Bi_2DKhc.mjs → session-initialization-Dn3vveGv.mjs} +2 -2
- package/dist/.setup/{session-retirement-B3U5hpGJ.mjs → session-retirement-Ci_JvOfH.mjs} +8 -8
- package/dist/.setup/{session-history.worker-DJQfek5p.mjs → settled-turn-evidence--tRW6fSm.mjs} +2 -18
- package/dist/.setup/{settled-turn-finalizer-CYCVpTv2.mjs → settled-turn-finalizer-D3-KXsbP.mjs} +8 -8
- package/dist/.setup/{shared-client-BCx1wbyA.mjs → shared-client-CE_uY0A1.mjs} +380 -557
- package/dist/.setup/side-question-OM18H9WJ.mjs +998 -0
- package/dist/.setup/{source-DipMO9hL.mjs → source-uGKgKWm8.mjs} +5 -5
- package/dist/.setup/{thread-archive-guard-LKdwQKyr.mjs → thread-archive-guard-BWjSsA92.mjs} +1 -1
- package/dist/.setup/{thread-lifecycle-run-C_aYiYqk.mjs → thread-lifecycle-run-mLueY6pH.mjs} +172 -75
- package/dist/.setup/{thread-model-selection-DcVebr8N.mjs → thread-model-selection-DxposL4X.mjs} +9 -9
- package/dist/.setup/{thread-ownership-BoUd0i6L.mjs → thread-ownership-t6Y9fLQS.mjs} +7 -7
- package/dist/.setup/{thread-policy-B3wBRNph.mjs → thread-policy-Cy301Or8.mjs} +6 -6
- package/dist/.setup/{thread-requests-BgzJwJtS.mjs → thread-requests-BjawdIVV.mjs} +14 -14
- package/dist/.setup/{thread-resume-D-3bsr1j.mjs → thread-resume-BUbsUfgF.mjs} +6 -6
- package/dist/.setup/{transcript-history-projection-DfKcoZCB.mjs → transcript-history-projection-i-FVpyha.mjs} +1 -1
- package/dist/.setup/{transcript-mirror-Bee2o6jj.mjs → transcript-mirror-CEQJZlF3.mjs} +6 -9
- package/dist/.setup/{transport-stdio-CRWTkKOn.mjs → transport-stdio-Bq160Dhv.mjs} +63 -64
- package/dist/.setup/{transport-websocket-DIyPfkHo.mjs → transport-websocket-0YqiI_MH.mjs} +1 -1
- package/dist/.setup/{turn-router-DBVMToGo.mjs → turn-router-Dbw17k3K.mjs} +2 -2
- package/dist/.setup/{upstream-session-fork-p5fwKi7w.mjs → upstream-session-fork-_LYkh0nZ.mjs} +46 -219
- package/dist/.setup/{usage-limit-error-BQX8RHAd.mjs → usage-limit-error-DcOSH3J4.mjs} +4 -4
- package/dist/.setup/{usage-C2Kq7oej.mjs → usage-w_93wnnR.mjs} +4 -4
- package/dist/.setup/{web-search-item-CvokaZOo.mjs → web-search-item-DHVuNSqk.mjs} +1 -1
- package/dist/.setup/{web-search-provider.runtime-D89djc7e.mjs → web-search-provider.runtime-DMHxve5v.mjs} +3 -3
- package/dist/.setup/{workspace-write-sandbox-probe-BDWO2Qkh.mjs → workspace-write-sandbox-probe-DJxOXcF3.mjs} +2 -2
- package/dist/api.js +7 -28
- package/dist/catalog-page.worker.js +1 -1
- package/dist/cli-metadata.js +1 -1
- package/dist/client-version-api.js +25 -0
- package/dist/doctor-contract-api.js +5 -5
- package/dist/harness.js +59 -36
- package/dist/index.js +259 -295
- package/dist/media-understanding-provider.js +2 -2
- package/dist/migration-provider-api.js +1 -2
- package/dist/native-session-binding-api.js +1 -2
- package/dist/provider-discovery.js +1 -1
- package/dist/session-history-worker-entrypoint.js +12 -0
- package/dist/session-history-worker-runtime.js +7 -18
- package/dist/session-history.worker.js +18 -2
- package/openclaw.plugin.json +1 -1
- package/package.json +6 -6
- package/dist/.setup/attempt-terminal-jO5IMj9K.mjs +0 -2
- package/dist/.setup/command-rpc-HIvsy3wS.mjs +0 -247
- package/dist/.setup/compact-ClZ7Ar7L.mjs +0 -808
- package/dist/.setup/inference-context-DNlGwzwy.mjs +0 -91
- package/dist/.setup/managed-binary-BtIjV7yN.mjs +0 -175
- package/dist/.setup/native-execution-policy-MXEe7PB3.mjs +0 -75
- package/dist/.setup/protocol-CANUwXJ3.mjs +0 -17
- package/dist/.setup/side-question-Bz2UQW0l.mjs +0 -826
package/dist/.setup/{native-subagent-monitor-DOLEIf9r.mjs → native-subagent-monitor-CFE7b4oC.mjs}
RENAMED
|
@@ -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-
|
|
2
|
-
import {
|
|
3
|
-
import { n as defineCodexBuildState } from "./build-state-
|
|
4
|
-
import { a as readHookOutputEntries, o as readItem, s as readNullableString } from "./event-projector-values-
|
|
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-VcujMRqP.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-
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
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-
|
|
10
|
-
import { s as interruptCodexTurnAndWaitBestEffort } from "./attempt-client-cleanup-
|
|
11
|
-
import { t as projectCodexWebSearchItem } from "./web-search-item-
|
|
12
|
-
import { n as codexApprovalTimeoutText } from "./plugin-approval-roundtrip-
|
|
6
|
+
import { t as readCodexMirroredSessionHistoryMessages } from "./session-history-7W0cgTXF.mjs";
|
|
7
|
+
import { A as hasCodexAppServerLiveThread, B as retainCodexAppServerLiveThread, E as claimCodexAppServerLiveThread } from "./shared-client-CE_uY0A1.mjs";
|
|
8
|
+
import { j as readCodexAppServerWarningMessage } from "./client-BS8X7HmG.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-Dbw17k3K.mjs";
|
|
10
|
+
import { s as interruptCodexTurnAndWaitBestEffort, t as CODEX_APP_SERVER_INTERRUPT_TIMEOUT_MS } from "./attempt-client-cleanup-6OcbMH46.mjs";
|
|
11
|
+
import { t as projectCodexWebSearchItem } from "./web-search-item-DHVuNSqk.mjs";
|
|
12
|
+
import { n as codexApprovalTimeoutText } from "./plugin-approval-roundtrip-DIZHLbAM.mjs";
|
|
13
13
|
import { t as resolveCodexLocalRuntimeAttribution } from "./local-runtime-attribution-CZz2DJ4q.mjs";
|
|
14
|
-
import { t as __exportAll } from "./session-binding-sidecars-
|
|
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 {
|
|
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.
|
|
630
|
-
|
|
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.
|
|
729
|
+
this.terminalThreads = /* @__PURE__ */ new Map();
|
|
687
730
|
this.recoveryPollDelaysMs = dependencies.recoveryPollDelaysMs ?? DEFAULT_RECOVERY_POLL_DELAYS_MS;
|
|
688
731
|
}
|
|
689
|
-
|
|
690
|
-
return this.
|
|
732
|
+
isTerminalThread(threadId) {
|
|
733
|
+
return this.terminalThreads.has(threadId);
|
|
691
734
|
}
|
|
692
|
-
|
|
693
|
-
|
|
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
|
-
|
|
746
|
+
childState.recoveryInFlight = void 0;
|
|
719
747
|
}
|
|
720
748
|
}
|
|
721
|
-
|
|
722
|
-
for (const [threadId,
|
|
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.
|
|
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.
|
|
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.
|
|
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
|
-
|
|
903
|
-
|
|
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 (
|
|
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
|
-
|
|
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.
|
|
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
|
|
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 (
|
|
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
|
|
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
|
|
2395
|
-
|
|
2396
|
-
|
|
2397
|
-
|
|
2398
|
-
|
|
2399
|
-
|
|
2400
|
-
|
|
2401
|
-
|
|
2402
|
-
|
|
2403
|
-
|
|
2404
|
-
|
|
2405
|
-
|
|
2406
|
-
|
|
2407
|
-
|
|
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
|
-
|
|
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)
|
|
2550
|
-
|
|
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
|
-
}
|
|
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
|
|
2730
|
-
return
|
|
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
|
|
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
|
|
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
|
|
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
|
|
2817
|
+
return args;
|
|
2792
2818
|
}
|
|
2793
2819
|
function itemToolResult(item) {
|
|
2794
|
-
if (item.type === "commandExecution") return
|
|
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
|
|
2824
|
+
};
|
|
2825
|
+
if (item.type === "fileChange") return {
|
|
2800
2826
|
status: item.status,
|
|
2801
2827
|
changes: itemFileChanges(item)
|
|
2802
|
-
}
|
|
2803
|
-
if (item.type === "mcpToolCall") return
|
|
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
|
|
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:
|
|
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
|
-
|
|
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:
|
|
4478
|
-
|
|
4479
|
-
|
|
4480
|
-
|
|
4481
|
-
|
|
4482
|
-
|
|
4483
|
-
|
|
4484
|
-
|
|
4485
|
-
|
|
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
|
-
|
|
4555
|
-
|
|
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
|
-
|
|
4561
|
-
|
|
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
|
-
|
|
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
|
|
4731
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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.
|
|
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.
|
|
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
|
|
4900
|
-
|
|
4901
|
-
|
|
4902
|
-
|
|
4903
|
-
|
|
4904
|
-
|
|
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
|
-
|
|
4907
|
-
|
|
4908
|
-
|
|
4909
|
-
|
|
4910
|
-
|
|
4911
|
-
|
|
4912
|
-
|
|
4913
|
-
|
|
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.
|
|
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.
|
|
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
|
-
|
|
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 (
|
|
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.
|
|
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,
|
|
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 };
|