@openclaw/codex 2026.9.6 → 2026.9.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -0
- package/assets/icon.png +0 -0
- package/dist/.setup/{account-usage-runtime-Eem_WGqY.mjs → account-usage-runtime-DFhbh1zz.mjs} +5 -5
- package/dist/.setup/{apply-DDOi8uNx.mjs → apply-D3GcSoSa.mjs} +22 -36
- package/dist/.setup/{attempt-client-cleanup-CEv1cKwF.mjs → attempt-client-cleanup-DOP-cW5j.mjs} +128 -37
- package/dist/.setup/attempt-workspace-context-C5HigshI.mjs +164 -0
- package/dist/.setup/{auth-binding-DhLWa_7K.mjs → auth-binding-BLWz7stm.mjs} +14 -1
- package/dist/.setup/{auth-cache-key-B2mpaI9D.mjs → auth-cache-key-Dbvq-QgB.mjs} +36 -34
- package/dist/.setup/{auth-profile-WqZtZfXN.mjs → auth-profile-B0okYl2D.mjs} +1 -2
- package/dist/.setup/auth-start-options-BPIPeEX8.mjs +44 -0
- package/dist/.setup/{binding-connection-ThoatDcb.mjs → binding-connection-DTtN1KrX.mjs} +2 -2
- package/dist/.setup/{binding-connection.runtime-yoHrABt-.mjs → binding-connection.runtime-6TpgD1M6.mjs} +4 -4
- package/dist/.setup/{bounded-turn-B2HScEgT.mjs → bounded-turn-CbjoN2OW.mjs} +15 -18
- package/dist/.setup/bounded-turn-isolation-B8K_ylqk.mjs +14 -0
- package/dist/.setup/{build-state-C7EnDVgr.mjs → build-state-Da1_z0kd.mjs} +1 -1
- package/dist/.setup/{capabilities-CDXOOFdZ.mjs → capabilities-B3WEZl4e.mjs} +2 -10
- package/dist/.setup/{client-Cs08OXVQ.mjs → client-N0JpgSzF.mjs} +138 -399
- package/dist/.setup/{client-catalog-response-BMgt_4q4.mjs → client-catalog-response-5HHLdcde.mjs} +1 -1
- package/dist/.setup/{command-dispatch-B4JuOsOk.mjs → command-dispatch-BeAoaovI.mjs} +5 -8
- package/dist/.setup/{command-formatters-Bmqvr9tO.mjs → command-formatters-R3ckE3Co.mjs} +29 -61
- package/dist/.setup/{command-handlers-DW7Lx9oH.mjs → command-handlers-ylTMS00z.mjs} +222 -343
- package/dist/.setup/{command-rpc-DixIj3HW.mjs → command-rpc-CGJGUQ6Y.mjs} +15 -18
- package/dist/.setup/compact-C2WamavS.mjs +776 -0
- package/dist/.setup/{config-BoTP_mrL.mjs → config-DKhXquav.mjs} +26 -28
- package/dist/.setup/{config-options-BvaRs51b.mjs → config-options-CzyWLTJt.mjs} +24 -37
- package/dist/.setup/{config-parsing-CcB9iPoq.mjs → config-parsing-b088LyhT.mjs} +57 -60
- package/dist/.setup/{config-runtime-C8Rw1m1m.mjs → config-runtime-C0NbLms1.mjs} +2 -2
- package/dist/.setup/{config-security-BEReZ6go.mjs → config-security-CE-FcGw9.mjs} +32 -111
- package/dist/.setup/{config-utils-DujwEnhg.mjs → config-utils-D0CXecki.mjs} +3 -13
- package/dist/.setup/context-engine-projection-PezSESth.mjs +387 -0
- package/dist/.setup/{conversation-binding-DP-gMrBP.mjs → conversation-binding-3Min8qvP.mjs} +67 -90
- package/dist/.setup/{conversation-binding-data-CrcyZk6O.mjs → conversation-binding-data-C746z5Pn.mjs} +8 -12
- package/dist/.setup/{conversation-control-uK9Jomlc.mjs → conversation-control-CEP8X5JC.mjs} +8 -8
- package/dist/.setup/{cyber-failover-DYwbmf1o.mjs → cyber-failover-XV0nNRZu.mjs} +1 -1
- package/dist/.setup/{cyber-failover-notice-e9G3J9-e.mjs → cyber-failover-notice-RNpGpTyP.mjs} +1 -1
- package/dist/.setup/{dynamic-tools-BDXl-8Cw.mjs → dynamic-tools-DzlsLUuS.mjs} +2305 -2606
- package/dist/.setup/{effective-mcp-catalog-CvnvnGIe.mjs → effective-mcp-catalog-CxUtC-xG.mjs} +8 -17
- package/dist/.setup/{ephemeral-turn-poidXgek.mjs → ephemeral-turn-CDsPJOa2.mjs} +3 -3
- package/dist/.setup/event-projector-assistant-message-CigreO4K.mjs +69 -0
- package/dist/.setup/{event-projector-usage-CnBS8Wa3.mjs → event-projector-usage-03R0I2dM.mjs} +3 -25
- package/dist/.setup/event-projector-values-DJSz8BTk.mjs +106 -0
- package/dist/.setup/incognito-session-DWYapfwf.mjs +2 -0
- package/dist/.setup/{inference-context-D96l9-ew.mjs → inference-context-D-9gWlTR.mjs} +16 -18
- package/dist/.setup/inference-dispatch-CMZtjQyz.mjs +359 -0
- package/dist/.setup/inference-metadata-CgIf7sOx.mjs +81 -0
- package/dist/.setup/{inference-proxy-b-aJMSxm.mjs → inference-proxy-DhcXOgUE.mjs} +174 -214
- package/dist/.setup/{isolated-completion-BIZFhTNG.mjs → isolated-completion-Dm3PzxJk.mjs} +9 -12
- package/dist/.setup/{managed-binary-BnshlFag.mjs → managed-binary-kiWRhNRE.mjs} +8 -12
- package/dist/.setup/{model-catalog-CfXJf9Ay.mjs → model-catalog-PAuZgJC6.mjs} +11 -10
- package/dist/.setup/model-runtime-BdqzOMkU.mjs +11 -0
- package/dist/.setup/{models-KnqBv0hE.mjs → models-DHXZtVVk.mjs} +9 -18
- package/dist/.setup/{native-auth-rWbGbMn3.mjs → native-auth-CuG53tu4.mjs} +4 -4
- package/dist/.setup/{native-execution-policy-umd0tgh4.mjs → native-execution-policy-BxZJy5mP.mjs} +5 -30
- package/dist/.setup/{native-subagent-monitor-D3filLY2.mjs → native-subagent-monitor-Dpsmf2wz.mjs} +4395 -3609
- package/dist/.setup/native-subagent-pending-assignments-DwkCzLvD.mjs +203 -0
- package/dist/.setup/native-task-assignments-DMQ0g3hu.mjs +194 -0
- package/dist/.setup/{node-cli-sessions-r3avj02l.mjs → node-cli-sessions-HC4W6FLI.mjs} +19 -49
- package/dist/.setup/{node-exec-server.runtime-BDwWXVpK.mjs → node-exec-server.runtime-BgBfWQqo.mjs} +3 -6
- package/dist/.setup/{plan-CN3VwfNU.mjs → plan-Y-QIvrKB.mjs} +49 -92
- package/dist/.setup/{plugin-activation-DT3MNtqj.mjs → plugin-activation-cNHRfaxU.mjs} +8 -36
- package/dist/.setup/{plugin-app-cache-key-B2CsSdnV.mjs → plugin-app-cache-key-BL9B5H0L.mjs} +6 -23
- package/dist/.setup/{plugin-inventory-BoRei8Z4.mjs → plugin-inventory-Cky2XJUw.mjs} +21 -21
- package/dist/.setup/{plugin-marketplace-discovery-CDOi8IFs.mjs → plugin-marketplace-discovery-D_dV9FXa.mjs} +18 -24
- package/dist/.setup/{plugin-metadata-cache-Ctmo83k_.mjs → plugin-metadata-cache-DsjsL1dr.mjs} +115 -175
- package/dist/.setup/{provider-BOsxQHOM.mjs → provider-DH8NSzGt.mjs} +11 -14
- package/dist/.setup/{provider-capabilities-BfE88FZ5.mjs → provider-capabilities-CAxoF-X1.mjs} +13 -18
- package/dist/.setup/{rate-limits-CMU3DUD0.mjs → rate-limits-B7-X2TgG.mjs} +9 -31
- package/dist/.setup/{request-D2L0zMrq.mjs → request-BHZ1nz8d.mjs} +7 -6
- package/dist/.setup/responses-oauth-twnuTaAa.mjs +93 -0
- package/dist/.setup/rpc-error-BlD2vuzn.mjs +31 -0
- package/dist/.setup/{run-attempt-BHu11r7h.mjs → run-attempt-D8RZUOzY.mjs} +1035 -1023
- package/dist/.setup/{run-attempt-lifecycle-B7JbY4-F.mjs → run-attempt-lifecycle-C-6O3Exn.mjs} +10 -24
- package/dist/.setup/{runtime-artifact-CLZ8udh-.mjs → runtime-artifact-DDQ-HGXf.mjs} +16 -4
- package/dist/.setup/runtime-artifact-connection-D68qQn1m.mjs +78 -0
- package/dist/.setup/sandbox-guard-DjCz2eOw.mjs +126 -0
- package/dist/.setup/scope-DOC1Xjc8.mjs +6 -0
- package/dist/.setup/session-binding-DGCYAfvD.mjs +443 -0
- package/dist/.setup/{session-binding-record-BGoz8wOK.mjs → session-binding-record-Oe9L-CNY.mjs} +52 -130
- package/dist/.setup/{session-binding-sidecars-BlB5EvIS.mjs → session-binding-sidecars-jo6H8dFr.mjs} +196 -17
- package/dist/.setup/{session-catalog-Pno1xGcl.mjs → session-catalog-4sCdv5qx.mjs} +170 -324
- package/dist/.setup/{session-catalog-adoption-BI6UTDZT.mjs → session-catalog-adoption-BU_pHWG7.mjs} +7 -6
- package/dist/.setup/{session-catalog-archive-lHBqzhaO.mjs → session-catalog-archive-spHfihri.mjs} +6 -6
- package/dist/.setup/session-catalog-events-DePDzzjc.mjs +139 -0
- package/dist/.setup/session-catalog-home-id-vlih0B_g.mjs +22 -0
- package/dist/.setup/{session-catalog-index-B9_VQIUz.mjs → session-catalog-index-CZvDzC6z.mjs} +126 -122
- package/dist/.setup/{session-catalog-index-order-hcdz07yN.mjs → session-catalog-index-order-BcQpHks3.mjs} +1 -1
- package/dist/.setup/{session-catalog-index-state-Dgh8ORJm.mjs → session-catalog-index-state-TeO7EyO-.mjs} +3 -2
- package/dist/.setup/session-catalog-limits-DDxOsQeC.mjs +14 -0
- package/dist/.setup/session-catalog-list-request-CvtxrYSe.mjs +170 -0
- package/dist/.setup/session-catalog-native-projection-DjhwGL6x.mjs +178 -0
- package/dist/.setup/{session-catalog-node-adoption-ITddWx_X.mjs → session-catalog-node-adoption-DgXvSGu0.mjs} +10 -27
- package/dist/.setup/{session-catalog-node-continue-6g6qi4A9.mjs → session-catalog-node-continue-DjKXHBbi.mjs} +8 -10
- package/dist/.setup/session-catalog-node-lookup-CtAXI5W5.mjs +56 -0
- package/dist/.setup/{session-catalog-native-projection-DowriLid.mjs → session-catalog-parsing-CPGaPYr-.mjs} +11 -194
- package/dist/.setup/{session-catalog-projection-zK_PUsiE.mjs → session-catalog-projection-Cr5qP5Dj.mjs} +6 -4
- package/dist/.setup/session-catalog-provenance-DoAvktcj.mjs +95 -0
- package/dist/.setup/{session-cli-irrD-uo7.mjs → session-cli-Cn_nCqfq.mjs} +9 -22
- package/dist/.setup/{session-history-BrqhSCf9.mjs → session-history-D83lJWHG.mjs} +4 -6
- package/dist/.setup/{session-history-import-D-3wAgOP.mjs → session-history-import-WhX-X33a.mjs} +7 -10
- package/dist/.setup/session-history-read-Ov3StuL4.mjs +133 -0
- package/dist/.setup/{session-history.worker-CaCh0xF_.mjs → session-history.worker-MnPKncqP.mjs} +9 -5
- package/dist/.setup/session-initialization-6aveB9qb.mjs +22 -0
- package/dist/.setup/{session-permission-policy-BI1QK_98.mjs → session-permission-policy-Ci_fVX6y.mjs} +4 -8
- package/dist/.setup/{session-retirement-BH-S6qkJ.mjs → session-retirement-qMTxkNx2.mjs} +17 -17
- package/dist/.setup/{settled-turn-context-fmwouT5I.mjs → settled-turn-context-D4yj4rxf.mjs} +1 -1
- package/dist/.setup/{settled-turn-finalizer-DiAi6Kx6.mjs → settled-turn-finalizer-BsvEabkw.mjs} +14 -10
- package/dist/.setup/{shared-client-DA4VR4Eb.mjs → shared-client-DqyTMYug.mjs} +783 -412
- package/dist/.setup/shared-client-lifecycle-DJIgqgMw.mjs +153 -0
- package/dist/.setup/{side-question-BJ1wSDcB.mjs → side-question-C4kCmQy1.mjs} +79 -143
- package/dist/.setup/{source-CUzJq5WN.mjs → source-CS_7GFJZ.mjs} +80 -137
- package/dist/.setup/{thread-lifecycle-B3mfz1TG.mjs → thread-lifecycle-DPflntEJ.mjs} +294 -737
- package/dist/.setup/{incognito-session-uhrBF6wJ.mjs → thread-ownership-queue-Dp24d7-F.mjs} +1 -2
- package/dist/.setup/{thread-ownership-DcTtAcXj.mjs → thread-ownership-roNP0l1c.mjs} +45 -10
- package/dist/.setup/{thread-policy-DGuQsuFC.mjs → thread-policy-DTd-DtkX.mjs} +46 -7
- package/dist/.setup/{thread-requests-BLvGkP2R.mjs → thread-requests-B_bRnMGN.mjs} +199 -302
- package/dist/.setup/{thread-resume-DIBXwOpE.mjs → thread-resume-CdDaoc7T.mjs} +6 -6
- package/dist/.setup/{timeout-C910MdAB.mjs → timeout-CXOfNoaX.mjs} +1 -35
- package/dist/.setup/{transcript-history-projection-ZZpkFkJ_.mjs → transcript-history-projection-DRSifI-1.mjs} +17 -89
- package/dist/.setup/{transcript-mirror-attestation-CzM-94NC.mjs → transcript-mirror-attestation-YSegaktH.mjs} +3 -4
- package/dist/.setup/{transcript-mirror-BtHDBp1G.mjs → transcript-mirror-kxmCYsuF.mjs} +7 -9
- package/dist/.setup/{transport-stdio-h2VHOskC.mjs → transport-stdio-Bdegpn2V.mjs} +5 -22
- package/dist/.setup/transport-websocket-BTBE-LD9.mjs +211 -0
- package/dist/.setup/{upstream-prompt-provenance-LphB8slG.mjs → upstream-prompt-provenance-fXkKbPVC.mjs} +3 -9
- package/dist/.setup/{upstream-session-fork-BUr4OUbC.mjs → upstream-session-fork-CBeVjBpT.mjs} +23 -23
- package/dist/.setup/{usage-BML0r-ua.mjs → usage-BMzNxeR_.mjs} +4 -4
- package/dist/.setup/{usage-limit-error-DUMbefVY.mjs → usage-limit-error-QXerDo3i.mjs} +4 -19
- package/dist/.setup/{web-search-provider.runtime-CDKlN-Rv.mjs → web-search-provider.runtime-P77OUeoo.mjs} +8 -19
- package/dist/api.js +9 -11
- package/dist/catalog-page.worker.js +1 -1
- package/dist/cli-metadata.js +1 -1
- package/dist/doctor-contract-api.js +50 -8
- package/dist/harness.js +344 -1
- package/dist/index.js +193 -245
- package/dist/media-understanding-provider.js +9 -22
- package/dist/migration-provider-api.js +1 -1
- package/dist/provider-discovery.js +1 -1
- package/dist/session-history-worker-runtime.js +3 -3
- package/dist/session-history.worker.js +1 -1
- package/openclaw.plugin.json +14 -2
- package/package.json +7 -6
- package/dist/.setup/attempt-workspace-context-DUVEn_CS.mjs +0 -331
- package/dist/.setup/compact-Du5UvtxA.mjs +0 -680
- package/dist/.setup/event-projector-assistant-message-BsruvNrH.mjs +0 -103
- package/dist/.setup/event-projector-items-C6L_5ZiT.mjs +0 -234
- package/dist/.setup/harness-a_MsE4-_.mjs +0 -355
- package/dist/.setup/history-rejection-B4nOXNXF.mjs +0 -13
- package/dist/.setup/image-payload-sanitizer-tupAr-2o.mjs +0 -79
- package/dist/.setup/local-runtime-attribution-B_2mnqhb.mjs +0 -19
- package/dist/.setup/native-subagent-history-0nYYgo0k.mjs +0 -148
- package/dist/.setup/native-subagent-task-ids-wb8CKZGN.mjs +0 -441
- package/dist/.setup/plugin-approval-roundtrip-C0MZzCuP.mjs +0 -122
- package/dist/.setup/rolldown-runtime-8H4AJuhK.mjs +0 -14
- package/dist/.setup/sandbox-guard-C2sRMOEY.mjs +0 -166
- package/dist/.setup/session-binding-Cm0apEbd.mjs +0 -692
- package/dist/.setup/session-catalog-events-Bj6j94E_.mjs +0 -347
- package/dist/.setup/session-history-read-B3ZfSUbF.mjs +0 -50
- package/dist/.setup/session-initialization-rcgbZiid.mjs +0 -75
- package/dist/.setup/thread-history-page-DoVpnHim.mjs +0 -83
|
@@ -1,83 +1,95 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import { d as resolveCodexAppServerHomeDir, l as shouldAutoApproveCodexAppServerApprovals, n as hasCodexMcpToolApprovalOverrides, u as withMcpElicitationsApprovalPolicy, y as readCodexRequirementsToml } from "./config-security-BEReZ6go.mjs";
|
|
5
|
-
import { c as isCodexPairedNodeRemoteExecPlacementSandbox, d as readCodexPluginConfig, f as resolveCodexPluginsPolicy, l as isCodexRemoteExecPlacementSandbox, u as isCodexSandboxExecServerEnabled } from "./config-parsing-CcB9iPoq.mjs";
|
|
1
|
+
import { n as readCodexRuntimeModelId } from "./model-runtime-BdqzOMkU.mjs";
|
|
2
|
+
import { c as resolveRecoverableCodexPluginConfigKeys } from "./plugin-inventory-Cky2XJUw.mjs";
|
|
3
|
+
import { g as createCodexNativeSubagentHistoryOwner } from "./native-subagent-pending-assignments-DwkCzLvD.mjs";
|
|
6
4
|
import { i as isJsonObject, r as flattenCodexDynamicToolFunctions } from "./protocol-CANUwXJ3.mjs";
|
|
7
|
-
import { i as
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
11
|
-
import {
|
|
12
|
-
import {
|
|
5
|
+
import { i as matchesCodexNativeSubagentSubmissionBinding, n as assertCodexBindingMayBeReplaced, v as sessionBindingIdentity } from "./session-binding-record-Oe9L-CNY.mjs";
|
|
6
|
+
import { n as defineCodexBuildState } from "./build-state-Da1_z0kd.mjs";
|
|
7
|
+
import { c as shouldAutoApproveCodexAppServerApprovals, l as withMcpElicitationsApprovalPolicy, m as readCodexRequirementsToml, n as hasCodexMcpToolApprovalOverrides } from "./config-security-CE-FcGw9.mjs";
|
|
8
|
+
import { c as isCodexPairedNodeRemoteExecPlacementSandbox, d as readCodexPluginConfig, f as resolveCodexPluginsPolicy, l as isCodexRemoteExecPlacementSandbox, u as isCodexSandboxExecServerEnabled } from "./config-parsing-b088LyhT.mjs";
|
|
9
|
+
import { n as isCodexAppServerProxyLaunch } from "./launch-args-DbFCehO7.mjs";
|
|
10
|
+
import { t as resolveCodexAppServerHomeDir } from "./auth-start-options-BPIPeEX8.mjs";
|
|
11
|
+
import { i as resolveCodexAppServerHomeScope, l as resolveCodexModelBackedReviewerPolicyContext, o as resolveCodexComputerUseConfig } from "./config-options-CzyWLTJt.mjs";
|
|
12
|
+
import { c as resolveCodexAppServerPreparedApiKeyCacheKey, s as resolveCodexAppServerFallbackApiKeyCacheKey } from "./auth-cache-key-Dbvq-QgB.mjs";
|
|
13
|
+
import { d as retireSharedCodexAppServerClientIfCurrent } from "./shared-client-lifecycle-DJIgqgMw.mjs";
|
|
14
|
+
import { o as formatCodexDisplayText } from "./command-formatters-R3ckE3Co.mjs";
|
|
15
|
+
import { t as isIncognitoSessionKey } from "./incognito-session-DWYapfwf.mjs";
|
|
16
|
+
import { n as CodexAppServerRpcError } from "./rpc-error-BlD2vuzn.mjs";
|
|
17
|
+
import { n as waitForPromiseOrAbort, r as withAbortableTimeout } from "./timeout-CXOfNoaX.mjs";
|
|
13
18
|
import { t as readCodexAsyncQuestions } from "./async-questions-DdhOCwGi.mjs";
|
|
14
|
-
import {
|
|
15
|
-
import { r as readMirrorIdentity, t as attachCodexMirrorIdentity } from "./upstream-prompt-provenance-
|
|
16
|
-
import { a as defaultCodexAppInventoryCache, n as buildCodexAppServerRuntimeFingerprint, r as buildCodexPluginAppCacheKey } from "./plugin-app-cache-key-
|
|
17
|
-
import { i as resolveCodexBindingAppServerConnection, t as assertCodexSessionRuntimeOwnership } from "./binding-connection-
|
|
18
|
-
import {
|
|
19
|
-
import {
|
|
20
|
-
import { t as
|
|
21
|
-
import {
|
|
22
|
-
import {
|
|
23
|
-
import {
|
|
24
|
-
import { _ as
|
|
25
|
-
import { r as
|
|
26
|
-
import {
|
|
27
|
-
import {
|
|
28
|
-
import {
|
|
29
|
-
import {
|
|
30
|
-
import {
|
|
31
|
-
import {
|
|
32
|
-
import {
|
|
33
|
-
import { a as
|
|
19
|
+
import { a as readCodexProviderRefusal, d as splitPlanText, i as readCodexErrorNotificationMessage, l as readNonNegativeInteger, n as extractRawAssistantText, s as readItem, u as readNullableString } from "./event-projector-values-DJSz8BTk.mjs";
|
|
20
|
+
import { r as readMirrorIdentity, t as attachCodexMirrorIdentity } from "./upstream-prompt-provenance-fXkKbPVC.mjs";
|
|
21
|
+
import { a as defaultCodexAppInventoryCache, n as buildCodexAppServerRuntimeFingerprint, r as buildCodexPluginAppCacheKey } from "./plugin-app-cache-key-BL9B5H0L.mjs";
|
|
22
|
+
import { i as resolveCodexBindingAppServerConnection, r as requireCodexSupervisionModelSelection, t as assertCodexSessionRuntimeOwnership } from "./binding-connection-DTtN1KrX.mjs";
|
|
23
|
+
import { r as requestCodexAppServerClientJson, t as CodexAppServerScopedRequestRejectedError } from "./request-BHZ1nz8d.mjs";
|
|
24
|
+
import { n as canUseCodexModelBackedApprovalsReviewerForModel, r as resolveOpenClawExecPolicyForCodexAppServer } from "./config-DKhXquav.mjs";
|
|
25
|
+
import { a as isCodexDurableCustomMessage, c as resolveCodexContextEngineProjectionMaxChars, i as fitCodexProjectedContextForTurnStart, l as resolveCodexContinuityProjectionMaxChars, n as CodexContextAttachmentError, o as neutralizeCodexExplicitMentionSigils, r as buildCodexContinuityCalibration, s as projectContextEngineAssemblyForCodex, t as CODEX_TURN_START_TEXT_INPUT_MAX_CHARS } from "./context-engine-projection-PezSESth.mjs";
|
|
26
|
+
import { o as hasCodexMirrorOrigin, t as applyCodexTranscriptTaint } from "./transcript-mirror-attestation-YSegaktH.mjs";
|
|
27
|
+
import { t as readCodexMirroredSessionHistoryMessages } from "./session-history-D83lJWHG.mjs";
|
|
28
|
+
import { i as resolveCodexAppServerAuthProfileIdForAgent, r as resolveCodexAppServerAuthProfileId } from "./auth-profile-B0okYl2D.mjs";
|
|
29
|
+
import { E as isCodexContextRestartSelectionChangedError, H as prepareCodexWorkspaceReferences, I as ensureCodexAppServerClientRuntime, M as getCodexInferenceThreadQualification, U as protectCodexAppServerLiveThread, X as readRecentCodexRateLimits, Y as readCodexRateLimitsRevision, _ as retainSharedCodexAppServerClientIfCurrent, a as clearSharedCodexAppServerClientIfCurrentAndUnclaimed, c as getLeasedSharedCodexAppServerClient, dt as TURN_TERMINAL_SETTLEMENT_TIMEOUT_MS, et as resolveCodexAppServerAuthAccountCacheKey, f as readCodexAppServerClientDesktopGenerationFingerprint, h as releaseLeasedSharedCodexAppServerClient, ht as withCodexStartupTimeout, i as clearSharedCodexAppServerClientIfCurrent, j as getCodexInferenceThread, l as getSharedCodexAppServerClient, lt as CodexAppServerStartupError, mt as resolveCodexStartupTimeoutMs, s as createIsolatedCodexAppServerClient, tt as resolveCodexAppServerPreparedAuthHandoff, u as isCodexAppServerStartSelectionChangedError, ut as TURN_FINALIZE_DRAIN_ABORT_GRACE_MS, w as CodexThreadClientReplacementError, x as CODEX_APP_SERVER_CONTEXT_RESTART_SELECTION_CHANGED } from "./shared-client-DqyTMYug.mjs";
|
|
30
|
+
import { a as isCodexResponsesOAuthRun, r as isCodexResponsesOAuth } from "./responses-oauth-twnuTaAa.mjs";
|
|
31
|
+
import { A as handleDynamicToolCallWithTimeout, E as readCodexTurnCompletedNotification, F as resolveTerminalDynamicToolBatchAction, I as shouldBlockTerminalReleaseForNonTerminalDynamicToolResult, L as shouldReleaseTurnAfterTerminalDynamicTool, M as isDynamicToolTerminalDiagnosticEvent, N as isMatchingDynamicToolTerminalDiagnostic, P as resolveDynamicToolCallTimeoutMs, R as toCodexDynamicToolProgressResponse, S as assertCodexTurnStartResponse, U as CODEX_APP_SERVER_OPT_OUT_NOTIFICATION_METHODS, c as isCodexAppServerIndeterminateTransportError, i as isCodexAppServerApprovalRequest, j as hasPendingDynamicToolTerminalDiagnostic, k as createCodexElicitationResponse, m as CodexServerRequestResolvedError, o as isCodexAppServerConnectionClosedError, p as resolveCodexAppServerClientInstanceId, r as getCodexAppServerClientInstanceId, s as isCodexAppServerIndeterminateRequestCancellationError, w as readCodexDynamicToolCallParams, z as toCodexDynamicToolProtocolResponse } from "./client-N0JpgSzF.mjs";
|
|
32
|
+
import { n as isCodexWebSocketOpenFailure } from "./transport-websocket-BTBE-LD9.mjs";
|
|
33
|
+
import { M as matchesCodexSnapshotTurn, N as shouldClearTerminalPresentationForNativeItem, _ as CodexProjectionDiagnostics, d as shouldRetireCodexStartupClient, f as terminateCodexBackgroundTerminals, h as getCodexAppServerTurnRouter, k as itemName, m as CODEX_APP_SERVER_NATIVE_TURN_WAIT_TIMEOUT_MS, n as CODEX_APP_SERVER_UNSUBSCRIBE_TIMEOUT_MS, o as closeCodexStartupClientBestEffort, p as unsubscribeCodexThreadBestEffort, r as CodexAppServerUnsafeSubscriptionError, s as interruptCodexTurnAndWaitBestEffort, u as retireUnsafeCodexTurnClientBestEffort, v as isCodexNotificationForTurn, y as readCodexNotificationThreadId } from "./attempt-client-cleanup-DOP-cW5j.mjs";
|
|
34
|
+
import { r as prepareCodexAppServerAuthBinding } from "./auth-binding-BLWz7stm.mjs";
|
|
35
|
+
import { a as isRawFunctionToolOutputCompletionNotification, c as readNotificationItemId, i as isPendingOpenClawDynamicToolCompletionNotification, l as readRawResponseToolCallId, o as isTerminalTurnStatus, r as isCodexTurnAbortMarkerNotification, s as readCodexNotificationItem, t as CodexUsageProjection, u as updateActiveTurnItemIds } from "./event-projector-usage-03R0I2dM.mjs";
|
|
36
|
+
import { n as listAllCodexAppServerModels } from "./models-DHXZtVVk.mjs";
|
|
37
|
+
import { A as createCodexNativeHookRelay, B as loadCodexNativeToolCatalog, D as buildCodexNativeHookRelayConfig, E as assertCodexNativeHookRelayAllowed, K as codexDynamicToolsFingerprint, M as resolveCodexNativeHookRelayEvents, N as resolveCodexNativeHookRelayTtlMs, O as buildCodexNativeHookRelayDisabledConfig, P as scheduleCodexNativeHookRelayUnregister, St as mergeCodexThreadConfigs, T as CodexManagedHooksOnlyError, W as areCodexDynamicToolFingerprintsCompatible, X as fingerprintJsonObject, _t as buildCodexPluginThreadConfigTimeoutFallback, gt as buildCodexPluginThreadConfigInputFingerprint, h as buildDeveloperInstructions, ht as buildCodexPluginThreadConfig, ot as filterCodexDynamicTools, p as resolveCodexWebSearchPlan, pt as resolveCodexDynamicToolsLoadingForRuntime, q as codexLegacyDynamicToolsFingerprint, tt as stabilizeJsonValue, ut as isSystemAgentOnlyCodexDynamicToolAllowlist, w as CODEX_NATIVE_HOOK_RELAY_TTL_GRACE_MS, wt as shouldBuildCodexPluginThreadConfig, x as joinPresentSections, y as resolveCodexAppServerThreadModelSelection, z as hasCodexNativeToolCatalog } from "./thread-requests-B_bRnMGN.mjs";
|
|
38
|
+
import { _ as readCodexMcpToolUiVisibility, a as buildTurnStartParams, b as isContextEngineBindingCompatible, c as assertScheduledCodexAppAuthorityRuntime, d as buildScheduledCodexAppServerConnectionIdentity, f as captureScheduledCodexAppAuthority, g as readCodexMcpToolConnectorId, h as resolveScheduledCodexAppCreatorCaptureDecision, i as buildTurnCollaborationMode, l as buildLegacyScheduledCodexAppRecoveryPrompt, m as readCurrentCodexScheduledAppPolicy, n as buildCodexParentLocalInstructions, o as buildCodexUserInput, p as intersectCodexPluginThreadConfigWithScheduledAuthority, s as startOrResumeThread, t as buildCodexHistoryProvenancePrefix, u as buildScheduledCodexAppAuthorityInputFingerprint, v as isCodexAppServerProfilerEnabled, y as buildContextEngineBinding } from "./thread-lifecycle-DPflntEJ.mjs";
|
|
39
|
+
import { a as resolveCodexRunSessionBindingAuthority, n as createCodexSessionGenerationSupersededError, o as resolveCodexSessionBinding } from "./session-binding-DGCYAfvD.mjs";
|
|
40
|
+
import { a as CodexToolTranscriptProjection, b as sanitizeCodexAgentEventRecord, c as shouldEmitTranscriptToolProgress, i as emitCodexAgentEvent, p as requestPluginApprovalOutcome, r as CodexEventProjection, s as CodexToolProgressProjection, t as codexNativeSubagentMonitorRuntime, v as isCodexCommandBearingToolCall, x as sanitizeCodexToolArguments, y as resolveCodexToolProgressDetailMode } from "./native-subagent-monitor-Dpsmf2wz.mjs";
|
|
41
|
+
import { n as CodexThreadPolicyHandoffError, s as restoreCodexThreadSkillsCatalogAfterCompaction } from "./thread-policy-DTd-DtkX.mjs";
|
|
42
|
+
import { c as withExclusiveCodexAppServerThread, r as retainCodexAppServerBindingSubscription, t as isSameCodexAppServerThreadOwner } from "./thread-ownership-roNP0l1c.mjs";
|
|
43
|
+
import { c as promptSnapshot, i as mirrorPromptAtTurnStartBestEffort, n as createCodexAppServerUserMessagePersistenceNotifier, o as buildCodexUserPromptMessage, s as buildResolvedCodexUserPromptMessage, t as codexTranscriptMirrorRuntime } from "./transcript-mirror-kxmCYsuF.mjs";
|
|
44
|
+
import { a as resolveCodexPromptError, i as refreshCodexUsageLimitPromptError, n as formatCodexTurnStartUsageLimitError, r as markCodexAuthProfileBlockedFromRateLimits, t as CodexUsageLimitPromptError } from "./usage-limit-error-QXerDo3i.mjs";
|
|
34
45
|
import { t as persistCodexContextCompactionActivity } from "./context-compaction-activity-CMla5FPJ.mjs";
|
|
35
46
|
import { t as attemptTerminal } from "./attempt-terminal-gZrxQ35N.mjs";
|
|
36
|
-
import { a as shouldKeepCodexSharedAbortOpen, i as runCodexAgentEndHook, n as ensureCodexWorkspaceDirOnce, o as withCodexAppServerFastModeServiceTier, r as estimateCodexAppServerProjectedTurnTokens, t as emitCodexAppServerEvent } from "./run-attempt-lifecycle-
|
|
37
|
-
import { t as CODEX_INFERENCE_GENERATION_KEY } from "./inference-
|
|
38
|
-
import
|
|
39
|
-
import {
|
|
40
|
-
import { C as
|
|
41
|
-
import {
|
|
42
|
-
import { a as
|
|
43
|
-
import {
|
|
44
|
-
import {
|
|
45
|
-
import { a as
|
|
46
|
-
import { n as captureCodexSettledTurnFinalizationContext } from "./settled-turn-context-fmwouT5I.mjs";
|
|
47
|
-
import { a as runCodexComputerUseLiveTest, n as ensureCodexComputerUse, t as defaultCodexPluginMetadataCache } from "./plugin-metadata-cache-Ctmo83k_.mjs";
|
|
47
|
+
import { a as shouldKeepCodexSharedAbortOpen, i as runCodexAgentEndHook, n as ensureCodexWorkspaceDirOnce, o as withCodexAppServerFastModeServiceTier, r as estimateCodexAppServerProjectedTurnTokens, t as emitCodexAppServerEvent } from "./run-attempt-lifecycle-C-6O3Exn.mjs";
|
|
48
|
+
import { t as CODEX_INFERENCE_GENERATION_KEY } from "./inference-metadata-CgIf7sOx.mjs";
|
|
49
|
+
import "./inference-context-D-9gWlTR.mjs";
|
|
50
|
+
import { i as createAssistantReasoningMessage, n as createAssistantCommentaryMessage, r as createAssistantMessage, t as createAssistantAsyncMessage } from "./event-projector-assistant-message-CigreO4K.mjs";
|
|
51
|
+
import { C as readCodexRetainedBackgroundCommands, E as CodexNativeToolLifecycleProjector, S as hasCodexNativeBackgroundProcesses, T as mapCodexAppServerRemoteWorkspacePath, _ as shouldWarnCodexDynamicToolBuildStageSummary, a as emitDynamicToolStartedDiagnostic, b as createCodexNativePreToolUseFailureBuffer, c as buildDynamicTools, d as resolveCodexAppServerHookChannelId, f as resolveCodexExternalSandboxPolicyForOpenClawSandbox, g as shouldRequireCodexSandboxExecServerEnvironment, h as shouldEnableCodexAppServerNativeToolSurface, i as emitDynamicToolErrorDiagnostic, l as disableCodexPluginThreadConfig, m as resolveCodexSandboxEnvironmentSelection, n as projectCodexExecutableDynamicTools, o as emitDynamicToolTerminalDiagnostic, p as resolveCodexMessageToolProvider, r as routeCodexAppServerElicitationRequest, s as handleCodexAppServerApprovalRequest, t as createCodexDynamicToolBridge, u as resolveCodexAppServerExecutionCwd, v as ensureCodexSandboxExecServerEnvironment, w as readBoundedCodexRemoteWorkspaceFile, x as CodexNativeProcessAuthority, y as releaseCodexSandboxExecServerEnvironment } from "./dynamic-tools-DzlsLUuS.mjs";
|
|
52
|
+
import { a as resolveCodexAppServerForModelProvider, i as resolveCodexSessionPermissionCwd, n as applyCodexSessionPermissionPolicy, r as resolveCodexEffectiveSessionPermissionPolicy } from "./session-permission-policy-Ci_fVX6y.mjs";
|
|
53
|
+
import { a as getCodexContextFileDisplayBasename, c as normalizeCodexDynamicToolName, i as getCodexContextFileBasename, n as CODEX_NATIVE_PROJECT_DOC_BASENAMES, o as isNonEmptyString, r as buildCodexWorkspaceBootstrapContext, s as normalizeCodexContextFilePath } from "./attempt-workspace-context-C5HigshI.mjs";
|
|
54
|
+
import { n as captureCodexSettledTurnFinalizationContext } from "./settled-turn-context-D4yj4rxf.mjs";
|
|
55
|
+
import { t as resolveCodexProviderWebSearchSupport } from "./provider-capabilities-CAxoF-X1.mjs";
|
|
56
|
+
import { a as createComputerUseRequest, n as ensureCodexComputerUse, o as runCodexComputerUseLiveTest, t as defaultCodexPluginMetadataCache } from "./plugin-metadata-cache-DsjsL1dr.mjs";
|
|
48
57
|
import { asOptionalRecord, normalizeOptionalString, readNonBlankString, readStringField } from "openclaw/plugin-sdk/string-coerce-runtime";
|
|
49
58
|
import { createHash } from "node:crypto";
|
|
50
59
|
import { isDeepStrictEqual } from "node:util";
|
|
51
60
|
import { resolveAgentConfig, resolveSessionAgentIdsStrict } from "openclaw/plugin-sdk/agent-scope-runtime";
|
|
52
|
-
import {
|
|
61
|
+
import { asDateTimestampMs } from "openclaw/plugin-sdk/number-runtime";
|
|
53
62
|
import path from "node:path";
|
|
54
63
|
import fs from "node:fs/promises";
|
|
55
64
|
import { isPathStrictlyInside, readFileWindowFully, root } from "openclaw/plugin-sdk/file-access-runtime";
|
|
56
65
|
import { addAbortListener } from "node:events";
|
|
66
|
+
import { Type } from "typebox";
|
|
57
67
|
import { truncateUtf16Safe, truncateUtf8Prefix } from "openclaw/plugin-sdk/text-utility-runtime";
|
|
58
68
|
import { createDiagnosticTraceContextFromActiveScope, emitTrustedDiagnosticEvent, emitTrustedDiagnosticEventWithPrivateData, freezeDiagnosticTraceContext, onInternalDiagnosticEvent, resolveDiagnosticModelContentCapturePolicy } from "openclaw/plugin-sdk/diagnostic-runtime";
|
|
59
69
|
import { createDeferred } from "openclaw/plugin-sdk/extension-shared";
|
|
70
|
+
import { createStageTimingTracker, formatStageTimings } from "openclaw/plugin-sdk/time-runtime";
|
|
60
71
|
import { Buffer as Buffer$1 } from "node:buffer";
|
|
61
72
|
import { resolveAgentDir as resolveAgentDir$1 } from "openclaw/plugin-sdk/agent-runtime";
|
|
62
|
-
import { AgentHarnessPreflightError, CODEX_APP_SERVER_CONTEXT_ENGINE_HOST, FAST_MODE_AUTO_PROGRESS_KIND, agentHarnessStructuredInput, assembleHarnessContextEngine, assertContextEngineHostSupport, bootstrapHarnessContextEngine, buildAgentHookContextChannelFields, buildEmbeddedForegroundPromptContext, buildHarnessContextEngineRuntimeContext, buildWatchedSessionsHarnessContext, cancelPendingAgentQuestionForSession, claimPendingAgentQuestionAnswer, classifyAgentHarnessTerminalOutcome, clearActiveEmbeddedRun, detectAndLoadAgentHarnessPromptImages, embeddedAgentLog, emptyAgentHarnessUserInputAnswers, formatErrorMessage, formatFastModeAutoProgressText, getAgentHarnessHookRunner, hasBeforeToolCallPolicy, isActiveHarnessContextEngine, isHostScopedAgentToolActive, loadCodexBundleMcpThreadConfig, materializeRequesterScopedMcpToolsForHarnessRun, prepareHarnessNativeMcpAppPreview, projectAgentHarnessTranscriptMessageForDisplay, projectAgentToolActivity, projectProgressCardChannelUpdate, resolveAgentDir as resolveAgentDir$2, resolveAgentHarnessBeforePromptBuildResult, resolveAgentRunAbortLifecycleFields, resolveAttemptFsWorkspaceOnly, resolveContextEngineOwnerPluginId, resolveFastModeForElapsed, resolveSandboxContext, resolveUserPath, runAgentCleanupStep, runAgentHarnessAfterCompactionHook, runAgentHarnessBeforeCompactionHook, runAgentHarnessLlmInputHook, runAgentHarnessLlmOutputHook, runHarnessContextEngineMaintenance, setActiveEmbeddedRun, supportsModelTools } from "openclaw/plugin-sdk/agent-harness-runtime";
|
|
73
|
+
import { AgentHarnessPreflightError, CODEX_APP_SERVER_CONTEXT_ENGINE_HOST, FAST_MODE_AUTO_PROGRESS_KIND, HEARTBEAT_RESPONSE_TOOL_NAME, agentHarnessStructuredInput, applyEmbeddedAttemptToolsAllow, assembleHarnessContextEngine, assertContextEngineHostSupport, bootstrapHarnessContextEngine, buildAgentHookContextChannelFields, buildEmbeddedForegroundPromptContext, buildHarnessContextEngineRuntimeContext, buildWatchedSessionsHarnessContext, cancelPendingAgentQuestionForSession, claimPendingAgentQuestionAnswer, classifyAgentHarnessTerminalOutcome, clearActiveEmbeddedRun, detectAndLoadAgentHarnessPromptImages, embeddedAgentLog, emptyAgentHarnessUserInputAnswers, formatErrorMessage, formatFastModeAutoProgressText, getAgentHarnessHookRunner, hasBeforeToolCallPolicy, inferToolMetaFromArgs, isActiveHarnessContextEngine, isHostScopedAgentToolActive, loadCodexBundleMcpThreadConfig, materializeRequesterScopedMcpToolsForHarnessRun, normalizeHeartbeatToolResponse, prepareHarnessNativeMcpAppPreview, projectAgentHarnessTranscriptMessageForDisplay, projectAgentToolActivity, projectProgressCardChannelUpdate, resolveAgentDir as resolveAgentDir$2, resolveAgentHarnessBeforePromptBuildResult, resolveAgentRunAbortLifecycleFields, resolveAttemptFsWorkspaceOnly, resolveContextEngineOwnerPluginId, resolveFastModeForElapsed, resolveSandboxContext, resolveUserPath, runAgentCleanupStep, runAgentHarnessAfterCompactionHook, runAgentHarnessBeforeCompactionHook, runAgentHarnessLlmInputHook, runAgentHarnessLlmOutputHook, runHarnessContextEngineMaintenance, setActiveEmbeddedRun, supportsModelTools } from "openclaw/plugin-sdk/agent-harness-runtime";
|
|
63
74
|
import { loadExecApprovals } from "openclaw/plugin-sdk/exec-approvals-runtime";
|
|
75
|
+
import { AgentHarnessProjectionSettlement, createAgentHarnessAttemptCancellation, createAgentHarnessAttemptDeadlineController, createAgentHarnessAttemptLifecycle, shouldIncludeAgentHarnessRuntimeContext } from "openclaw/plugin-sdk/agent-harness-attempt-runtime";
|
|
64
76
|
import { getSessionEntry } from "openclaw/plugin-sdk/session-store-runtime";
|
|
65
|
-
import { acknowledgeInternalToolResult } from "openclaw/plugin-sdk/agent-harness-tool-runtime";
|
|
77
|
+
import { acknowledgeInternalToolResult, createAgentHarnessToolExecutionRegistry } from "openclaw/plugin-sdk/agent-harness-tool-runtime";
|
|
78
|
+
import { sleepWithAbort } from "openclaw/plugin-sdk/runtime-env";
|
|
66
79
|
import { captureFinalCodexCronCreatorToolAllowlist, formatMcpCodexApprovalRemedy, materializeStaticMcpToolsForHarnessRun, resolveCodexMcpToolOverridesForAgent, resolveCodexTtsProvenanceTransfer } from "openclaw/plugin-sdk/codex-mcp-projection";
|
|
67
80
|
import { appendSessionYieldContext, hasPromptImageInput } from "openclaw/plugin-sdk/session-transcript-runtime";
|
|
68
|
-
import { prepareAgentWorkspaceAttachments } from "openclaw/plugin-sdk/agent-workspace-runtime";
|
|
69
81
|
import { getAgentScopedMediaLocalRoots } from "openclaw/plugin-sdk/media-local-roots";
|
|
70
82
|
import { isSilentReplyPayloadText } from "openclaw/plugin-sdk/reply-chunking";
|
|
71
83
|
import { generatedImageAssetFromBase64 } from "openclaw/plugin-sdk/image-generation";
|
|
72
84
|
import { resolveGeneratedMediaMaxBytes } from "openclaw/plugin-sdk/media-generation-runtime";
|
|
73
85
|
import { normalizeMediaReferenceForComparison, saveMediaBuffer } from "openclaw/plugin-sdk/media-store";
|
|
74
86
|
import { stripInvisibleUnicode } from "openclaw/plugin-sdk/web-content-extractor";
|
|
87
|
+
import { prepareAgentWorkspaceAttachments } from "openclaw/plugin-sdk/agent-workspace-runtime";
|
|
75
88
|
import { MESSAGE_TOOL_DELIVERY_HINTS } from "openclaw/plugin-sdk/message-tool-delivery-hints";
|
|
76
|
-
import { sleepWithAbort } from "openclaw/plugin-sdk/runtime-env";
|
|
77
89
|
//#region extensions/codex/src/app-server/attempt-preparation-timing.ts
|
|
78
90
|
/** Records startup before the native turn owns inference and tool execution. */
|
|
79
91
|
function createCodexAttemptPreparationTiming(params) {
|
|
80
|
-
const tracker =
|
|
92
|
+
const tracker = createStageTimingTracker();
|
|
81
93
|
const profilerEnabled = isCodexAppServerProfilerEnabled(params.config);
|
|
82
94
|
const totalWarnMs = profilerEnabled ? 1e3 : 1e4;
|
|
83
95
|
const stageWarnMs = profilerEnabled ? 500 : 5e3;
|
|
@@ -87,7 +99,7 @@ function createCodexAttemptPreparationTiming(params) {
|
|
|
87
99
|
const slowTotal = outcome !== "completed" && summary.totalMs >= totalWarnMs;
|
|
88
100
|
const slowStage = outcome !== "ready" && (lastStage?.durationMs ?? 0) >= stageWarnMs;
|
|
89
101
|
if (!slowTotal && !slowStage) return;
|
|
90
|
-
embeddedAgentLog.warn(`codex app-server preparation timings runId=${params.runId} sessionId=${params.sessionId} stage=${stage} outcome=${outcome} totalMs=${summary.totalMs} stages=${
|
|
102
|
+
embeddedAgentLog.warn(`codex app-server preparation timings runId=${params.runId} sessionId=${params.sessionId} stage=${stage} outcome=${outcome} totalMs=${summary.totalMs} stages=${formatStageTimings(summary.stages)}`, {
|
|
91
103
|
runId: params.runId,
|
|
92
104
|
sessionId: params.sessionId,
|
|
93
105
|
sessionKey: params.sessionKey,
|
|
@@ -116,10 +128,6 @@ function createCodexAttemptPreparationTiming(params) {
|
|
|
116
128
|
}
|
|
117
129
|
//#endregion
|
|
118
130
|
//#region extensions/codex/src/app-server/attempt-steering.ts
|
|
119
|
-
/**
|
|
120
|
-
* Debounced steering queue for forwarding user messages to an active Codex
|
|
121
|
-
* app-server turn.
|
|
122
|
-
*/
|
|
123
131
|
const CODEX_STEER_ALL_DEBOUNCE_MS = 500;
|
|
124
132
|
var CodexSteeringAcceptedUnconfirmedError = class extends Error {
|
|
125
133
|
constructor(message, options) {
|
|
@@ -182,7 +190,7 @@ function createCodexSteeringQueue(params) {
|
|
|
182
190
|
params.signal.removeEventListener("abort", abortQueue);
|
|
183
191
|
clearBatchTimer();
|
|
184
192
|
batchedMessages = [];
|
|
185
|
-
for (const batch of dispatchedBatches.values()) for (const item of batch
|
|
193
|
+
for (const batch of dispatchedBatches.values()) for (const item of batch) acceptItem(item);
|
|
186
194
|
dispatchedBatches.clear();
|
|
187
195
|
for (const item of pendingMessages) rejectItem(item, error);
|
|
188
196
|
};
|
|
@@ -191,7 +199,7 @@ function createCodexSteeringQueue(params) {
|
|
|
191
199
|
sealedError = /* @__PURE__ */ new Error("codex app-server steering queue admission sealed");
|
|
192
200
|
clearBatchTimer();
|
|
193
201
|
batchedMessages = [];
|
|
194
|
-
const dispatchedItems = new Set([...dispatchedBatches.values()].
|
|
202
|
+
const dispatchedItems = new Set([...dispatchedBatches.values()].flat());
|
|
195
203
|
for (const item of pendingMessages) if (!dispatchedItems.has(item)) rejectItem(item, sealedError);
|
|
196
204
|
};
|
|
197
205
|
const abortQueue = () => {
|
|
@@ -241,7 +249,7 @@ function createCodexSteeringQueue(params) {
|
|
|
241
249
|
if (liveItems.length === 0) return;
|
|
242
250
|
}
|
|
243
251
|
clientUserMessageId = `openclaw:${params.turnId}:steer:${++batchSequence}`;
|
|
244
|
-
dispatchedBatches.set(clientUserMessageId,
|
|
252
|
+
dispatchedBatches.set(clientUserMessageId, liveItems);
|
|
245
253
|
const request = {
|
|
246
254
|
threadId: params.threadId,
|
|
247
255
|
expectedTurnId: params.turnId,
|
|
@@ -255,7 +263,7 @@ function createCodexSteeringQueue(params) {
|
|
|
255
263
|
assertActive();
|
|
256
264
|
liveItems = liveItems.filter(isCurrent);
|
|
257
265
|
request.input = liveItems.flatMap((item) => item.prepared.input);
|
|
258
|
-
dispatchedBatches.set(request.clientUserMessageId,
|
|
266
|
+
dispatchedBatches.set(request.clientUserMessageId, liveItems);
|
|
259
267
|
if (liveItems.length === 0) {
|
|
260
268
|
skippedRevokedBatch = true;
|
|
261
269
|
throw new Error("Codex steering batch has no authorized inputs");
|
|
@@ -290,19 +298,14 @@ function createCodexSteeringQueue(params) {
|
|
|
290
298
|
return send;
|
|
291
299
|
};
|
|
292
300
|
const createPendingMessage = (text, options, assertCurrent = () => {}) => {
|
|
293
|
-
|
|
294
|
-
let rejectDelivery;
|
|
295
|
-
const delivery = new Promise((resolve, reject) => {
|
|
296
|
-
resolveDelivery = resolve;
|
|
297
|
-
rejectDelivery = reject;
|
|
298
|
-
});
|
|
301
|
+
const { promise: delivery, resolve, reject } = createDeferred();
|
|
299
302
|
const item = {
|
|
300
303
|
...options,
|
|
301
304
|
assertCurrent,
|
|
302
305
|
acceptance: "open",
|
|
303
306
|
text,
|
|
304
|
-
resolve
|
|
305
|
-
reject
|
|
307
|
+
resolve,
|
|
308
|
+
reject,
|
|
306
309
|
settled: false
|
|
307
310
|
};
|
|
308
311
|
pendingMessages.add(item);
|
|
@@ -337,7 +340,7 @@ function createCodexSteeringQueue(params) {
|
|
|
337
340
|
const batch = dispatchedBatches.get(clientUserMessageId);
|
|
338
341
|
if (!batch) return false;
|
|
339
342
|
dispatchedBatches.delete(clientUserMessageId);
|
|
340
|
-
for (const item of batch
|
|
343
|
+
for (const item of batch) resolveItem(item);
|
|
341
344
|
return true;
|
|
342
345
|
},
|
|
343
346
|
getAcceptedMessages: () => acceptedMessages.slice(),
|
|
@@ -573,11 +576,15 @@ var CodexAssistantProjection = class {
|
|
|
573
576
|
this.supersedeVisibleAnswerCandidate();
|
|
574
577
|
return;
|
|
575
578
|
}
|
|
579
|
+
for (const itemId of this.assistantItemOrder) if (!this.completedAssistantItemIds.has(itemId) && !this.isAsyncAssistantItem(itemId) && (this.isFinalAnswerAssistantItem(itemId) || this.isCommentaryAssistantItem(itemId))) {
|
|
580
|
+
if (itemId === this.visibleAnswerCandidateItemId) this.supersedeVisibleAnswerCandidate();
|
|
581
|
+
this.assistantTextByItem.delete(itemId);
|
|
582
|
+
}
|
|
576
583
|
const turnItems = turn.items ?? [];
|
|
577
584
|
const authoritativeIndex = turnItems.findLastIndex((item) => {
|
|
578
585
|
if (item.type !== "agentMessage" || typeof item.text !== "string" || item.text.trim().length === 0) return false;
|
|
579
|
-
const phase =
|
|
580
|
-
return
|
|
586
|
+
const phase = readStringField(item, "phase");
|
|
587
|
+
return readStringField(item, "delivery") !== "async" && (phase === "final_answer" || phase === void 0);
|
|
581
588
|
});
|
|
582
589
|
const authoritative = authoritativeIndex >= 0 ? turnItems[authoritativeIndex] : void 0;
|
|
583
590
|
if (turnItems.slice(authoritativeIndex + 1).some(shouldClearTerminalPresentationForNativeItem) || authoritative?.id === this.latestTerminalAssistantCandidateItemId && this.latestTerminalAssistantCandidateSuperseded) {
|
|
@@ -620,9 +627,9 @@ var CodexAssistantProjection = class {
|
|
|
620
627
|
}
|
|
621
628
|
rememberAssistantPhase(item) {
|
|
622
629
|
if (item?.type !== "agentMessage") return;
|
|
623
|
-
const phase =
|
|
630
|
+
const phase = readStringField(item, "phase");
|
|
624
631
|
if (phase) this.assistantPhaseByItem.set(item.id, phase);
|
|
625
|
-
const delivery =
|
|
632
|
+
const delivery = readStringField(item, "delivery");
|
|
626
633
|
if (delivery) this.assistantDeliveryByItem.set(item.id, delivery);
|
|
627
634
|
if (item.questions !== void 0) {
|
|
628
635
|
const questions = readCodexAsyncQuestions(item.questions);
|
|
@@ -831,17 +838,17 @@ var CodexGeneratedMediaProjection = class {
|
|
|
831
838
|
async recordNative(item) {
|
|
832
839
|
if (item?.type !== "imageGeneration") return;
|
|
833
840
|
this.itemIds.add(item.id);
|
|
834
|
-
const savedPath =
|
|
841
|
+
const savedPath = readStringField(item, "savedPath")?.trim();
|
|
835
842
|
if (savedPath) this.mediaByItemId.set(item.id, {
|
|
836
843
|
...this.mediaByItemId.get(item.id),
|
|
837
844
|
savedPath
|
|
838
845
|
});
|
|
839
|
-
const result =
|
|
846
|
+
const result = readStringField(item, "result");
|
|
840
847
|
if (result) {
|
|
841
848
|
await this.recordImage({
|
|
842
849
|
itemId: item.id,
|
|
843
850
|
result,
|
|
844
|
-
revisedPrompt:
|
|
851
|
+
revisedPrompt: readStringField(item, "revisedPrompt"),
|
|
845
852
|
source: "native"
|
|
846
853
|
});
|
|
847
854
|
return;
|
|
@@ -866,7 +873,7 @@ var CodexGeneratedMediaProjection = class {
|
|
|
866
873
|
await this.recordImage({
|
|
867
874
|
itemId: item.id,
|
|
868
875
|
result: response.dataBase64,
|
|
869
|
-
revisedPrompt:
|
|
876
|
+
revisedPrompt: readStringField(item, "revisedPrompt"),
|
|
870
877
|
source: "native"
|
|
871
878
|
});
|
|
872
879
|
} catch (error) {
|
|
@@ -1062,13 +1069,12 @@ var CodexReasoningProjection = class {
|
|
|
1062
1069
|
async handleTurnPlanUpdated(params, source = "codex-app-server") {
|
|
1063
1070
|
const explanation = readNullableString(params, "explanation");
|
|
1064
1071
|
const plan = Array.isArray(params.plan) ? params.plan.flatMap((entry) => {
|
|
1065
|
-
if (!
|
|
1066
|
-
const
|
|
1067
|
-
const step = readStringField(record, "step");
|
|
1072
|
+
if (!isJsonObject(entry)) return [];
|
|
1073
|
+
const step = readStringField(entry, "step");
|
|
1068
1074
|
if (!step) return [];
|
|
1069
1075
|
return [{
|
|
1070
1076
|
step,
|
|
1071
|
-
status: normalizePlanStepStatus(readStringField(
|
|
1077
|
+
status: normalizePlanStepStatus(readStringField(entry, "status"))
|
|
1072
1078
|
}];
|
|
1073
1079
|
}) : void 0;
|
|
1074
1080
|
const planText = [explanation, ...(plan ?? []).map(({ step, status }) => `- [${status}] ${step}`)].filter((part) => Boolean(part)).join("\n");
|
|
@@ -1150,38 +1156,10 @@ function readReasoningSections(value) {
|
|
|
1150
1156
|
}
|
|
1151
1157
|
//#endregion
|
|
1152
1158
|
//#region extensions/codex/src/app-server/event-projector-settlement.ts
|
|
1153
|
-
var CodexProjectionSettlement = class {
|
|
1159
|
+
var CodexProjectionSettlement = class extends AgentHarnessProjectionSettlement {
|
|
1154
1160
|
constructor(params, isActive) {
|
|
1161
|
+
super(params, isActive, { label: "codex app-server" });
|
|
1155
1162
|
this.turnTainted = false;
|
|
1156
|
-
this.pending = /* @__PURE__ */ new Map();
|
|
1157
|
-
const detach = (stage, callback) => callback ? (...args) => {
|
|
1158
|
-
if (!isActive()) return;
|
|
1159
|
-
const completion = createDeferred();
|
|
1160
|
-
this.pending.set(completion.promise, stage);
|
|
1161
|
-
const settled = () => {
|
|
1162
|
-
this.pending.delete(completion.promise);
|
|
1163
|
-
completion.resolve();
|
|
1164
|
-
};
|
|
1165
|
-
const failed = (error) => {
|
|
1166
|
-
embeddedAgentLog.warn(`codex app-server ${stage} callback failed: ${String(error)}`);
|
|
1167
|
-
settled();
|
|
1168
|
-
};
|
|
1169
|
-
try {
|
|
1170
|
-
Promise.resolve(callback(...args)).then(settled, failed);
|
|
1171
|
-
} catch (error) {
|
|
1172
|
-
failed(error);
|
|
1173
|
-
}
|
|
1174
|
-
} : void 0;
|
|
1175
|
-
this.params = {
|
|
1176
|
-
...params,
|
|
1177
|
-
onAssistantMessageStart: detach("onAssistantMessageStart", params.onAssistantMessageStart),
|
|
1178
|
-
onPartialReply: detach("onPartialReply", params.onPartialReply),
|
|
1179
|
-
onReasoningStream: detach("onReasoningStream", params.onReasoningStream),
|
|
1180
|
-
onReasoningEnd: detach("onReasoningEnd", params.onReasoningEnd)
|
|
1181
|
-
};
|
|
1182
|
-
}
|
|
1183
|
-
get pendingStage() {
|
|
1184
|
-
return this.stage ?? this.pending.values().next().value;
|
|
1185
1163
|
}
|
|
1186
1164
|
get completedAnswer() {
|
|
1187
1165
|
const turn = this.terminalReceipt;
|
|
@@ -1191,18 +1169,6 @@ var CodexProjectionSettlement = class {
|
|
|
1191
1169
|
answer
|
|
1192
1170
|
} : void 0;
|
|
1193
1171
|
}
|
|
1194
|
-
async project(stage, project) {
|
|
1195
|
-
const previous = this.stage;
|
|
1196
|
-
this.stage = stage;
|
|
1197
|
-
try {
|
|
1198
|
-
return await project();
|
|
1199
|
-
} finally {
|
|
1200
|
-
this.stage = previous;
|
|
1201
|
-
}
|
|
1202
|
-
}
|
|
1203
|
-
async drain() {
|
|
1204
|
-
while (this.pending.size > 0) await Promise.all(this.pending.keys());
|
|
1205
|
-
}
|
|
1206
1172
|
};
|
|
1207
1173
|
//#endregion
|
|
1208
1174
|
//#region extensions/codex/src/app-server/event-projector-snapshot.ts
|
|
@@ -1361,6 +1327,7 @@ var CodexTurnProjection = class {
|
|
|
1361
1327
|
this.threadId = threadId;
|
|
1362
1328
|
this.turnId = turnId;
|
|
1363
1329
|
this.options = options;
|
|
1330
|
+
this.observedItemIds = /* @__PURE__ */ new Set();
|
|
1364
1331
|
this.activeItemIds = /* @__PURE__ */ new Set();
|
|
1365
1332
|
this.completedItemIds = /* @__PURE__ */ new Set();
|
|
1366
1333
|
this.activeCompactionItemIds = /* @__PURE__ */ new Set();
|
|
@@ -1404,11 +1371,17 @@ var CodexTurnProjection = class {
|
|
|
1404
1371
|
const { promptError: initialPromptError, promptErrorSource: initialPromptErrorSource, providerRefusal } = this.terminalFailure;
|
|
1405
1372
|
const upstreamUserText = this.options.upstreamUserText;
|
|
1406
1373
|
const turnTainted = this.settlement.turnTainted;
|
|
1374
|
+
const observedItemCount = (/* @__PURE__ */ new Set([...this.observedItemIds, ...this.completedItemIds])).size;
|
|
1407
1375
|
const activeItemCount = this.activeItemIds.size;
|
|
1408
1376
|
const completedItemCount = this.completedItemIds.size;
|
|
1409
1377
|
const guardianReviewCount = this.eventProjection.guardianReviewCount;
|
|
1410
1378
|
const yieldDetected = options?.yieldDetected;
|
|
1411
|
-
|
|
1379
|
+
const retainedCommands = /* @__PURE__ */ new Map();
|
|
1380
|
+
if (!aborted && !this.options.runAbortSignal?.aborted && completedTurn?.status === "completed" && !initialPromptError) {
|
|
1381
|
+
const pending = this.nativeToolLifecycleProjector.pendingCommands();
|
|
1382
|
+
for (const [id, processId] of options?.readRetainedNativeCommands?.() ?? []) if (pending.has(id) && (pending.get(id) === null || pending.get(id) === processId)) retainedCommands.set(id, processId);
|
|
1383
|
+
}
|
|
1384
|
+
this.nativeToolLifecycleProjector.finalizeActive(void 0, retainedCommands);
|
|
1412
1385
|
const assistantTexts = this.assistantProjection.collectAssistantTexts();
|
|
1413
1386
|
const asyncMessages = this.assistantProjection.collectAsyncMessages();
|
|
1414
1387
|
const commentaryMessages = this.assistantProjection.collectCommentaryMessages();
|
|
@@ -1424,6 +1397,7 @@ var CodexTurnProjection = class {
|
|
|
1424
1397
|
const hasDeliverableAssistantOnCompletedTurn = completedTurn?.status === "completed" && assistantTexts.some((text) => text.trim().length > 0);
|
|
1425
1398
|
const synthesizedMissingToolResultError = this.toolTranscriptProjection.synthesizeMissingToolResults({
|
|
1426
1399
|
synthesize: legacyFailClosed,
|
|
1400
|
+
retainedCommands,
|
|
1427
1401
|
terminalDisposition: aborted ? "tool_error" : hasDeliverableAssistantOnCompletedTurn ? "diagnostic_only" : "prompt_error"
|
|
1428
1402
|
});
|
|
1429
1403
|
const storedMissingToolResultError = synthesizedMissingToolResultError ?? previousMissingToolResultError;
|
|
@@ -1504,7 +1478,7 @@ var CodexTurnProjection = class {
|
|
|
1504
1478
|
replaySafe: !hadPotentialSideEffects
|
|
1505
1479
|
},
|
|
1506
1480
|
itemLifecycle: {
|
|
1507
|
-
startedCount:
|
|
1481
|
+
startedCount: observedItemCount,
|
|
1508
1482
|
completedCount: completedItemCount,
|
|
1509
1483
|
activeCount: activeItemCount
|
|
1510
1484
|
},
|
|
@@ -1523,13 +1497,21 @@ var CodexTurnProjection = class {
|
|
|
1523
1497
|
//#region extensions/codex/src/app-server/event-projector.ts
|
|
1524
1498
|
const optedOutNotificationMethods = new Set(CODEX_APP_SERVER_OPT_OUT_NOTIFICATION_METHODS);
|
|
1525
1499
|
var CodexAppServerEventProjector = class extends CodexTurnProjection {
|
|
1500
|
+
constructor(..._args) {
|
|
1501
|
+
super(..._args);
|
|
1502
|
+
this.compactionProgress = /* @__PURE__ */ new Map();
|
|
1503
|
+
}
|
|
1526
1504
|
getCompletedTurnStatus() {
|
|
1527
1505
|
return this.completedTurn?.status;
|
|
1528
1506
|
}
|
|
1507
|
+
getPendingNativeCommands() {
|
|
1508
|
+
return !this.projectionClosed && !this.aborted && !this.options.runAbortSignal?.aborted && this.completedTurn?.status === "completed" && !this.terminalFailure.promptError ? this.nativeToolLifecycleProjector.pendingCommands() : /* @__PURE__ */ new Map();
|
|
1509
|
+
}
|
|
1529
1510
|
/** Native completion owns the answer independently of unfinished host projection. */
|
|
1530
1511
|
recoverCompletedAnswer() {
|
|
1531
1512
|
const completed = this.settlement.completedAnswer;
|
|
1532
1513
|
if (!completed || this.aborted || this.terminalFailure.promptError) return false;
|
|
1514
|
+
this.closeCompactionProgress();
|
|
1533
1515
|
this.projectionController.abort();
|
|
1534
1516
|
this.transcriptCheckpoint.abandon();
|
|
1535
1517
|
this.completedTurn = completed.turn;
|
|
@@ -1565,6 +1547,7 @@ var CodexAppServerEventProjector = class extends CodexTurnProjection {
|
|
|
1565
1547
|
}
|
|
1566
1548
|
/** Fence delayed projections before the turn's final snapshot leaves its owner. */
|
|
1567
1549
|
closeProjection() {
|
|
1550
|
+
this.closeCompactionProgress();
|
|
1568
1551
|
this.projectionController.abort();
|
|
1569
1552
|
return this.settlement.project("transcript/checkpoint", () => this.transcriptCheckpoint.flush(true));
|
|
1570
1553
|
}
|
|
@@ -1747,6 +1730,16 @@ var CodexAppServerEventProjector = class extends CodexTurnProjection {
|
|
|
1747
1730
|
isCompacting() {
|
|
1748
1731
|
return this.activeCompactionItemIds.size > 0;
|
|
1749
1732
|
}
|
|
1733
|
+
finishCompactionProgress(itemId, completed) {
|
|
1734
|
+
if (this.compactionProgress.get(itemId) === "closed") return;
|
|
1735
|
+
this.compactionProgress.set(itemId, "closed");
|
|
1736
|
+
this.eventProjection.emitCompactionEnd(itemId, completed);
|
|
1737
|
+
}
|
|
1738
|
+
closeCompactionProgress() {
|
|
1739
|
+
for (const itemId of this.activeCompactionItemIds) this.activeItemIds.delete(itemId);
|
|
1740
|
+
this.activeCompactionItemIds.clear();
|
|
1741
|
+
for (const [itemId, progress] of this.compactionProgress) if (progress === "open") this.finishCompactionProgress(itemId, this.completedItemIds.has(itemId));
|
|
1742
|
+
}
|
|
1750
1743
|
isCompactionProjectionActive() {
|
|
1751
1744
|
return !this.projectionClosed && !this.aborted && !this.options.runAbortSignal?.aborted;
|
|
1752
1745
|
}
|
|
@@ -1754,20 +1747,26 @@ var CodexAppServerEventProjector = class extends CodexTurnProjection {
|
|
|
1754
1747
|
const item = readItem(params.item);
|
|
1755
1748
|
if (item?.type === "agentMessage" && item.text) this.eventProjection.markSafetyBufferingAssistantStarted();
|
|
1756
1749
|
const itemId = item?.id ?? readStringField(params, "itemId");
|
|
1750
|
+
if (itemId) this.observedItemIds.add(itemId);
|
|
1751
|
+
if (item?.type === "contextCompaction" && itemId) {
|
|
1752
|
+
if (this.completedTurn || this.activeCompactionItemIds.has(itemId) || this.completedItemIds.has(itemId) || this.compactionProgress.has(itemId)) return;
|
|
1753
|
+
this.activeCompactionItemIds.add(itemId);
|
|
1754
|
+
}
|
|
1757
1755
|
await this.assistantProjection.recordItemStarted(item, itemId);
|
|
1756
|
+
if (this.projectionClosed || item?.type === "contextCompaction" && itemId && !this.activeCompactionItemIds.has(itemId)) return;
|
|
1758
1757
|
if (itemId) this.activeItemIds.add(itemId);
|
|
1759
1758
|
this.recordNativeToolOutcome(item);
|
|
1760
1759
|
if (item?.type === "contextCompaction" && itemId) {
|
|
1761
|
-
if (!this.isCompactionProjectionActive()) return;
|
|
1762
|
-
this.activeCompactionItemIds.add(itemId);
|
|
1760
|
+
if (!this.isCompactionProjectionActive() || !this.activeCompactionItemIds.has(itemId)) return;
|
|
1763
1761
|
const messages = await this.toolTranscriptProjection.readMirroredSessionMessages(this.options.runAbortSignal);
|
|
1764
|
-
if (!this.isCompactionProjectionActive()) return;
|
|
1762
|
+
if (!this.isCompactionProjectionActive() || !this.activeCompactionItemIds.has(itemId)) return;
|
|
1765
1763
|
await runAgentHarnessBeforeCompactionHook({
|
|
1766
1764
|
sessionFile: this.params.sessionFile,
|
|
1767
1765
|
messages,
|
|
1768
1766
|
ctx: this.options.agentHookContext ?? {}
|
|
1769
1767
|
});
|
|
1770
|
-
if (!this.isCompactionProjectionActive()) return;
|
|
1768
|
+
if (!this.isCompactionProjectionActive() || !this.activeCompactionItemIds.has(itemId)) return;
|
|
1769
|
+
this.compactionProgress.set(itemId, "open");
|
|
1771
1770
|
this.emitAgentEvent({
|
|
1772
1771
|
stream: "compaction",
|
|
1773
1772
|
data: {
|
|
@@ -1809,9 +1808,14 @@ var CodexAppServerEventProjector = class extends CodexTurnProjection {
|
|
|
1809
1808
|
this.recordNativeToolOutcome(item);
|
|
1810
1809
|
this.nativeToolLifecycleProjector.clearTerminalPresentationForNativeItem(item);
|
|
1811
1810
|
if (itemId) {
|
|
1811
|
+
this.observedItemIds.add(itemId);
|
|
1812
1812
|
this.activeItemIds.delete(itemId);
|
|
1813
1813
|
this.completedItemIds.add(itemId);
|
|
1814
1814
|
}
|
|
1815
|
+
if (item?.type === "contextCompaction" && itemId) {
|
|
1816
|
+
this.activeCompactionItemIds.delete(itemId);
|
|
1817
|
+
this.completedCompactionCount += 1;
|
|
1818
|
+
}
|
|
1815
1819
|
if (!this.asyncDeliveryProjection.allows(item, true)) return;
|
|
1816
1820
|
const asyncMessage = this.assistantProjection.recordItemCompleted(item, itemId, this.activeItemIds);
|
|
1817
1821
|
if (asyncMessage) await this.asyncDeliveryProjection.deliver(asyncMessage);
|
|
@@ -1821,8 +1825,6 @@ var CodexAppServerEventProjector = class extends CodexTurnProjection {
|
|
|
1821
1825
|
if (this.projectionClosed) return;
|
|
1822
1826
|
if (item?.type === "contextCompaction" && itemId) {
|
|
1823
1827
|
if (!this.isCompactionProjectionActive()) return;
|
|
1824
|
-
this.activeCompactionItemIds.delete(itemId);
|
|
1825
|
-
this.completedCompactionCount += 1;
|
|
1826
1828
|
await this.options.onContextCompacted?.();
|
|
1827
1829
|
if (!this.isCompactionProjectionActive()) return;
|
|
1828
1830
|
const messages = await this.toolTranscriptProjection.readMirroredSessionMessages(this.options.runAbortSignal);
|
|
@@ -1845,7 +1847,7 @@ var CodexAppServerEventProjector = class extends CodexTurnProjection {
|
|
|
1845
1847
|
timestamp: this.transcriptCheckpoint.nextTimestamp()
|
|
1846
1848
|
});
|
|
1847
1849
|
if (!this.isCompactionProjectionActive()) return;
|
|
1848
|
-
this.
|
|
1850
|
+
this.finishCompactionProgress(itemId, true);
|
|
1849
1851
|
}
|
|
1850
1852
|
this.toolProgressProjection.recordToolMeta(item);
|
|
1851
1853
|
this.toolProgressProjection.rememberCommandAggregateOutputEcho(item);
|
|
@@ -1895,14 +1897,7 @@ var CodexAppServerEventProjector = class extends CodexTurnProjection {
|
|
|
1895
1897
|
promptErrorSource: compactionFailure ? "compaction" : "prompt"
|
|
1896
1898
|
});
|
|
1897
1899
|
}
|
|
1898
|
-
|
|
1899
|
-
const failedCompactionItemIds = [...this.activeCompactionItemIds];
|
|
1900
|
-
for (const itemId of failedCompactionItemIds) {
|
|
1901
|
-
this.activeItemIds.delete(itemId);
|
|
1902
|
-
this.activeCompactionItemIds.delete(itemId);
|
|
1903
|
-
this.eventProjection.emitCompactionEnd(itemId, false);
|
|
1904
|
-
}
|
|
1905
|
-
}
|
|
1900
|
+
this.closeCompactionProgress();
|
|
1906
1901
|
const turnItems = turn.items;
|
|
1907
1902
|
const unsettledAsyncDeliveries = this.asyncDeliveryProjection.pending();
|
|
1908
1903
|
const lastToolItem = turnItems.findLast((item) => matchesCodexSnapshotTurn(item, this.turnId) && (item.type === "dynamicToolCall" || shouldClearTerminalPresentationForNativeItem(item)));
|
|
@@ -1940,7 +1935,6 @@ var CodexAppServerEventProjector = class extends CodexTurnProjection {
|
|
|
1940
1935
|
}
|
|
1941
1936
|
if (this.projectionClosed) return;
|
|
1942
1937
|
this.assistantProjection.finalizeAnswerCandidate(turn);
|
|
1943
|
-
this.activeCompactionItemIds.clear();
|
|
1944
1938
|
await this.reasoningProjection.maybeEndReasoning();
|
|
1945
1939
|
}
|
|
1946
1940
|
async handleRawResponseItemCompleted(params) {
|
|
@@ -1965,9 +1959,6 @@ function readMcpAppResourceUri(item) {
|
|
|
1965
1959
|
const uri = normalizeOptionalString(appContext?.resourceUri) ?? normalizeOptionalString(item.mcpAppResourceUri);
|
|
1966
1960
|
return uri?.startsWith("ui://") ? uri : void 0;
|
|
1967
1961
|
}
|
|
1968
|
-
function readMcpAppConnectorId(item) {
|
|
1969
|
-
return normalizeOptionalString(asOptionalRecord(item.appContext)?.connectorId);
|
|
1970
|
-
}
|
|
1971
1962
|
function readMcpToolResult(item) {
|
|
1972
1963
|
const result = asOptionalRecord(item.result);
|
|
1973
1964
|
if (!result || !Array.isArray(result.content)) return;
|
|
@@ -2071,7 +2062,7 @@ function createCodexNativeMcpAppResultDetailsPreparer(params) {
|
|
|
2071
2062
|
const serverName = normalizeOptionalString(item.server);
|
|
2072
2063
|
const toolName = normalizeOptionalString(item.tool);
|
|
2073
2064
|
const uiResourceUri = readMcpAppResourceUri(item);
|
|
2074
|
-
const connectorId =
|
|
2065
|
+
const connectorId = normalizeOptionalString(asOptionalRecord(item.appContext)?.connectorId);
|
|
2075
2066
|
const toolResult = readMcpToolResult(item);
|
|
2076
2067
|
if (!serverName || !toolName || !uiResourceUri || !toolResult) return;
|
|
2077
2068
|
if (serverName === CODEX_APPS_MCP_SERVER && !connectorId) return;
|
|
@@ -2134,8 +2125,7 @@ function canonicalizeNativeProgressCardInput(input) {
|
|
|
2134
2125
|
var CodexCompactionPlanState = class {
|
|
2135
2126
|
record(event) {
|
|
2136
2127
|
if (event.stream !== "plan") return;
|
|
2137
|
-
|
|
2138
|
-
this.latestPlan = plan;
|
|
2128
|
+
this.latestPlan = readBoundedPlan(event.data.explanation, event.data.steps);
|
|
2139
2129
|
}
|
|
2140
2130
|
/** Retains markdown that migration-only plan events intentionally omit. */
|
|
2141
2131
|
recordProgressCardInput(value) {
|
|
@@ -2194,7 +2184,7 @@ function truncateUtf8(value, maxBytes) {
|
|
|
2194
2184
|
function readPlanSteps(value) {
|
|
2195
2185
|
if (!Array.isArray(value)) return [];
|
|
2196
2186
|
return value.flatMap((entry) => {
|
|
2197
|
-
if (!
|
|
2187
|
+
if (!isJsonObject(entry)) return [];
|
|
2198
2188
|
const { step, status } = entry;
|
|
2199
2189
|
if (typeof step !== "string" || !isPlanStatus(status)) return [];
|
|
2200
2190
|
return [{
|
|
@@ -2207,6 +2197,48 @@ function isPlanStatus(value) {
|
|
|
2207
2197
|
return value === "pending" || value === "in_progress" || value === "completed";
|
|
2208
2198
|
}
|
|
2209
2199
|
//#endregion
|
|
2200
|
+
//#region extensions/codex/src/app-server/run-attempt-compaction.ts
|
|
2201
|
+
/** Restore host-owned context after native compaction rebuilds a live thread. */
|
|
2202
|
+
async function restoreCodexAttemptCompactionContext(resources) {
|
|
2203
|
+
const { state, prompt } = resources;
|
|
2204
|
+
const { runtime, attemptTools } = prompt.context;
|
|
2205
|
+
const { connection } = runtime;
|
|
2206
|
+
const { params, runAbortController } = connection;
|
|
2207
|
+
const { computerContextEpoch, compactionPlanState } = attemptTools;
|
|
2208
|
+
const { client, thread } = state;
|
|
2209
|
+
const assertCurrent = () => {
|
|
2210
|
+
params.hostCapabilities.assertActive();
|
|
2211
|
+
connection.assertCurrent();
|
|
2212
|
+
thread.liveThreadOwnership?.assertCurrent();
|
|
2213
|
+
if (state.thread !== thread || state.client !== client) throw new Error("Codex compaction thread ownership changed");
|
|
2214
|
+
};
|
|
2215
|
+
computerContextEpoch.value += 1;
|
|
2216
|
+
delete computerContextEpoch.frameToolCallId;
|
|
2217
|
+
delete computerContextEpoch.frameImageIdentity;
|
|
2218
|
+
try {
|
|
2219
|
+
await compactionPlanState.restore({
|
|
2220
|
+
client,
|
|
2221
|
+
threadId: thread.threadId,
|
|
2222
|
+
timeoutMs: connection.appServer.requestTimeoutMs,
|
|
2223
|
+
signal: runAbortController.signal
|
|
2224
|
+
});
|
|
2225
|
+
} catch (error) {
|
|
2226
|
+
embeddedAgentLog.warn("failed to restore Codex plan state after compaction", {
|
|
2227
|
+
runId: params.runId,
|
|
2228
|
+
threadId: thread.threadId,
|
|
2229
|
+
error: formatErrorMessage(error)
|
|
2230
|
+
});
|
|
2231
|
+
}
|
|
2232
|
+
thread.liveThreadEphemeralPolicy = await restoreCodexThreadSkillsCatalogAfterCompaction({
|
|
2233
|
+
client,
|
|
2234
|
+
threadId: thread.threadId,
|
|
2235
|
+
ephemeralPolicy: thread.liveThreadEphemeralPolicy,
|
|
2236
|
+
timeoutMs: connection.appServer.requestTimeoutMs,
|
|
2237
|
+
signal: runAbortController.signal,
|
|
2238
|
+
assertCurrent
|
|
2239
|
+
});
|
|
2240
|
+
}
|
|
2241
|
+
//#endregion
|
|
2210
2242
|
//#region extensions/codex/src/app-server/user-input-bridge.ts
|
|
2211
2243
|
/** Owns per-turn Codex request_user_input and ordinary MCP elicitation lifecycles. */
|
|
2212
2244
|
const DEFAULT_USER_INPUT_TIMEOUT_MS = 9e5;
|
|
@@ -2262,10 +2294,13 @@ function createCodexUserInputBridge(params) {
|
|
|
2262
2294
|
async handleRequest(request, requestSignal) {
|
|
2263
2295
|
const requestParams = readUserInputParams(request.params);
|
|
2264
2296
|
if (!requestParams || requestParams.threadId !== params.threadId || requestParams.turnId !== params.turnId) return;
|
|
2265
|
-
if (requestParams.questions.length === 0) return
|
|
2297
|
+
if (requestParams.questions.length === 0) return emptyAgentHarnessUserInputAnswers();
|
|
2266
2298
|
const timeoutMs = requestParams.isBlocking ? params.paramsForRun.timeoutMs ?? DEFAULT_USER_INPUT_TIMEOUT_MS : NONBLOCKING_USER_INPUT_TIMEOUT_MS;
|
|
2267
|
-
const input =
|
|
2268
|
-
|
|
2299
|
+
const input = agentHarnessStructuredInput.compileQuestions({
|
|
2300
|
+
questions: requestParams.questions,
|
|
2301
|
+
intro: "Codex needs input:"
|
|
2302
|
+
});
|
|
2303
|
+
const cancelValue = emptyAgentHarnessUserInputAnswers();
|
|
2269
2304
|
return await enqueue({
|
|
2270
2305
|
cancelValue,
|
|
2271
2306
|
failureValue: cancelValue,
|
|
@@ -2318,12 +2353,6 @@ function createCodexUserInputBridge(params) {
|
|
|
2318
2353
|
}
|
|
2319
2354
|
};
|
|
2320
2355
|
}
|
|
2321
|
-
function compileUserInputQuestions(questions) {
|
|
2322
|
-
return agentHarnessStructuredInput.compileQuestions({
|
|
2323
|
-
questions,
|
|
2324
|
-
intro: "Codex needs input:"
|
|
2325
|
-
});
|
|
2326
|
-
}
|
|
2327
2356
|
function readUserInputParams(value) {
|
|
2328
2357
|
const snapshot = agentHarnessStructuredInput.snapshot(value);
|
|
2329
2358
|
if (!agentHarnessStructuredInput.isRecord(snapshot)) return;
|
|
@@ -2399,9 +2428,6 @@ function readOwnDataString(value, key) {
|
|
|
2399
2428
|
function gatewayAnswersToCodexResponse(answers) {
|
|
2400
2429
|
return { answers: Object.fromEntries(Object.entries(answers).map(([questionId, values]) => [questionId, { answers: values }])) };
|
|
2401
2430
|
}
|
|
2402
|
-
function emptyUserInputResponse() {
|
|
2403
|
-
return { ...emptyAgentHarnessUserInputAnswers() };
|
|
2404
|
-
}
|
|
2405
2431
|
function declineElicitation(message) {
|
|
2406
2432
|
return createCodexElicitationResponse("decline", null, message ? { message } : null);
|
|
2407
2433
|
}
|
|
@@ -2412,8 +2438,8 @@ function activateCodexAttemptTurn(resources, turnRuntime, lifecycle, notificatio
|
|
|
2412
2438
|
const { context, turnState } = prompt;
|
|
2413
2439
|
const { runtime, attemptTools, hookContext } = context;
|
|
2414
2440
|
const { connection } = runtime;
|
|
2415
|
-
const { params, runAbortController, terminalState, abortExplicitly,
|
|
2416
|
-
const { dynamicToolParams,
|
|
2441
|
+
const { params, runAbortController, terminalState, abortExplicitly, cancellation, sessionAgentId, contextSessionKey, effectiveCwd } = connection;
|
|
2442
|
+
const { dynamicToolParams, toolBridge } = attemptTools;
|
|
2417
2443
|
const { state, completion, userInputBridgeRef, steeringQueueRef, deadlines, noteProgress, completeTurn, interruptTurn } = turnRuntime;
|
|
2418
2444
|
const { emitExecutionPhaseOnce, emitLifecycleStart, maybeAnnounceFastModeAutoOff } = lifecycle;
|
|
2419
2445
|
const { enqueueNotification } = notifications;
|
|
@@ -2532,25 +2558,7 @@ function activateCodexAttemptTurn(resources, turnRuntime, lifecycle, notificatio
|
|
|
2532
2558
|
} } : {},
|
|
2533
2559
|
...prepareNativeMcpAppResultDetails ? { prepareNativeMcpAppResultDetails } : {},
|
|
2534
2560
|
upstreamUserText,
|
|
2535
|
-
onContextCompacted:
|
|
2536
|
-
computerContextEpoch.value += 1;
|
|
2537
|
-
delete computerContextEpoch.frameToolCallId;
|
|
2538
|
-
delete computerContextEpoch.frameImageIdentity;
|
|
2539
|
-
try {
|
|
2540
|
-
await compactionPlanState.restore({
|
|
2541
|
-
client: resourceState.client,
|
|
2542
|
-
threadId: resourceState.thread.threadId,
|
|
2543
|
-
timeoutMs: connection.appServer.requestTimeoutMs,
|
|
2544
|
-
signal: runAbortController.signal
|
|
2545
|
-
});
|
|
2546
|
-
} catch (error) {
|
|
2547
|
-
embeddedAgentLog.warn("failed to restore Codex plan state after compaction", {
|
|
2548
|
-
runId: params.runId,
|
|
2549
|
-
threadId: resourceState.thread.threadId,
|
|
2550
|
-
error: formatErrorMessage(error)
|
|
2551
|
-
});
|
|
2552
|
-
}
|
|
2553
|
-
}
|
|
2561
|
+
onContextCompacted: () => restoreCodexAttemptCompactionContext(resources)
|
|
2554
2562
|
});
|
|
2555
2563
|
const activeProjector = projectorRef.current;
|
|
2556
2564
|
let activationFailed = false;
|
|
@@ -2558,7 +2566,7 @@ function activateCodexAttemptTurn(resources, turnRuntime, lifecycle, notificatio
|
|
|
2558
2566
|
state.abortCleanup = interruptTurn(activeTurnId).then(async (confirmed) => {
|
|
2559
2567
|
if (!activationFailed && !terminalState.explicitCancellationObserved && !state.permissionChangeRestart && !state.timeout) return;
|
|
2560
2568
|
if (!confirmed) throw new Error(state.permissionChangeRestart ? "Permission change could not confirm the previous Codex turn stopped." : "Codex cancellation could not confirm the turn stopped; background terminals may still be running.");
|
|
2561
|
-
if (resources.nativeProcessAuthority) await resources.nativeProcessAuthority.cancelTurn(resourceState.client, resourceState.thread.threadId, activeTurnId);
|
|
2569
|
+
if (resources.nativeProcessAuthority?.requiresProcessAdmission) await resources.nativeProcessAuthority.cancelTurn(resourceState.client, resourceState.thread.threadId, activeTurnId);
|
|
2562
2570
|
else await terminateCodexBackgroundTerminals(resourceState.client, resourceState.thread.threadId);
|
|
2563
2571
|
if (state.permissionChangeRestart) state.permissionChangeRestart = "confirmed";
|
|
2564
2572
|
});
|
|
@@ -2626,16 +2634,14 @@ function activateCodexAttemptTurn(resources, turnRuntime, lifecycle, notificatio
|
|
|
2626
2634
|
signal: runAbortController.signal,
|
|
2627
2635
|
assertActive: assertSteeringActive,
|
|
2628
2636
|
prepareMessage: async (text, options, assertMessageCurrent) => {
|
|
2629
|
-
const attachmentNote = await
|
|
2630
|
-
|
|
2637
|
+
const attachmentNote = await connection.prepareInputAttachments({
|
|
2638
|
+
maxChars: Math.max(0, CODEX_TURN_START_TEXT_INPUT_MAX_CHARS - text.length - 2),
|
|
2631
2639
|
turn: {
|
|
2632
|
-
config: params.config,
|
|
2633
2640
|
media: options.media,
|
|
2634
|
-
timeoutMs: params.timeoutMs,
|
|
2635
|
-
abortSignal: runAbortController.signal,
|
|
2636
2641
|
userTurnTranscriptRecorder: options.userTurnTranscriptRecorder
|
|
2637
2642
|
},
|
|
2638
|
-
assertCurrent: assertMessageCurrent
|
|
2643
|
+
assertCurrent: assertMessageCurrent,
|
|
2644
|
+
signal: runAbortController.signal
|
|
2639
2645
|
});
|
|
2640
2646
|
const result = await detectAndLoadAgentHarnessPromptImages({
|
|
2641
2647
|
...imageContext,
|
|
@@ -2796,11 +2802,7 @@ function activateCodexAttemptTurn(resources, turnRuntime, lifecycle, notificatio
|
|
|
2796
2802
|
cancel: () => abortExplicitly("cancelled"),
|
|
2797
2803
|
abort: () => abortExplicitly("aborted")
|
|
2798
2804
|
};
|
|
2799
|
-
const freezeRunTerminalOutcome =
|
|
2800
|
-
if (terminalState.terminalOutcomeFrozen) return;
|
|
2801
|
-
terminalState.terminalOutcomeFrozen = true;
|
|
2802
|
-
params.abortSignal?.removeEventListener("abort", abortFromUpstream);
|
|
2803
|
-
};
|
|
2805
|
+
const freezeRunTerminalOutcome = cancellation.freezeTerminalOutcome;
|
|
2804
2806
|
const projectionReady = Promise.resolve().then(async () => {
|
|
2805
2807
|
runAbortController.signal.addEventListener("abort", abortListener, { once: true });
|
|
2806
2808
|
if (runAbortController.signal.aborted) abortListener();
|
|
@@ -2931,15 +2933,9 @@ async function cleanupCodexAttempt(resources, turnRuntime, lifecycle, requestRun
|
|
|
2931
2933
|
kind: "clear",
|
|
2932
2934
|
threadId: resourceState.thread.threadId
|
|
2933
2935
|
}) : true;
|
|
2934
|
-
if (!retainLiveThread) {
|
|
2935
|
-
|
|
2936
|
-
|
|
2937
|
-
if (params.oneShotCliRun) await runCleanupStep("codex-one-shot-unsubscribe", async () => {
|
|
2938
|
-
throw new Error("Codex one-shot thread unsubscribe was not confirmed");
|
|
2939
|
-
});
|
|
2940
|
-
}
|
|
2941
|
-
}
|
|
2942
|
-
}
|
|
2936
|
+
if (!retainLiveThread && bindingReleased && !await releaseThreadSubscription() && params.oneShotCliRun) await runCleanupStep("codex-one-shot-unsubscribe", async () => {
|
|
2937
|
+
throw new Error("Codex one-shot thread unsubscribe was not confirmed");
|
|
2938
|
+
});
|
|
2943
2939
|
}
|
|
2944
2940
|
} finally {
|
|
2945
2941
|
if (resourceState.thread.liveThreadOwnership) await runCleanupStep("codex-unsettled-subscription", async () => {
|
|
@@ -2977,6 +2973,13 @@ async function cleanupCodexAttempt(resources, turnRuntime, lifecycle, requestRun
|
|
|
2977
2973
|
}
|
|
2978
2974
|
//#endregion
|
|
2979
2975
|
//#region extensions/codex/src/app-server/session-binding-scope.ts
|
|
2976
|
+
/** Both read and write projections must leave retained assignment facts unchanged. */
|
|
2977
|
+
function projectAssignmentOwner(assignment, owner) {
|
|
2978
|
+
return {
|
|
2979
|
+
...assignment,
|
|
2980
|
+
owner
|
|
2981
|
+
};
|
|
2982
|
+
}
|
|
2980
2983
|
/** Carries one prepared run identity through callers that rederive it from public params. */
|
|
2981
2984
|
function scopeCodexRunBindingStore(params) {
|
|
2982
2985
|
const mapSessionIdentity = (identity) => identity.agentId === params.logicalIdentity.agentId && identity.sessionId === params.logicalIdentity.sessionId && identity.sessionKey?.trim() === params.logicalIdentity.sessionKey?.trim() ? params.physicalIdentity : identity;
|
|
@@ -2993,9 +2996,17 @@ function scopeCodexRunBindingStore(params) {
|
|
|
2993
2996
|
...params.bindingStore,
|
|
2994
2997
|
read: (identity) => params.bindingStore.read(mapIdentity(identity)),
|
|
2995
2998
|
...readMany ? { readMany: (identities) => readMany(identities.map(mapIdentity)) } : {},
|
|
2999
|
+
readNativeSubagentAssignments: (identity, owner) => (params.bindingStore.readNativeSubagentAssignments?.(mapIdentity(identity), mapHistoryOwner(identity, owner)) ?? []).map((assignment) => projectAssignmentOwner(assignment, {
|
|
3000
|
+
...assignment.owner,
|
|
3001
|
+
sessionId: owner.sessionId
|
|
3002
|
+
})),
|
|
2996
3003
|
readNativeSubagentSubmissions: (identity, owner) => params.bindingStore.readNativeSubagentSubmissions(mapIdentity(identity), mapHistoryOwner(identity, owner)),
|
|
2997
3004
|
hasOtherThreadOwner: (threadId, identity) => params.bindingStore.hasOtherThreadOwner(threadId, identity ? mapIdentity(identity) : void 0),
|
|
2998
|
-
mutate: (identity, mutation, assertCurrent) => params.bindingStore.mutate(mapIdentity(identity), mutation.kind === "record-native-subagent-
|
|
3005
|
+
mutate: (identity, mutation, assertCurrent) => params.bindingStore.mutate(mapIdentity(identity), mutation.kind === "record-native-subagent-assignment" || mutation.kind === "consume-native-subagent-assignment" ? {
|
|
3006
|
+
...mutation,
|
|
3007
|
+
owner: mapHistoryOwner(identity, mutation.owner),
|
|
3008
|
+
assignment: projectAssignmentOwner(mutation.assignment, mapHistoryOwner(identity, mutation.assignment.owner))
|
|
3009
|
+
} : mutation.kind === "record-native-subagent-submission" || mutation.kind === "consume-native-subagent-submission" ? {
|
|
2999
3010
|
...mutation,
|
|
3000
3011
|
owner: mapHistoryOwner(identity, mutation.owner)
|
|
3001
3012
|
} : mutation, assertCurrent),
|
|
@@ -3257,7 +3268,7 @@ async function prepareCodexAttemptConnection({ params, options }) {
|
|
|
3257
3268
|
offAnnounced: false,
|
|
3258
3269
|
resetAnnounced: false
|
|
3259
3270
|
};
|
|
3260
|
-
const preDynamicStartupStages =
|
|
3271
|
+
const preDynamicStartupStages = createStageTimingTracker();
|
|
3261
3272
|
const runtimeArtifactRequest = params.captureRuntimeArtifact || params.expectedRuntimeArtifact ? params.expectedRuntimeArtifact ? { expected: params.expectedRuntimeArtifact } : {} : void 0;
|
|
3262
3273
|
const pluginConfig = readCodexPluginConfig(options.pluginConfig);
|
|
3263
3274
|
const requirementsToml = readCodexRequirementsToml({});
|
|
@@ -3301,10 +3312,19 @@ async function prepareCodexAttemptConnection({ params, options }) {
|
|
|
3301
3312
|
...sandbox?.enabled || remoteExec ? void 0 : preparedEnvironment.localIdentityEnv,
|
|
3302
3313
|
...preparedEnvironment.localProcessEnv
|
|
3303
3314
|
} : void 0;
|
|
3304
|
-
const
|
|
3315
|
+
const baseShellEnvironment = preparedShellEnvironment && Object.keys(preparedShellEnvironment).length > 0 ? preparedShellEnvironment : void 0;
|
|
3305
3316
|
const disableLoginShell = remoteExec || preparedEnvironment?.localProcessEnv !== void 0 || preparedEnvironment?.managedLocalIdentity === true || preparedEnvironment !== void 0 && Object.keys(preparedEnvironment.credentialScrubEnv).length > 0;
|
|
3317
|
+
let shellEnvironment = baseShellEnvironment;
|
|
3318
|
+
let shellPathPrepend;
|
|
3306
3319
|
const withPreparedProcessEnv = (appServer) => {
|
|
3307
3320
|
assertLocalTargetSupported(appServer.start.transport !== "stdio" || Boolean(appServer.remoteWorkspaceRoot));
|
|
3321
|
+
const localToolEnv = !sandbox?.enabled && !remoteExec && appServer.start.transport === "stdio" && !isCodexAppServerProxyLaunch(appServer.start.args) && !appServer.remoteWorkspaceRoot ? preparedEnvironment?.localToolEnv : void 0;
|
|
3322
|
+
const hasLocalToolEnv = localToolEnv && Object.keys(localToolEnv).length > 0;
|
|
3323
|
+
shellPathPrepend = hasLocalToolEnv ? preparedEnvironment?.localToolPathPrepend : void 0;
|
|
3324
|
+
shellEnvironment = hasLocalToolEnv ? {
|
|
3325
|
+
...baseShellEnvironment,
|
|
3326
|
+
...localToolEnv
|
|
3327
|
+
} : baseShellEnvironment;
|
|
3308
3328
|
return shellEnvironment ? {
|
|
3309
3329
|
...appServer,
|
|
3310
3330
|
start: {
|
|
@@ -3348,7 +3368,9 @@ async function prepareCodexAttemptConnection({ params, options }) {
|
|
|
3348
3368
|
bindingIdentity = physicalIdentity;
|
|
3349
3369
|
}
|
|
3350
3370
|
}
|
|
3351
|
-
|
|
3371
|
+
let modelExecution;
|
|
3372
|
+
const assertModelExecutionCurrent = () => modelExecution?.assertCurrent();
|
|
3373
|
+
const { binding: admittedBinding, assertCurrent: assertBindingCurrent } = await resolveCodexSessionBinding({
|
|
3352
3374
|
reclaimStale: true,
|
|
3353
3375
|
bindingStore,
|
|
3354
3376
|
identity: bindingIdentity,
|
|
@@ -3358,9 +3380,14 @@ async function prepareCodexAttemptConnection({ params, options }) {
|
|
|
3358
3380
|
signal: params.abortSignal,
|
|
3359
3381
|
assertBinding: params.expectedSessionRuntimeOwnership ? (binding) => assertCodexSessionRuntimeOwnership(binding, params.expectedSessionRuntimeOwnership) : void 0
|
|
3360
3382
|
});
|
|
3383
|
+
const assertCurrent = () => {
|
|
3384
|
+
assertBindingCurrent();
|
|
3385
|
+
assertModelExecutionCurrent();
|
|
3386
|
+
};
|
|
3361
3387
|
let startupBinding = admittedBinding;
|
|
3362
3388
|
preDynamicStartupStages.mark("read-binding");
|
|
3363
3389
|
const usesSupervisionConnection = startupBinding?.connectionScope === "supervision";
|
|
3390
|
+
if (usesSupervisionConnection && isCodexResponsesOAuthRun(params)) throw new Error("ChatGPT subscription sharing requires an OpenClaw-owned Codex session; detach from native supervision first.");
|
|
3364
3391
|
if (usesSupervisionConnection) activeContextEngine = void 0;
|
|
3365
3392
|
if (usesSupervisionConnection && pluginConfig.supervision?.enabled !== true) throw new Error("Codex supervision is disabled; refusing to open a native user-home supervised session");
|
|
3366
3393
|
const resolveRuntimeOptionsForBinding = async (binding, selection) => (await resolveCodexBindingAppServerConnection({
|
|
@@ -3472,13 +3499,9 @@ async function prepareCodexAttemptConnection({ params, options }) {
|
|
|
3472
3499
|
},
|
|
3473
3500
|
agentDir
|
|
3474
3501
|
});
|
|
3475
|
-
return
|
|
3476
|
-
session,
|
|
3477
|
-
appServer: withPreparedProcessEnv(trusted)
|
|
3478
|
-
};
|
|
3502
|
+
return withPreparedProcessEnv(trusted);
|
|
3479
3503
|
};
|
|
3480
|
-
let
|
|
3481
|
-
let appServer = resolvedAppServer.appServer;
|
|
3504
|
+
let appServer = resolveFinalAppServer(configuredAppServer, reviewerPolicyContext);
|
|
3482
3505
|
preDynamicStartupStages.mark("app-server-policy");
|
|
3483
3506
|
preDynamicStartupStages.mark("native-hook-relay");
|
|
3484
3507
|
const terminalState = {
|
|
@@ -3488,28 +3511,32 @@ async function prepareCodexAttemptConnection({ params, options }) {
|
|
|
3488
3511
|
terminalOutcomeFrozen: false,
|
|
3489
3512
|
sharedAbortAllowedAfterTerminalOutcome: false
|
|
3490
3513
|
};
|
|
3491
|
-
const
|
|
3492
|
-
|
|
3493
|
-
|
|
3494
|
-
|
|
3495
|
-
|
|
3496
|
-
|
|
3497
|
-
|
|
3498
|
-
const
|
|
3499
|
-
|
|
3500
|
-
|
|
3501
|
-
|
|
3502
|
-
|
|
3503
|
-
|
|
3504
|
-
|
|
3505
|
-
|
|
3506
|
-
|
|
3507
|
-
|
|
3508
|
-
|
|
3509
|
-
|
|
3514
|
+
const cancellation = createAgentHarnessAttemptCancellation({
|
|
3515
|
+
upstreamSignal: params.abortSignal,
|
|
3516
|
+
onAttemptAbort: () => params.onAttemptAbort?.(),
|
|
3517
|
+
state: terminalState
|
|
3518
|
+
});
|
|
3519
|
+
const { controller: runAbortController, abortExplicitly } = cancellation;
|
|
3520
|
+
let detachModelAbort;
|
|
3521
|
+
const releaseModelExecution = () => {
|
|
3522
|
+
detachModelAbort?.();
|
|
3523
|
+
detachModelAbort = void 0;
|
|
3524
|
+
modelExecution?.release();
|
|
3525
|
+
};
|
|
3526
|
+
const bindModelExecution = (model) => {
|
|
3527
|
+
assertCurrent();
|
|
3528
|
+
const bind = params.hostCapabilities.bindModelExecution;
|
|
3529
|
+
if (!bind) throw new Error("Codex inference requires host model execution authority.");
|
|
3530
|
+
const execution = bind(model);
|
|
3531
|
+
releaseModelExecution();
|
|
3532
|
+
modelExecution = execution;
|
|
3533
|
+
if (!execution) return;
|
|
3534
|
+
const abortModelExecution = () => abortExplicitly(execution.signal.reason);
|
|
3535
|
+
execution.signal.addEventListener("abort", abortModelExecution, { once: true });
|
|
3536
|
+
detachModelAbort = () => execution.signal.removeEventListener("abort", abortModelExecution);
|
|
3537
|
+
if (execution.signal.aborted) abortModelExecution();
|
|
3538
|
+
execution.assertCurrent();
|
|
3510
3539
|
};
|
|
3511
|
-
if (params.abortSignal?.aborted) abortFromUpstream();
|
|
3512
|
-
else params.abortSignal?.addEventListener("abort", abortFromUpstream, { once: true });
|
|
3513
3540
|
try {
|
|
3514
3541
|
const startupBindingBeforeRotation = startupBinding;
|
|
3515
3542
|
const startupBindingResolution = await rotateOversizedCodexAppServerStartupBinding({
|
|
@@ -3532,8 +3559,7 @@ async function prepareCodexAttemptConnection({ params, options }) {
|
|
|
3532
3559
|
modelProvider: reviewerPolicyContext.modelProvider,
|
|
3533
3560
|
model: reviewerPolicyContext.model
|
|
3534
3561
|
});
|
|
3535
|
-
|
|
3536
|
-
appServer = resolvedAppServer.appServer;
|
|
3562
|
+
appServer = resolveFinalAppServer(configuredAppServer, reviewerPolicyContext);
|
|
3537
3563
|
}
|
|
3538
3564
|
const sessionPermissionPolicy = resolveCodexEffectiveSessionPermissionPolicy({
|
|
3539
3565
|
appServer,
|
|
@@ -3556,11 +3582,44 @@ async function prepareCodexAttemptConnection({ params, options }) {
|
|
|
3556
3582
|
pluginAppServer: appServer,
|
|
3557
3583
|
continuityCalibration: startupBindingBeforeRotation?.continuityCalibration
|
|
3558
3584
|
};
|
|
3559
|
-
const resolveRuntimeOptionsForCurrentBinding = async (selection) => resolveFinalAppServer(await resolveRuntimeOptionsForBinding(mutable.startupBinding, selection), selection)
|
|
3585
|
+
const resolveRuntimeOptionsForCurrentBinding = async (selection) => resolveFinalAppServer(await resolveRuntimeOptionsForBinding(mutable.startupBinding, selection), selection);
|
|
3560
3586
|
assertCurrent();
|
|
3561
3587
|
return {
|
|
3562
3588
|
params,
|
|
3589
|
+
prepareInputAttachments: async (request) => {
|
|
3590
|
+
const assertPreparationCurrent = () => {
|
|
3591
|
+
assertCurrent();
|
|
3592
|
+
request.signal?.throwIfAborted();
|
|
3593
|
+
request.assertCurrent();
|
|
3594
|
+
};
|
|
3595
|
+
assertPreparationCurrent();
|
|
3596
|
+
if (request.turn) {
|
|
3597
|
+
const remoteNote = await prepareAgentWorkspaceAttachments({
|
|
3598
|
+
workspaceDir: params.workspaceDir,
|
|
3599
|
+
turn: {
|
|
3600
|
+
...request.turn,
|
|
3601
|
+
config: params.config,
|
|
3602
|
+
timeoutMs: params.timeoutMs,
|
|
3603
|
+
abortSignal: request.signal
|
|
3604
|
+
},
|
|
3605
|
+
assertCurrent: assertPreparationCurrent
|
|
3606
|
+
});
|
|
3607
|
+
assertPreparationCurrent();
|
|
3608
|
+
if (remoteNote) return remoteNote;
|
|
3609
|
+
}
|
|
3610
|
+
if (sandbox?.enabled || params.disableTools || params.toolsAllow?.length === 0 || params.toolExecutionAllow?.length === 0 || remoteExec || appServer.start.transport !== "stdio" || appServer.remoteWorkspaceRoot || params.permissionMode && params.permissionMode !== "full") return;
|
|
3611
|
+
const note = await params.hostCapabilities.prepareInputAttachments?.({
|
|
3612
|
+
...request,
|
|
3613
|
+
placement: "local-host",
|
|
3614
|
+
assertCurrent: assertPreparationCurrent
|
|
3615
|
+
});
|
|
3616
|
+
assertPreparationCurrent();
|
|
3617
|
+
return note;
|
|
3618
|
+
},
|
|
3563
3619
|
assertCurrent,
|
|
3620
|
+
assertModelExecutionCurrent,
|
|
3621
|
+
bindModelExecution,
|
|
3622
|
+
releaseModelExecution,
|
|
3564
3623
|
options,
|
|
3565
3624
|
attemptStartedAt,
|
|
3566
3625
|
profilerEnabled,
|
|
@@ -3582,6 +3641,7 @@ async function prepareCodexAttemptConnection({ params, options }) {
|
|
|
3582
3641
|
sandbox,
|
|
3583
3642
|
agentDir,
|
|
3584
3643
|
shellEnvironment,
|
|
3644
|
+
shellPathPrepend,
|
|
3585
3645
|
disableLoginShell,
|
|
3586
3646
|
bindingIdentity,
|
|
3587
3647
|
bindingStore,
|
|
@@ -3600,7 +3660,7 @@ async function prepareCodexAttemptConnection({ params, options }) {
|
|
|
3600
3660
|
runAbortController,
|
|
3601
3661
|
terminalState,
|
|
3602
3662
|
abortExplicitly,
|
|
3603
|
-
|
|
3663
|
+
cancellation,
|
|
3604
3664
|
resolveReviewerPolicyContext,
|
|
3605
3665
|
resolveRuntimeOptionsForCurrentBinding,
|
|
3606
3666
|
mutable,
|
|
@@ -3608,24 +3668,19 @@ async function prepareCodexAttemptConnection({ params, options }) {
|
|
|
3608
3668
|
initialInactiveThreadBootstrapBindingForcedFreshStart
|
|
3609
3669
|
};
|
|
3610
3670
|
} catch (error) {
|
|
3611
|
-
|
|
3671
|
+
cancellation.dispose();
|
|
3672
|
+
releaseModelExecution();
|
|
3612
3673
|
throw error;
|
|
3613
3674
|
}
|
|
3614
3675
|
}
|
|
3615
3676
|
//#endregion
|
|
3616
3677
|
//#region extensions/codex/src/app-server/attempt-context.ts
|
|
3617
|
-
/**
|
|
3618
|
-
* Builds Codex app-server prompt context,
|
|
3619
|
-
* system-prompt reports, and context-engine projection decisions.
|
|
3620
|
-
*/
|
|
3621
|
-
/** Reads mirrored Codex session history for harness hooks. */
|
|
3622
3678
|
async function readMirroredSessionHistoryMessages(params) {
|
|
3623
3679
|
const { admission, signal, contextTokenBudget, ...target } = params;
|
|
3624
3680
|
const messages = await readCodexMirroredSessionHistoryMessages(target, admission, signal, contextTokenBudget);
|
|
3625
3681
|
if (!messages) embeddedAgentLog.warn("failed to read mirrored session history for codex harness hooks", { sessionFile: params.sessionFile });
|
|
3626
3682
|
return messages;
|
|
3627
3683
|
}
|
|
3628
|
-
/** Reads a valid thread-bootstrap projection request from context-engine output. */
|
|
3629
3684
|
function readContextEngineThreadBootstrapProjection(projection) {
|
|
3630
3685
|
if (projection?.mode !== "thread_bootstrap") return;
|
|
3631
3686
|
const epoch = projection.epoch?.trim();
|
|
@@ -3640,10 +3695,6 @@ function readContextEngineThreadBootstrapProjection(projection) {
|
|
|
3640
3695
|
...fingerprint ? { fingerprint } : {}
|
|
3641
3696
|
};
|
|
3642
3697
|
}
|
|
3643
|
-
/**
|
|
3644
|
-
* Decides whether an existing Codex thread can reuse its context-engine
|
|
3645
|
-
* bootstrap projection or must be reprojected.
|
|
3646
|
-
*/
|
|
3647
3698
|
function resolveContextEngineBootstrapProjectionDecision(params) {
|
|
3648
3699
|
const bindingProjection = params.startupBinding?.contextEngine?.projection;
|
|
3649
3700
|
if (!params.startupBinding?.threadId || !bindingProjection) return {
|
|
@@ -3670,10 +3721,6 @@ function resolveContextEngineBootstrapProjectionDecision(params) {
|
|
|
3670
3721
|
reason: "matching-thread-bootstrap-binding"
|
|
3671
3722
|
};
|
|
3672
3723
|
}
|
|
3673
|
-
/**
|
|
3674
|
-
* Builds the prompt-size, bootstrap-file, skill, and tool-schema accounting
|
|
3675
|
-
* report for a Codex run.
|
|
3676
|
-
*/
|
|
3677
3724
|
function buildCodexSystemPromptReport(params) {
|
|
3678
3725
|
const toolEntries = flattenCodexDynamicToolFunctions(params.tools).map(buildCodexToolReportEntry);
|
|
3679
3726
|
const schemaChars = toolEntries.reduce((sum, tool) => sum + tool.schemaChars, 0);
|
|
@@ -3718,26 +3765,22 @@ function buildCodexSystemPromptReport(params) {
|
|
|
3718
3765
|
}
|
|
3719
3766
|
function buildCodexSkillReportEntries(skillsPrompt) {
|
|
3720
3767
|
if (!skillsPrompt) return [];
|
|
3721
|
-
return Array.from(skillsPrompt.matchAll(/<skill>[\s\S]*?<\/skill>/gi)
|
|
3768
|
+
return Array.from(skillsPrompt.matchAll(/<skill>[\s\S]*?<\/skill>/gi), ([block]) => ({
|
|
3722
3769
|
name: block.match(/<name>\s*([^<]+?)\s*<\/name>/i)?.[1]?.trim() || "(unknown)",
|
|
3723
3770
|
blockChars: block.length
|
|
3724
|
-
}))
|
|
3771
|
+
}));
|
|
3725
3772
|
}
|
|
3726
3773
|
function buildCodexToolReportEntry(tool) {
|
|
3727
3774
|
const summary = tool.description.trim();
|
|
3728
|
-
if (tool.deferLoading === true) return {
|
|
3729
|
-
name: tool.name,
|
|
3730
|
-
summaryChars: summary.length,
|
|
3731
|
-
summaryHash: sha256Text(summary),
|
|
3732
|
-
schemaChars: 0,
|
|
3733
|
-
schemaHash: stableJsonHash(null),
|
|
3734
|
-
propertiesCount: null
|
|
3735
|
-
};
|
|
3736
3775
|
return {
|
|
3737
3776
|
name: tool.name,
|
|
3738
3777
|
summaryChars: summary.length,
|
|
3739
3778
|
summaryHash: sha256Text(summary),
|
|
3740
|
-
...
|
|
3779
|
+
...tool.deferLoading === true ? {
|
|
3780
|
+
schemaChars: 0,
|
|
3781
|
+
schemaHash: stableJsonHash(null),
|
|
3782
|
+
propertiesCount: null
|
|
3783
|
+
} : buildCodexToolSchemaStats(tool.inputSchema)
|
|
3741
3784
|
};
|
|
3742
3785
|
}
|
|
3743
3786
|
function buildCodexToolSchemaStats(schema) {
|
|
@@ -3758,21 +3801,13 @@ function buildCodexToolSchemaStats(schema) {
|
|
|
3758
3801
|
function sha256Text(value) {
|
|
3759
3802
|
return createHash("sha256").update(value).digest("hex");
|
|
3760
3803
|
}
|
|
3761
|
-
function normalizeForStableHash(value) {
|
|
3762
|
-
if (Array.isArray(value)) return value.map((entry) => normalizeForStableHash(entry));
|
|
3763
|
-
if (value && typeof value === "object") {
|
|
3764
|
-
const record = value;
|
|
3765
|
-
return Object.fromEntries(Object.keys(record).toSorted((left, right) => left.localeCompare(right)).map((key) => [key, normalizeForStableHash(record[key])]));
|
|
3766
|
-
}
|
|
3767
|
-
return value;
|
|
3768
|
-
}
|
|
3769
3804
|
function stableJsonHash(value) {
|
|
3770
|
-
return sha256Text(JSON.stringify(
|
|
3805
|
+
return sha256Text(JSON.stringify(stabilizeJsonValue(value)) ?? "null");
|
|
3771
3806
|
}
|
|
3772
3807
|
function buildCodexBootstrapInjectionStats(params) {
|
|
3773
3808
|
const injectedIndex = indexCodexContextFileContent(params.injectedFiles);
|
|
3774
3809
|
const developerInstructionIndex = indexCodexContextFileContent(params.developerInstructionFiles ?? []);
|
|
3775
|
-
const memoryToolRoutedPaths = new Set((params.memoryToolRoutedBootstrapFiles ?? []).map((file) => readNonBlankString(file.path)).filter(isNonEmptyString
|
|
3810
|
+
const memoryToolRoutedPaths = new Set((params.memoryToolRoutedBootstrapFiles ?? []).map((file) => readNonBlankString(file.path)).filter(isNonEmptyString).map(normalizeCodexContextFilePath));
|
|
3776
3811
|
return params.bootstrapFiles.map((file) => {
|
|
3777
3812
|
const fileName = readNonBlankString(file.name);
|
|
3778
3813
|
const pathValue = readNonBlankString(file.path) ?? fileName ?? "";
|
|
@@ -3819,28 +3854,19 @@ function indexCodexContextFileContent(files) {
|
|
|
3819
3854
|
};
|
|
3820
3855
|
}
|
|
3821
3856
|
function readCodexIndexedContextFileContent(index, pathValue, fileName) {
|
|
3822
|
-
const pathContent = index.byPath.get(pathValue);
|
|
3823
|
-
if (pathContent !== void 0) return pathContent;
|
|
3824
|
-
if (fileName) {
|
|
3825
|
-
const nameContent = index.byPath.get(fileName);
|
|
3826
|
-
if (nameContent !== void 0) return nameContent;
|
|
3827
|
-
}
|
|
3828
3857
|
const baseName = getCodexContextFileBasename(fileName ?? pathValue);
|
|
3829
|
-
return baseName ? index.byBaseName.get(baseName) : void 0;
|
|
3858
|
+
return index.byPath.get(pathValue) ?? (fileName ? index.byPath.get(fileName) : void 0) ?? (baseName ? index.byBaseName.get(baseName) : void 0);
|
|
3830
3859
|
}
|
|
3831
3860
|
function readPositiveNumber(value) {
|
|
3832
3861
|
return typeof value === "number" && Number.isFinite(value) && value > 0 ? Math.floor(value) : void 0;
|
|
3833
3862
|
}
|
|
3834
|
-
/**
|
|
3835
|
-
* Builds OpenClaw-provided workspace prompt context for the current Codex turn.
|
|
3836
|
-
*/
|
|
3837
3863
|
function buildCodexOpenClawPromptContext(params) {
|
|
3838
|
-
if (!
|
|
3864
|
+
if (!shouldIncludeAgentHarnessRuntimeContext(params.params)) return;
|
|
3839
3865
|
const sections = [params.workspacePromptContext?.trim() ? [
|
|
3840
3866
|
"## OpenClaw Workspace Context",
|
|
3841
3867
|
"",
|
|
3842
3868
|
params.workspacePromptContext.trim()
|
|
3843
|
-
].join("\n") : void 0, params.watchedSessionsContext?.trim() || void 0].filter(isNonEmptyString
|
|
3869
|
+
].join("\n") : void 0, params.watchedSessionsContext?.trim() || void 0].filter(isNonEmptyString);
|
|
3844
3870
|
if (sections.length === 0) return;
|
|
3845
3871
|
return [
|
|
3846
3872
|
"OpenClaw runtime context for this turn:",
|
|
@@ -3856,7 +3882,7 @@ function buildCodexOpenClawPromptContext(params) {
|
|
|
3856
3882
|
* keep refusing cross-session questions (openclaw#114797).
|
|
3857
3883
|
*/
|
|
3858
3884
|
function buildCodexWatchedSessionsContext(params) {
|
|
3859
|
-
if (!
|
|
3885
|
+
if (!shouldIncludeAgentHarnessRuntimeContext(params.attempt)) return;
|
|
3860
3886
|
return buildWatchedSessionsHarnessContext({
|
|
3861
3887
|
config: params.attempt.config,
|
|
3862
3888
|
sessionKey: params.sessionKey,
|
|
@@ -3864,9 +3890,8 @@ function buildCodexWatchedSessionsContext(params) {
|
|
|
3864
3890
|
toolNames: flattenCodexDynamicToolFunctions(params.dynamicTools).map((tool) => normalizeCodexDynamicToolName(tool.name))
|
|
3865
3891
|
});
|
|
3866
3892
|
}
|
|
3867
|
-
|
|
3868
|
-
|
|
3869
|
-
if (!shouldInjectCodexOpenClawPromptContext(params.attempt)) return;
|
|
3893
|
+
function renderCodexSkillsInstructions(params) {
|
|
3894
|
+
if (!shouldIncludeAgentHarnessRuntimeContext(params.attempt)) return;
|
|
3870
3895
|
return params.skillsPrompt?.trim() ? [
|
|
3871
3896
|
"## OpenClaw Skills",
|
|
3872
3897
|
"",
|
|
@@ -3921,59 +3946,15 @@ function splitLeadingCodexDeliveryHint(prompt) {
|
|
|
3921
3946
|
};
|
|
3922
3947
|
}
|
|
3923
3948
|
//#endregion
|
|
3924
|
-
//#region extensions/codex/src/app-server/run-attempt-state.ts
|
|
3925
|
-
async function clearCodexBindingAfterInvalidImagePayload(bindingStore, identity, fields, expected) {
|
|
3926
|
-
const currentBinding = bindingStore.read(identity);
|
|
3927
|
-
const expectedThreadId = fields.threadId ?? currentBinding?.threadId;
|
|
3928
|
-
if (!expectedThreadId) return;
|
|
3929
|
-
if (currentBinding && currentBinding.threadId !== expectedThreadId) {
|
|
3930
|
-
embeddedAgentLog.warn("codex app-server image payload error detected for unbound thread; preserving thread binding", {
|
|
3931
|
-
...fields,
|
|
3932
|
-
boundThreadId: currentBinding.threadId
|
|
3933
|
-
});
|
|
3934
|
-
return;
|
|
3935
|
-
}
|
|
3936
|
-
if (expected || currentBinding?.connectionScope === "supervision") {
|
|
3937
|
-
embeddedAgentLog.warn("codex app-server image payload error detected for native-owned thread; preserving binding", fields);
|
|
3938
|
-
return;
|
|
3939
|
-
}
|
|
3940
|
-
embeddedAgentLog.warn("codex app-server image payload error detected; clearing thread binding", fields);
|
|
3941
|
-
await bindingStore.mutate(identity, {
|
|
3942
|
-
kind: "clear",
|
|
3943
|
-
threadId: expectedThreadId
|
|
3944
|
-
});
|
|
3945
|
-
}
|
|
3946
|
-
function isNonEmptyString(value) {
|
|
3947
|
-
return typeof value === "string" && value.length > 0;
|
|
3948
|
-
}
|
|
3949
|
-
function shouldUseFreshCodexThreadAfterContextEngineOverflow(params) {
|
|
3950
|
-
if (!params.contextEngineActive || params.thread.lifecycle.action !== "resumed") return false;
|
|
3951
|
-
const message = formatErrorMessage(params.error);
|
|
3952
|
-
return /ran out of room in the model'?s context window/iu.test(message) || /context window/iu.test(message) || /context length/iu.test(message) || /maximum context/iu.test(message) || /too many tokens/iu.test(message);
|
|
3953
|
-
}
|
|
3954
|
-
function isCodexActiveCompactTurnError(error) {
|
|
3955
|
-
if (!(error instanceof CodexAppServerRpcError)) return false;
|
|
3956
|
-
const data = isJsonObject(error.data) ? error.data : void 0;
|
|
3957
|
-
const codexErrorInfo = isJsonObject(data?.codexErrorInfo) ? data.codexErrorInfo : void 0;
|
|
3958
|
-
return (isJsonObject(codexErrorInfo?.activeTurnNotSteerable) ? codexErrorInfo.activeTurnNotSteerable : void 0)?.turnKind === "compact";
|
|
3959
|
-
}
|
|
3960
|
-
function joinPresentSections(...sections) {
|
|
3961
|
-
return sections.filter((section) => Boolean(section?.trim())).join("\n\n");
|
|
3962
|
-
}
|
|
3963
|
-
function prependCurrentInboundContext(prompt, context) {
|
|
3964
|
-
const text = context?.text.trim();
|
|
3965
|
-
return text ? [neutralizeCodexExplicitMentionSigils(text), prompt].filter(Boolean).join("\n\n") : prompt;
|
|
3966
|
-
}
|
|
3967
|
-
//#endregion
|
|
3968
3949
|
//#region extensions/codex/src/app-server/run-attempt-context.ts
|
|
3969
3950
|
async function prepareCodexAttemptContext(runtime, attemptTools) {
|
|
3970
|
-
const { connection, runtimeParams,
|
|
3951
|
+
const { connection, runtimeParams, effectiveContextWindowInfo, effectiveContextTokenBudget, effectiveRuntimeProviderId, effectiveRuntimeModelId, hookChannelId } = runtime;
|
|
3971
3952
|
const { params, sessionAgentId, contextSessionKey, activeContextEngine, initialStartupBindingHadInactiveThreadBootstrap, effectiveWorkspace, effectiveCwd, agentDir, usesSupervisionConnection, resolvedWorkspace, initialInactiveThreadBootstrapBindingForcedFreshStart, sandbox } = connection;
|
|
3972
3953
|
const { toolBridge } = attemptTools;
|
|
3973
3954
|
const activeTranscriptTarget = {
|
|
3974
3955
|
agentId: sessionAgentId,
|
|
3975
|
-
sessionFile:
|
|
3976
|
-
sessionId:
|
|
3956
|
+
sessionFile: runtimeParams.sessionFile,
|
|
3957
|
+
sessionId: runtimeParams.sessionId,
|
|
3977
3958
|
sessionKey: contextSessionKey,
|
|
3978
3959
|
sessionTarget: params.sessionTarget
|
|
3979
3960
|
};
|
|
@@ -4022,7 +4003,7 @@ async function prepareCodexAttemptContext(runtime, attemptTools) {
|
|
|
4022
4003
|
};
|
|
4023
4004
|
const hookRunner = getAgentHarnessHookRunner();
|
|
4024
4005
|
const buildActiveContextEngineRuntimeContext = () => buildHarnessContextEngineRuntimeContext({
|
|
4025
|
-
attempt:
|
|
4006
|
+
attempt: { ...runtimeParams },
|
|
4026
4007
|
workspaceDir: effectiveWorkspace,
|
|
4027
4008
|
cwd: effectiveCwd,
|
|
4028
4009
|
agentDir,
|
|
@@ -4034,9 +4015,9 @@ async function prepareCodexAttemptContext(runtime, attemptTools) {
|
|
|
4034
4015
|
await bootstrapHarnessContextEngine({
|
|
4035
4016
|
hadSessionFile: hadSessionTranscriptState,
|
|
4036
4017
|
contextEngine: activeContextEngine,
|
|
4037
|
-
sessionId:
|
|
4018
|
+
sessionId: runtimeParams.sessionId,
|
|
4038
4019
|
sessionKey: contextSessionKey,
|
|
4039
|
-
sessionFile:
|
|
4020
|
+
sessionFile: runtimeParams.sessionFile,
|
|
4040
4021
|
sessionTarget: params.sessionTarget,
|
|
4041
4022
|
runtimeContext: buildActiveContextEngineRuntimeContext(),
|
|
4042
4023
|
transcriptReadFence: params.userTurnTranscriptRecorder?.getAdmissionReceipt(),
|
|
@@ -4053,7 +4034,6 @@ async function prepareCodexAttemptContext(runtime, attemptTools) {
|
|
|
4053
4034
|
historyState.messages = await readFencedHistory() ?? historyState.messages;
|
|
4054
4035
|
}
|
|
4055
4036
|
historyState.messages.push(...params.pluginRuntimeRefreshMessages ?? []);
|
|
4056
|
-
const memoryToolNames = getCodexWorkspaceMemoryToolNames(toolBridge.availableSpecs);
|
|
4057
4037
|
const workspaceBootstrapContext = await buildCodexWorkspaceBootstrapContext({
|
|
4058
4038
|
params: runtimeParams,
|
|
4059
4039
|
agentWorkspaceDeveloperInstructions: connection.mutable.startupBinding?.agentWorkspaceDeveloperInstructions,
|
|
@@ -4062,11 +4042,15 @@ async function prepareCodexAttemptContext(runtime, attemptTools) {
|
|
|
4062
4042
|
effectiveWorkspace,
|
|
4063
4043
|
sessionKey: contextSessionKey,
|
|
4064
4044
|
sessionAgentId,
|
|
4065
|
-
|
|
4045
|
+
tools: toolBridge.availableSpecs,
|
|
4066
4046
|
ringZeroActive: isHostScopedAgentToolActive("openclaw") && isSystemAgentOnlyCodexDynamicToolAllowlist(runtimeParams.toolsAllow),
|
|
4067
4047
|
sandboxed: sandbox?.enabled === true
|
|
4068
4048
|
});
|
|
4069
4049
|
const agentWorkspaceDeveloperInstructions = workspaceBootstrapContext.threadDeveloperInstructions;
|
|
4050
|
+
const skillsInstructions = renderCodexSkillsInstructions({
|
|
4051
|
+
attempt: runtimeParams,
|
|
4052
|
+
skillsPrompt: params.skillsSnapshot?.prompt
|
|
4053
|
+
});
|
|
4070
4054
|
const baseDeveloperInstructions = joinPresentSections(buildDeveloperInstructions(runtimeParams, { dynamicTools: toolBridge.availableSpecs }), agentWorkspaceDeveloperInstructions);
|
|
4071
4055
|
const watchedSessionsContext = buildCodexWatchedSessionsContext({
|
|
4072
4056
|
attempt: runtimeParams,
|
|
@@ -4092,25 +4076,18 @@ async function prepareCodexAttemptContext(runtime, attemptTools) {
|
|
|
4092
4076
|
agentWorkspaceDeveloperInstructions,
|
|
4093
4077
|
baseDeveloperInstructions,
|
|
4094
4078
|
buildOpenClawPromptContext,
|
|
4095
|
-
|
|
4096
|
-
attempt: runtimeParams,
|
|
4097
|
-
skillsPrompt: params.skillsSnapshot?.prompt
|
|
4098
|
-
}),
|
|
4079
|
+
skillsInstructions,
|
|
4099
4080
|
promptState: {
|
|
4100
4081
|
promptText: params.prompt,
|
|
4101
4082
|
promptContextRange: void 0,
|
|
4102
4083
|
developerInstructions: baseDeveloperInstructions,
|
|
4103
|
-
prePromptMessageCount: historyState.messages.length,
|
|
4104
4084
|
contextEngineProjection: void 0,
|
|
4105
4085
|
precomputedStaleBindingContinuityProjectionApplied: false,
|
|
4106
4086
|
staleBindingContinuityForcedFreshStart: false,
|
|
4107
4087
|
noEngineContinuityProjectionApplied: false,
|
|
4108
4088
|
inactiveThreadBootstrapBindingForcedFreshStart: initialInactiveThreadBootstrapBindingForcedFreshStart
|
|
4109
4089
|
},
|
|
4110
|
-
codexContextProjectionMaxChars: resolveCodexContextEngineProjectionMaxChars({
|
|
4111
|
-
contextTokenBudget: effectiveContextTokenBudget,
|
|
4112
|
-
reserveTokens: resolveCodexContextEngineProjectionReserveTokens()
|
|
4113
|
-
}),
|
|
4090
|
+
codexContextProjectionMaxChars: resolveCodexContextEngineProjectionMaxChars({ contextTokenBudget: effectiveContextTokenBudget }),
|
|
4114
4091
|
codexContinuityProjectionMaxChars: resolveCodexContinuityProjectionMaxChars({
|
|
4115
4092
|
contextTokenBudget: effectiveContextTokenBudget,
|
|
4116
4093
|
calibration: connection.mutable.continuityCalibration
|
|
@@ -4119,23 +4096,6 @@ async function prepareCodexAttemptContext(runtime, attemptTools) {
|
|
|
4119
4096
|
}
|
|
4120
4097
|
//#endregion
|
|
4121
4098
|
//#region extensions/codex/src/app-server/attempt-diagnostics.ts
|
|
4122
|
-
/**
|
|
4123
|
-
* Diagnostic helpers for Codex app-server model calls and plugin-thread config
|
|
4124
|
-
* eligibility.
|
|
4125
|
-
*/
|
|
4126
|
-
/** Reads a tool schema field in either app-server or OpenClaw naming. */
|
|
4127
|
-
function readCodexDiagnosticToolParameters(tool) {
|
|
4128
|
-
return tool.inputSchema ?? tool.parameters;
|
|
4129
|
-
}
|
|
4130
|
-
/** Builds compact diagnostic tool definitions for trusted private telemetry. */
|
|
4131
|
-
function buildCodexDiagnosticToolDefinitions(tools) {
|
|
4132
|
-
return tools.map((tool) => ({
|
|
4133
|
-
name: tool.name,
|
|
4134
|
-
description: tool.description,
|
|
4135
|
-
parameters: readCodexDiagnosticToolParameters(tool)
|
|
4136
|
-
}));
|
|
4137
|
-
}
|
|
4138
|
-
/** Returns the serialized UTF-8 byte length for a JSON-compatible value. */
|
|
4139
4099
|
function utf8JsonByteLength(value) {
|
|
4140
4100
|
try {
|
|
4141
4101
|
return Buffer.byteLength(JSON.stringify(value), "utf8");
|
|
@@ -4143,7 +4103,6 @@ function utf8JsonByteLength(value) {
|
|
|
4143
4103
|
return;
|
|
4144
4104
|
}
|
|
4145
4105
|
}
|
|
4146
|
-
/** Builds a short namespaced fingerprint for sensitive log values. */
|
|
4147
4106
|
function fingerprintCodexLogValue(namespace, value) {
|
|
4148
4107
|
const hash = createHash("sha256");
|
|
4149
4108
|
hash.update(namespace);
|
|
@@ -4151,10 +4110,6 @@ function fingerprintCodexLogValue(namespace, value) {
|
|
|
4151
4110
|
hash.update(value);
|
|
4152
4111
|
return `sha256:${hash.digest("hex").slice(0, 16)}`;
|
|
4153
4112
|
}
|
|
4154
|
-
/**
|
|
4155
|
-
* Builds redacted diagnostics explaining whether plugin thread config was
|
|
4156
|
-
* eligible for a Codex app-server attempt.
|
|
4157
|
-
*/
|
|
4158
4113
|
function buildCodexPluginThreadConfigEligibilityLogData(params) {
|
|
4159
4114
|
return {
|
|
4160
4115
|
sessionId: params.sessionId,
|
|
@@ -4171,27 +4126,38 @@ function buildCodexPluginThreadConfigEligibilityLogData(params) {
|
|
|
4171
4126
|
appServerCommandSource: params.appServer.start.commandSource
|
|
4172
4127
|
};
|
|
4173
4128
|
}
|
|
4174
|
-
/**
|
|
4175
|
-
* Creates lifecycle emitters for trusted model-call diagnostics with optional
|
|
4176
|
-
* private payload capture.
|
|
4177
|
-
*/
|
|
4178
4129
|
function createCodexModelCallDiagnosticEmitter(params) {
|
|
4179
4130
|
const now = params.now ?? (() => Date.now());
|
|
4180
|
-
const toolDefinitions = params.capture.toolDefinitions ?
|
|
4131
|
+
const toolDefinitions = params.capture.toolDefinitions ? params.tools.map((tool) => ({
|
|
4132
|
+
name: tool.name,
|
|
4133
|
+
description: tool.description,
|
|
4134
|
+
parameters: tool.inputSchema ?? tool.parameters
|
|
4135
|
+
})) : void 0;
|
|
4181
4136
|
let startedAt = now();
|
|
4182
4137
|
let started = false;
|
|
4183
4138
|
let terminalEmitted = false;
|
|
4184
4139
|
let requestPayloadBytes;
|
|
4185
4140
|
const privateData = (modelContent) => modelContent && Object.keys(modelContent).length > 0 ? { modelContent } : void 0;
|
|
4186
|
-
const buildContent = () => {
|
|
4187
|
-
|
|
4188
|
-
|
|
4189
|
-
|
|
4190
|
-
|
|
4191
|
-
|
|
4192
|
-
|
|
4141
|
+
const buildContent = () => ({
|
|
4142
|
+
...params.capture.inputMessages ? { inputMessages: params.buildInputMessages() } : {},
|
|
4143
|
+
...params.capture.systemPrompt ? { systemPrompt: params.buildSystemPrompt() } : {},
|
|
4144
|
+
...toolDefinitions ? { toolDefinitions } : {}
|
|
4145
|
+
});
|
|
4146
|
+
const emitTerminal = (type, outputMessages, fields = {}) => {
|
|
4147
|
+
if (!started || terminalEmitted) return false;
|
|
4148
|
+
terminalEmitted = true;
|
|
4149
|
+
emitTrustedDiagnosticEventWithPrivateData({
|
|
4150
|
+
type,
|
|
4151
|
+
...params.baseFields,
|
|
4152
|
+
durationMs: Math.max(0, now() - startedAt),
|
|
4153
|
+
...fields,
|
|
4154
|
+
...requestPayloadBytes !== void 0 ? { requestPayloadBytes } : {}
|
|
4155
|
+
}, privateData({
|
|
4156
|
+
...buildContent(),
|
|
4157
|
+
...params.capture.outputMessages ? { outputMessages } : {}
|
|
4158
|
+
}));
|
|
4159
|
+
return true;
|
|
4193
4160
|
};
|
|
4194
|
-
const requestPayloadBytesField = () => requestPayloadBytes !== void 0 ? { requestPayloadBytes } : {};
|
|
4195
4161
|
return {
|
|
4196
4162
|
setRequestPayloadBytes(bytes) {
|
|
4197
4163
|
requestPayloadBytes = bytes;
|
|
@@ -4205,37 +4171,16 @@ function createCodexModelCallDiagnosticEmitter(params) {
|
|
|
4205
4171
|
}, privateData(buildContent()));
|
|
4206
4172
|
},
|
|
4207
4173
|
emitCompleted(result) {
|
|
4208
|
-
|
|
4209
|
-
terminalEmitted = true;
|
|
4210
|
-
emitTrustedDiagnosticEventWithPrivateData({
|
|
4211
|
-
type: "model.call.completed",
|
|
4212
|
-
...params.baseFields,
|
|
4213
|
-
durationMs: Math.max(0, now() - startedAt),
|
|
4214
|
-
...requestPayloadBytesField()
|
|
4215
|
-
}, privateData({
|
|
4216
|
-
...buildContent(),
|
|
4217
|
-
...params.capture.outputMessages ? { outputMessages: result.lastAssistant ? [result.lastAssistant] : result.assistantTexts } : {}
|
|
4218
|
-
}));
|
|
4174
|
+
emitTerminal("model.call.completed", result.lastAssistant ? [result.lastAssistant] : result.assistantTexts);
|
|
4219
4175
|
},
|
|
4220
4176
|
emitError(error, fields = {}) {
|
|
4221
|
-
if (
|
|
4222
|
-
terminalEmitted = true;
|
|
4223
|
-
emitTrustedDiagnosticEventWithPrivateData({
|
|
4224
|
-
type: "model.call.error",
|
|
4225
|
-
...params.baseFields,
|
|
4226
|
-
durationMs: Math.max(0, now() - startedAt),
|
|
4177
|
+
if (emitTerminal("model.call.error", [], {
|
|
4227
4178
|
errorCategory: fields.failureKind ?? "error",
|
|
4228
|
-
...fields.failureKind ? { failureKind: fields.failureKind } : {}
|
|
4229
|
-
|
|
4230
|
-
}, privateData({
|
|
4231
|
-
...buildContent(),
|
|
4232
|
-
...params.capture.outputMessages ? { outputMessages: [] } : {}
|
|
4233
|
-
}));
|
|
4234
|
-
params.onErrorDiagnostic?.(error);
|
|
4179
|
+
...fields.failureKind ? { failureKind: fields.failureKind } : {}
|
|
4180
|
+
})) params.onErrorDiagnostic?.(error);
|
|
4235
4181
|
}
|
|
4236
4182
|
};
|
|
4237
4183
|
}
|
|
4238
|
-
/** Classifies model-call failures into timeout/abort buckets for diagnostics. */
|
|
4239
4184
|
function classifyCodexModelCallFailureKind(params) {
|
|
4240
4185
|
if (params.timedOut) return "timeout";
|
|
4241
4186
|
const errorMessage = params.error ? params.formatError(params.error).toLowerCase() : "";
|
|
@@ -4245,7 +4190,6 @@ function classifyCodexModelCallFailureKind(params) {
|
|
|
4245
4190
|
}
|
|
4246
4191
|
//#endregion
|
|
4247
4192
|
//#region extensions/codex/src/app-server/attempt-results.ts
|
|
4248
|
-
/** Joins terminal assistant text blocks into the final attempt answer. */
|
|
4249
4193
|
function collectTerminalAssistantText(result) {
|
|
4250
4194
|
return result.assistantTexts.join("\n\n").trim();
|
|
4251
4195
|
}
|
|
@@ -4258,14 +4202,12 @@ function buildCodexAppServerPromptTimeoutOutcome(timeout) {
|
|
|
4258
4202
|
livenessState: "abandoned"
|
|
4259
4203
|
};
|
|
4260
4204
|
}
|
|
4261
|
-
/** Explains why an incomplete app-server turn cannot be safely replayed. */
|
|
4262
4205
|
function resolveCodexAppServerReplayBlockedReason(result) {
|
|
4263
4206
|
if (result.replayMetadata.hadPotentialSideEffects) return "potential_side_effect";
|
|
4264
4207
|
if (result.assistantTexts.some((text) => text.trim().length > 0)) return "assistant_output";
|
|
4265
4208
|
if (result.toolMetas.length > 0 || result.clientToolCalls || result.lastToolError || result.didSendDeterministicApprovalPrompt) return "tool_activity";
|
|
4266
4209
|
if (result.itemLifecycle.startedCount > 0 || result.itemLifecycle.activeCount > 0) return "active_item";
|
|
4267
4210
|
}
|
|
4268
|
-
/** Builds an attempt result for failures before the app-server turn starts. */
|
|
4269
4211
|
function buildCodexTurnStartFailureResult(params) {
|
|
4270
4212
|
return {
|
|
4271
4213
|
terminal: attemptTerminal.normalize({
|
|
@@ -4296,7 +4238,6 @@ function buildCodexTurnStartFailureResult(params) {
|
|
|
4296
4238
|
systemPromptReport: params.systemPromptReport
|
|
4297
4239
|
};
|
|
4298
4240
|
}
|
|
4299
|
-
/** Detects app-server errors caused by invalid image payload data. */
|
|
4300
4241
|
function isInvalidCodexImagePayloadError(message) {
|
|
4301
4242
|
if (typeof message !== "string" || !message.trim()) return false;
|
|
4302
4243
|
const normalizedMessage = message.replace(/[_-]+/gu, " ");
|
|
@@ -4325,37 +4266,150 @@ async function settleReplyMedia(activeTurn, result, { state, settlementExpired }
|
|
|
4325
4266
|
if (signal.aborted) await state.abortCleanup;
|
|
4326
4267
|
}
|
|
4327
4268
|
//#endregion
|
|
4328
|
-
//#region extensions/codex/src/app-server/
|
|
4329
|
-
|
|
4330
|
-
|
|
4331
|
-
|
|
4332
|
-
const
|
|
4333
|
-
|
|
4334
|
-
|
|
4335
|
-
|
|
4336
|
-
|
|
4337
|
-
|
|
4338
|
-
|
|
4339
|
-
|
|
4269
|
+
//#region extensions/codex/src/app-server/run-attempt-settlement.ts
|
|
4270
|
+
async function beginCodexAttemptSettlement(resources, turnRuntime, notifications, activeTurn) {
|
|
4271
|
+
const { state: resourceState } = resources;
|
|
4272
|
+
const { connection } = resources.prompt.context.runtime;
|
|
4273
|
+
const { params, runAbortController, appServer } = connection;
|
|
4274
|
+
const { state, deadlines, settlementExpired } = turnRuntime;
|
|
4275
|
+
const { drainNotificationQueue } = notifications;
|
|
4276
|
+
const { activeProjector, activeTurnId } = activeTurn;
|
|
4277
|
+
const drainGraceElapsed = createDeferred();
|
|
4278
|
+
let settlementPhase = "active";
|
|
4279
|
+
let drainGraceTimer;
|
|
4280
|
+
const beginDrainGrace = () => {
|
|
4281
|
+
if (settlementPhase !== "active" || drainGraceTimer) return;
|
|
4282
|
+
drainGraceTimer = setTimeout(() => {
|
|
4283
|
+
settlementPhase = "expired";
|
|
4284
|
+
drainGraceElapsed.resolve();
|
|
4285
|
+
}, TURN_FINALIZE_DRAIN_ABORT_GRACE_MS);
|
|
4286
|
+
drainGraceTimer.unref?.();
|
|
4340
4287
|
};
|
|
4341
|
-
|
|
4342
|
-
|
|
4343
|
-
function recordCodexTrajectoryContext(recorder, params) {
|
|
4344
|
-
if (!recorder) return;
|
|
4345
|
-
recorder.recordEvent("context.compiled", {
|
|
4346
|
-
systemPrompt: params.developerInstructions,
|
|
4347
|
-
prompt: params.prompt ?? params.attempt.prompt,
|
|
4348
|
-
imagesCount: params.attempt.images?.length ?? 0,
|
|
4349
|
-
tools: toTrajectoryToolDefinitions(params.tools)
|
|
4288
|
+
const abortListener = addAbortListener(runAbortController.signal, () => {
|
|
4289
|
+
state.abortCleanup.then(beginDrainGrace, beginDrainGrace);
|
|
4350
4290
|
});
|
|
4291
|
+
const closeProjection = () => {
|
|
4292
|
+
state.projectionClosed = true;
|
|
4293
|
+
return activeProjector.closeProjection();
|
|
4294
|
+
};
|
|
4295
|
+
const closeSettlement = () => {
|
|
4296
|
+
if (settlementPhase === "closed") return;
|
|
4297
|
+
settlementPhase = "closed";
|
|
4298
|
+
abortListener[Symbol.dispose]();
|
|
4299
|
+
clearTimeout(drainGraceTimer);
|
|
4300
|
+
deadlines.dispose();
|
|
4301
|
+
};
|
|
4302
|
+
if (state.pluginRuntimeRefreshStop) await state.pluginRuntimeRefreshStop.catch(() => void 0);
|
|
4303
|
+
let readRetainedNativeCommands;
|
|
4304
|
+
return {
|
|
4305
|
+
settlement: drainNotificationQueue().then(async () => {
|
|
4306
|
+
const commands = activeProjector.getPendingNativeCommands();
|
|
4307
|
+
if (commands.size > 0 && !params.oneShotCliRun && !state.pluginRuntimeRefreshStop) {
|
|
4308
|
+
try {
|
|
4309
|
+
const readCurrent = await readCodexRetainedBackgroundCommands({
|
|
4310
|
+
client: resourceState.client,
|
|
4311
|
+
threadId: resourceState.thread.threadId,
|
|
4312
|
+
turnId: activeTurnId,
|
|
4313
|
+
commands,
|
|
4314
|
+
authority: resources.nativeProcessAuthority,
|
|
4315
|
+
assertCurrent: connection.assertCurrent,
|
|
4316
|
+
signal: runAbortController.signal,
|
|
4317
|
+
timeoutMs: appServer.requestTimeoutMs
|
|
4318
|
+
});
|
|
4319
|
+
readRetainedNativeCommands = () => {
|
|
4320
|
+
try {
|
|
4321
|
+
return readCurrent();
|
|
4322
|
+
} catch {
|
|
4323
|
+
return /* @__PURE__ */ new Map();
|
|
4324
|
+
}
|
|
4325
|
+
};
|
|
4326
|
+
} catch (error) {
|
|
4327
|
+
embeddedAgentLog.debug("could not confirm retained native commands", {
|
|
4328
|
+
threadId: resourceState.thread.threadId,
|
|
4329
|
+
error: formatErrorMessage(error)
|
|
4330
|
+
});
|
|
4331
|
+
}
|
|
4332
|
+
await drainNotificationQueue();
|
|
4333
|
+
}
|
|
4334
|
+
await closeProjection();
|
|
4335
|
+
await activeProjector.settlement.drain();
|
|
4336
|
+
}),
|
|
4337
|
+
degradedSettlement: settlementExpired.then(() => {
|
|
4338
|
+
beginDrainGrace();
|
|
4339
|
+
}),
|
|
4340
|
+
drainGraceElapsed,
|
|
4341
|
+
closeProjection,
|
|
4342
|
+
closeSettlement,
|
|
4343
|
+
isActive: () => settlementPhase === "active",
|
|
4344
|
+
readRetainedNativeCommands: () => readRetainedNativeCommands?.() ?? /* @__PURE__ */ new Map()
|
|
4345
|
+
};
|
|
4351
4346
|
}
|
|
4352
|
-
|
|
4353
|
-
|
|
4354
|
-
|
|
4355
|
-
const
|
|
4356
|
-
|
|
4357
|
-
|
|
4358
|
-
|
|
4347
|
+
//#endregion
|
|
4348
|
+
//#region extensions/codex/src/app-server/run-attempt-state.ts
|
|
4349
|
+
async function clearCodexBindingAfterInvalidImagePayload(bindingStore, identity, fields, expected) {
|
|
4350
|
+
const currentBinding = bindingStore.read(identity);
|
|
4351
|
+
const expectedThreadId = fields.threadId ?? currentBinding?.threadId;
|
|
4352
|
+
if (!expectedThreadId) return;
|
|
4353
|
+
if (currentBinding && currentBinding.threadId !== expectedThreadId) {
|
|
4354
|
+
embeddedAgentLog.warn("codex app-server image payload error detected for unbound thread; preserving thread binding", {
|
|
4355
|
+
...fields,
|
|
4356
|
+
boundThreadId: currentBinding.threadId
|
|
4357
|
+
});
|
|
4358
|
+
return;
|
|
4359
|
+
}
|
|
4360
|
+
if (expected || currentBinding?.connectionScope === "supervision") {
|
|
4361
|
+
embeddedAgentLog.warn("codex app-server image payload error detected for native-owned thread; preserving binding", fields);
|
|
4362
|
+
return;
|
|
4363
|
+
}
|
|
4364
|
+
embeddedAgentLog.warn("codex app-server image payload error detected; clearing thread binding", fields);
|
|
4365
|
+
await bindingStore.mutate(identity, {
|
|
4366
|
+
kind: "clear",
|
|
4367
|
+
threadId: expectedThreadId
|
|
4368
|
+
});
|
|
4369
|
+
}
|
|
4370
|
+
function shouldUseFreshCodexThreadAfterContextEngineOverflow(params) {
|
|
4371
|
+
if (!params.contextEngineActive || params.thread.lifecycle.action !== "resumed") return false;
|
|
4372
|
+
return /context (?:window|length)|maximum context|too many tokens/iu.test(formatErrorMessage(params.error));
|
|
4373
|
+
}
|
|
4374
|
+
function isCodexActiveCompactTurnError(error) {
|
|
4375
|
+
if (!(error instanceof CodexAppServerRpcError)) return false;
|
|
4376
|
+
const data = isJsonObject(error.data) ? error.data : void 0;
|
|
4377
|
+
const codexErrorInfo = isJsonObject(data?.codexErrorInfo) ? data.codexErrorInfo : void 0;
|
|
4378
|
+
return (isJsonObject(codexErrorInfo?.activeTurnNotSteerable) ? codexErrorInfo.activeTurnNotSteerable : void 0)?.turnKind === "compact";
|
|
4379
|
+
}
|
|
4380
|
+
function prependCurrentInboundContext(prompt, context) {
|
|
4381
|
+
const text = context?.text.trim();
|
|
4382
|
+
return text ? [neutralizeCodexExplicitMentionSigils(text), prompt].filter(Boolean).join("\n\n") : prompt;
|
|
4383
|
+
}
|
|
4384
|
+
//#endregion
|
|
4385
|
+
//#region extensions/codex/src/app-server/trajectory.ts
|
|
4386
|
+
function createCodexTrajectoryRecorder(params) {
|
|
4387
|
+
if (!params.trajectory) return null;
|
|
4388
|
+
const trajectory = params.trajectory;
|
|
4389
|
+
return {
|
|
4390
|
+
recordEvent: (type, data) => {
|
|
4391
|
+
try {
|
|
4392
|
+
trajectory.recordEvent(type, data);
|
|
4393
|
+
} catch {}
|
|
4394
|
+
},
|
|
4395
|
+
flush: trajectory.flush
|
|
4396
|
+
};
|
|
4397
|
+
}
|
|
4398
|
+
function recordCodexTrajectoryContext(recorder, params) {
|
|
4399
|
+
if (!recorder) return;
|
|
4400
|
+
recorder.recordEvent("context.compiled", {
|
|
4401
|
+
systemPrompt: params.developerInstructions,
|
|
4402
|
+
prompt: params.prompt ?? params.attempt.prompt,
|
|
4403
|
+
imagesCount: params.attempt.images?.length ?? 0,
|
|
4404
|
+
tools: toTrajectoryToolDefinitions(params.tools)
|
|
4405
|
+
});
|
|
4406
|
+
}
|
|
4407
|
+
function recordCodexTrajectoryCompletion(recorder, params) {
|
|
4408
|
+
if (!recorder) return;
|
|
4409
|
+
const terminal = attemptTerminal.project(params.result.terminal);
|
|
4410
|
+
recorder.recordEvent("model.completed", {
|
|
4411
|
+
threadId: params.threadId,
|
|
4412
|
+
turnId: params.turnId,
|
|
4359
4413
|
timedOut: params.timedOut,
|
|
4360
4414
|
yieldDetected: params.yieldDetected ?? false,
|
|
4361
4415
|
aborted: terminal.aborted,
|
|
@@ -4378,7 +4432,6 @@ function toTrajectoryToolDefinitions(tools) {
|
|
|
4378
4432
|
}];
|
|
4379
4433
|
}).toSorted((left, right) => left.name.localeCompare(right.name));
|
|
4380
4434
|
}
|
|
4381
|
-
/** Converts arbitrary prompt errors into trajectory-safe text. */
|
|
4382
4435
|
function normalizeCodexTrajectoryError(value) {
|
|
4383
4436
|
if (!value) return null;
|
|
4384
4437
|
if (value instanceof Error) return value.message;
|
|
@@ -4395,7 +4448,7 @@ async function finalizeCodexAttempt(resources, turnRuntime, lifecycle, notificat
|
|
|
4395
4448
|
const { prompt, state: resourceState, trajectoryRecorder, markTrajectoryEndRecorded } = resources;
|
|
4396
4449
|
const { context, systemPromptReport } = prompt;
|
|
4397
4450
|
const { runtime, attemptTools, activeTranscriptTarget, hookContext } = context;
|
|
4398
|
-
const {
|
|
4451
|
+
const { hookRunner } = context;
|
|
4399
4452
|
const { connection, preparedAuthBinding } = runtime;
|
|
4400
4453
|
const { effectiveRuntimeProviderId, effectiveRuntimeModelId } = runtime;
|
|
4401
4454
|
const { params, terminalState, runAbortController, activeContextEngine, bindingStore, bindingIdentity, appServer, usesSupervisionConnection, sessionAgentId, contextSessionKey, effectiveCwd, agentDir, attemptStartedAt, startupAuthProfileId } = connection;
|
|
@@ -4411,45 +4464,12 @@ async function finalizeCodexAttempt(resources, turnRuntime, lifecycle, notificat
|
|
|
4411
4464
|
assertCodexBindingMayBeReplaced(resourceState.thread, operation);
|
|
4412
4465
|
return true;
|
|
4413
4466
|
};
|
|
4414
|
-
const { state, completion
|
|
4467
|
+
const { state, completion } = turnRuntime;
|
|
4415
4468
|
const { emitLifecycleTerminal, buildLifecycleTerminalMeta } = lifecycle;
|
|
4416
|
-
const {
|
|
4417
|
-
const { codexModelCallDiagnostics } = requestRuntime;
|
|
4469
|
+
const { codexModelCallDiagnostics, buildLlmOutputEvent } = requestRuntime;
|
|
4418
4470
|
const { activeTurnId, activeProjector, runtimeModelSelection, streamState, freezeRunTerminalOutcome, notifyUserMessagePersisted } = activeTurn;
|
|
4419
4471
|
await completion;
|
|
4420
|
-
const drainGraceElapsed =
|
|
4421
|
-
let settlementPhase = "active";
|
|
4422
|
-
let drainGraceTimer;
|
|
4423
|
-
const beginDrainGrace = () => {
|
|
4424
|
-
if (settlementPhase !== "active" || drainGraceTimer) return;
|
|
4425
|
-
drainGraceTimer = setTimeout(() => {
|
|
4426
|
-
settlementPhase = "expired";
|
|
4427
|
-
drainGraceElapsed.resolve();
|
|
4428
|
-
}, TURN_FINALIZE_DRAIN_ABORT_GRACE_MS);
|
|
4429
|
-
drainGraceTimer.unref?.();
|
|
4430
|
-
};
|
|
4431
|
-
const abortListener = addAbortListener(runAbortController.signal, () => {
|
|
4432
|
-
state.abortCleanup.then(beginDrainGrace, beginDrainGrace);
|
|
4433
|
-
});
|
|
4434
|
-
const closeProjection = () => {
|
|
4435
|
-
state.projectionClosed = true;
|
|
4436
|
-
return activeProjector.closeProjection();
|
|
4437
|
-
};
|
|
4438
|
-
const closeSettlement = () => {
|
|
4439
|
-
if (settlementPhase === "closed") return;
|
|
4440
|
-
settlementPhase = "closed";
|
|
4441
|
-
abortListener[Symbol.dispose]();
|
|
4442
|
-
clearTimeout(drainGraceTimer);
|
|
4443
|
-
deadlines.dispose();
|
|
4444
|
-
};
|
|
4445
|
-
if (state.pluginRuntimeRefreshStop) await state.pluginRuntimeRefreshStop.catch(() => void 0);
|
|
4446
|
-
const settlement = drainNotificationQueue().then(async () => {
|
|
4447
|
-
await closeProjection();
|
|
4448
|
-
await activeProjector.settlement.drain();
|
|
4449
|
-
});
|
|
4450
|
-
const degradedSettlement = settlementExpired.then(() => {
|
|
4451
|
-
beginDrainGrace();
|
|
4452
|
-
});
|
|
4472
|
+
const { settlement, degradedSettlement, drainGraceElapsed, closeProjection, closeSettlement, isActive: isSettlementActive, readRetainedNativeCommands } = await beginCodexAttemptSettlement(resources, turnRuntime, notifications, activeTurn);
|
|
4453
4473
|
let projectionDrained = false;
|
|
4454
4474
|
try {
|
|
4455
4475
|
try {
|
|
@@ -4464,6 +4484,7 @@ async function finalizeCodexAttempt(resources, turnRuntime, lifecycle, notificat
|
|
|
4464
4484
|
}
|
|
4465
4485
|
const result = activeProjector.buildResult(toolBridge.telemetry, {
|
|
4466
4486
|
yieldDetected: toolState.yieldDetected,
|
|
4487
|
+
readRetainedNativeCommands,
|
|
4467
4488
|
steeringMessages: params.pluginRuntimeRefreshPending?.() ? turnRuntime.steeringQueueRef.current?.getAcceptedMessages() : void 0
|
|
4468
4489
|
});
|
|
4469
4490
|
const projectedTerminal = attemptTerminal.project(result.terminal);
|
|
@@ -4578,7 +4599,7 @@ async function finalizeCodexAttempt(resources, turnRuntime, lifecycle, notificat
|
|
|
4578
4599
|
state.pendingSettlementStage = "transcript/mirror";
|
|
4579
4600
|
return codexTranscriptMirrorRuntime.mirrorBestEffort({
|
|
4580
4601
|
assertWriteCurrent: () => {
|
|
4581
|
-
if (
|
|
4602
|
+
if (!isSettlementActive() || state.settlementWarning !== warning) throw new Error("Codex transcript settlement is no longer active");
|
|
4582
4603
|
const current = projectTerminalOutcome();
|
|
4583
4604
|
if (current.finalAborted !== mirrorTerminal.finalAborted || current.effectiveTimedOut !== mirrorTerminal.effectiveTimedOut || current.finalPromptError !== mirrorTerminal.finalPromptError) throw new Error("Codex transcript terminal outcome changed before write");
|
|
4584
4605
|
},
|
|
@@ -4594,7 +4615,7 @@ async function finalizeCodexAttempt(resources, turnRuntime, lifecycle, notificat
|
|
|
4594
4615
|
});
|
|
4595
4616
|
};
|
|
4596
4617
|
try {
|
|
4597
|
-
if (projectionDrained &&
|
|
4618
|
+
if (projectionDrained && isSettlementActive() && !state.settlementWarning) mirrorOutcome = await Promise.race([
|
|
4598
4619
|
mirrorFinal(),
|
|
4599
4620
|
drainGraceElapsed.promise.then(() => unavailableMirror),
|
|
4600
4621
|
degradedSettlement.then(() => unavailableMirror)
|
|
@@ -4619,7 +4640,7 @@ async function finalizeCodexAttempt(resources, turnRuntime, lifecycle, notificat
|
|
|
4619
4640
|
message: toolState.yieldMessage,
|
|
4620
4641
|
assertCurrent: () => {
|
|
4621
4642
|
connection.assertCurrent();
|
|
4622
|
-
if (
|
|
4643
|
+
if (!isSettlementActive() || !projectTerminalOutcome().turnSucceeded) throw new Error("Codex yield settlement is no longer active");
|
|
4623
4644
|
}
|
|
4624
4645
|
}),
|
|
4625
4646
|
drainGraceElapsed.promise,
|
|
@@ -4670,13 +4691,7 @@ async function finalizeCodexAttempt(resources, turnRuntime, lifecycle, notificat
|
|
|
4670
4691
|
});
|
|
4671
4692
|
runAgentHarnessLlmOutputHook({
|
|
4672
4693
|
event: {
|
|
4673
|
-
|
|
4674
|
-
sessionId: params.sessionId,
|
|
4675
|
-
provider: usesSupervisionConnection ? resourceState.thread.modelProvider ?? effectiveRuntimeProviderId : params.provider,
|
|
4676
|
-
model: usesSupervisionConnection ? resourceState.thread.model ?? effectiveRuntimeModelId : params.modelId,
|
|
4677
|
-
...hookContextWindowFields,
|
|
4678
|
-
resolvedRef: usesSupervisionConnection ? `${resourceState.thread.modelProvider ?? effectiveRuntimeProviderId}/${resourceState.thread.model ?? effectiveRuntimeModelId}` : params.runtimePlan?.observability.resolvedRef ?? `${params.provider}/${params.modelId}`,
|
|
4679
|
-
...!usesSupervisionConnection && params.runtimePlan?.observability.harnessId ? { harnessId: params.runtimePlan.observability.harnessId } : {},
|
|
4694
|
+
...buildLlmOutputEvent(),
|
|
4680
4695
|
assistantTexts: result.assistantTexts,
|
|
4681
4696
|
...result.lastAssistant ? { lastAssistant: result.lastAssistant } : {},
|
|
4682
4697
|
...result.attemptUsage ? { usage: result.attemptUsage } : {}
|
|
@@ -4812,7 +4827,7 @@ function reportCodexExecutionNotification(params) {
|
|
|
4812
4827
|
}
|
|
4813
4828
|
if (notification.method !== "item/started") return;
|
|
4814
4829
|
const item = readCodexNotificationItem(notification.params);
|
|
4815
|
-
const tool = item ?
|
|
4830
|
+
const tool = item ? itemName(item) : void 0;
|
|
4816
4831
|
if (!item || !tool) return;
|
|
4817
4832
|
params.emitExecutionPhaseOnce(`tool:${item.id}`, {
|
|
4818
4833
|
phase: "tool_execution_started",
|
|
@@ -4820,10 +4835,6 @@ function reportCodexExecutionNotification(params) {
|
|
|
4820
4835
|
itemId: item.id
|
|
4821
4836
|
});
|
|
4822
4837
|
}
|
|
4823
|
-
/** Returns true when a notification ends the current app-server turn. */
|
|
4824
|
-
function isTerminalCodexTurnNotificationForTurn(params) {
|
|
4825
|
-
return params.notification.method === "turn/completed" && isCodexNotificationForTurn(params.notification.params, params.threadId, params.turnId) && readCodexTurnCompletedNotification(params.notification.params) !== void 0;
|
|
4826
|
-
}
|
|
4827
4838
|
//#endregion
|
|
4828
4839
|
//#region extensions/codex/src/app-server/run-attempt-lifecycle-terminal.ts
|
|
4829
4840
|
function buildCodexLifecycleTerminalMeta(input) {
|
|
@@ -4905,36 +4916,14 @@ function createCodexAttemptLifecycleController(resources, turnRuntime) {
|
|
|
4905
4916
|
state.pendingTerminalDynamicToolRelease = value;
|
|
4906
4917
|
scheduleTerminalDynamicToolReleaseCheck();
|
|
4907
4918
|
};
|
|
4908
|
-
const emitLifecycleStart = (
|
|
4909
|
-
|
|
4910
|
-
|
|
4911
|
-
|
|
4912
|
-
|
|
4913
|
-
|
|
4914
|
-
|
|
4915
|
-
|
|
4916
|
-
emitCodexAppServerEvent(params, {
|
|
4917
|
-
stream: "lifecycle",
|
|
4918
|
-
data: {
|
|
4919
|
-
phase: "model",
|
|
4920
|
-
...model
|
|
4921
|
-
}
|
|
4922
|
-
});
|
|
4923
|
-
state.lifecycleStarted = true;
|
|
4924
|
-
};
|
|
4925
|
-
const emitLifecycleTerminal = (data) => {
|
|
4926
|
-
if (!state.lifecycleStarted || state.lifecycleTerminalEmitted || state.permissionChangeRestart || params.pluginRuntimeRefreshPending?.()) return;
|
|
4927
|
-
emitCodexAppServerEvent(params, {
|
|
4928
|
-
stream: "lifecycle",
|
|
4929
|
-
data: {
|
|
4930
|
-
startedAt: attemptStartedAt,
|
|
4931
|
-
endedAt: Date.now(),
|
|
4932
|
-
...data,
|
|
4933
|
-
...params.deferTerminalLifecycle ? { phase: "finishing" } : {}
|
|
4934
|
-
}
|
|
4935
|
-
});
|
|
4936
|
-
state.lifecycleTerminalEmitted = true;
|
|
4937
|
-
};
|
|
4919
|
+
const { emitLifecycleStart, emitLifecycleTerminal, emitExecutionPhaseOnce } = createAgentHarnessAttemptLifecycle({
|
|
4920
|
+
attempt: params,
|
|
4921
|
+
backend: "codex-app-server",
|
|
4922
|
+
startedAtMs: attemptStartedAt,
|
|
4923
|
+
state,
|
|
4924
|
+
emitEvent: (event) => emitCodexAppServerEvent(params, event),
|
|
4925
|
+
shouldSuppressTerminal: () => Boolean(state.permissionChangeRestart || params.pluginRuntimeRefreshPending?.())
|
|
4926
|
+
});
|
|
4938
4927
|
const buildLifecycleTerminalMeta = (input) => {
|
|
4939
4928
|
const abortFields = input.aborted ? resolveAgentRunAbortLifecycleFields(runAbortController.signal) : void 0;
|
|
4940
4929
|
return buildCodexLifecycleTerminalMeta({
|
|
@@ -4942,17 +4931,6 @@ function createCodexAttemptLifecycleController(resources, turnRuntime) {
|
|
|
4942
4931
|
abortStopReason: abortFields?.stopReason
|
|
4943
4932
|
});
|
|
4944
4933
|
};
|
|
4945
|
-
const executionPhaseKeys = /* @__PURE__ */ new Set();
|
|
4946
|
-
const emitExecutionPhaseOnce = (key, info) => {
|
|
4947
|
-
if (executionPhaseKeys.has(key)) return;
|
|
4948
|
-
executionPhaseKeys.add(key);
|
|
4949
|
-
params.onExecutionPhase?.({
|
|
4950
|
-
provider: params.provider,
|
|
4951
|
-
model: params.modelId,
|
|
4952
|
-
backend: "codex-app-server",
|
|
4953
|
-
...info
|
|
4954
|
-
});
|
|
4955
|
-
};
|
|
4956
4934
|
const reportExecutionNotification = (notification) => {
|
|
4957
4935
|
reportCodexExecutionNotification({
|
|
4958
4936
|
notification,
|
|
@@ -4990,18 +4968,15 @@ function createCodexAttemptLifecycleController(resources, turnRuntime) {
|
|
|
4990
4968
|
fastModeAutoProgressState.offAnnounced = true;
|
|
4991
4969
|
await emitFastModeAutoProgress(next);
|
|
4992
4970
|
};
|
|
4993
|
-
const maybeEmitFastModeAutoReset = async () => {
|
|
4994
|
-
if (params.fastModeAuto !== true || !fastModeAutoProgressState.offAnnounced || fastModeAutoProgressState.resetAnnounced) return;
|
|
4995
|
-
fastModeAutoProgressState.resetAnnounced = true;
|
|
4996
|
-
await emitFastModeAutoProgress({
|
|
4997
|
-
enabled: true,
|
|
4998
|
-
elapsedSeconds: 0,
|
|
4999
|
-
fastAutoOnSeconds: params.fastModeAutoOnSeconds
|
|
5000
|
-
});
|
|
5001
|
-
};
|
|
5002
4971
|
const maybeEmitFastModeAutoResetBestEffort = async () => {
|
|
5003
4972
|
try {
|
|
5004
|
-
|
|
4973
|
+
if (params.fastModeAuto !== true || !fastModeAutoProgressState.offAnnounced || fastModeAutoProgressState.resetAnnounced) return;
|
|
4974
|
+
fastModeAutoProgressState.resetAnnounced = true;
|
|
4975
|
+
await emitFastModeAutoProgress({
|
|
4976
|
+
enabled: true,
|
|
4977
|
+
elapsedSeconds: 0,
|
|
4978
|
+
fastAutoOnSeconds: params.fastModeAutoOnSeconds
|
|
4979
|
+
});
|
|
5005
4980
|
} catch (error) {
|
|
5006
4981
|
embeddedAgentLog.warn(`codex app-server fast mode auto reset progress failed: ${formatErrorMessage(error)}`);
|
|
5007
4982
|
}
|
|
@@ -5044,11 +5019,7 @@ function createCodexAttemptNotificationController(resources, turnRuntime, lifecy
|
|
|
5044
5019
|
nativeItemObservers.delete(observe);
|
|
5045
5020
|
}
|
|
5046
5021
|
};
|
|
5047
|
-
const
|
|
5048
|
-
notification,
|
|
5049
|
-
threadId: resourceState.thread.threadId,
|
|
5050
|
-
turnId: notificationTurnId
|
|
5051
|
-
});
|
|
5022
|
+
const readTerminalTurn = (notification, notificationTurnId) => notification.method === "turn/completed" && isCodexNotificationForTurn(notification.params, resourceState.thread.threadId, notificationTurnId) ? readCodexTurnCompletedNotification(notification.params)?.turn : void 0;
|
|
5052
5023
|
const handleNotification = async (notification) => {
|
|
5053
5024
|
if (state.projectionClosed) return;
|
|
5054
5025
|
const projector = projectorRef.current;
|
|
@@ -5058,8 +5029,8 @@ function createCodexAttemptNotificationController(resources, turnRuntime, lifecy
|
|
|
5058
5029
|
return;
|
|
5059
5030
|
}
|
|
5060
5031
|
const isCurrentTurn = isCodexNotificationForTurn(notification.params, resourceState.thread.threadId, turnId);
|
|
5061
|
-
const
|
|
5062
|
-
if ((state.timeout || state.localCompletionRequested) &&
|
|
5032
|
+
const completedTurn = readTerminalTurn(notification, turnId);
|
|
5033
|
+
if ((state.timeout || state.localCompletionRequested) && completedTurn?.status === "interrupted") {
|
|
5063
5034
|
completeTurn();
|
|
5064
5035
|
return;
|
|
5065
5036
|
}
|
|
@@ -5076,7 +5047,7 @@ function createCodexAttemptNotificationController(resources, turnRuntime, lifecy
|
|
|
5076
5047
|
if (notification.method === "item/completed") {
|
|
5077
5048
|
if (activeTurnItemIds.size === 0) scheduleTerminalDynamicToolReleaseCheck();
|
|
5078
5049
|
const item = readCodexNotificationItem(notification.params);
|
|
5079
|
-
if (item?.type === "dynamicToolCall"
|
|
5050
|
+
if (item?.type === "dynamicToolCall") {
|
|
5080
5051
|
const response = await openClawDynamicToolExecutions.get({
|
|
5081
5052
|
threadId: resourceState.thread.threadId,
|
|
5082
5053
|
turnId,
|
|
@@ -5099,11 +5070,11 @@ function createCodexAttemptNotificationController(resources, turnRuntime, lifecy
|
|
|
5099
5070
|
state.activeLocalProjections -= 1;
|
|
5100
5071
|
if (isCurrentTurn && notification.method === "item/completed") {
|
|
5101
5072
|
const item = readCodexNotificationItem(notification.params);
|
|
5102
|
-
if (item?.type === "commandExecution"
|
|
5073
|
+
if (item?.type === "commandExecution") pendingNativeCommandItems.delete(item.id);
|
|
5103
5074
|
}
|
|
5104
5075
|
for (const observe of nativeItemObservers) observe();
|
|
5105
|
-
if (
|
|
5106
|
-
if (
|
|
5076
|
+
if (completedTurn) {
|
|
5077
|
+
if (completedTurn.status === "interrupted" && state.sawCodexInterruptMarker) projector.markAborted();
|
|
5107
5078
|
completeTurn();
|
|
5108
5079
|
}
|
|
5109
5080
|
}
|
|
@@ -5129,9 +5100,9 @@ function createCodexAttemptNotificationController(resources, turnRuntime, lifecy
|
|
|
5129
5100
|
const turnId = turnIdRef.current;
|
|
5130
5101
|
if (!projector || !turnId || state.projectionClosed) return;
|
|
5131
5102
|
projector.recordMcpToolCallReceipt(notification);
|
|
5132
|
-
|
|
5133
|
-
|
|
5134
|
-
|
|
5103
|
+
const completedTurn = readTerminalTurn(notification, turnId);
|
|
5104
|
+
if (completedTurn) {
|
|
5105
|
+
projector.settlement.terminalReceipt = completedTurn;
|
|
5135
5106
|
state.terminalTurnNotificationQueued = true;
|
|
5136
5107
|
steeringQueueRef.current?.sealAdmission();
|
|
5137
5108
|
deadlines.beginSettlement(receivedAtMs);
|
|
@@ -5140,7 +5111,7 @@ function createCodexAttemptNotificationController(resources, turnRuntime, lifecy
|
|
|
5140
5111
|
const modelToolCallId = readRawResponseToolCallId(notification);
|
|
5141
5112
|
if (modelToolCallId) allocateCodexToolOutcomeOrdinal?.(modelToolCallId);
|
|
5142
5113
|
const nativeItem = readCodexNotificationItem(notification.params);
|
|
5143
|
-
if (notification.method === "item/started" && nativeItem?.type === "commandExecution"
|
|
5114
|
+
if (notification.method === "item/started" && nativeItem?.type === "commandExecution") pendingNativeCommandItems.add(nativeItem.id);
|
|
5144
5115
|
if (nativeItem?.type === "webSearch") {
|
|
5145
5116
|
projector.settlement.turnTainted ||= notification.method === "item/completed";
|
|
5146
5117
|
projector.recordNativeToolOutcome(nativeItem);
|
|
@@ -5167,12 +5138,9 @@ function createCodexAttemptNotificationController(resources, turnRuntime, lifecy
|
|
|
5167
5138
|
}
|
|
5168
5139
|
//#endregion
|
|
5169
5140
|
//#region extensions/codex/src/app-server/run-attempt-prompt.ts
|
|
5170
|
-
function isRestrictivePromptToolsAllow(toolsAllow) {
|
|
5171
|
-
return toolsAllow !== void 0 && !toolsAllow.some((name) => name.trim() === "*");
|
|
5172
|
-
}
|
|
5173
5141
|
async function prepareCodexAttemptPrompt(context) {
|
|
5174
|
-
const { runtime, attemptTools, historyState, hookContext, workspaceBootstrapContext, buildActiveContextEngineRuntimeContext, baseDeveloperInstructions, buildOpenClawPromptContext,
|
|
5175
|
-
const { connection,
|
|
5142
|
+
const { runtime, attemptTools, historyState, hookContext, workspaceBootstrapContext, buildActiveContextEngineRuntimeContext, baseDeveloperInstructions, buildOpenClawPromptContext, skillsInstructions, promptState, codexContextProjectionMaxChars, codexContinuityProjectionMaxChars } = context;
|
|
5143
|
+
const { connection, runtimeParams, effectiveContextTokenBudget, effectiveRuntimeModelId, effectiveRuntimeProviderId } = runtime;
|
|
5176
5144
|
const { params, activeContextEngine, usesSupervisionConnection, mutable, isInactiveThreadBootstrapBinding, bindingStore, bindingIdentity, agentDir, appServer, contextSessionKey, effectiveWorkspace, sandbox } = connection;
|
|
5177
5145
|
const { toolBridge } = attemptTools;
|
|
5178
5146
|
const nativeHistoryProvenancePrefix = params.trigger === "user" ? buildCodexHistoryProvenancePrefix(params) : void 0;
|
|
@@ -5190,6 +5158,12 @@ async function prepareCodexAttemptPrompt(context) {
|
|
|
5190
5158
|
connection.assertCurrent();
|
|
5191
5159
|
connection.runAbortController.signal.throwIfAborted();
|
|
5192
5160
|
};
|
|
5161
|
+
const inputAttachmentNote = await connection.prepareInputAttachments({
|
|
5162
|
+
maxChars: Math.max(0, CODEX_TURN_START_TEXT_INPUT_MAX_CHARS - (nativeHistoryProvenancePrefix?.length ?? 0) - params.prompt.length - 2),
|
|
5163
|
+
assertCurrent: assertProjectionCurrent,
|
|
5164
|
+
signal: connection.runAbortController.signal
|
|
5165
|
+
});
|
|
5166
|
+
assertProjectionCurrent();
|
|
5193
5167
|
const admittedMessage = params.userTurnTranscriptRecorder?.message ?? await params.userTurnTranscriptRecorder?.resolveMessage();
|
|
5194
5168
|
assertProjectionCurrent();
|
|
5195
5169
|
const currentUserTurnIdempotencyKey = params.pluginRuntimeRefreshMessages ? void 0 : admittedMessage?.idempotencyKey;
|
|
@@ -5215,7 +5189,6 @@ async function prepareCodexAttemptPrompt(context) {
|
|
|
5215
5189
|
const applyContinuityProjection = async (messages) => {
|
|
5216
5190
|
const projection = await projectContextEngineAssemblyForCodex({
|
|
5217
5191
|
assembledMessages: messages,
|
|
5218
|
-
originalHistoryMessages: historyState.messages,
|
|
5219
5192
|
prompt: params.prompt,
|
|
5220
5193
|
maxRenderedContextChars: codexContinuityProjectionMaxChars,
|
|
5221
5194
|
toolPayloadMode: params.pluginRuntimeRefreshMessages || preserveForkedToolResults ? "preserve" : "elide",
|
|
@@ -5226,107 +5199,97 @@ async function prepareCodexAttemptPrompt(context) {
|
|
|
5226
5199
|
contextImageGroups = projection.imageGroups ?? [];
|
|
5227
5200
|
promptState.promptText = projection.promptText;
|
|
5228
5201
|
promptState.promptContextRange = projection.promptContextRange;
|
|
5229
|
-
promptState.prePromptMessageCount = projection.prePromptMessageCount;
|
|
5230
5202
|
promptState.noEngineContinuityProjectionApplied = true;
|
|
5231
5203
|
};
|
|
5232
5204
|
const applyActiveContextEngineProjection = async (decisionStartupBinding) => {
|
|
5233
5205
|
if (!activeContextEngine) return;
|
|
5234
|
-
|
|
5235
|
-
|
|
5236
|
-
|
|
5237
|
-
|
|
5238
|
-
|
|
5239
|
-
|
|
5240
|
-
|
|
5241
|
-
|
|
5242
|
-
|
|
5243
|
-
|
|
5244
|
-
|
|
5245
|
-
|
|
5246
|
-
|
|
5247
|
-
|
|
5248
|
-
|
|
5249
|
-
|
|
5250
|
-
|
|
5251
|
-
|
|
5252
|
-
|
|
5253
|
-
|
|
5254
|
-
|
|
5255
|
-
|
|
5256
|
-
|
|
5257
|
-
|
|
5258
|
-
|
|
5259
|
-
|
|
5260
|
-
|
|
5261
|
-
|
|
5262
|
-
|
|
5263
|
-
|
|
5264
|
-
|
|
5265
|
-
|
|
5266
|
-
|
|
5267
|
-
|
|
5268
|
-
|
|
5269
|
-
|
|
5270
|
-
|
|
5271
|
-
|
|
5272
|
-
|
|
5273
|
-
|
|
5274
|
-
|
|
5275
|
-
|
|
5276
|
-
|
|
5277
|
-
|
|
5278
|
-
|
|
5279
|
-
|
|
5280
|
-
|
|
5281
|
-
|
|
5282
|
-
|
|
5283
|
-
|
|
5284
|
-
|
|
5285
|
-
|
|
5286
|
-
|
|
5287
|
-
|
|
5288
|
-
|
|
5289
|
-
|
|
5290
|
-
|
|
5291
|
-
|
|
5292
|
-
|
|
5293
|
-
|
|
5294
|
-
|
|
5295
|
-
|
|
5296
|
-
|
|
5297
|
-
|
|
5298
|
-
|
|
5299
|
-
|
|
5300
|
-
|
|
5301
|
-
|
|
5302
|
-
|
|
5303
|
-
} catch (assembleErr) {
|
|
5304
|
-
if (assembleErr instanceof CodexContextAttachmentError || params.pluginRuntimeRefreshMessages) throw assembleErr;
|
|
5305
|
-
assertProjectionCurrent();
|
|
5306
|
-
embeddedAgentLog.warn("context engine assemble failed; using Codex baseline prompt", { error: formatErrorMessage(assembleErr) });
|
|
5307
|
-
}
|
|
5308
|
-
const codexModelInputHistoryMessages = [];
|
|
5309
|
-
const admittedContent = admittedMessage?.content;
|
|
5310
|
-
const currentUserMessage = admittedMessage ? typeof admittedContent === "string" ? admittedContent : (admittedContent ?? []).flatMap((part) => part.type === "text" ? [part.text] : []).join("\n") : params.pluginRuntimeRefreshMessages ? "" : params.prompt;
|
|
5311
|
-
const buildPromptFromCurrentInputs = async () => {
|
|
5312
|
-
return await resolveAgentHarnessBeforePromptBuildResult({
|
|
5313
|
-
currentUserMessage,
|
|
5314
|
-
currentUserMessageId: admittedMessage?.idempotencyKey,
|
|
5315
|
-
prompt: prependCurrentInboundContext(promptState.promptText, params.currentInboundContext),
|
|
5316
|
-
developerInstructions: { build: ({ toolsAllow }) => {
|
|
5317
|
-
if (isRestrictivePromptToolsAllow(toolsAllow)) throw new Error("Codex app-server cannot enforce before_prompt_build toolsAllow; use the embedded or Copilot runtime for turn-scoped tool policy.");
|
|
5318
|
-
return promptState.developerInstructions;
|
|
5319
|
-
} },
|
|
5320
|
-
messages: historyState.messages,
|
|
5321
|
-
ctx: hookContext,
|
|
5322
|
-
bootstrapContextRunKind: params.bootstrapContextRunKind,
|
|
5323
|
-
toolAuthority: {
|
|
5324
|
-
fingerprint: params.toolAuthorityFingerprint,
|
|
5325
|
-
activeToolNames: () => flattenCodexDynamicToolFunctions(toolBridge.availableSpecs).map((tool) => tool.name).filter(isNonEmptyString),
|
|
5326
|
-
assertActive: connection.assertCurrent
|
|
5327
|
-
}
|
|
5328
|
-
});
|
|
5206
|
+
try {
|
|
5207
|
+
const assembled = await assembleHarnessContextEngine({
|
|
5208
|
+
contextEngine: activeContextEngine,
|
|
5209
|
+
sessionId: runtimeParams.sessionId,
|
|
5210
|
+
sessionKey: contextSessionKey,
|
|
5211
|
+
messages: historyState.messages,
|
|
5212
|
+
tokenBudget: effectiveContextTokenBudget,
|
|
5213
|
+
availableTools: new Set(flattenCodexDynamicToolFunctions(toolBridge.availableSpecs).map((tool) => tool.name).filter(isNonEmptyString)),
|
|
5214
|
+
citationsMode: params.config?.memory?.citations,
|
|
5215
|
+
sandboxed: sandbox?.enabled === true,
|
|
5216
|
+
modelId: effectiveRuntimeModelId,
|
|
5217
|
+
contextEngineHostSupport: CODEX_APP_SERVER_CONTEXT_ENGINE_HOST,
|
|
5218
|
+
providerId: effectiveRuntimeProviderId,
|
|
5219
|
+
requestedModelId: usesSupervisionConnection ? void 0 : params.requestedModelId,
|
|
5220
|
+
fallbackReason: usesSupervisionConnection ? void 0 : params.fallbackReason,
|
|
5221
|
+
degradedReason: usesSupervisionConnection ? void 0 : params.degradedReason,
|
|
5222
|
+
runtimeContext: buildActiveContextEngineRuntimeContext(),
|
|
5223
|
+
transcriptReadFence: params.userTurnTranscriptRecorder?.getAdmissionReceipt(),
|
|
5224
|
+
prompt: params.prompt
|
|
5225
|
+
});
|
|
5226
|
+
if (!assembled) throw new Error("context engine assemble returned no result");
|
|
5227
|
+
const contextEngineProjection = readContextEngineThreadBootstrapProjection(assembled.contextProjection);
|
|
5228
|
+
const projectionDecision = contextEngineProjection ? resolveContextEngineBootstrapProjectionDecision({
|
|
5229
|
+
startupBinding: decisionStartupBinding,
|
|
5230
|
+
expectedBinding: buildContextEngineBinding({ ...runtimeParams }, contextEngineProjection),
|
|
5231
|
+
projection: contextEngineProjection,
|
|
5232
|
+
dynamicToolsFingerprint: codexDynamicToolsFingerprint(toolBridge.specs),
|
|
5233
|
+
legacyDynamicToolsFingerprint: codexLegacyDynamicToolsFingerprint(toolBridge.specs)
|
|
5234
|
+
}) : {
|
|
5235
|
+
project: true,
|
|
5236
|
+
reason: "per-turn-projection"
|
|
5237
|
+
};
|
|
5238
|
+
const projection = await projectContextEngineAssemblyForCodex({
|
|
5239
|
+
assembledMessages: assembled.messages,
|
|
5240
|
+
prompt: params.prompt,
|
|
5241
|
+
systemPromptAddition: assembled.systemPromptAddition,
|
|
5242
|
+
maxRenderedContextChars: codexContextProjectionMaxChars,
|
|
5243
|
+
toolPayloadMode: contextEngineProjection || params.pluginRuntimeRefreshMessages || preserveForkedToolResults ? "preserve" : "elide",
|
|
5244
|
+
...projectionDecision.project ? { prepareFileContext } : {},
|
|
5245
|
+
currentUserTurnIdempotencyKey
|
|
5246
|
+
});
|
|
5247
|
+
assertProjectionCurrent();
|
|
5248
|
+
contextImageGroups = projectionDecision.project ? projection.imageGroups ?? [] : [];
|
|
5249
|
+
embeddedAgentLog.info("codex app-server context-engine projection decision", {
|
|
5250
|
+
sessionId: params.sessionId,
|
|
5251
|
+
sessionKey: contextSessionKey,
|
|
5252
|
+
engineId: activeContextEngine.info.id,
|
|
5253
|
+
mode: contextEngineProjection?.mode ?? assembled.contextProjection?.mode ?? "per_turn",
|
|
5254
|
+
epoch: contextEngineProjection?.epoch,
|
|
5255
|
+
fingerprint: contextEngineProjection?.fingerprint,
|
|
5256
|
+
previousThreadId: decisionStartupBinding?.threadId,
|
|
5257
|
+
previousEpoch: decisionStartupBinding?.contextEngine?.projection?.epoch,
|
|
5258
|
+
previousFingerprint: decisionStartupBinding?.contextEngine?.projection?.fingerprint,
|
|
5259
|
+
projected: projectionDecision.project,
|
|
5260
|
+
reason: projectionDecision.reason,
|
|
5261
|
+
assembledMessages: assembled.messages.length,
|
|
5262
|
+
originalHistoryMessages: historyState.messages.length,
|
|
5263
|
+
projectedPromptChars: projection.promptText.length,
|
|
5264
|
+
developerInstructionAdditionChars: projection.developerInstructionAddition?.length ?? 0
|
|
5265
|
+
});
|
|
5266
|
+
promptState.contextEngineProjection = contextEngineProjection;
|
|
5267
|
+
promptState.promptText = projectionDecision.project ? projection.promptText : params.prompt;
|
|
5268
|
+
promptState.promptContextRange = projectionDecision.project ? projection.promptContextRange : void 0;
|
|
5269
|
+
promptState.developerInstructions = joinPresentSections(baseDeveloperInstructions, projection.developerInstructionAddition);
|
|
5270
|
+
} catch (assembleErr) {
|
|
5271
|
+
if (assembleErr instanceof CodexContextAttachmentError || params.pluginRuntimeRefreshMessages) throw assembleErr;
|
|
5272
|
+
assertProjectionCurrent();
|
|
5273
|
+
embeddedAgentLog.warn("context engine assemble failed; using Codex baseline prompt", { error: formatErrorMessage(assembleErr) });
|
|
5274
|
+
}
|
|
5329
5275
|
};
|
|
5276
|
+
if (activeContextEngine) await applyActiveContextEngineProjection(runtime.nativeToolSurfaceEnabled ? mutable.startupBinding : void 0);
|
|
5277
|
+
const buildPromptFromCurrentInputs = () => resolveAgentHarnessBeforePromptBuildResult({
|
|
5278
|
+
currentUserMessage: admittedMessage ?? (params.pluginRuntimeRefreshMessages ? "" : params.prompt),
|
|
5279
|
+
prompt: prependCurrentInboundContext(promptState.promptText, params.currentInboundContext),
|
|
5280
|
+
developerInstructions: { build: ({ hasToolRestrictions }) => {
|
|
5281
|
+
if (hasToolRestrictions) throw new Error("Codex app-server cannot enforce before_prompt_build toolsAllow; use the embedded or Copilot runtime for turn-scoped tool policy.");
|
|
5282
|
+
return promptState.developerInstructions;
|
|
5283
|
+
} },
|
|
5284
|
+
messages: historyState.messages,
|
|
5285
|
+
ctx: hookContext,
|
|
5286
|
+
bootstrapContextRunKind: params.bootstrapContextRunKind,
|
|
5287
|
+
toolAuthority: {
|
|
5288
|
+
fingerprint: params.toolAuthorityFingerprint,
|
|
5289
|
+
activeToolNames: () => flattenCodexDynamicToolFunctions(toolBridge.availableSpecs).map((tool) => tool.name).filter(isNonEmptyString),
|
|
5290
|
+
assertActive: connection.assertCurrent
|
|
5291
|
+
}
|
|
5292
|
+
});
|
|
5330
5293
|
const resolveShiftedPromptInputRange = (prompt, promptInputRange, turnPromptText) => {
|
|
5331
5294
|
if (!promptInputRange || promptInputRange.start < 0 || promptInputRange.end < promptInputRange.start || promptInputRange.end > prompt.length || !turnPromptText.endsWith(prompt)) return;
|
|
5332
5295
|
const turnPromptOffset = turnPromptText.length - prompt.length;
|
|
@@ -5362,9 +5325,12 @@ async function prepareCodexAttemptPrompt(context) {
|
|
|
5362
5325
|
decoratedPrompt: turnPromptText
|
|
5363
5326
|
});
|
|
5364
5327
|
const imageOffset = projectedRanges && promptState.promptContextRange ? projectedRanges.contextRange.start - promptState.promptContextRange.start : void 0;
|
|
5328
|
+
const inputLimit = CODEX_TURN_START_TEXT_INPUT_MAX_CHARS - (nativeHistoryProvenancePrefix?.length ?? 0);
|
|
5329
|
+
const requiredInputChars = turnPromptText.length - (projectedRanges ? projectedRanges.contextRange.end - projectedRanges.contextRange.start : 0);
|
|
5330
|
+
const attachmentNote = inputAttachmentNote && requiredInputChars + inputAttachmentNote.length + 2 <= inputLimit ? inputAttachmentNote : void 0;
|
|
5365
5331
|
const fitted = fitCodexProjectedContextForTurnStart({
|
|
5366
5332
|
promptText: turnPromptText,
|
|
5367
|
-
maxChars:
|
|
5333
|
+
maxChars: inputLimit - (attachmentNote ? attachmentNote.length + 2 : 0),
|
|
5368
5334
|
contextRange: projectedRanges?.contextRange,
|
|
5369
5335
|
requestRange: projectedRanges?.requestRange,
|
|
5370
5336
|
preservedRange,
|
|
@@ -5375,7 +5341,7 @@ async function prepareCodexAttemptPrompt(context) {
|
|
|
5375
5341
|
}))
|
|
5376
5342
|
});
|
|
5377
5343
|
turnContextImageGroups = fitted.imageGroups ?? [];
|
|
5378
|
-
return fitted.promptText;
|
|
5344
|
+
return attachmentNote ? `${fitted.promptText}\n\n${attachmentNote}` : fitted.promptText;
|
|
5379
5345
|
};
|
|
5380
5346
|
const firstPromptBuild = await buildPromptFromCurrentInputs();
|
|
5381
5347
|
const turnState = {
|
|
@@ -5385,10 +5351,12 @@ async function prepareCodexAttemptPrompt(context) {
|
|
|
5385
5351
|
let parentLocalEgress = false;
|
|
5386
5352
|
const parentLocalContext = {
|
|
5387
5353
|
turnScopedDeveloperInstructions: workspaceBootstrapContext.turnScopedDeveloperInstructions,
|
|
5388
|
-
skillsCollaborationInstructions,
|
|
5389
5354
|
memoryCollaborationInstructions: workspaceBootstrapContext.memoryCollaborationInstructions
|
|
5390
5355
|
};
|
|
5391
|
-
const buildRenderedCodexDeveloperInstructions = () => joinPresentSections(turnState.promptBuild.developerInstructions,
|
|
5356
|
+
const buildRenderedCodexDeveloperInstructions = () => joinPresentSections(turnState.promptBuild.developerInstructions, parentLocalEgress ? void 0 : skillsInstructions, (parentLocalEgress ? buildCodexParentLocalInstructions(params, {
|
|
5357
|
+
...parentLocalContext,
|
|
5358
|
+
skillsInstructions
|
|
5359
|
+
}) : buildTurnCollaborationMode(params, parentLocalContext).settings.developer_instructions) ?? void 0);
|
|
5392
5360
|
const rebuildCodexPromptBuildFromCurrentProjection = async () => {
|
|
5393
5361
|
turnState.promptBuild = await buildPromptFromCurrentInputs();
|
|
5394
5362
|
turnState.codexTurnPromptText = decorateCodexTurnPromptText(turnState.promptBuild);
|
|
@@ -5472,13 +5440,7 @@ async function prepareCodexAttemptPrompt(context) {
|
|
|
5472
5440
|
if (promptState.staleBindingContinuityForcedFreshStart) await applyContinuityProjection(historyState.messages);
|
|
5473
5441
|
if (activeContextEngine) {
|
|
5474
5442
|
promptState.contextEngineProjection = void 0;
|
|
5475
|
-
|
|
5476
|
-
await applyActiveContextEngineProjection(void 0);
|
|
5477
|
-
} catch (assembleErr) {
|
|
5478
|
-
if (assembleErr instanceof CodexContextAttachmentError || params.pluginRuntimeRefreshMessages) throw assembleErr;
|
|
5479
|
-
assertProjectionCurrent();
|
|
5480
|
-
embeddedAgentLog.warn("context engine assemble failed; using Codex baseline prompt", { error: formatErrorMessage(assembleErr) });
|
|
5481
|
-
}
|
|
5443
|
+
await applyActiveContextEngineProjection(void 0);
|
|
5482
5444
|
}
|
|
5483
5445
|
await rebuildCodexPromptBuildFromCurrentProjection();
|
|
5484
5446
|
embeddedAgentLog.info("codex app-server rebuilt turn prompt after native thread rotation", {
|
|
@@ -5497,7 +5459,7 @@ async function prepareCodexAttemptPrompt(context) {
|
|
|
5497
5459
|
developerInstructions: buildRenderedCodexDeveloperInstructions(),
|
|
5498
5460
|
workspaceBootstrapContext,
|
|
5499
5461
|
omitWorkspaceReferences,
|
|
5500
|
-
skillsPrompt:
|
|
5462
|
+
skillsPrompt: skillsInstructions ? params.skillsSnapshot?.prompt ?? "" : "",
|
|
5501
5463
|
tools: toolBridge.availableSpecs
|
|
5502
5464
|
});
|
|
5503
5465
|
const systemPromptReport = buildSystemPromptReport();
|
|
@@ -5507,7 +5469,6 @@ async function prepareCodexAttemptPrompt(context) {
|
|
|
5507
5469
|
get contextImageGroups() {
|
|
5508
5470
|
return turnContextImageGroups;
|
|
5509
5471
|
},
|
|
5510
|
-
codexModelInputHistoryMessages,
|
|
5511
5472
|
nativeHistoryProvenancePrefix,
|
|
5512
5473
|
turnState,
|
|
5513
5474
|
refreshWorkspaceReferences: (include) => {
|
|
@@ -5542,6 +5503,39 @@ function buildCodexHookRequester(params) {
|
|
|
5542
5503
|
return Object.keys(requester).length > 0 ? requester : void 0;
|
|
5543
5504
|
}
|
|
5544
5505
|
//#endregion
|
|
5506
|
+
//#region extensions/codex/src/app-server/native-subagent-assignment-store.ts
|
|
5507
|
+
function createNativeSubagentAssignmentStore(params) {
|
|
5508
|
+
const { bindingStore, identity, owner } = params;
|
|
5509
|
+
const assertCurrent = () => {
|
|
5510
|
+
params.assertLifecycleCurrent?.();
|
|
5511
|
+
const binding = bindingStore.read(identity);
|
|
5512
|
+
if (!binding || !matchesCodexNativeSubagentSubmissionBinding(binding, owner)) throw new Error("Native assignment binding is no longer current.");
|
|
5513
|
+
};
|
|
5514
|
+
return {
|
|
5515
|
+
assertCurrent,
|
|
5516
|
+
read: () => {
|
|
5517
|
+
assertCurrent();
|
|
5518
|
+
return bindingStore.readNativeSubagentAssignments?.(identity, owner) ?? [];
|
|
5519
|
+
},
|
|
5520
|
+
record: (assignment, assertSourceCurrent) => bindingStore.mutate(identity, {
|
|
5521
|
+
kind: "record-native-subagent-assignment",
|
|
5522
|
+
owner,
|
|
5523
|
+
assignment
|
|
5524
|
+
}, () => {
|
|
5525
|
+
assertCurrent();
|
|
5526
|
+
assertSourceCurrent();
|
|
5527
|
+
}),
|
|
5528
|
+
consume: (assignment, assertSourceCurrent) => bindingStore.mutate(identity, {
|
|
5529
|
+
kind: "consume-native-subagent-assignment",
|
|
5530
|
+
owner,
|
|
5531
|
+
assignment
|
|
5532
|
+
}, () => {
|
|
5533
|
+
assertCurrent();
|
|
5534
|
+
assertSourceCurrent();
|
|
5535
|
+
})
|
|
5536
|
+
};
|
|
5537
|
+
}
|
|
5538
|
+
//#endregion
|
|
5545
5539
|
//#region extensions/codex/src/app-server/run-attempt-resources.ts
|
|
5546
5540
|
function prepareCodexAttemptResources(prompt) {
|
|
5547
5541
|
const { context, turnState, buildRenderedCodexDeveloperInstructions } = prompt;
|
|
@@ -5549,6 +5543,13 @@ function prepareCodexAttemptResources(prompt) {
|
|
|
5549
5543
|
const { connection, hookChannelId } = runtime;
|
|
5550
5544
|
const { appServer, params, effectiveCwd, sessionAgentId, contextSessionKey, runAbortController, sandbox, options, nativeHookRelayEvents } = connection;
|
|
5551
5545
|
const { toolBridge } = attemptTools;
|
|
5546
|
+
const modelAdmissionSource = runtime.nativeToolSurfaceEnabled ? params.hostCapabilities.retainSourceAuthority?.() : void 0;
|
|
5547
|
+
let nativeModelAdmission;
|
|
5548
|
+
try {
|
|
5549
|
+
nativeModelAdmission = modelAdmissionSource ? modelAdmissionSource.modelPolicyRequired !== false ? "required" : options.nativeHookRelay?.enabled === false ? "disabled" : "optional" : void 0;
|
|
5550
|
+
} finally {
|
|
5551
|
+
modelAdmissionSource?.release();
|
|
5552
|
+
}
|
|
5552
5553
|
let nativeProcessAuthorityReleased = false;
|
|
5553
5554
|
const releaseNativeProcessAuthority = () => {
|
|
5554
5555
|
if (!nativeProcessAuthorityReleased) {
|
|
@@ -5576,8 +5577,6 @@ function prepareCodexAttemptResources(prompt) {
|
|
|
5576
5577
|
nativeHookRelay: void 0,
|
|
5577
5578
|
nativeSubagentMonitor: void 0,
|
|
5578
5579
|
runtimeContinuationStarted: false,
|
|
5579
|
-
nativePreToolUseFailureFallbackActive: false,
|
|
5580
|
-
nativePreToolUseFailureFallbackTerminalReason: void 0,
|
|
5581
5580
|
releaseSharedClientLease: void 0,
|
|
5582
5581
|
startupClientUnsafe: false,
|
|
5583
5582
|
turnStartAttempted: false,
|
|
@@ -5590,29 +5589,14 @@ function prepareCodexAttemptResources(prompt) {
|
|
|
5590
5589
|
codexSandboxPolicy: void 0,
|
|
5591
5590
|
restartContextEngineCodexThread: void 0
|
|
5592
5591
|
};
|
|
5593
|
-
const pendingNativePreToolUseFailures = [];
|
|
5594
5592
|
const projectorRef = {};
|
|
5595
|
-
const
|
|
5596
|
-
|
|
5597
|
-
|
|
5598
|
-
|
|
5599
|
-
|
|
5600
|
-
|
|
5601
|
-
|
|
5602
|
-
failure,
|
|
5603
|
-
...state.nativePreToolUseFailureFallbackActive ? { terminalReason: state.nativePreToolUseFailureFallbackTerminalReason ?? failure.disposition } : {}
|
|
5604
|
-
});
|
|
5605
|
-
};
|
|
5606
|
-
const flushPendingNativePreToolUseFailures = () => {
|
|
5607
|
-
for (const failure of pendingNativePreToolUseFailures.splice(0)) emitNativePreToolUseFailure(failure);
|
|
5608
|
-
};
|
|
5609
|
-
const activateNativePreToolUseFailureFallback = () => {
|
|
5610
|
-
if (!state.nativePreToolUseFailureFallbackActive) {
|
|
5611
|
-
state.nativePreToolUseFailureFallbackTerminalReason = runAbortController.signal.aborted ? resolveCodexToolAbortTerminalReason(runAbortController.signal) : void 0;
|
|
5612
|
-
state.nativePreToolUseFailureFallbackActive = true;
|
|
5613
|
-
}
|
|
5614
|
-
flushPendingNativePreToolUseFailures();
|
|
5615
|
-
};
|
|
5593
|
+
const nativePreToolUseFailures = createCodexNativePreToolUseFailureBuffer({
|
|
5594
|
+
agentId: sessionAgentId,
|
|
5595
|
+
sessionId: params.sessionId,
|
|
5596
|
+
sessionKey: contextSessionKey,
|
|
5597
|
+
runId: params.runId,
|
|
5598
|
+
signal: runAbortController.signal
|
|
5599
|
+
});
|
|
5616
5600
|
const releaseSharedClientLeaseOnce = () => {
|
|
5617
5601
|
const release = state.releaseSharedClientLease;
|
|
5618
5602
|
if (!release) return;
|
|
@@ -5672,15 +5656,19 @@ function prepareCodexAttemptResources(prompt) {
|
|
|
5672
5656
|
}
|
|
5673
5657
|
});
|
|
5674
5658
|
let nativeSubagentMonitorSettlement;
|
|
5659
|
+
let nativeSubagentMonitorGeneration = 0;
|
|
5675
5660
|
const unregisterNativeSubagentMonitor = async () => {
|
|
5661
|
+
nativeSubagentMonitorGeneration += 1;
|
|
5676
5662
|
const registration = state.nativeSubagentMonitor;
|
|
5677
5663
|
state.nativeSubagentMonitor = void 0;
|
|
5678
5664
|
if (registration) nativeSubagentMonitorSettlement = registration.unregister();
|
|
5679
5665
|
await nativeSubagentMonitorSettlement;
|
|
5680
5666
|
};
|
|
5681
5667
|
const registerNativeSubagentMonitor = async (parentThreadId) => {
|
|
5668
|
+
const { client, thread, nativeHookRelay, turnRoute } = state;
|
|
5682
5669
|
await unregisterNativeSubagentMonitor();
|
|
5683
5670
|
connection.assertCurrent();
|
|
5671
|
+
const generation = ++nativeSubagentMonitorGeneration;
|
|
5684
5672
|
const sessionKey = params.sessionKey;
|
|
5685
5673
|
const storePath = params.sessionTarget?.storePath;
|
|
5686
5674
|
const parentSession = sessionKey && storePath ? getSessionEntry({
|
|
@@ -5694,22 +5682,25 @@ function prepareCodexAttemptResources(prompt) {
|
|
|
5694
5682
|
parentThreadId,
|
|
5695
5683
|
sessionId: params.sessionId,
|
|
5696
5684
|
...parentSession?.sessionId === params.sessionId ? { lifecycleRevision: parentSession.lifecycleRevision } : {},
|
|
5697
|
-
binding:
|
|
5685
|
+
binding: thread
|
|
5698
5686
|
});
|
|
5699
5687
|
const { bindingStore, bindingIdentity } = connection;
|
|
5700
|
-
const
|
|
5688
|
+
const assertParentSessionCurrent = () => {
|
|
5689
|
+
if (historyOwner?.lifecycleRevision && sessionKey && storePath) {
|
|
5690
|
+
if (getSessionEntry({
|
|
5691
|
+
agentId: sessionAgentId,
|
|
5692
|
+
sessionKey,
|
|
5693
|
+
storePath,
|
|
5694
|
+
readConsistency: "latest",
|
|
5695
|
+
hydrateSkillPromptRefs: false
|
|
5696
|
+
})?.lifecycleRevision !== historyOwner.lifecycleRevision) throw new Error("Native submission session lifecycle is no longer current.");
|
|
5697
|
+
}
|
|
5698
|
+
};
|
|
5699
|
+
const submissionStore = historyOwner && thread.lifecycle.preserveExistingBinding !== true ? {
|
|
5701
5700
|
assertCurrent: () => {
|
|
5702
5701
|
const current = bindingStore.read(bindingIdentity);
|
|
5703
5702
|
if (!current || !matchesCodexNativeSubagentSubmissionBinding(current, historyOwner)) throw new Error("Native submission binding is no longer current.");
|
|
5704
|
-
|
|
5705
|
-
if (getSessionEntry({
|
|
5706
|
-
agentId: sessionAgentId,
|
|
5707
|
-
sessionKey,
|
|
5708
|
-
storePath,
|
|
5709
|
-
readConsistency: "latest",
|
|
5710
|
-
hydrateSkillPromptRefs: false
|
|
5711
|
-
})?.lifecycleRevision !== historyOwner.lifecycleRevision) throw new Error("Native submission session lifecycle is no longer current.");
|
|
5712
|
-
}
|
|
5703
|
+
assertParentSessionCurrent();
|
|
5713
5704
|
},
|
|
5714
5705
|
read: () => bindingStore.readNativeSubagentSubmissions(bindingIdentity, historyOwner),
|
|
5715
5706
|
record: (receipt, assertCurrent) => bindingStore.mutate(bindingIdentity, {
|
|
@@ -5723,22 +5714,60 @@ function prepareCodexAttemptResources(prompt) {
|
|
|
5723
5714
|
receipt
|
|
5724
5715
|
}, assertCurrent)
|
|
5725
5716
|
} : void 0;
|
|
5726
|
-
|
|
5727
|
-
|
|
5728
|
-
|
|
5729
|
-
|
|
5730
|
-
|
|
5731
|
-
|
|
5732
|
-
|
|
5733
|
-
|
|
5734
|
-
|
|
5735
|
-
|
|
5736
|
-
|
|
5737
|
-
|
|
5738
|
-
|
|
5739
|
-
|
|
5740
|
-
|
|
5741
|
-
|
|
5717
|
+
const assignmentStore = historyOwner && submissionStore ? createNativeSubagentAssignmentStore({
|
|
5718
|
+
bindingStore,
|
|
5719
|
+
identity: bindingIdentity,
|
|
5720
|
+
owner: historyOwner,
|
|
5721
|
+
assertLifecycleCurrent: () => submissionStore.assertCurrent()
|
|
5722
|
+
}) : void 0;
|
|
5723
|
+
const assertRegistrationCurrent = () => {
|
|
5724
|
+
runAbortController.signal.throwIfAborted();
|
|
5725
|
+
params.hostCapabilities.assertActive();
|
|
5726
|
+
connection.assertCurrent();
|
|
5727
|
+
if (submissionStore) submissionStore.assertCurrent();
|
|
5728
|
+
else assertParentSessionCurrent();
|
|
5729
|
+
thread.liveThreadOwnership?.assertCurrent();
|
|
5730
|
+
if (generation !== nativeSubagentMonitorGeneration || state.client !== client || state.thread !== thread || state.nativeHookRelay !== nativeHookRelay || state.turnRoute !== turnRoute) throw new Error("Codex native subagent registration was superseded during setup");
|
|
5731
|
+
};
|
|
5732
|
+
const retainModelSource = params.hostCapabilities.retainSourceAuthority;
|
|
5733
|
+
const modelSource = retainModelSource?.();
|
|
5734
|
+
try {
|
|
5735
|
+
const configurationQualification = getCodexInferenceThreadQualification(client, parentThreadId);
|
|
5736
|
+
const registration = await codexNativeSubagentMonitorRuntime.register({
|
|
5737
|
+
client,
|
|
5738
|
+
parentThreadId,
|
|
5739
|
+
...retainModelSource ? { modelSource } : {},
|
|
5740
|
+
configurationQualification,
|
|
5741
|
+
unqualifiedModelExecution: modelSource && !configurationQualification ? true : void 0,
|
|
5742
|
+
onUnqualifiedModelCancelled: connection.abortExplicitly,
|
|
5743
|
+
requesterSessionKey: params.sessionKey,
|
|
5744
|
+
completionScope: params.agentHarnessCompletionScope,
|
|
5745
|
+
historyOwner,
|
|
5746
|
+
submissionStore,
|
|
5747
|
+
assignmentStore,
|
|
5748
|
+
agentId: sessionAgentId,
|
|
5749
|
+
assertCurrent: assertRegistrationCurrent,
|
|
5750
|
+
isTurnYielded: () => attemptTools.toolState.yieldDetected,
|
|
5751
|
+
retainClient: () => retainSharedCodexAppServerClientIfCurrent(client),
|
|
5752
|
+
retainParentThread: (protectedThreadId) => protectCodexAppServerLiveThread(client, protectedThreadId),
|
|
5753
|
+
claimDirectChild: (childThreadId) => nativeHookRelay?.claimDirectChild(childThreadId),
|
|
5754
|
+
rejectPendingDirectChild: (childThreadId, reason) => nativeHookRelay?.rejectPendingDirectChild(childThreadId, reason),
|
|
5755
|
+
...params.sessionKey && params.agentHarnessCompletionScope ? { onDirectChildAccepted: () => {
|
|
5756
|
+
state.runtimeContinuationStarted = true;
|
|
5757
|
+
} } : {}
|
|
5758
|
+
});
|
|
5759
|
+
try {
|
|
5760
|
+
await registration.ready;
|
|
5761
|
+
assertRegistrationCurrent();
|
|
5762
|
+
state.nativeSubagentMonitor = registration;
|
|
5763
|
+
} catch (error) {
|
|
5764
|
+
await registration.unregister();
|
|
5765
|
+
throw error;
|
|
5766
|
+
}
|
|
5767
|
+
} catch (error) {
|
|
5768
|
+
modelSource?.release();
|
|
5769
|
+
throw error;
|
|
5770
|
+
}
|
|
5742
5771
|
};
|
|
5743
5772
|
const releaseCurrentRoute = async () => {
|
|
5744
5773
|
state.releaseInferenceContext?.();
|
|
@@ -5804,7 +5833,7 @@ function prepareCodexAttemptResources(prompt) {
|
|
|
5804
5833
|
return released;
|
|
5805
5834
|
};
|
|
5806
5835
|
const cleanupBeforeActiveTurn = async () => {
|
|
5807
|
-
await runCleanupStep("codex-pre-turn-hook-fallback",
|
|
5836
|
+
await runCleanupStep("codex-pre-turn-hook-fallback", () => nativePreToolUseFailures.activateFallback(runAbortController.signal.aborted));
|
|
5808
5837
|
await runCleanupStep("codex-pre-turn-subscription", async () => {
|
|
5809
5838
|
const { thread } = state;
|
|
5810
5839
|
if (!thread || subscriptionSettlement?.thread === thread || state.startupClientUnsafe) return;
|
|
@@ -5843,8 +5872,10 @@ function prepareCodexAttemptResources(prompt) {
|
|
|
5843
5872
|
previousRelay?.unregister();
|
|
5844
5873
|
await previousRelay?.drain();
|
|
5845
5874
|
connection.assertCurrent();
|
|
5846
|
-
const requiresProcessAdmission = nativeProcessAuthority && runtime.nativeToolSurfaceEnabled;
|
|
5847
|
-
const
|
|
5875
|
+
const requiresProcessAdmission = nativeProcessAuthority?.requiresProcessAdmission && runtime.nativeToolSurfaceEnabled;
|
|
5876
|
+
const requiresModelAdmission = nativeModelAdmission !== void 0 && decision.nativeModelInputTools !== void 0;
|
|
5877
|
+
const requiresExecutionAdmission = requiresProcessAdmission || requiresModelAdmission;
|
|
5878
|
+
const relayEvents = requiresExecutionAdmission && !nativeHookRelayEvents.includes("pre_tool_use") ? [...nativeHookRelayEvents, "pre_tool_use"] : nativeHookRelayEvents;
|
|
5848
5879
|
if (params.pluginHarnessToolPolicyRestricted === true) {
|
|
5849
5880
|
state.nativeHookRelay = void 0;
|
|
5850
5881
|
return {
|
|
@@ -5853,7 +5884,7 @@ function prepareCodexAttemptResources(prompt) {
|
|
|
5853
5884
|
};
|
|
5854
5885
|
}
|
|
5855
5886
|
state.nativeHookRelay = createCodexNativeHookRelay({
|
|
5856
|
-
options:
|
|
5887
|
+
options: requiresExecutionAdmission ? {
|
|
5857
5888
|
...options.nativeHookRelay,
|
|
5858
5889
|
enabled: true
|
|
5859
5890
|
} : options.nativeHookRelay,
|
|
@@ -5887,12 +5918,17 @@ function prepareCodexAttemptResources(prompt) {
|
|
|
5887
5918
|
owner: nativeProcessAuthority,
|
|
5888
5919
|
client: () => state.client
|
|
5889
5920
|
} : void 0,
|
|
5921
|
+
nativeModelAdmission: requiresModelAdmission ? {
|
|
5922
|
+
client: () => state.client,
|
|
5923
|
+
threadId: () => state.thread?.threadId,
|
|
5924
|
+
tools: decision.nativeModelInputTools,
|
|
5925
|
+
readQualification: (threadId) => getCodexInferenceThreadQualification(state.client, threadId)
|
|
5926
|
+
} : void 0,
|
|
5890
5927
|
assertCurrent: connection.assertCurrent,
|
|
5891
5928
|
onPreToolUseFailure: (failure) => {
|
|
5892
5929
|
const projector = projectorRef.current;
|
|
5893
5930
|
if (projector) projector.recordNativeToolPreToolUseFailure(failure);
|
|
5894
|
-
else
|
|
5895
|
-
else pendingNativePreToolUseFailures.push(failure);
|
|
5931
|
+
else nativePreToolUseFailures.record(failure);
|
|
5896
5932
|
}
|
|
5897
5933
|
});
|
|
5898
5934
|
await state.nativeHookRelay?.prepareInvocation();
|
|
@@ -5906,7 +5942,7 @@ function prepareCodexAttemptResources(prompt) {
|
|
|
5906
5942
|
nativeHookRelayGeneration: state.nativeHookRelay?.generation
|
|
5907
5943
|
};
|
|
5908
5944
|
};
|
|
5909
|
-
const nativeProcessAuthority =
|
|
5945
|
+
const nativeProcessAuthority = params.hostCapabilities.retainSourceAuthority ? new CodexNativeProcessAuthority(params.hostCapabilities, (error) => {
|
|
5910
5946
|
const message = formatErrorMessage(error);
|
|
5911
5947
|
embeddedAgentLog.warn("codex native background work remains unsettled", {
|
|
5912
5948
|
runId: params.runId,
|
|
@@ -5920,20 +5956,19 @@ function prepareCodexAttemptResources(prompt) {
|
|
|
5920
5956
|
error: message
|
|
5921
5957
|
}
|
|
5922
5958
|
});
|
|
5923
|
-
}) : void 0;
|
|
5959
|
+
}, Boolean(sandbox?.enabled && sandbox.backend)) : void 0;
|
|
5924
5960
|
return {
|
|
5925
5961
|
prompt,
|
|
5926
5962
|
trajectoryRecorder,
|
|
5927
5963
|
state,
|
|
5928
5964
|
projectorRef,
|
|
5929
|
-
pendingNativePreToolUseFailures,
|
|
5965
|
+
pendingNativePreToolUseFailures: nativePreToolUseFailures.pending,
|
|
5966
|
+
nativeModelAdmission,
|
|
5930
5967
|
nativeProcessAuthority,
|
|
5931
5968
|
releaseNativeProcessAuthority,
|
|
5932
5969
|
markTrajectoryEndRecorded: () => {
|
|
5933
5970
|
state.trajectoryEndRecorded = true;
|
|
5934
5971
|
},
|
|
5935
|
-
activateNativePreToolUseFailureFallback,
|
|
5936
|
-
releaseSharedClientLeaseOnce,
|
|
5937
5972
|
releaseSharedClientLeaseAndRetireOneShotClient,
|
|
5938
5973
|
releaseSandboxExecEnvironment,
|
|
5939
5974
|
runCleanupStep,
|
|
@@ -5985,7 +6020,6 @@ async function prepareCodexAttemptRoute(resources, turnRuntime, notifications, h
|
|
|
5985
6020
|
await releaseCurrentRoute();
|
|
5986
6021
|
resourceState.turnRoute = resourceState.turnRouter.reserveThread({ threadId: resourceState.thread.threadId });
|
|
5987
6022
|
}
|
|
5988
|
-
if (!resourceState.turnRoute) throw new Error("codex app-server turn route was not reserved");
|
|
5989
6023
|
if (!resourceState.routeActivated) {
|
|
5990
6024
|
if (!resourceState.nativeSubagentMonitor) await registerNativeSubagentMonitor(resourceState.thread.threadId);
|
|
5991
6025
|
resourceState.detachRouteAbort = attachRouteAbort(resourceState.turnRoute);
|
|
@@ -6088,13 +6122,6 @@ async function prepareCodexAttemptRuntime(connection) {
|
|
|
6088
6122
|
...legacyScheduledAppRecoveryPrompt ? { extraSystemPrompt: [params.extraSystemPrompt, legacyScheduledAppRecoveryPrompt].filter((value) => Boolean(value?.trim())).join("\n\n") } : {},
|
|
6089
6123
|
...startupAuthProfileId ? { authProfileId: startupAuthProfileId } : {}
|
|
6090
6124
|
};
|
|
6091
|
-
const activeSessionId = params.sessionId;
|
|
6092
|
-
const activeSessionFile = params.sessionFile;
|
|
6093
|
-
const buildActiveRunAttemptParams = () => ({
|
|
6094
|
-
...runtimeParams,
|
|
6095
|
-
sessionId: activeSessionId,
|
|
6096
|
-
sessionFile: activeSessionFile
|
|
6097
|
-
});
|
|
6098
6125
|
const startupAuthAccountCacheKey = usesSupervisionConnection ? void 0 : startupPreparedAuth?.kind === "api-key" ? resolveCodexAppServerPreparedApiKeyCacheKey(startupPreparedAuth.apiKey) : startupPreparedAuth?.kind === "profile" ? startupPreparedAuth.snapshot?.secretFreeCacheKey : await resolveCodexAppServerAuthAccountCacheKey({
|
|
6099
6126
|
authProfileId: startupAuthProfileId,
|
|
6100
6127
|
authProfileStore: attemptAuthProfileStore,
|
|
@@ -6188,7 +6215,8 @@ async function prepareCodexAttemptRuntime(connection) {
|
|
|
6188
6215
|
});
|
|
6189
6216
|
const supervisedSearchFingerprint = usesSupervisionConnection && !mutable.startupBinding?.pendingSupervisionBranch ? mutable.startupBinding?.webSearchThreadConfigFingerprint : void 0;
|
|
6190
6217
|
let nativeProviderWebSearchSupport;
|
|
6191
|
-
if (
|
|
6218
|
+
if (isCodexResponsesOAuth(startupPreparedAuth)) nativeProviderWebSearchSupport = "supported";
|
|
6219
|
+
else if (webSearchPlan.kind !== "native-hosted" || supervisedSearchFingerprint === fingerprintJsonObject(resolveCodexWebSearchPlan({ disableTools: true }).threadConfig)) nativeProviderWebSearchSupport = "unsupported";
|
|
6192
6220
|
else if (supervisedSearchFingerprint === fingerprintJsonObject(webSearchPlan.threadConfig)) nativeProviderWebSearchSupport = "supported";
|
|
6193
6221
|
else nativeProviderWebSearchSupport = await resolveCodexProviderWebSearchSupport({
|
|
6194
6222
|
clientFactory: attemptClientFactory,
|
|
@@ -6199,6 +6227,7 @@ async function prepareCodexAttemptRuntime(connection) {
|
|
|
6199
6227
|
config: params.config,
|
|
6200
6228
|
expectedNativeModelProvider: usesSupervisionConnection ? mutable.startupBinding?.modelProvider : void 0,
|
|
6201
6229
|
modelProviderOverride: usesSupervisionConnection ? void 0 : resolveCodexAppServerThreadModelSelection({
|
|
6230
|
+
homeScope: appServer.start.homeScope,
|
|
6202
6231
|
provider: params.provider,
|
|
6203
6232
|
model: params.modelId,
|
|
6204
6233
|
binding: mutable.startupBinding,
|
|
@@ -6222,10 +6251,6 @@ async function prepareCodexAttemptRuntime(connection) {
|
|
|
6222
6251
|
connection,
|
|
6223
6252
|
preparedAuthBinding,
|
|
6224
6253
|
runtimeParams,
|
|
6225
|
-
activeSessionId,
|
|
6226
|
-
activeSessionFile,
|
|
6227
|
-
buildActiveRunAttemptParams,
|
|
6228
|
-
attemptAuthProfileStore,
|
|
6229
6254
|
effectiveContextWindowInfo,
|
|
6230
6255
|
effectiveContextTokenBudget,
|
|
6231
6256
|
effectiveRuntimeProviderId,
|
|
@@ -6263,7 +6288,7 @@ function recordCodexDynamicToolResult(projector, call, response, protocolRespons
|
|
|
6263
6288
|
//#endregion
|
|
6264
6289
|
//#region extensions/codex/src/app-server/run-attempt-tools.ts
|
|
6265
6290
|
function toTranscriptToolResult(response) {
|
|
6266
|
-
const sanitized =
|
|
6291
|
+
const sanitized = sanitizeCodexAgentEventRecord({ ...response });
|
|
6267
6292
|
const contentItems = Array.isArray(sanitized.contentItems) ? sanitized.contentItems : [];
|
|
6268
6293
|
const result = {
|
|
6269
6294
|
...sanitized,
|
|
@@ -6299,32 +6324,6 @@ function formatUnsupportedCodexDynamicToolOutput(type) {
|
|
|
6299
6324
|
const rawType = typeof type === "string" ? type.replace(/\s+/g, " ").trim() : "";
|
|
6300
6325
|
return `[Unsupported Codex dynamic tool output: ${rawType ? truncateUtf16Safe(rawType, 80) : "unknown"}${rawType.length > 80 ? "..." : ""}]`;
|
|
6301
6326
|
}
|
|
6302
|
-
function createCodexDynamicToolExecutionRegistry() {
|
|
6303
|
-
const executions = /* @__PURE__ */ new Map();
|
|
6304
|
-
const keyFor = (call) => JSON.stringify([
|
|
6305
|
-
call.threadId,
|
|
6306
|
-
call.turnId,
|
|
6307
|
-
call.callId
|
|
6308
|
-
]);
|
|
6309
|
-
return {
|
|
6310
|
-
get(call) {
|
|
6311
|
-
return executions.get(keyFor(call));
|
|
6312
|
-
},
|
|
6313
|
-
claim(call, start) {
|
|
6314
|
-
const existing = executions.get(keyFor(call));
|
|
6315
|
-
if (existing) return {
|
|
6316
|
-
execution: existing,
|
|
6317
|
-
replayed: true
|
|
6318
|
-
};
|
|
6319
|
-
const execution = start();
|
|
6320
|
-
executions.set(keyFor(call), execution);
|
|
6321
|
-
return {
|
|
6322
|
-
execution,
|
|
6323
|
-
replayed: false
|
|
6324
|
-
};
|
|
6325
|
-
}
|
|
6326
|
-
};
|
|
6327
|
-
}
|
|
6328
6327
|
function resolveCodexDynamicToolDirectNames(params, registeredTools, hostSystemAgentActive = false) {
|
|
6329
6328
|
const names = [];
|
|
6330
6329
|
if (hostSystemAgentActive && isSystemAgentOnlyCodexDynamicToolAllowlist(params.toolsAllow)) names.push("openclaw");
|
|
@@ -6444,7 +6443,7 @@ function createCodexAttemptServerRequestController(resources, turnRuntime, lifec
|
|
|
6444
6443
|
tool: call.tool,
|
|
6445
6444
|
toolCallId: call.callId
|
|
6446
6445
|
});
|
|
6447
|
-
const toolMeta =
|
|
6446
|
+
const toolMeta = inferToolMetaFromArgs(call.tool, call.arguments, { detailMode: resolveCodexToolProgressDetailMode(params.toolProgressDetail) });
|
|
6448
6447
|
const toolArgs = sanitizeCodexToolArguments(call.arguments);
|
|
6449
6448
|
const commandBearing = isCodexCommandBearingToolCall(call.tool, toolArgs);
|
|
6450
6449
|
const shouldEmitDynamicToolProgress = shouldEmitTranscriptToolProgress(call.tool);
|
|
@@ -6480,26 +6479,24 @@ function createCodexAttemptServerRequestController(resources, turnRuntime, lifec
|
|
|
6480
6479
|
});
|
|
6481
6480
|
setExecutionTimeoutMs?.(dynamicToolTimeoutMs);
|
|
6482
6481
|
const toolStartedAt = Date.now();
|
|
6482
|
+
const diagnosticContext = {
|
|
6483
|
+
call,
|
|
6484
|
+
agentId: sessionAgentId,
|
|
6485
|
+
runId: params.runId,
|
|
6486
|
+
sessionId: params.sessionId,
|
|
6487
|
+
sessionKey: params.sessionKey
|
|
6488
|
+
};
|
|
6483
6489
|
let terminalDiagnosticObserved = false;
|
|
6484
6490
|
const unsubscribeToolDiagnosticObserver = onInternalDiagnosticEvent((event) => {
|
|
6485
6491
|
if (isDynamicToolTerminalDiagnosticEvent(event) && isMatchingDynamicToolTerminalDiagnostic({
|
|
6486
|
-
|
|
6487
|
-
|
|
6488
|
-
runId: params.runId,
|
|
6489
|
-
sessionId: params.sessionId,
|
|
6490
|
-
sessionKey: params.sessionKey
|
|
6492
|
+
...diagnosticContext,
|
|
6493
|
+
event
|
|
6491
6494
|
})) terminalDiagnosticObserved = true;
|
|
6492
6495
|
}, { include: DYNAMIC_TOOL_TERMINAL_DIAGNOSTIC_TYPES });
|
|
6493
6496
|
try {
|
|
6494
6497
|
const { execution } = openClawDynamicToolExecutions.claim(call, async () => {
|
|
6495
6498
|
await projector?.transcriptCheckpoint.flush();
|
|
6496
|
-
emitDynamicToolStartedDiagnostic(
|
|
6497
|
-
call,
|
|
6498
|
-
agentId: sessionAgentId,
|
|
6499
|
-
runId: params.runId,
|
|
6500
|
-
sessionId: params.sessionId,
|
|
6501
|
-
sessionKey: params.sessionKey
|
|
6502
|
-
});
|
|
6499
|
+
emitDynamicToolStartedDiagnostic(diagnosticContext);
|
|
6503
6500
|
const response = await handleDynamicToolCallWithTimeout({
|
|
6504
6501
|
call,
|
|
6505
6502
|
toolBridge,
|
|
@@ -6581,18 +6578,9 @@ function createCodexAttemptServerRequestController(resources, turnRuntime, lifec
|
|
|
6581
6578
|
data: activity
|
|
6582
6579
|
});
|
|
6583
6580
|
}
|
|
6584
|
-
if (!terminalDiagnosticObserved && !hasPendingDynamicToolTerminalDiagnostic({
|
|
6585
|
-
|
|
6586
|
-
runId: params.runId,
|
|
6587
|
-
sessionId: params.sessionId,
|
|
6588
|
-
sessionKey: params.sessionKey
|
|
6589
|
-
})) emitDynamicToolTerminalDiagnostic({
|
|
6581
|
+
if (!terminalDiagnosticObserved && !hasPendingDynamicToolTerminalDiagnostic(diagnosticContext)) emitDynamicToolTerminalDiagnostic({
|
|
6582
|
+
...diagnosticContext,
|
|
6590
6583
|
response,
|
|
6591
|
-
call,
|
|
6592
|
-
agentId: sessionAgentId,
|
|
6593
|
-
runId: params.runId,
|
|
6594
|
-
sessionId: params.sessionId,
|
|
6595
|
-
sessionKey: params.sessionKey,
|
|
6596
6584
|
durationMs: toolDurationMs
|
|
6597
6585
|
});
|
|
6598
6586
|
pendingOpenClawDynamicToolCompletionIds.delete(call.callId);
|
|
@@ -6610,17 +6598,8 @@ function createCodexAttemptServerRequestController(resources, turnRuntime, lifec
|
|
|
6610
6598
|
return protocolResponse;
|
|
6611
6599
|
} catch (error) {
|
|
6612
6600
|
pendingOpenClawDynamicToolCompletionIds.delete(call.callId);
|
|
6613
|
-
if (!terminalDiagnosticObserved && !hasPendingDynamicToolTerminalDiagnostic({
|
|
6614
|
-
|
|
6615
|
-
runId: params.runId,
|
|
6616
|
-
sessionId: params.sessionId,
|
|
6617
|
-
sessionKey: params.sessionKey
|
|
6618
|
-
})) emitDynamicToolErrorDiagnostic({
|
|
6619
|
-
call,
|
|
6620
|
-
agentId: sessionAgentId,
|
|
6621
|
-
runId: params.runId,
|
|
6622
|
-
sessionId: params.sessionId,
|
|
6623
|
-
sessionKey: params.sessionKey,
|
|
6601
|
+
if (!terminalDiagnosticObserved && !hasPendingDynamicToolTerminalDiagnostic(diagnosticContext)) emitDynamicToolErrorDiagnostic({
|
|
6602
|
+
...diagnosticContext,
|
|
6624
6603
|
durationMs: Math.max(0, Date.now() - toolStartedAt)
|
|
6625
6604
|
});
|
|
6626
6605
|
await settlePluginRuntimeRefresh(turnId);
|
|
@@ -6643,11 +6622,11 @@ function createCodexAttemptServerRequestController(resources, turnRuntime, lifec
|
|
|
6643
6622
|
//#region extensions/codex/src/app-server/attempt-runtime-artifact.ts
|
|
6644
6623
|
async function verifyStartupArtifact(params) {
|
|
6645
6624
|
if (!params.request) return;
|
|
6646
|
-
const { readCodexAppServerClientRuntimeArtifact, validateCodexAppServerRuntimeArtifact } = await import("./runtime-artifact-
|
|
6625
|
+
const { readCodexAppServerClientRuntimeArtifact, validateCodexAppServerRuntimeArtifact } = await import("./runtime-artifact-DDQ-HGXf.mjs");
|
|
6647
6626
|
const runtimeArtifact = readCodexAppServerClientRuntimeArtifact(params.client);
|
|
6648
6627
|
const expected = params.request.expected;
|
|
6649
6628
|
const matchesExpected = !expected || runtimeArtifact?.id === expected.id && runtimeArtifact.fingerprint === expected.fingerprint;
|
|
6650
|
-
if (!runtimeArtifact || !matchesExpected || !await validateCodexAppServerRuntimeArtifact(runtimeArtifact, params.signal)) {
|
|
6629
|
+
if (!runtimeArtifact || !matchesExpected || !await validateCodexAppServerRuntimeArtifact(runtimeArtifact, params.signal, params.startOptions)) {
|
|
6651
6630
|
retireSharedCodexAppServerClientIfCurrent(params.client);
|
|
6652
6631
|
throw new Error(expected ? "Codex app-server runtime artifact does not match verified inference" : "Codex app-server runtime artifact is unavailable or stale");
|
|
6653
6632
|
}
|
|
@@ -6676,7 +6655,6 @@ function startCodexComputerUseHealthMonitor(params) {
|
|
|
6676
6655
|
if (existing) clearComputerUseHealthMonitor(params.client, existing);
|
|
6677
6656
|
const monitor = {
|
|
6678
6657
|
fingerprint,
|
|
6679
|
-
intervalMs,
|
|
6680
6658
|
timer: setInterval(() => {
|
|
6681
6659
|
runCodexComputerUseHealthProbe(params.client, params.config, monitor, params.tools);
|
|
6682
6660
|
}, intervalMs),
|
|
@@ -6712,9 +6690,9 @@ async function runCodexComputerUseHealthProbe(client, config, monitor, tools) {
|
|
|
6712
6690
|
client,
|
|
6713
6691
|
config,
|
|
6714
6692
|
tools,
|
|
6715
|
-
request:
|
|
6716
|
-
|
|
6717
|
-
|
|
6693
|
+
request: createComputerUseRequest({
|
|
6694
|
+
client,
|
|
6695
|
+
timeoutMs: config.liveTestTimeoutMs
|
|
6718
6696
|
})
|
|
6719
6697
|
});
|
|
6720
6698
|
if (!liveTest.ok) {
|
|
@@ -6756,8 +6734,8 @@ var CodexPluginThreadConfigDeadlineError = class extends Error {
|
|
|
6756
6734
|
};
|
|
6757
6735
|
/** Resolves the plugin policy state reused throughout app-server startup. */
|
|
6758
6736
|
function resolveCodexPluginThreadConfigStartupPolicy(params) {
|
|
6759
|
-
const pluginThreadConfigRequired = Boolean(params.scheduledRuntimeAuthority) || !params.nativeToolSurfaceEnabled || shouldBuildCodexPluginThreadConfig(params.pluginConfig);
|
|
6760
|
-
const pluginThreadConfigPluginConfig = params.nativeToolSurfaceEnabled || params.scheduledRuntimeAuthority ? params.pluginConfig : disableCodexPluginThreadConfig(params.pluginConfig);
|
|
6737
|
+
const pluginThreadConfigRequired = params.hostedAppsSupported === false || Boolean(params.scheduledRuntimeAuthority) || !params.nativeToolSurfaceEnabled || shouldBuildCodexPluginThreadConfig(params.pluginConfig);
|
|
6738
|
+
const pluginThreadConfigPluginConfig = params.hostedAppsSupported !== false && (params.nativeToolSurfaceEnabled || params.scheduledRuntimeAuthority) ? params.pluginConfig : disableCodexPluginThreadConfig(params.pluginConfig);
|
|
6761
6739
|
const resolvedPluginPolicy = pluginThreadConfigRequired ? resolveCodexPluginsPolicy(pluginThreadConfigPluginConfig) : void 0;
|
|
6762
6740
|
return {
|
|
6763
6741
|
pluginThreadConfigRequired,
|
|
@@ -6771,10 +6749,10 @@ async function buildCodexPluginThreadConfigWithinDeadline(params) {
|
|
|
6771
6749
|
const { requestTimeoutMs, signal, request, failClosedOnTimeout, transform, ...buildParams } = params;
|
|
6772
6750
|
signal.throwIfAborted();
|
|
6773
6751
|
const timeoutMs = resolveCodexPluginThreadConfigTimeoutMs(requestTimeoutMs);
|
|
6774
|
-
const deadlineMs =
|
|
6752
|
+
const deadlineMs = performance.now() + timeoutMs;
|
|
6775
6753
|
let requestTimedOut = false;
|
|
6776
6754
|
const boundedRequest = async (method, requestParams) => {
|
|
6777
|
-
const remainingTimeoutMs = deadlineMs -
|
|
6755
|
+
const remainingTimeoutMs = deadlineMs - performance.now();
|
|
6778
6756
|
if (requestTimedOut || remainingTimeoutMs <= 0) throw new CodexPluginThreadConfigDeadlineError();
|
|
6779
6757
|
try {
|
|
6780
6758
|
return await request(method, requestParams, {
|
|
@@ -6796,14 +6774,14 @@ async function buildCodexPluginThreadConfigWithinDeadline(params) {
|
|
|
6796
6774
|
request: boundedRequest
|
|
6797
6775
|
});
|
|
6798
6776
|
const result = transform ? await transform(config, boundedRequest) : config;
|
|
6799
|
-
if (requestTimedOut ||
|
|
6777
|
+
if (requestTimedOut || performance.now() >= deadlineMs) throw new CodexPluginThreadConfigDeadlineError();
|
|
6800
6778
|
return result;
|
|
6801
6779
|
})(),
|
|
6802
6780
|
timeoutMessage: "Codex plugin thread config deadline elapsed",
|
|
6803
6781
|
createTimeoutError: () => new CodexPluginThreadConfigDeadlineError()
|
|
6804
6782
|
});
|
|
6805
6783
|
} catch (error) {
|
|
6806
|
-
if (signal.aborted || !requestTimedOut && !isCodexPluginThreadConfigTimeoutError(error) &&
|
|
6784
|
+
if (signal.aborted || !requestTimedOut && !isCodexPluginThreadConfigTimeoutError(error) && performance.now() < deadlineMs) throw error;
|
|
6807
6785
|
if (failClosedOnTimeout) throw new AgentHarnessPreflightError(`Codex app policy verification exceeded its ${timeoutMs} ms startup budget. No app tools were executed. Retry after Codex app inventory is responsive.`);
|
|
6808
6786
|
return buildCodexPluginThreadConfigTimeoutFallback({
|
|
6809
6787
|
pluginConfig: buildParams.pluginConfig,
|
|
@@ -6835,7 +6813,11 @@ function createCodexPluginThreadConfigStartupProvider(params) {
|
|
|
6835
6813
|
appCache: appCache ?? defaultCodexAppInventoryCache,
|
|
6836
6814
|
metadataCache,
|
|
6837
6815
|
failClosedOnTimeout: Boolean(params.scheduledRuntimeAuthority),
|
|
6838
|
-
transform: params.scheduledRuntimeAuthority ? async (builtConfig, request) => intersectCodexPluginThreadConfigWithScheduledAuthority(builtConfig, params.scheduledRuntimeAuthority, await readCurrentCodexScheduledAppPolicy(
|
|
6816
|
+
transform: params.scheduledRuntimeAuthority ? async (builtConfig, request) => intersectCodexPluginThreadConfigWithScheduledAuthority(builtConfig, params.scheduledRuntimeAuthority, await readCurrentCodexScheduledAppPolicy({
|
|
6817
|
+
request,
|
|
6818
|
+
configCwd: params.configCwd,
|
|
6819
|
+
threadId: buildOptions?.threadId
|
|
6820
|
+
})) : void 0,
|
|
6839
6821
|
request: (method, requestParams, options) => client.request(method, requestParams, options)
|
|
6840
6822
|
});
|
|
6841
6823
|
return params.scheduledRuntimeAuthority && params.inputFingerprint ? {
|
|
@@ -6845,13 +6827,6 @@ function createCodexPluginThreadConfigStartupProvider(params) {
|
|
|
6845
6827
|
}
|
|
6846
6828
|
};
|
|
6847
6829
|
}
|
|
6848
|
-
async function readCurrentCodexScheduledAppPolicy(request, cwd, threadId) {
|
|
6849
|
-
return await readCurrentCodexScheduledAppPolicy$1({
|
|
6850
|
-
request,
|
|
6851
|
-
configCwd: cwd,
|
|
6852
|
-
threadId
|
|
6853
|
-
});
|
|
6854
|
-
}
|
|
6855
6830
|
function resolveCodexPluginThreadConfigTimeoutMs(requestTimeoutMs) {
|
|
6856
6831
|
return Math.min(CODEX_PLUGIN_THREAD_CONFIG_MAX_TIMEOUT_MS, Math.max(CODEX_PLUGIN_THREAD_CONFIG_MIN_TIMEOUT_MS, Math.floor((Number.isFinite(requestTimeoutMs) && requestTimeoutMs > 0 ? requestTimeoutMs : CODEX_PLUGIN_THREAD_CONFIG_MAX_TIMEOUT_MS * CODEX_PLUGIN_THREAD_CONFIG_TIMEOUT_DIVISOR) / CODEX_PLUGIN_THREAD_CONFIG_TIMEOUT_DIVISOR)));
|
|
6857
6832
|
}
|
|
@@ -6860,20 +6835,7 @@ function isCodexPluginThreadConfigTimeoutError(error) {
|
|
|
6860
6835
|
}
|
|
6861
6836
|
//#endregion
|
|
6862
6837
|
//#region extensions/codex/src/app-server/attempt-startup.ts
|
|
6863
|
-
/**
|
|
6864
|
-
* Startup orchestration for Codex app-server attempts, including shared-client
|
|
6865
|
-
* leasing, plugin thread config, sandbox environment, and thread lifecycle binding.
|
|
6866
|
-
*/
|
|
6867
6838
|
const CODEX_APP_SERVER_STARTUP_MAX_ATTEMPTS = 3;
|
|
6868
|
-
const CODEX_APP_SERVER_CONTEXT_RESTART_SELECTION_CHANGED = "CODEX_APP_SERVER_CONTEXT_RESTART_SELECTION_CHANGED";
|
|
6869
|
-
/** True when a pre-write context restart must replay on the newly selected owner. */
|
|
6870
|
-
function isCodexContextRestartSelectionChangedError(error) {
|
|
6871
|
-
return error instanceof Error && "code" in error && error.code === CODEX_APP_SERVER_CONTEXT_RESTART_SELECTION_CHANGED;
|
|
6872
|
-
}
|
|
6873
|
-
/**
|
|
6874
|
-
* Starts or resumes the Codex app-server thread and returns the resources the
|
|
6875
|
-
* run loop must later release.
|
|
6876
|
-
*/
|
|
6877
6839
|
async function startCodexAttemptThread(params) {
|
|
6878
6840
|
let pluginAppServer = params.appServer;
|
|
6879
6841
|
const startupRuntimeAuthProfileId = params.startupPreparedAuth?.kind === "profile" ? params.startupPreparedAuth.profileId : params.startupAuthProfileId ?? void 0;
|
|
@@ -6902,6 +6864,7 @@ async function startCodexAttemptThread(params) {
|
|
|
6902
6864
|
const { pluginThreadConfigRequired, pluginThreadConfigPluginConfig, resolvedPluginPolicy, enabledPluginConfigKeys } = resolveCodexPluginThreadConfigStartupPolicy({
|
|
6903
6865
|
pluginConfig: params.pluginConfig,
|
|
6904
6866
|
nativeToolSurfaceEnabled: params.nativeToolSurfaceEnabled,
|
|
6867
|
+
hostedAppsSupported: !isCodexResponsesOAuth(params.startupPreparedAuth),
|
|
6905
6868
|
scheduledRuntimeAuthority: params.buildAttemptParams().scheduledRuntimeAuthority
|
|
6906
6869
|
});
|
|
6907
6870
|
pluginAppServer = resolvedPluginPolicy?.enabled === true || params.computerUseConfig.enabled || params.nativeToolSurfaceEnabled && params.configuredMcpOwnershipVersion !== 1 && hasCodexMcpToolApprovalOverrides(params.config?.mcp?.servers, params.bundleMcpThreadConfig.userStaticServerNames, params.bundleMcpThreadConfig.configPatch?.mcp_servers) ? {
|
|
@@ -6954,6 +6917,7 @@ async function startCodexAttemptThread(params) {
|
|
|
6954
6917
|
if (startupAbandonController.signal.aborted) throw new CodexAppServerStartupError("aborted");
|
|
6955
6918
|
const runtimeArtifact = await verifyStartupArtifact({
|
|
6956
6919
|
client: activeStartupClient,
|
|
6920
|
+
startOptions: params.appServer.start,
|
|
6957
6921
|
request: params.runtimeArtifactRequest,
|
|
6958
6922
|
signal: startupAbandonController.signal
|
|
6959
6923
|
});
|
|
@@ -6961,21 +6925,28 @@ async function startCodexAttemptThread(params) {
|
|
|
6961
6925
|
ensureCodexAppServerClientRuntime(activeStartupClient, {
|
|
6962
6926
|
agentDir: params.agentDir,
|
|
6963
6927
|
authProfileId: startupRuntimeAuthProfileId,
|
|
6964
|
-
authMode: params.startupPreparedAuth?.kind === "api-key" ? "prepared-api-key" : "profile",
|
|
6928
|
+
authMode: params.startupPreparedAuth?.kind === "api-key" || isCodexResponsesOAuth(params.startupPreparedAuth) ? "prepared-api-key" : "profile",
|
|
6965
6929
|
authProfileStore: startupRuntimeAuthProfileStore ?? attemptParams.authProfileStore,
|
|
6966
6930
|
config: params.config
|
|
6967
6931
|
});
|
|
6968
6932
|
const turnRouter = getCodexAppServerTurnRouter(activeStartupClient);
|
|
6969
6933
|
let computerUseTools = [];
|
|
6934
|
+
let computerUseConfig = params.computerUseConfig;
|
|
6970
6935
|
try {
|
|
6971
|
-
|
|
6936
|
+
const computerUseStatus = await ensureCodexComputerUse({
|
|
6972
6937
|
client: activeStartupClient,
|
|
6973
6938
|
pluginConfig: params.pluginConfig,
|
|
6974
6939
|
config: params.config,
|
|
6975
6940
|
agentDir: params.agentDir,
|
|
6976
6941
|
timeoutMs: params.appServer.requestTimeoutMs,
|
|
6977
6942
|
signal: startupAbandonController.signal
|
|
6978
|
-
})
|
|
6943
|
+
});
|
|
6944
|
+
computerUseTools = computerUseStatus.tools;
|
|
6945
|
+
computerUseConfig = {
|
|
6946
|
+
...computerUseConfig,
|
|
6947
|
+
pluginName: computerUseStatus.pluginName,
|
|
6948
|
+
mcpServerName: computerUseStatus.mcpServerName
|
|
6949
|
+
};
|
|
6979
6950
|
} catch (error) {
|
|
6980
6951
|
if (startupAbandonController.signal.aborted || isCodexAppServerStartSelectionChangedError(error)) throw error;
|
|
6981
6952
|
throw new AgentHarnessPreflightError(`Codex Computer Use readiness failed: ${formatErrorMessage(error)}`, {
|
|
@@ -7089,14 +7060,17 @@ async function startCodexAttemptThread(params) {
|
|
|
7089
7060
|
webSearchAllowed: params.webSearchAllowed,
|
|
7090
7061
|
appServer: pluginAppServer,
|
|
7091
7062
|
developerInstructions: params.developerInstructions,
|
|
7063
|
+
skillsInstructions: params.skillsInstructions,
|
|
7092
7064
|
agentWorkspaceDeveloperInstructions: params.agentWorkspaceDeveloperInstructions,
|
|
7093
7065
|
config: threadConfig,
|
|
7094
7066
|
shellEnvironment: params.shellEnvironment,
|
|
7067
|
+
shellPathPrepend: params.shellPathPrepend,
|
|
7095
7068
|
disableLoginShell: params.disableLoginShell,
|
|
7096
7069
|
finalConfigPatch: params.finalConfigPatch,
|
|
7097
7070
|
buildFinalConfigPatch: params.buildFinalConfigPatch,
|
|
7098
7071
|
nativeHookRelayGeneration: params.nativeHookRelayGeneration,
|
|
7099
7072
|
nativeHookRelayRequired: params.nativeHookRelayRequired,
|
|
7073
|
+
nativeModelAdmission: params.nativeModelAdmission,
|
|
7100
7074
|
nativeCodeModeEnabled: params.nativeToolSurfaceEnabled,
|
|
7101
7075
|
nativeProviderWebSearchSupport: params.nativeProviderWebSearchSupport,
|
|
7102
7076
|
nativeCodeModeOnlyEnabled: params.appServer.codeModeOnly,
|
|
@@ -7138,7 +7112,7 @@ async function startCodexAttemptThread(params) {
|
|
|
7138
7112
|
startupSandboxEnvironmentAcquired = false;
|
|
7139
7113
|
startCodexComputerUseHealthMonitor({
|
|
7140
7114
|
client: activeStartupClient,
|
|
7141
|
-
config:
|
|
7115
|
+
config: computerUseConfig,
|
|
7142
7116
|
tools: computerUseTools
|
|
7143
7117
|
});
|
|
7144
7118
|
startupAttemptSucceeded = true;
|
|
@@ -7154,7 +7128,10 @@ async function startCodexAttemptThread(params) {
|
|
|
7154
7128
|
...runtimeArtifact ? { runtimeArtifact } : {},
|
|
7155
7129
|
restartContextEngineCodexThread: async () => {
|
|
7156
7130
|
try {
|
|
7157
|
-
return await startOrResumeThread(
|
|
7131
|
+
return await startOrResumeThread({
|
|
7132
|
+
...buildThreadLifecycleParams(params.signal),
|
|
7133
|
+
contextEngineProjection: void 0
|
|
7134
|
+
});
|
|
7158
7135
|
} catch (error) {
|
|
7159
7136
|
if (!isCodexAppServerStartSelectionChangedError(error)) throw error;
|
|
7160
7137
|
retireSharedCodexAppServerClientIfCurrent(activeStartupClient);
|
|
@@ -7195,7 +7172,7 @@ async function startCodexAttemptThread(params) {
|
|
|
7195
7172
|
} catch (error) {
|
|
7196
7173
|
const selectionChanged = isCodexAppServerStartSelectionChangedError(error);
|
|
7197
7174
|
const clientRetired = error instanceof CodexThreadClientReplacementError;
|
|
7198
|
-
if (startupAbandonController.signal.aborted || clientRetired && replacedSettledFailureClient || !clientRetired && !selectionChanged && !isCodexAppServerConnectionClosedError(error)) throw error;
|
|
7175
|
+
if (startupAbandonController.signal.aborted || isCodexWebSocketOpenFailure(error) || clientRetired && replacedSettledFailureClient || !clientRetired && !selectionChanged && !isCodexAppServerConnectionClosedError(error)) throw error;
|
|
7199
7176
|
replacedSettledFailureClient ||= clientRetired;
|
|
7200
7177
|
const refreshedSharedClient = clientRetired ? void 0 : selectionChanged ? retireSharedCodexAppServerClientIfCurrent(attemptedClient) : clearSharedCodexAppServerClientIfCurrent(attemptedClient);
|
|
7201
7178
|
if (startupClientForAbandonedRequestCleanup === attemptedClient) startupClientForAbandonedRequestCleanup = void 0;
|
|
@@ -7246,7 +7223,7 @@ async function startCodexAttemptRuntime(resources) {
|
|
|
7246
7223
|
const { prompt, state, trajectoryRecorder, startupTimeoutMs, buildNativeHookRelayFinalConfigPatch } = resources;
|
|
7247
7224
|
const { context, turnState, rebuildCodexTurnPromptTextFromCurrentProjection, applyNoContextEngineContinuityProjection } = prompt;
|
|
7248
7225
|
const { runtime, attemptTools, promptState } = context;
|
|
7249
|
-
const { connection, runtimeParams, preparedAuthBinding,
|
|
7226
|
+
const { connection, runtimeParams, preparedAuthBinding, startupAuthAccountCacheKey, startupEnvApiKeyCacheKey, bundleMcpThreadConfig, nativeToolSurfaceEnabled, nativeProviderWebSearchSupport, effectiveRuntimeModelId, sandboxExecServerEnabled } = runtime;
|
|
7250
7227
|
const { toolBridge, toolState } = attemptTools;
|
|
7251
7228
|
const developerInstructions = joinPresentSections(turnState.promptBuild.developerInstructions, attemptTools.configuredMcp?.diagnosticNotice);
|
|
7252
7229
|
const { params, attemptClientFactory, bindingStore, appServer, pluginConfig, computerUseConfig, startupClientAuthProfileId, runtimeArtifactRequest, startupPreparedAuth, agentDir, sessionAgentId, effectiveWorkspace, effectiveCwd, sandbox, runAbortController, usesSupervisionConnection, resolveReviewerPolicyContext, resolveRuntimeOptionsForCurrentBinding, startupAuthProfileId, startupAuthRequirement } = connection;
|
|
@@ -7275,8 +7252,9 @@ async function startCodexAttemptRuntime(resources) {
|
|
|
7275
7252
|
agentDir,
|
|
7276
7253
|
config: params.config,
|
|
7277
7254
|
shellEnvironment: connection.shellEnvironment,
|
|
7255
|
+
shellPathPrepend: connection.shellPathPrepend,
|
|
7278
7256
|
disableLoginShell: connection.disableLoginShell,
|
|
7279
|
-
buildAttemptParams:
|
|
7257
|
+
buildAttemptParams: () => ({ ...runtimeParams }),
|
|
7280
7258
|
...effectiveRuntimeModelId !== runtimeParams.modelId ? { runtimeModelId: effectiveRuntimeModelId } : {},
|
|
7281
7259
|
sessionAgentId,
|
|
7282
7260
|
effectiveWorkspace,
|
|
@@ -7285,9 +7263,11 @@ async function startCodexAttemptRuntime(resources) {
|
|
|
7285
7263
|
persistentWebSearchAllowed: toolState.persistentWebSearchAllowed,
|
|
7286
7264
|
webSearchAllowed: toolState.webSearchAllowed,
|
|
7287
7265
|
developerInstructions,
|
|
7266
|
+
skillsInstructions: context.skillsInstructions,
|
|
7288
7267
|
agentWorkspaceDeveloperInstructions: context.agentWorkspaceDeveloperInstructions,
|
|
7289
7268
|
buildFinalConfigPatch: buildNativeHookRelayFinalConfigPatch,
|
|
7290
|
-
|
|
7269
|
+
nativeModelAdmission: resources.nativeModelAdmission,
|
|
7270
|
+
nativeHookRelayRequired: nativeToolSurfaceEnabled && params.pluginHarnessToolPolicyRestricted !== true && (resources.nativeProcessAuthority?.requiresProcessAdmission || resources.nativeModelAdmission === "required") || connection.options.nativeHookRelay?.enabled !== false && params.pluginHarnessToolPolicyRestricted !== true && connection.nativeHookRelayEvents.includes("pre_tool_use") && (hasBeforeToolCallPolicy() || appServer.loopDetectionPreToolUseRelay && Boolean(connection.sandboxSessionKey) && loopDetectionEnabled),
|
|
7291
7271
|
bundleMcpThreadConfig,
|
|
7292
7272
|
configuredMcpDynamicSurface: attemptTools.configuredMcp !== void 0,
|
|
7293
7273
|
configuredMcpOwnershipVersion: attemptTools.configuredMcpOwnershipVersion,
|
|
@@ -7378,6 +7358,53 @@ async function startCodexAttemptRuntime(resources) {
|
|
|
7378
7358
|
}
|
|
7379
7359
|
}
|
|
7380
7360
|
//#endregion
|
|
7361
|
+
//#region extensions/codex/src/app-server/heartbeat-tool-fallback.ts
|
|
7362
|
+
const InactiveHeartbeatResponseParameters = Type.Object({}, { additionalProperties: true });
|
|
7363
|
+
function resolveInactiveCodexHeartbeatResponseDescriptor(params) {
|
|
7364
|
+
if (params.registeredSpecs) {
|
|
7365
|
+
const spec = flattenCodexDynamicToolFunctions(params.registeredSpecs).find((tool) => tool.name === HEARTBEAT_RESPONSE_TOOL_NAME);
|
|
7366
|
+
return spec ? {
|
|
7367
|
+
name: spec.name,
|
|
7368
|
+
description: spec.description
|
|
7369
|
+
} : void 0;
|
|
7370
|
+
}
|
|
7371
|
+
const descriptor = params.registeredTools.find((tool) => tool.name === HEARTBEAT_RESPONSE_TOOL_NAME);
|
|
7372
|
+
return descriptor ? {
|
|
7373
|
+
name: descriptor.name,
|
|
7374
|
+
description: descriptor.description
|
|
7375
|
+
} : void 0;
|
|
7376
|
+
}
|
|
7377
|
+
/** Keeps the thread-stable heartbeat endpoint executable on ordinary Codex turns. */
|
|
7378
|
+
function createInactiveCodexHeartbeatResponseTool(descriptor) {
|
|
7379
|
+
if (descriptor.name !== HEARTBEAT_RESPONSE_TOOL_NAME) throw new Error(`Expected ${HEARTBEAT_RESPONSE_TOOL_NAME}, received ${descriptor.name}`);
|
|
7380
|
+
return {
|
|
7381
|
+
name: descriptor.name,
|
|
7382
|
+
label: descriptor.name,
|
|
7383
|
+
description: descriptor.description,
|
|
7384
|
+
parameters: InactiveHeartbeatResponseParameters,
|
|
7385
|
+
execute: async (_toolCallId, args) => {
|
|
7386
|
+
const response = normalizeHeartbeatToolResponse(args);
|
|
7387
|
+
if (!response) throw new Error("Invalid heartbeat response. Provide outcome, notify, and non-empty summary.");
|
|
7388
|
+
if (response.notify) throw new Error("heartbeat_respond cannot send notifications outside a heartbeat turn");
|
|
7389
|
+
return {
|
|
7390
|
+
content: [{
|
|
7391
|
+
type: "text",
|
|
7392
|
+
text: "No heartbeat is active for this turn. Continue the current task and respond normally."
|
|
7393
|
+
}],
|
|
7394
|
+
details: {
|
|
7395
|
+
status: "ignored",
|
|
7396
|
+
reason: "non-heartbeat-turn"
|
|
7397
|
+
}
|
|
7398
|
+
};
|
|
7399
|
+
}
|
|
7400
|
+
};
|
|
7401
|
+
}
|
|
7402
|
+
function selectInactiveCodexHeartbeatResponseTool(params) {
|
|
7403
|
+
if (params.disableTools) return;
|
|
7404
|
+
const allowed = applyEmbeddedAttemptToolsAllow([createInactiveCodexHeartbeatResponseTool(params.descriptor)], params.toolsAllow);
|
|
7405
|
+
return filterCodexDynamicTools(allowed, params.pluginConfig)[0];
|
|
7406
|
+
}
|
|
7407
|
+
//#endregion
|
|
7381
7408
|
//#region extensions/codex/src/app-server/run-attempt-tool-setup.ts
|
|
7382
7409
|
function isAuthorityResolutionOperationAbort(error, signal) {
|
|
7383
7410
|
return signal?.aborted === true && error === signal.reason;
|
|
@@ -7386,7 +7413,7 @@ async function prepareCodexAttemptTools(runtime) {
|
|
|
7386
7413
|
const { connection, bundleMcpThreadConfig, bundleManifestRegistry, runtimeParams, effectiveRuntimeModelId, nativeToolSurfaceEnabled, nativeProviderWebSearchSupport, hookChannelId, codexMcpToolOverrides, authenticatedScheduledMode, configuredMcpSurface, canResolveScheduledConfiguredMcpCreatorAuthority } = runtime;
|
|
7387
7414
|
const { params, preDynamicStartupStages, mutable, resolvedWorkspace, effectiveWorkspace, effectiveCwd, sandboxSessionKey, contextSessionKey, sandbox, sessionPermissionPolicy, runAbortController, sessionAgentId, policyAgentId, pluginConfig, profilerEnabled, agentDir } = connection;
|
|
7388
7415
|
const preDynamicSummary = preDynamicStartupStages.snapshot();
|
|
7389
|
-
if (shouldWarnCodexDynamicToolBuildStageSummary(preDynamicSummary, profilerEnabled)) embeddedAgentLog.warn(`codex app-server pre-dynamic startup timings runId=${params.runId} sessionId=${params.sessionId} totalMs=${preDynamicSummary.totalMs} stages=${
|
|
7416
|
+
if (shouldWarnCodexDynamicToolBuildStageSummary(preDynamicSummary, profilerEnabled)) embeddedAgentLog.warn(`codex app-server pre-dynamic startup timings runId=${params.runId} sessionId=${params.sessionId} totalMs=${preDynamicSummary.totalMs} stages=${formatStageTimings(preDynamicSummary.stages)}`, {
|
|
7390
7417
|
runId: params.runId,
|
|
7391
7418
|
sessionId: params.sessionId,
|
|
7392
7419
|
totalMs: preDynamicSummary.totalMs,
|
|
@@ -7441,7 +7468,7 @@ async function prepareCodexAttemptTools(runtime) {
|
|
|
7441
7468
|
} : void 0;
|
|
7442
7469
|
const scheduledCodexAppAuth = preparedChatgptAuth ?? configuredAppServerAuth;
|
|
7443
7470
|
const appPolicy = resolveCodexPluginsPolicy(pluginConfig);
|
|
7444
|
-
const codexAppsMayBeVisible = appPolicy.enabled && (appPolicy.allowAllPlugins || appPolicy.pluginPolicies.some((entry) => entry.enabled));
|
|
7471
|
+
const codexAppsMayBeVisible = !isCodexResponsesOAuth(connection.startupPreparedAuth) && appPolicy.enabled && (appPolicy.allowAllPlugins || appPolicy.pluginPolicies.some((entry) => entry.enabled));
|
|
7445
7472
|
const appCreatorCapture = resolveScheduledCodexAppCreatorCaptureDecision({
|
|
7446
7473
|
appsMayBeVisible: codexAppsMayBeVisible,
|
|
7447
7474
|
authenticatedScheduledMode,
|
|
@@ -7612,20 +7639,8 @@ async function prepareCodexAttemptTools(runtime) {
|
|
|
7612
7639
|
const reservedToolNames = [...tools.map((tool) => tool.name), ...registeredTools.map((tool) => tool.name)];
|
|
7613
7640
|
const turnSourceChannel = params.messageChannel ?? params.messageProvider;
|
|
7614
7641
|
const turnSourceTo = params.currentMessagingTarget ?? params.currentChannelId;
|
|
7615
|
-
const requester =
|
|
7616
|
-
|
|
7617
|
-
...params.agentAccountId ? { accountId: params.agentAccountId } : {},
|
|
7618
|
-
...params.senderId ? { senderId: params.senderId } : {},
|
|
7619
|
-
...params.senderIsOwner !== void 0 ? { senderIsOwner: params.senderIsOwner } : {},
|
|
7620
|
-
...params.memberRoleIds?.length ? { roleIds: [...params.memberRoleIds] } : {}
|
|
7621
|
-
};
|
|
7622
|
-
const hasRequester = Object.keys(requester).length > 0;
|
|
7623
|
-
const requestInteractiveMcpApproval = async (approval) => {
|
|
7624
|
-
const allowedDecisions = approval.mode === "prompt" ? ["allow-once", "deny"] : [
|
|
7625
|
-
"allow-once",
|
|
7626
|
-
"allow-always",
|
|
7627
|
-
"deny"
|
|
7628
|
-
];
|
|
7642
|
+
const requester = buildCodexHookRequester(params);
|
|
7643
|
+
const requestInteractiveMcpApproval = async (approval, allowedDecisions) => {
|
|
7629
7644
|
const outcome = await requestPluginApprovalOutcome({
|
|
7630
7645
|
hostCapabilities: params.hostCapabilities,
|
|
7631
7646
|
signal: approval.signal,
|
|
@@ -7642,57 +7657,39 @@ async function prepareCodexAttemptTools(runtime) {
|
|
|
7642
7657
|
});
|
|
7643
7658
|
if (outcome !== "approved-once" && outcome !== "approved-session") throw new Error(`${approval.serverName}/${approval.toolName}: interactive Codex approval (${approval.mode}) was not granted: ${outcome}`);
|
|
7644
7659
|
};
|
|
7645
|
-
const
|
|
7646
|
-
const outcome = await requestPluginApprovalOutcome({
|
|
7647
|
-
hostCapabilities: params.hostCapabilities,
|
|
7648
|
-
signal: approval.signal,
|
|
7649
|
-
title: `Run MCP tool ${approval.serverName}/${approval.toolName}`,
|
|
7650
|
-
description: `Codex approval mode "${approval.mode}" requires an operator decision before this MCP tool runs. ${formatMcpCodexApprovalRemedy(approval.serverName)}`,
|
|
7651
|
-
allowedDecisions: ["allow-once", "deny"],
|
|
7652
|
-
toolName: approval.safeToolName,
|
|
7653
|
-
toolCallId: approval.toolCallId,
|
|
7654
|
-
mcpTool: {
|
|
7655
|
-
server: approval.serverName,
|
|
7656
|
-
tool: approval.toolName
|
|
7657
|
-
},
|
|
7658
|
-
isMcpToolApprovalActive: approval.isActive
|
|
7659
|
-
});
|
|
7660
|
-
if (outcome !== "approved-once" && outcome !== "approved-session") throw new Error(`${approval.serverName}/${approval.toolName}: interactive Codex approval (${approval.mode}) was not granted: ${outcome}`);
|
|
7661
|
-
};
|
|
7662
|
-
configuredMcp = configuredMcpSurface ? await materializeStaticMcpToolsForHarnessRun({
|
|
7663
|
-
sessionId: params.sessionId,
|
|
7664
|
-
sessionKey: params.sessionKey,
|
|
7665
|
-
agentId: sessionAgentId,
|
|
7660
|
+
const mcpOptions = {
|
|
7666
7661
|
workspaceDir: effectiveWorkspace,
|
|
7667
7662
|
agentDir: policyContext.agentDir,
|
|
7668
7663
|
cfg: params.config,
|
|
7669
7664
|
manifestRegistry: bundleManifestRegistry,
|
|
7670
|
-
reservedToolNames,
|
|
7671
7665
|
toolsAllow: params.toolsAllow,
|
|
7672
7666
|
toolOverrides: codexMcpToolOverrides,
|
|
7673
7667
|
autoApproveCodexAppServerApprovals: shouldAutoApproveCodexAppServerApprovals(connection.appServer),
|
|
7674
|
-
projectedMcpServers: bundleMcpThreadConfig.configPatch?.mcp_servers,
|
|
7675
|
-
...configuredMcpSurface === "transient" ? { requestInteractiveCodexApproval: requestInteractiveMcpApproval } : {},
|
|
7676
7668
|
policyContext,
|
|
7677
7669
|
warn: (message) => embeddedAgentLog.warn(message)
|
|
7670
|
+
};
|
|
7671
|
+
configuredMcp = configuredMcpSurface ? await materializeStaticMcpToolsForHarnessRun({
|
|
7672
|
+
...mcpOptions,
|
|
7673
|
+
sessionId: params.sessionId,
|
|
7674
|
+
sessionKey: params.sessionKey,
|
|
7675
|
+
agentId: sessionAgentId,
|
|
7676
|
+
reservedToolNames,
|
|
7677
|
+
projectedMcpServers: bundleMcpThreadConfig.configPatch?.mcp_servers,
|
|
7678
|
+
...configuredMcpSurface === "transient" ? { requestInteractiveCodexApproval: (approval) => requestInteractiveMcpApproval(approval, approval.mode === "prompt" ? ["allow-once", "deny"] : [
|
|
7679
|
+
"allow-once",
|
|
7680
|
+
"allow-always",
|
|
7681
|
+
"deny"
|
|
7682
|
+
]) } : {}
|
|
7678
7683
|
}) : void 0;
|
|
7679
7684
|
scopedMcpTools = authenticatedScheduledMode ? void 0 : await materializeRequesterScopedMcpToolsForHarnessRun({
|
|
7685
|
+
...mcpOptions,
|
|
7680
7686
|
sessionId: params.sessionId,
|
|
7681
7687
|
sessionKey: params.sessionKey,
|
|
7682
|
-
|
|
7683
|
-
agentDir: policyContext.agentDir,
|
|
7684
|
-
cfg: params.config,
|
|
7685
|
-
manifestRegistry: bundleManifestRegistry,
|
|
7686
|
-
toolOverrides: codexMcpToolOverrides,
|
|
7687
|
-
autoApproveCodexAppServerApprovals: shouldAutoApproveCodexAppServerApprovals(connection.appServer),
|
|
7688
|
-
requestInteractiveCodexApproval: requestRequesterMcpApproval,
|
|
7688
|
+
requestInteractiveCodexApproval: (approval) => requestInteractiveMcpApproval(approval, ["allow-once", "deny"]),
|
|
7689
7689
|
requesterSenderId: params.senderId,
|
|
7690
7690
|
agentAccountId: params.agentAccountId,
|
|
7691
7691
|
messageChannel: params.messageChannel ?? params.messageProvider,
|
|
7692
|
-
reservedToolNames: [...reservedToolNames, ...configuredMcp?.tools.map((tool) => tool.name) ?? []]
|
|
7693
|
-
toolsAllow: params.toolsAllow,
|
|
7694
|
-
policyContext,
|
|
7695
|
-
warn: (message) => embeddedAgentLog.warn(message)
|
|
7692
|
+
reservedToolNames: [...reservedToolNames, ...configuredMcp?.tools.map((tool) => tool.name) ?? []]
|
|
7696
7693
|
});
|
|
7697
7694
|
const scopedExecutable = filterCodexDynamicTools([...configuredMcp?.tools ?? [], ...scopedMcpTools?.tools ?? []], pluginConfig);
|
|
7698
7695
|
const scopedAdvertised = filterCodexDynamicTools([...configuredMcp?.tools ?? [], ...scopedMcpTools?.advertisedTools ?? []], pluginConfig);
|
|
@@ -7721,19 +7718,32 @@ async function prepareCodexAttemptTools(runtime) {
|
|
|
7721
7718
|
allocateToolOutcomeOrdinal: allocateCodexToolOutcomeOrdinal,
|
|
7722
7719
|
trigger: params.trigger,
|
|
7723
7720
|
approvalReviewerDeviceId: params.approvalReviewerDeviceId,
|
|
7724
|
-
...
|
|
7721
|
+
...requester ? { requester } : {},
|
|
7725
7722
|
...turnSourceChannel ? { turnSourceChannel } : {},
|
|
7726
7723
|
...turnSourceTo ? { turnSourceTo } : {},
|
|
7727
7724
|
...params.agentAccountId ? { turnSourceAccountId: params.agentAccountId } : {},
|
|
7728
7725
|
...params.currentThreadTs !== void 0 ? { turnSourceThreadId: params.currentThreadTs } : {}
|
|
7729
7726
|
};
|
|
7727
|
+
const heartbeatFallbackDescriptor = resolveInactiveCodexHeartbeatResponseDescriptor({
|
|
7728
|
+
registeredTools: registeredWithScopedMcp,
|
|
7729
|
+
...nativeSpecs ? { registeredSpecs: nativeSpecs } : {}
|
|
7730
|
+
});
|
|
7731
|
+
const heartbeatFallbackTool = heartbeatFallbackDescriptor && supportsModelTools(params.model) ? selectInactiveCodexHeartbeatResponseTool({
|
|
7732
|
+
descriptor: heartbeatFallbackDescriptor,
|
|
7733
|
+
disableTools: params.disableTools,
|
|
7734
|
+
toolsAllow: params.toolsAllow,
|
|
7735
|
+
pluginConfig
|
|
7736
|
+
}) : void 0;
|
|
7737
|
+
const registeredFallbackTools = params.trigger === "heartbeat" || params.enableHeartbeatTool === true || params.forceHeartbeatTool === true || !heartbeatFallbackTool ? void 0 : params.hostCapabilities.bindToolSurface([heartbeatFallbackTool], { cwd: effectiveCwd ?? effectiveWorkspace });
|
|
7730
7738
|
const toolBridge = createCodexDynamicToolBridge({
|
|
7731
7739
|
tools: toolsWithScopedMcp,
|
|
7732
7740
|
registeredTools: registeredWithScopedMcp,
|
|
7741
|
+
registeredFallbackTools,
|
|
7733
7742
|
registeredSpecs: nativeSpecs,
|
|
7734
7743
|
signal: runAbortController.signal,
|
|
7735
7744
|
computerContextEpoch,
|
|
7736
|
-
|
|
7745
|
+
functionToolsOnly: isCodexResponsesOAuth(connection.startupPreparedAuth),
|
|
7746
|
+
loading: isCodexResponsesOAuth(connection.startupPreparedAuth) ? "direct" : resolveCodexDynamicToolsLoadingForRuntime(pluginConfig, effectiveRuntimeModelId, { connectionClass: connection.appServer.connectionClass }),
|
|
7737
7747
|
directToolNames: resolveCodexDynamicToolDirectNames(params, registeredWithScopedMcp, isHostScopedAgentToolActive("openclaw")),
|
|
7738
7748
|
hookContext
|
|
7739
7749
|
});
|
|
@@ -7757,19 +7767,11 @@ async function prepareCodexAttemptTools(runtime) {
|
|
|
7757
7767
|
try {
|
|
7758
7768
|
if (canResolveScheduledConfiguredMcpCreatorAuthority) try {
|
|
7759
7769
|
materialized = await materializeStaticMcpToolsForHarnessRun({
|
|
7770
|
+
...mcpOptions,
|
|
7760
7771
|
sessionId: `cron-authority:${params.runId}`,
|
|
7761
7772
|
agentId: sessionAgentId,
|
|
7762
|
-
workspaceDir: effectiveWorkspace,
|
|
7763
|
-
agentDir: policyContext.agentDir,
|
|
7764
|
-
cfg: params.config,
|
|
7765
|
-
manifestRegistry: bundleManifestRegistry,
|
|
7766
7773
|
reservedToolNames: configuredMcp ? reservedToolNames : toolBridge.availableTools.map((tool) => tool.name),
|
|
7767
|
-
toolsAllow: params.toolsAllow,
|
|
7768
|
-
toolOverrides: codexMcpToolOverrides,
|
|
7769
|
-
autoApproveCodexAppServerApprovals: shouldAutoApproveCodexAppServerApprovals(connection.appServer),
|
|
7770
7774
|
projectedMcpServers: bundleMcpThreadConfig.configPatch?.mcp_servers,
|
|
7771
|
-
policyContext,
|
|
7772
|
-
warn: (message) => embeddedAgentLog.warn(message),
|
|
7773
7775
|
retireSessionRuntimeAfterDispose: true
|
|
7774
7776
|
});
|
|
7775
7777
|
} catch (error) {
|
|
@@ -7798,9 +7800,7 @@ async function prepareCodexAttemptTools(runtime) {
|
|
|
7798
7800
|
};
|
|
7799
7801
|
return {
|
|
7800
7802
|
tools: toolsWithScopedMcp,
|
|
7801
|
-
registeredTools: registeredWithScopedMcp,
|
|
7802
7803
|
requireExplicitMessageTarget,
|
|
7803
|
-
scopedMcpTools,
|
|
7804
7804
|
configuredMcp,
|
|
7805
7805
|
disposeTools,
|
|
7806
7806
|
configuredMcpOwnershipVersion: configuredMcpSurface === "scheduled" ? 1 : void 0,
|
|
@@ -7813,7 +7813,6 @@ async function prepareCodexAttemptTools(runtime) {
|
|
|
7813
7813
|
toolState,
|
|
7814
7814
|
toolOutcomeOrdinals,
|
|
7815
7815
|
suppressedDynamicToolOutcomeOrdinals,
|
|
7816
|
-
onCodexToolOutcome,
|
|
7817
7816
|
allocateCodexToolOutcomeOrdinal,
|
|
7818
7817
|
runtimeYieldCompletionClaim
|
|
7819
7818
|
};
|
|
@@ -7944,6 +7943,40 @@ async function prepareCodexProviderReviewContinuation(params) {
|
|
|
7944
7943
|
}
|
|
7945
7944
|
}
|
|
7946
7945
|
//#endregion
|
|
7946
|
+
//#region extensions/codex/src/app-server/service-tier.ts
|
|
7947
|
+
/** Optional speed upgrades follow this turn's native model and authenticated client. */
|
|
7948
|
+
async function resolveCodexUltrafastServiceTier(params) {
|
|
7949
|
+
if (!params.enabled || params.modelProvider !== "openai" && params.modelProvider !== "openclaw_token_sharing" || !params.model) return params.serviceTier;
|
|
7950
|
+
params.signal.throwIfAborted();
|
|
7951
|
+
params.assertCurrent();
|
|
7952
|
+
const deadline = Date.now() + params.timeoutMs;
|
|
7953
|
+
try {
|
|
7954
|
+
const catalog = await listAllCodexAppServerModels({
|
|
7955
|
+
includeHidden: true,
|
|
7956
|
+
request: (request) => {
|
|
7957
|
+
const timeoutMs = deadline - Date.now();
|
|
7958
|
+
if (timeoutMs <= 0) throw new Error("Codex Ultrafast catalog deadline exceeded");
|
|
7959
|
+
return requestCodexAppServerClientJson({
|
|
7960
|
+
...request,
|
|
7961
|
+
client: params.client,
|
|
7962
|
+
signal: params.signal,
|
|
7963
|
+
assertCurrent: params.assertCurrent,
|
|
7964
|
+
timeoutMs,
|
|
7965
|
+
config: params.config
|
|
7966
|
+
});
|
|
7967
|
+
}
|
|
7968
|
+
});
|
|
7969
|
+
params.signal.throwIfAborted();
|
|
7970
|
+
params.assertCurrent();
|
|
7971
|
+
return catalog.models.find((entry) => entry.model === params.model)?.serviceTiers?.includes("ultrafast") ? "ultrafast" : params.serviceTier;
|
|
7972
|
+
} catch (error) {
|
|
7973
|
+
params.signal.throwIfAborted();
|
|
7974
|
+
params.assertCurrent();
|
|
7975
|
+
if (error instanceof CodexAppServerScopedRequestRejectedError) throw error;
|
|
7976
|
+
return params.serviceTier;
|
|
7977
|
+
}
|
|
7978
|
+
}
|
|
7979
|
+
//#endregion
|
|
7947
7980
|
//#region extensions/codex/src/app-server/run-attempt-turn-request.ts
|
|
7948
7981
|
async function prepareCodexAttemptTurnRequest(resources, turnRuntime, ensureCurrentThreadRoute, waitForActiveNativeTurnCompletion) {
|
|
7949
7982
|
const { prompt, state: resourceState, releaseCurrentRoute } = resources;
|
|
@@ -7951,7 +7984,7 @@ async function prepareCodexAttemptTurnRequest(resources, turnRuntime, ensureCurr
|
|
|
7951
7984
|
const { runtime, attemptTools, hookContextWindowFields, workspaceBootstrapContext } = context;
|
|
7952
7985
|
const { connection, runtimeParams, effectiveRuntimeProviderId, effectiveRuntimeModelId } = runtime;
|
|
7953
7986
|
const { tools, toolBridge } = attemptTools;
|
|
7954
|
-
const { params, usesSupervisionConnection, codexModelCallId, codexModelCallTrace, codexModelContentCapture, appServer, runAbortController } = connection;
|
|
7987
|
+
const { params, sessionAgentId, usesSupervisionConnection, codexModelCallId, codexModelCallTrace, codexModelContentCapture, appServer, runAbortController } = connection;
|
|
7955
7988
|
const { state } = turnRuntime;
|
|
7956
7989
|
const explicitSkillInputs = await resolveCodexExplicitSkillInputs({
|
|
7957
7990
|
client: resourceState.client,
|
|
@@ -7959,18 +7992,22 @@ async function prepareCodexAttemptTurnRequest(resources, turnRuntime, ensureCurr
|
|
|
7959
7992
|
selections: runtimeParams.explicitSkillSelections,
|
|
7960
7993
|
signal: runAbortController.signal
|
|
7961
7994
|
});
|
|
7962
|
-
const buildCodexModelInputMessages = () => [
|
|
7995
|
+
const buildCodexModelInputMessages = () => [buildCodexUserPromptMessage({
|
|
7963
7996
|
...runtimeParams,
|
|
7964
7997
|
prompt: turnState.codexTurnPromptText
|
|
7965
7998
|
})];
|
|
7999
|
+
const buildModelCallIdentity = () => ({
|
|
8000
|
+
runId: params.runId,
|
|
8001
|
+
sessionId: params.sessionId,
|
|
8002
|
+
provider: usesSupervisionConnection ? resourceState.thread.modelProvider ?? effectiveRuntimeProviderId : params.provider,
|
|
8003
|
+
model: usesSupervisionConnection ? resourceState.thread.model ?? effectiveRuntimeModelId : params.modelId
|
|
8004
|
+
});
|
|
7966
8005
|
const codexModelCallDiagnostics = createCodexModelCallDiagnosticEmitter({
|
|
7967
8006
|
baseFields: {
|
|
7968
|
-
|
|
8007
|
+
...buildModelCallIdentity(),
|
|
8008
|
+
agentId: sessionAgentId,
|
|
7969
8009
|
callId: codexModelCallId,
|
|
7970
8010
|
...params.sessionKey ? { sessionKey: params.sessionKey } : {},
|
|
7971
|
-
sessionId: params.sessionId,
|
|
7972
|
-
provider: usesSupervisionConnection ? resourceState.thread.modelProvider ?? effectiveRuntimeProviderId : params.provider,
|
|
7973
|
-
model: usesSupervisionConnection ? resourceState.thread.model ?? effectiveRuntimeModelId : params.modelId,
|
|
7974
8011
|
api: usesSupervisionConnection ? runtimeParams.model.api : params.model.api,
|
|
7975
8012
|
transport: appServer.start.transport,
|
|
7976
8013
|
observationUnit: "turn",
|
|
@@ -8004,15 +8041,16 @@ async function prepareCodexAttemptTurnRequest(resources, turnRuntime, ensureCurr
|
|
|
8004
8041
|
const selectedThread = resourceState.thread;
|
|
8005
8042
|
const { threadId, liveThreadOwnership, model, modelProvider } = selectedThread;
|
|
8006
8043
|
const turnClient = resourceState.client;
|
|
8044
|
+
const nativeModel = usesSupervisionConnection ? requireCodexSupervisionModelSelection(selectedThread) : void 0;
|
|
8007
8045
|
const assertTurnCurrent = () => {
|
|
8008
8046
|
connection.assertCurrent();
|
|
8009
8047
|
liveThreadOwnership?.assertCurrent();
|
|
8010
8048
|
if (resourceState.thread !== selectedThread || selectedThread.threadId !== threadId || selectedThread.liveThreadOwnership !== liveThreadOwnership || selectedThread.model !== model || selectedThread.modelProvider !== modelProvider) throw new Error("Codex native model or thread ownership changed during turn start.");
|
|
8011
8049
|
};
|
|
8012
|
-
const
|
|
8013
|
-
connection.mutable.pluginAppServer
|
|
8050
|
+
const fastMode = typeof runtimeParams.fastMode === "function" ? runtimeParams.fastMode() : runtimeParams.fastMode;
|
|
8051
|
+
const turnAppServer = withCodexAppServerFastModeServiceTier(connection.mutable.pluginAppServer, { fastMode }, connection.appServer);
|
|
8014
8052
|
const references = prepareWorkspaceReferences();
|
|
8015
|
-
const inferenceRoute =
|
|
8053
|
+
const inferenceRoute = getCodexInferenceThread(resourceState.client, resourceState.thread.threadId);
|
|
8016
8054
|
const turnStartParams = buildTurnStartParams(runtimeParams, {
|
|
8017
8055
|
threadId: resourceState.thread.threadId,
|
|
8018
8056
|
cwd: resourceState.codexExecutionCwd,
|
|
@@ -8029,7 +8067,6 @@ async function prepareCodexAttemptTurnRequest(resources, turnRuntime, ensureCurr
|
|
|
8029
8067
|
modelProvider: resourceState.thread.modelProvider
|
|
8030
8068
|
},
|
|
8031
8069
|
turnScopedDeveloperInstructions: workspaceBootstrapContext.turnScopedDeveloperInstructions,
|
|
8032
|
-
skillsCollaborationInstructions: context.skillsCollaborationInstructions,
|
|
8033
8070
|
memoryCollaborationInstructions: workspaceBootstrapContext.memoryCollaborationInstructions,
|
|
8034
8071
|
preserveNativeTurnSettings: usesSupervisionConnection,
|
|
8035
8072
|
parentLocalEgress: inferenceRoute !== void 0,
|
|
@@ -8037,15 +8074,51 @@ async function prepareCodexAttemptTurnRequest(resources, turnRuntime, ensureCurr
|
|
|
8037
8074
|
requireExplicitMessageTarget: attemptTools.requireExplicitMessageTarget,
|
|
8038
8075
|
sessionStatusAvailable: toolBridge.availableTools.some((tool) => tool.name === "session_status")
|
|
8039
8076
|
});
|
|
8077
|
+
const serviceTier = await resolveCodexUltrafastServiceTier({
|
|
8078
|
+
enabled: turnAppServer.enableUltrafast === true && fastMode !== false,
|
|
8079
|
+
serviceTier: turnStartParams.serviceTier,
|
|
8080
|
+
model: turnStartParams.model ?? model,
|
|
8081
|
+
modelProvider,
|
|
8082
|
+
client: turnClient,
|
|
8083
|
+
timeoutMs: Math.min(params.timeoutMs, 2500),
|
|
8084
|
+
signal: runAbortController.signal,
|
|
8085
|
+
assertCurrent: assertTurnCurrent,
|
|
8086
|
+
config: params.config
|
|
8087
|
+
});
|
|
8088
|
+
assertTurnCurrent();
|
|
8089
|
+
turnStartParams.serviceTier = serviceTier;
|
|
8090
|
+
connection.mutable.pluginAppServer = {
|
|
8091
|
+
...turnAppServer,
|
|
8092
|
+
serviceTier
|
|
8093
|
+
};
|
|
8094
|
+
const authorizedModel = nativeModel ? {
|
|
8095
|
+
provider: nativeModel.modelProvider,
|
|
8096
|
+
model: nativeModel.model
|
|
8097
|
+
} : effectiveRuntimeModelId === readCodexRuntimeModelId(params.model, params.modelId) ? {
|
|
8098
|
+
provider: params.provider,
|
|
8099
|
+
model: params.modelId
|
|
8100
|
+
} : turnStartParams.model ? {
|
|
8101
|
+
provider: modelProvider ?? params.provider,
|
|
8102
|
+
model: turnStartParams.model
|
|
8103
|
+
} : void 0;
|
|
8104
|
+
connection.bindModelExecution(authorizedModel);
|
|
8105
|
+
const nativeRequestModel = turnStartParams.model ?? model;
|
|
8106
|
+
const modelMapping = authorizedModel && nativeRequestModel ? {
|
|
8107
|
+
nativeModel: {
|
|
8108
|
+
provider: modelProvider ?? params.provider,
|
|
8109
|
+
model: nativeRequestModel
|
|
8110
|
+
},
|
|
8111
|
+
authorizedModel
|
|
8112
|
+
} : void 0;
|
|
8040
8113
|
if (inferenceRoute) {
|
|
8041
|
-
prompt.setParentLocalEgress();
|
|
8114
|
+
if (!usesSupervisionConnection) prompt.setParentLocalEgress();
|
|
8042
8115
|
resourceState.releaseInferenceContext?.();
|
|
8043
8116
|
const inferenceThread = resourceState.thread;
|
|
8044
8117
|
const registration = inferenceRoute.context.register({
|
|
8045
8118
|
threadId: resourceState.thread.threadId,
|
|
8046
|
-
text: buildCodexParentLocalInstructions(runtimeParams, {
|
|
8119
|
+
text: usesSupervisionConnection ? "" : buildCodexParentLocalInstructions(runtimeParams, {
|
|
8047
8120
|
turnScopedDeveloperInstructions: workspaceBootstrapContext.turnScopedDeveloperInstructions,
|
|
8048
|
-
|
|
8121
|
+
skillsInstructions: context.skillsInstructions,
|
|
8049
8122
|
memoryCollaborationInstructions: workspaceBootstrapContext.memoryCollaborationInstructions
|
|
8050
8123
|
}) ?? "",
|
|
8051
8124
|
signal: runAbortController.signal,
|
|
@@ -8122,6 +8195,7 @@ async function prepareCodexAttemptTurnRequest(resources, turnRuntime, ensureCurr
|
|
|
8122
8195
|
acceptedTurnId = startedTurn.turn.id;
|
|
8123
8196
|
resources.nativeProcessAuthority?.bindTurn(turnClient, threadId, acceptedTurnId);
|
|
8124
8197
|
assertTurnCurrent();
|
|
8198
|
+
resourceState.nativeSubagentMonitor?.bindTurn(acceptedTurnId, modelMapping);
|
|
8125
8199
|
if (upstreamUserText.includes(workspaceBootstrapContext.promptContext ?? "")) references.accepted();
|
|
8126
8200
|
throwIfTurnStartAcceptedAfterAbort();
|
|
8127
8201
|
await continuation?.accept(acceptedTurnId);
|
|
@@ -8160,20 +8234,24 @@ async function prepareCodexAttemptTurnRequest(resources, turnRuntime, ensureCurr
|
|
|
8160
8234
|
}
|
|
8161
8235
|
prepareWorkspaceReferences();
|
|
8162
8236
|
const buildLlmInputEvent = () => ({
|
|
8163
|
-
|
|
8164
|
-
sessionId: params.sessionId,
|
|
8165
|
-
provider: usesSupervisionConnection ? resourceState.thread.modelProvider ?? effectiveRuntimeProviderId : params.provider,
|
|
8166
|
-
model: usesSupervisionConnection ? resourceState.thread.model ?? effectiveRuntimeModelId : params.modelId,
|
|
8237
|
+
...buildModelCallIdentity(),
|
|
8167
8238
|
systemPrompt: buildRenderedCodexDeveloperInstructions(),
|
|
8168
8239
|
prompt: turnState.codexTurnPromptText,
|
|
8169
|
-
historyMessages:
|
|
8240
|
+
historyMessages: [],
|
|
8170
8241
|
imagesCount: prompt.contextImageGroups.reduce((count, group) => count + group.images.length, 0) + (params.images?.length ?? 0),
|
|
8171
8242
|
tools
|
|
8172
8243
|
});
|
|
8244
|
+
const buildLlmOutputEvent = () => ({
|
|
8245
|
+
...buildModelCallIdentity(),
|
|
8246
|
+
...hookContextWindowFields,
|
|
8247
|
+
resolvedRef: usesSupervisionConnection ? `${resourceState.thread.modelProvider ?? effectiveRuntimeProviderId}/${resourceState.thread.model ?? effectiveRuntimeModelId}` : params.runtimePlan?.observability.resolvedRef ?? `${params.provider}/${params.modelId}`,
|
|
8248
|
+
...!usesSupervisionConnection && params.runtimePlan?.observability.harnessId ? { harnessId: params.runtimePlan.observability.harnessId } : {}
|
|
8249
|
+
});
|
|
8173
8250
|
return {
|
|
8174
8251
|
codexModelCallDiagnostics,
|
|
8175
8252
|
startCodexTurn,
|
|
8176
|
-
buildLlmInputEvent
|
|
8253
|
+
buildLlmInputEvent,
|
|
8254
|
+
buildLlmOutputEvent
|
|
8177
8255
|
};
|
|
8178
8256
|
}
|
|
8179
8257
|
//#endregion
|
|
@@ -8181,12 +8259,12 @@ async function prepareCodexAttemptTurnRequest(resources, turnRuntime, ensureCurr
|
|
|
8181
8259
|
async function startCodexAttemptTurn(resources, turnRuntime, notifications, requestRuntime) {
|
|
8182
8260
|
const { prompt, state: resourceState, trajectoryRecorder, markTrajectoryEndRecorded } = resources;
|
|
8183
8261
|
const { context, turnState, systemPromptReport } = prompt;
|
|
8184
|
-
const { runtime, historyState, hookContext,
|
|
8185
|
-
const { connection, runtimeParams
|
|
8186
|
-
const { params,
|
|
8262
|
+
const { runtime, historyState, hookContext, hookRunner } = context;
|
|
8263
|
+
const { connection, runtimeParams } = runtime;
|
|
8264
|
+
const { params, runAbortController, activeContextEngine, bindingStore, bindingIdentity, appServer, attemptStartedAt, startupAuthProfileId } = connection;
|
|
8187
8265
|
const { state, turnIdRef } = turnRuntime;
|
|
8188
8266
|
const { waitForActiveNativeTurnCompletion } = notifications;
|
|
8189
|
-
const { codexModelCallDiagnostics, startCodexTurn, buildLlmInputEvent } = requestRuntime;
|
|
8267
|
+
const { codexModelCallDiagnostics, startCodexTurn, buildLlmInputEvent, buildLlmOutputEvent } = requestRuntime;
|
|
8190
8268
|
let started;
|
|
8191
8269
|
resourceState.turnStartAttempted = true;
|
|
8192
8270
|
try {
|
|
@@ -8229,27 +8307,12 @@ async function startCodexAttemptTurn(resources, turnRuntime, notifications, requ
|
|
|
8229
8307
|
if (!await bindingStore.mutate(bindingIdentity, {
|
|
8230
8308
|
kind: "clear",
|
|
8231
8309
|
threadId: resourceState.thread.threadId
|
|
8232
|
-
})) embeddedAgentLog.warn("codex app-server preserved newer context-engine binding after resume overflow; skipping fresh retry", {
|
|
8310
|
+
}, connection.assertCurrent)) embeddedAgentLog.warn("codex app-server preserved newer context-engine binding after resume overflow; skipping fresh retry", {
|
|
8233
8311
|
threadId: resourceState.thread.threadId,
|
|
8234
8312
|
error: formatErrorMessage(turnStartError)
|
|
8235
8313
|
});
|
|
8236
8314
|
else {
|
|
8237
8315
|
resourceState.thread = await resourceState.restartContextEngineCodexThread();
|
|
8238
|
-
const retryBinding = bindingStore.read(bindingIdentity);
|
|
8239
|
-
if (retryBinding && retryBinding.threadId === resourceState.thread.threadId && retryBinding.contextEngine?.projection) {
|
|
8240
|
-
await bindingStore.mutate(bindingIdentity, {
|
|
8241
|
-
kind: "patch",
|
|
8242
|
-
threadId: retryBinding.threadId,
|
|
8243
|
-
patch: { contextEngine: {
|
|
8244
|
-
...retryBinding.contextEngine,
|
|
8245
|
-
projection: void 0
|
|
8246
|
-
} }
|
|
8247
|
-
});
|
|
8248
|
-
embeddedAgentLog.info("codex app-server cleared stale context-engine projection after overflow retry", {
|
|
8249
|
-
threadId: resourceState.thread.threadId,
|
|
8250
|
-
previousEpoch: retryBinding.contextEngine.projection.epoch
|
|
8251
|
-
});
|
|
8252
|
-
}
|
|
8253
8316
|
emitCodexAppServerEvent(params, {
|
|
8254
8317
|
stream: "codex_app_server.lifecycle",
|
|
8255
8318
|
data: {
|
|
@@ -8298,13 +8361,7 @@ async function startCodexAttemptTurn(resources, turnRuntime, notifications, requ
|
|
|
8298
8361
|
markTrajectoryEndRecorded();
|
|
8299
8362
|
runAgentHarnessLlmOutputHook({
|
|
8300
8363
|
event: {
|
|
8301
|
-
|
|
8302
|
-
sessionId: params.sessionId,
|
|
8303
|
-
provider: usesSupervisionConnection ? resourceState.thread.modelProvider ?? effectiveRuntimeProviderId : params.provider,
|
|
8304
|
-
model: usesSupervisionConnection ? resourceState.thread.model ?? effectiveRuntimeModelId : params.modelId,
|
|
8305
|
-
...hookContextWindowFields,
|
|
8306
|
-
resolvedRef: usesSupervisionConnection ? `${resourceState.thread.modelProvider ?? effectiveRuntimeProviderId}/${resourceState.thread.model ?? effectiveRuntimeModelId}` : params.runtimePlan?.observability.resolvedRef ?? `${params.provider}/${params.modelId}`,
|
|
8307
|
-
...!usesSupervisionConnection && params.runtimePlan?.observability.harnessId ? { harnessId: params.runtimePlan.observability.harnessId } : {},
|
|
8364
|
+
...buildLlmOutputEvent(),
|
|
8308
8365
|
assistantTexts: []
|
|
8309
8366
|
},
|
|
8310
8367
|
ctx: hookContext,
|
|
@@ -8373,63 +8430,9 @@ async function startCodexAttemptTurn(resources, turnRuntime, notifications, requ
|
|
|
8373
8430
|
configCwd: connection.effectiveCwd
|
|
8374
8431
|
};
|
|
8375
8432
|
turnIdRef.current = started.turn.turn.id;
|
|
8376
|
-
resourceState.nativeSubagentMonitor?.bindTurn(started.turn.turn.id);
|
|
8377
8433
|
return started;
|
|
8378
8434
|
}
|
|
8379
8435
|
//#endregion
|
|
8380
|
-
//#region extensions/codex/src/app-server/attempt-deadlines.ts
|
|
8381
|
-
function createCodexAttemptDeadlineController(params) {
|
|
8382
|
-
let deadline = { kind: "closed" };
|
|
8383
|
-
let timer;
|
|
8384
|
-
const armDeadline = (next) => {
|
|
8385
|
-
clearTimeout(timer);
|
|
8386
|
-
deadline = next;
|
|
8387
|
-
const deadlineAtMs = next.startedAtMs + next.timeoutMs;
|
|
8388
|
-
params.onDeadlineChanged?.({
|
|
8389
|
-
kind: "bounded",
|
|
8390
|
-
deadlineAtMs
|
|
8391
|
-
});
|
|
8392
|
-
timer = setTimeout(() => {
|
|
8393
|
-
if (deadline !== next || params.signal.aborted) return;
|
|
8394
|
-
deadline = { kind: "closed" };
|
|
8395
|
-
params.onTimeout({
|
|
8396
|
-
kind: next.kind,
|
|
8397
|
-
elapsedMs: Math.max(0, Date.now() - next.startedAtMs),
|
|
8398
|
-
timeoutMs: next.timeoutMs
|
|
8399
|
-
});
|
|
8400
|
-
}, resolveTimerTimeoutMs(Math.max(1, deadlineAtMs - Date.now()), 1));
|
|
8401
|
-
timer.unref?.();
|
|
8402
|
-
};
|
|
8403
|
-
const dispose = () => {
|
|
8404
|
-
deadline = { kind: "closed" };
|
|
8405
|
-
clearTimeout(timer);
|
|
8406
|
-
params.signal.removeEventListener("abort", dispose);
|
|
8407
|
-
};
|
|
8408
|
-
if (!params.signal.aborted) {
|
|
8409
|
-
params.signal.addEventListener("abort", dispose, { once: true });
|
|
8410
|
-
if (params.timeoutMs >= MAX_TIMER_TIMEOUT_MS) {
|
|
8411
|
-
deadline = { kind: "unlimited" };
|
|
8412
|
-
params.onDeadlineChanged?.({ kind: "unlimited" });
|
|
8413
|
-
} else armDeadline({
|
|
8414
|
-
kind: "execution",
|
|
8415
|
-
startedAtMs: params.startedAtMs,
|
|
8416
|
-
timeoutMs: params.timeoutMs
|
|
8417
|
-
});
|
|
8418
|
-
}
|
|
8419
|
-
return {
|
|
8420
|
-
ownsExecutionWait: () => deadline.kind === "unlimited" || deadline.kind === "execution" && Date.now() < deadline.startedAtMs + deadline.timeoutMs,
|
|
8421
|
-
beginSettlement: (startedAtMs) => {
|
|
8422
|
-
if (deadline.kind === "closed" || deadline.kind === "settlement") return;
|
|
8423
|
-
armDeadline({
|
|
8424
|
-
kind: "settlement",
|
|
8425
|
-
startedAtMs,
|
|
8426
|
-
timeoutMs: TURN_TERMINAL_SETTLEMENT_TIMEOUT_MS
|
|
8427
|
-
});
|
|
8428
|
-
},
|
|
8429
|
-
dispose
|
|
8430
|
-
};
|
|
8431
|
-
}
|
|
8432
|
-
//#endregion
|
|
8433
8436
|
//#region extensions/codex/src/app-server/run-attempt-turn-state.ts
|
|
8434
8437
|
const CODEX_NATIVE_HOOK_RELAY_RENEW_INTERVAL_MS = 6e4;
|
|
8435
8438
|
var CodexAttemptState = class {
|
|
@@ -8459,7 +8462,11 @@ function createCodexAttemptTurnState(resources) {
|
|
|
8459
8462
|
const { promise: completion, resolve: resolveCompletion } = createDeferred();
|
|
8460
8463
|
const settlementExpired = createDeferred();
|
|
8461
8464
|
const pendingOpenClawDynamicToolCompletionIds = /* @__PURE__ */ new Set();
|
|
8462
|
-
const openClawDynamicToolExecutions =
|
|
8465
|
+
const openClawDynamicToolExecutions = createAgentHarnessToolExecutionRegistry((call) => [
|
|
8466
|
+
call.threadId,
|
|
8467
|
+
call.turnId,
|
|
8468
|
+
call.callId
|
|
8469
|
+
]);
|
|
8463
8470
|
const activeTurnItemIds = /* @__PURE__ */ new Set();
|
|
8464
8471
|
const turnIdRef = {};
|
|
8465
8472
|
const userInputBridgeRef = {};
|
|
@@ -8521,9 +8528,10 @@ function createCodexAttemptTurnState(resources) {
|
|
|
8521
8528
|
reason: `codex_app_server:${reason}`
|
|
8522
8529
|
});
|
|
8523
8530
|
};
|
|
8524
|
-
const deadlines =
|
|
8531
|
+
const deadlines = createAgentHarnessAttemptDeadlineController({
|
|
8525
8532
|
startedAtMs: connection.attemptStartedAt,
|
|
8526
8533
|
timeoutMs: params.timeoutMs,
|
|
8534
|
+
settlementTimeoutMs: TURN_TERMINAL_SETTLEMENT_TIMEOUT_MS,
|
|
8527
8535
|
signal: runAbortController.signal,
|
|
8528
8536
|
onDeadlineChanged: params.onAttemptDeadlineChanged,
|
|
8529
8537
|
onTimeout: (timeout) => {
|
|
@@ -8572,7 +8580,6 @@ function createCodexAttemptTurnState(resources) {
|
|
|
8572
8580
|
steeringQueueRef,
|
|
8573
8581
|
completeTurn,
|
|
8574
8582
|
interruptTurn,
|
|
8575
|
-
renewNativeHookRelayForTurnProgress,
|
|
8576
8583
|
noteProgress,
|
|
8577
8584
|
deadlines
|
|
8578
8585
|
};
|
|
@@ -8604,7 +8611,10 @@ async function runCodexAppServerAttempt(params, options) {
|
|
|
8604
8611
|
const turnRequest = await preparation.measure("turn-request", () => prepareCodexAttemptTurnRequest(resources, turnRuntime, ensureCurrentThreadRoute, notifications.waitForActiveNativeTurnCompletion));
|
|
8605
8612
|
preparation.ready();
|
|
8606
8613
|
const turnStart = await startCodexAttemptTurn(resources, turnRuntime, notifications, turnRequest);
|
|
8607
|
-
if ("result" in turnStart)
|
|
8614
|
+
if ("result" in turnStart) {
|
|
8615
|
+
connection.assertModelExecutionCurrent();
|
|
8616
|
+
return turnStart.result;
|
|
8617
|
+
}
|
|
8608
8618
|
const activeTurn = activateCodexAttemptTurn(resources, turnRuntime, lifecycle, notifications, turnStart);
|
|
8609
8619
|
activeTurnOwnsCleanup = true;
|
|
8610
8620
|
let finalizedResult;
|
|
@@ -8627,6 +8637,7 @@ async function runCodexAppServerAttempt(params, options) {
|
|
|
8627
8637
|
delete finalizedResult.settledTurnFinalizationContext;
|
|
8628
8638
|
}
|
|
8629
8639
|
if (resources.state.executionDisconnectError && !connection.terminalState.explicitCancellationObserved) throw resources.state.executionDisconnectError;
|
|
8640
|
+
connection.assertModelExecutionCurrent();
|
|
8630
8641
|
return finalizedResult;
|
|
8631
8642
|
} finally {
|
|
8632
8643
|
turnRuntime.deadlines.dispose();
|
|
@@ -8638,7 +8649,8 @@ async function runCodexAppServerAttempt(params, options) {
|
|
|
8638
8649
|
await attemptTools.disposeTools(connection.runAbortController.signal.aborted ? "cancel" : "error");
|
|
8639
8650
|
}
|
|
8640
8651
|
} finally {
|
|
8641
|
-
|
|
8652
|
+
connection.cancellation.dispose();
|
|
8653
|
+
connection.releaseModelExecution();
|
|
8642
8654
|
}
|
|
8643
8655
|
}
|
|
8644
8656
|
//#endregion
|