@openclaw/codex 2026.9.2 → 2026.9.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (120) hide show
  1. package/README.md +2 -0
  2. package/dist/api.js +29 -26
  3. package/dist/apply-CvT8tW5i.js +356 -0
  4. package/dist/{attempt-client-cleanup-Bp1ZOnk2.js → attempt-client-cleanup-DKHzbwt5.js} +38 -214
  5. package/dist/{attempt-context-CSazkWns.js → attempt-context-D44yeDII.js} +9 -7
  6. package/dist/{event-projector-usage-ZqEVbAEY.js → attempt-notifications-C9XufG6l.js} +3 -106
  7. package/dist/{auth-binding-Ds_QVm-X.js → auth-binding-CWlKVccJ.js} +2 -2
  8. package/dist/auth-cache-key-7orQae_j.js +498 -0
  9. package/dist/auth-profile-CwzO4_RG.js +43 -0
  10. package/dist/auth-profile-selection-DFu9e167.js +45 -0
  11. package/dist/binding-connection-D3udKbIE.js +60 -0
  12. package/dist/{bounded-turn-DxGJRYbY.js → bounded-turn-C_Hneydj.js} +28 -125
  13. package/dist/build-state-BCmg9-5p.js +19 -0
  14. package/dist/{capabilities-B1mgvpP8.js → capabilities-8vx68WLH.js} +1 -1
  15. package/dist/cli-metadata.js +1 -1
  16. package/dist/client-B57KWPQx.js +4005 -0
  17. package/dist/command-dispatch-BpduNGVf.js +21 -0
  18. package/dist/{command-formatters-DSbGMXA0.js → command-formatters-lxlkNZgU.js} +4 -3
  19. package/dist/{command-handlers-DOJvGv6-.js → command-handlers-tiL9iWj7.js} +788 -135
  20. package/dist/command-rpc-CR5EOEZX.js +233 -0
  21. package/dist/{compact-Y_xBqrHN.js → compact-B_H3AOd7.js} +19 -14
  22. package/dist/config-oIORaQ5T.js +106 -0
  23. package/dist/{config-CyapYSji.js → config-options-CXMq1T-C.js} +205 -593
  24. package/dist/config-runtime-D0zGNIHu.js +11 -0
  25. package/dist/{config-utils-C57JiJrU.js → config-utils-DujwEnhg.js} +2 -4
  26. package/dist/conversation-binding-DsB4-O7U.js +900 -0
  27. package/dist/{plugin-marketplace-discovery-B7gHXJ3d.js → conversation-control-CtUu1b3m.js} +11 -143
  28. package/dist/doctor-contract-api.js +5 -5
  29. package/dist/{dynamic-tools-BwpvTxaX.js → dynamic-tools-CmN5RAip.js} +133 -76
  30. package/dist/{effective-mcp-catalog-CY9Jn4bA.js → effective-mcp-catalog-Bd73bqA8.js} +3 -3
  31. package/dist/{elicitation-input-DMkeki8d.js → elicitation-input-DPoK8F7w.js} +8 -22
  32. package/dist/ephemeral-turn-D78_VmzO.js +101 -0
  33. package/dist/{event-projector-assistant-message-B9kp6iGC.js → event-projector-assistant-message-BmBM4qBV.js} +12 -25
  34. package/dist/event-projector-items-5VhsECCO.js +200 -0
  35. package/dist/event-projector-usage-BfXmpOec.js +102 -0
  36. package/dist/{harness-Czh2Sdoc.js → harness-C7rRa7bm.js} +48 -24
  37. package/dist/harness.js +1 -1
  38. package/dist/history-rejection-B4nOXNXF.js +13 -0
  39. package/dist/incognito-session-uhrBF6wJ.js +15 -0
  40. package/dist/index.js +406 -2915
  41. package/dist/inference-context-Dr_mzvk4.js +94 -0
  42. package/dist/inference-proxy-HGXKUIre.js +311 -0
  43. package/dist/{isolated-completion-CRh-51AK.js → isolated-completion-DWVb5U2J.js} +7 -4
  44. package/dist/launch-args-RXQwn8zV.js +90 -0
  45. package/dist/{managed-binary-DcpnJF9x.js → managed-binary-D22rNEcR.js} +13 -103
  46. package/dist/managed-thread-store-D1t5jh3G.js +66 -0
  47. package/dist/media-understanding-provider.js +4 -1
  48. package/dist/migration-provider-api.js +2 -0
  49. package/dist/{model-catalog-DT5vo6qo.js → model-catalog-Dq2n8f_p.js} +6 -5
  50. package/dist/{models-CcrgSMQR.js → models-PCKOim-h.js} +3 -3
  51. package/dist/native-execution-policy-umd0tgh4.js +128 -0
  52. package/dist/native-subagent-history-DjtPloaU.js +140 -0
  53. package/dist/native-subagent-history-owner-Pcp7JuVF.js +34 -0
  54. package/dist/{native-subagent-monitor-B3bvQGcg.js → native-subagent-monitor-fQ7eIXEf.js} +115 -460
  55. package/dist/native-subagent-task-ids-BzTdT0Uw.js +387 -0
  56. package/dist/node-cli-sessions-DKaOmVUh.js +527 -0
  57. package/dist/{node-exec-server.runtime-nfbUOtUB.js → node-exec-server.runtime-Cl2vapEi.js} +55 -24
  58. package/dist/plan-7uG-Fp36.js +947 -0
  59. package/dist/plugin-activation-BYQculil.js +138 -0
  60. package/dist/{thread-resume-BLgqkUc1.js → plugin-app-cache-key-d0eKxy7b.js} +4 -52
  61. package/dist/{plugin-approval-roundtrip-aQVdyL5g.js → plugin-approval-roundtrip-Bz3FT8W5.js} +1 -1
  62. package/dist/plugin-inventory-oL4Na1ZG.js +328 -0
  63. package/dist/plugin-marketplace-discovery-P-Vndfqq.js +137 -0
  64. package/dist/{plugin-metadata-cache-BwCLTY_U.js → plugin-metadata-cache-ClPJpRio.js} +17 -9
  65. package/dist/protocol-5bh1G-H7.js +275 -0
  66. package/dist/provider-MQ8PVkuE.js +50 -0
  67. package/dist/{provider-capabilities-BpG9Ltc5.js → provider-capabilities-BvCUL69A.js} +2 -2
  68. package/dist/{rate-limits-Fx_l4eNa.js → rate-limits-CBMmWBr9.js} +1 -1
  69. package/dist/request-B7hEkBGq.js +212 -0
  70. package/dist/rpc-error-ttN_QjEm.js +30 -0
  71. package/dist/{run-attempt-BzthFQSM.js → run-attempt-CvsAAGa0.js} +664 -377
  72. package/dist/{runtime-artifact-Bh_gf6-t.js → runtime-artifact-BJ0rXBZ_.js} +27 -27
  73. package/dist/sandbox-guard-BxgyoM8M.js +166 -0
  74. package/dist/{session-binding-4Ki04sW-.js → session-binding-CI8UuilT.js} +30 -48
  75. package/dist/{session-binding-record-CyaXZvTe.js → session-binding-record-Bcvslnhf.js} +12 -26
  76. package/dist/session-catalog-adoption-tcZi1IfX.js +251 -0
  77. package/dist/session-catalog-archive-CwKg8Xz2.js +56 -0
  78. package/dist/session-catalog-ct-AH01I.js +1477 -0
  79. package/dist/session-catalog-home-id-CwhLdC03.js +18 -0
  80. package/dist/session-catalog-node-adoption-B1tgDW-m.js +182 -0
  81. package/dist/session-catalog-node-continue-Ci-DXyJP.js +238 -0
  82. package/dist/session-catalog-provenance-D-dIfRAH.js +96 -0
  83. package/dist/{session-cli-BjLhpmS1.js → session-cli-DNN_jhGc.js} +3 -2
  84. package/dist/{session-history-DWmMqiqW.js → session-history-Cz-tOOYj.js} +6 -3
  85. package/dist/{session-upstream-marker-DReTpGz6.js → session-history-import-DwyijFI6.js} +5 -50
  86. package/dist/{session-history-read-LHldwvyh.js → session-history-read-cxPUxyVV.js} +21 -7
  87. package/dist/session-history-worker-runtime.js +18 -6
  88. package/dist/session-history.worker-BeK1YOyT.js +378 -0
  89. package/dist/session-history.worker.js +1 -1
  90. package/dist/{session-initialization-BCFVnLL4.js → session-initialization-Ct0_Hzmg.js} +2 -2
  91. package/dist/{session-permission-policy-BaueHmSj.js → session-permission-policy-BBmXA8Eg.js} +4 -7
  92. package/dist/{session-retirement-DNdmYdFc.js → session-retirement-B2YfbAAT.js} +6 -5
  93. package/dist/session-upstream-marker-D15C9NHp.js +46 -0
  94. package/dist/{settled-turn-context-BOM3Y1pl.js → settled-turn-context-Du6gdUDd.js} +9 -9
  95. package/dist/{settled-turn-finalizer-BI-b1sry.js → settled-turn-finalizer-Dn91stmc.js} +8 -7
  96. package/dist/shared-client-CscigXXL.js +3109 -0
  97. package/dist/{side-question-B6DWAw1A.js → side-question-BGMJQf4U.js} +65 -170
  98. package/dist/source-CElXU0Oy.js +518 -0
  99. package/dist/thread-archive-guard-DfpBr-Sz.js +53 -0
  100. package/dist/thread-history-page-D0JIp48V.js +361 -0
  101. package/dist/{thread-lifecycle-DPK30jad.js → thread-lifecycle-DXl1-I6b.js} +187 -639
  102. package/dist/{thread-ownership-CbucAmmp.js → thread-ownership-BsDRTsyp.js} +13 -15
  103. package/dist/thread-policy-BuEQfE0g.js +54 -0
  104. package/dist/thread-resume-DsDOZpFg.js +52 -0
  105. package/dist/timeout-BVw8aaM1.js +33 -0
  106. package/dist/transcript-history-projection-v17wXgdK.js +238 -0
  107. package/dist/{transcript-mirror-_njEB84z.js → transcript-mirror-C5CKgNy6.js} +50 -260
  108. package/dist/{transcript-mirror-attestation-Byl34PC-.js → transcript-mirror-attestation-DibE0krH.js} +17 -4
  109. package/dist/{transport-stdio-CzTngV0j.js → transport-stdio-BGjHoYLr.js} +73 -43
  110. package/dist/{upstream-session-fork-1fwbNKzQ.js → upstream-session-fork-BZerMte_.js} +27 -19
  111. package/dist/{usage-i9fv5-4m.js → usage-tCk-mg_x.js} +4 -3
  112. package/dist/version-omm6IPI3.js +12 -0
  113. package/dist/{web-search-provider.runtime-DKQn67A7.js → web-search-provider.runtime-B7bGbGWq.js} +3 -3
  114. package/openclaw.plugin.json +23 -1
  115. package/package.json +4 -4
  116. package/dist/request-C8H22rPi.js +0 -475
  117. package/dist/session-catalog-B47uwekb.js +0 -3272
  118. package/dist/session-history.worker-zZVcx0ME.js +0 -267
  119. package/dist/shared-client-CKhX2kFt.js +0 -7505
  120. package/dist/thread-policy-CTalhWFy.js +0 -105
@@ -1,50 +1,65 @@
1
- import { l as sessionBindingIdentity } from "./session-binding-record-CyaXZvTe.js";
2
- import { A as resolveOpenClawExecPolicyForCodexAppServer, B as isJsonObject, D as isCodexSandboxExecServerEnabled, E as isCodexRemoteExecPlacementSandbox, M as resolveCodexAppServerHomeDir, O as readCodexPluginConfig, T as isCodexPairedNodeRemoteExecPlacementSandbox, d as shouldAutoApproveCodexAppServerApprovals, f as withMcpElicitationsApprovalPolicy, h as resolveCodexModelBackedReviewerPolicyContext, k as resolveCodexPluginsPolicy, l as hasCodexMcpToolApprovalOverrides, m as canUseCodexModelBackedApprovalsReviewerForModel, o as resolveCodexComputerUseConfig, r as resolveCodexAppServerHomeScope, y as readCodexRequirementsToml, z as flattenCodexDynamicToolFunctions } from "./config-CyapYSji.js";
3
- import { A as TURN_FINALIZE_DRAIN_ABORT_GRACE_MS, B as isCodexAppServerIndeterminateRequestCancellationError, Bt as resolveCodexAppServerAuthAccountCacheKey, F as withCodexStartupTimeout, Gt as resolveCodexAppServerPreparedApiKeyCacheKey, H as isCodexAppServerOverloadError, Ht as resolveCodexAppServerAuthProfileIdForAgent, I as getCodexAppServerClientInstanceId, It as readCodexRateLimitsRevision, K as resolveCodexAppServerClientInstanceId, Kt as resolveCodexAppServerPreparedAuthHandoff, L as isCodexAppServerApprovalRequest, Lt as readRecentCodexRateLimits, M as isCodexAppServerStartupError, P as resolveCodexStartupTimeoutMs, Pt as withAbortableTimeout, R as isCodexAppServerBrokenPipeError, Rt as rememberCodexRateLimitsRead, Tt as ensureCodexAppServerClientRuntime, V as isCodexAppServerIndeterminateTransportError, Vt as resolveCodexAppServerAuthProfileId, W as isCodexAppServerRequestTimeoutError, Wt as resolveCodexAppServerFallbackApiKeyCacheKey, _t as toCodexDynamicToolProgressResponse, a as clearSharedCodexAppServerClientIfCurrentAndUnclaimed, c as getLeasedSharedCodexAppServerClient, ct as createCodexElicitationResponse, dt as isDynamicToolTerminalDiagnosticEvent, f as readCodexAppServerClientDesktopGenerationFingerprint, ft as isMatchingDynamicToolTerminalDiagnostic, gt as shouldReleaseTurnAfterTerminalDynamicTool, h as releaseLeasedSharedCodexAppServerClient, ht as shouldBlockTerminalReleaseForNonTerminalDynamicToolResult, i as clearSharedCodexAppServerClientIfCurrent, it as readCodexDynamicToolCallParams, j as TURN_TERMINAL_SETTLEMENT_TIMEOUT_MS, k as CodexAppServerStartupError, kt as protectCodexAppServerLiveThread, l as getSharedCodexAppServerClient, lt as handleDynamicToolCallWithTimeout, mt as resolveTerminalDynamicToolBatchAction, ot as readCodexTurn, pt as resolveDynamicToolCallTimeoutMs, q as CodexAppServerRpcError, rt as assertCodexTurnStartResponse, s as createIsolatedCodexAppServerClient, st as readCodexTurnCompletedNotification, u as isCodexAppServerStartSelectionChangedError, ut as hasPendingDynamicToolTerminalDiagnostic, v as retainSharedCodexAppServerClientIfCurrent, vt as toCodexDynamicToolProtocolResponse, y as retireSharedCodexAppServerClientIfCurrent, yt as resolveCodexToolAbortTerminalReason, z as isCodexAppServerConnectionClosedError } from "./shared-client-CKhX2kFt.js";
4
- import { c as resolveCodexRunSessionBindingAuthority, l as resolveCodexSessionBinding, n as assertCodexBindingMayBeReplaced, r as createCodexSessionGenerationSupersededError, u as scopeCodexRunBindingStore } from "./session-binding-4Ki04sW-.js";
5
- import { E as itemStatus, F as readCodexProviderRefusal, H as readNullableString, L as readItem, M as extractRawAssistantText, O as matchesCodexSnapshotTurn, P as readCodexErrorNotificationMessage, R as readItemString, U as splitPlanText, V as readNonNegativeInteger, a as closeCodexStartupClientBestEffort, d as unsubscribeCodexThreadBestEffort, f as CODEX_APP_SERVER_NATIVE_TURN_WAIT_TIMEOUT_MS, g as readCodexNotificationThreadId, h as isCodexNotificationForTurn, j as shouldSynthesizeToolProgressForItem, k as shouldClearTerminalPresentationForNativeItem, l as retireUnsafeCodexTurnClientBestEffort, m as CodexProjectionDiagnostics, o as interruptCodexTurnAndWaitBestEffort, p as getCodexAppServerTurnRouter, r as CodexAppServerUnsafeSubscriptionError, u as terminateCodexBackgroundTerminals } from "./attempt-client-cleanup-Bp1ZOnk2.js";
6
- import { a as isCodexTurnAbortMarkerNotification, d as readNotificationItemId, f as readRawResponseToolCallId, l as isTerminalTurnStatus, o as isPendingOpenClawDynamicToolCompletionNotification, p as updateActiveTurnItemIds, r as codexExecutionToolName, s as isRawFunctionToolOutputCompletionNotification, t as CodexUsageProjection, u as readCodexNotificationItem } from "./event-projector-usage-ZqEVbAEY.js";
7
- import { c as defaultCodexAppInventoryCache, i as buildCodexPluginAppCacheKey, r as buildCodexAppServerRuntimeFingerprint } from "./thread-resume-BLgqkUc1.js";
8
- import { A as readCodexMcpToolConnectorId, B as emitCodexNativePreToolUseFailureDiagnostic, C as buildDeveloperInstructions, Ct as buildCodexPluginThreadConfigInputFingerprint, D as resolveCodexAppServerThreadModelSelection, Et as mergeCodexThreadConfigs, H as resolveCodexNativeHookRelayTtlMs, I as buildCodexNativeHookRelayConfig, L as buildCodexNativeHookRelayDisabledConfig, M as isCodexAppServerProfilerEnabled, Ot as shouldBuildCodexPluginThreadConfig, P as CODEX_NATIVE_HOOK_RELAY_TTL_GRACE_MS, Pt as resolveRecoverableCodexPluginConfigKeys, S as resolveCodexWebSearchPlan, St as buildCodexPluginThreadConfig, U as scheduleCodexNativeHookRelayUnregister, V as resolveCodexNativeHookRelayEvents, X as loadCodexNativeToolCatalog, Y as hasCodexNativeToolCatalog, _t as neutralizeCodexExplicitMentionSigils, at as filterCodexDynamicTools, bt as resolveCodexContextEngineProjectionReserveTokens, c as assertScheduledCodexAppAuthorityRuntime, d as buildScheduledCodexAppServerConnectionIdentity, f as captureScheduledCodexAppAuthority, ft as resolveCodexDynamicToolsLoadingForRuntime, gt as fitCodexProjectedContextForTurnStart, h as resolveScheduledCodexAppCreatorCaptureDecision, ht as buildCodexContinuityCalibration, i as buildCodexUserInput, j as readCodexMcpToolUiVisibility, l as buildLegacyScheduledCodexAppRecoveryPrompt, lt as isSystemAgentOnlyCodexDynamicToolAllowlist, m as readCurrentCodexScheduledAppPolicy$1, n as buildTurnCollaborationMode, nt as codexLegacyDynamicToolsFingerprint, p as intersectCodexPluginThreadConfigWithScheduledAuthority, pt as buildContextEngineBinding, r as buildTurnStartParams, s as startOrResumeThread, tt as codexDynamicToolsFingerprint, u as buildScheduledCodexAppAuthorityInputFingerprint, vt as projectContextEngineAssemblyForCodex, wt as buildCodexPluginThreadConfigTimeoutFallback, xt as resolveCodexContinuityProjectionMaxChars, yt as resolveCodexContextEngineProjectionMaxChars, z as createCodexNativeHookRelay } from "./thread-lifecycle-DPK30jad.js";
9
- import { l as isIncognitoSessionKey, r as retainCodexAppServerBindingSubscription } from "./thread-ownership-CbucAmmp.js";
10
- import { a as assertCodexSessionRuntimeOwnership, n as CodexThreadPolicyHandoffError, s as resolveCodexBindingAppServerConnection } from "./thread-policy-CTalhWFy.js";
11
- import { a as buildCodexUserPromptMessage, i as mirrorPromptAtTurnStartBestEffort, n as createCodexAppServerUserMessagePersistenceNotifier, o as promptSnapshot, t as codexTranscriptMirrorRuntime } from "./transcript-mirror-_njEB84z.js";
1
+ import { s as resolveRecoverableCodexPluginConfigKeys } from "./plugin-inventory-oL4Na1ZG.js";
2
+ import { l as sessionBindingIdentity, n as assertCodexBindingMayBeReplaced } from "./session-binding-record-Bcvslnhf.js";
3
+ import { n as defineCodexBuildState } from "./build-state-BCmg9-5p.js";
4
+ import { b as readCodexRequirementsToml, c as hasCodexMcpToolApprovalOverrides, d as withMcpElicitationsApprovalPolicy, i as resolveCodexAppServerHomeScope, m as resolveCodexModelBackedReviewerPolicyContext, o as resolveCodexComputerUseConfig, u as shouldAutoApproveCodexAppServerApprovals } from "./config-options-CXMq1T-C.js";
5
+ import { S as resolveCodexPluginsPolicy, a as flattenCodexDynamicToolFunctions, b as isCodexSandboxExecServerEnabled, o as isJsonObject, s as resolveCodexAppServerHomeDir, v as isCodexPairedNodeRemoteExecPlacementSandbox, x as readCodexPluginConfig, y as isCodexRemoteExecPlacementSandbox } from "./protocol-5bh1G-H7.js";
6
+ import { A as isMatchingDynamicToolTerminalDiagnostic, D as handleDynamicToolCallWithTimeout, E as createCodexElicitationResponse, F as toCodexDynamicToolProgressResponse, I as toCodexDynamicToolProtocolResponse, L as resolveCodexToolAbortTerminalReason, M as resolveTerminalDynamicToolBatchAction, N as shouldBlockTerminalReleaseForNonTerminalDynamicToolResult, O as hasPendingDynamicToolTerminalDiagnostic, P as shouldReleaseTurnAfterTerminalDynamicTool, S as readCodexDynamicToolCallParams, T as readCodexTurnCompletedNotification, a as isCodexAppServerBrokenPipeError, c as isCodexAppServerIndeterminateTransportError, d as isCodexAppServerRequestTimeoutError, i as isCodexAppServerApprovalRequest, j as resolveDynamicToolCallTimeoutMs, k as isDynamicToolTerminalDiagnosticEvent, l as isCodexAppServerOverloadError, o as isCodexAppServerConnectionClosedError, p as resolveCodexAppServerClientInstanceId, r as getCodexAppServerClientInstanceId, s as isCodexAppServerIndeterminateRequestCancellationError, w as readCodexTurn, x as assertCodexTurnStartResponse } from "./client-B57KWPQx.js";
7
+ import { c as resolveCodexAppServerPreparedApiKeyCacheKey, m as retireSharedCodexAppServerClientIfCurrent, s as resolveCodexAppServerFallbackApiKeyCacheKey } from "./auth-cache-key-7orQae_j.js";
8
+ import { t as isIncognitoSessionKey } from "./incognito-session-uhrBF6wJ.js";
9
+ import { a as shouldRefreshCodexRateLimitsForUsageLimitMessage, i as resolveCodexUsageLimitResetAtMs, n as formatCodexUsageLimitErrorMessage } from "./rate-limits-CBMmWBr9.js";
10
+ import { o as formatCodexDisplayText } from "./command-formatters-lxlkNZgU.js";
11
+ import { t as CodexAppServerRpcError } from "./rpc-error-ttN_QjEm.js";
12
+ import { t as CODEX_CONTROL_METHODS } from "./capabilities-8vx68WLH.js";
13
+ import { D as splitPlanText, E as readNullableString, S as readItemString, T as readNonNegativeInteger, d as matchesCodexSnapshotTurn, f as shouldClearTerminalPresentationForNativeItem, g as extractRawAssistantText, v as readCodexErrorNotificationMessage, x as readItem, y as readCodexProviderRefusal } from "./event-projector-items-5VhsECCO.js";
12
14
  import { r as readMirrorIdentity, t as attachCodexMirrorIdentity } from "./upstream-prompt-provenance-LphB8slG.js";
13
- import { a as hasCodexMirrorOrigin, t as applyCodexTranscriptTaint } from "./transcript-mirror-attestation-Byl34PC-.js";
14
- import { t as CODEX_CONTROL_METHODS } from "./capabilities-B1mgvpP8.js";
15
- import { a as shouldRefreshCodexRateLimitsForUsageLimitMessage, i as resolveCodexUsageLimitResetAtMs, n as formatCodexUsageLimitErrorMessage } from "./rate-limits-Fx_l4eNa.js";
16
- import { a as formatCodexDisplayText } from "./command-formatters-DSbGMXA0.js";
17
- import { a as resolveCodexAppServerForModelProvider, i as resolveCodexSessionPermissionCwd, n as applyCodexSessionPermissionPolicy, r as resolveCodexEffectiveSessionPermissionPolicy } from "./session-permission-policy-BaueHmSj.js";
18
- import { n as prepareCodexAppServerAuthBinding } from "./auth-binding-Ds_QVm-X.js";
15
+ import { n as buildCodexAppServerRuntimeFingerprint, r as buildCodexPluginAppCacheKey, s as defaultCodexAppInventoryCache } from "./plugin-app-cache-key-d0eKxy7b.js";
16
+ import { t as withAbortableTimeout } from "./timeout-BVw8aaM1.js";
17
+ import { n as resolveOpenClawExecPolicyForCodexAppServer, t as canUseCodexModelBackedApprovalsReviewerForModel } from "./config-oIORaQ5T.js";
18
+ import { o as hasCodexMirrorOrigin, t as applyCodexTranscriptTaint } from "./transcript-mirror-attestation-DibE0krH.js";
19
+ import { r as prepareCodexAppServerAuthBinding } from "./auth-binding-CWlKVccJ.js";
20
+ import { i as resolveCodexBindingAppServerConnection, t as assertCodexSessionRuntimeOwnership } from "./binding-connection-D3udKbIE.js";
21
+ import { i as resolveCodexAppServerAuthProfileIdForAgent, r as resolveCodexAppServerAuthProfileId } from "./auth-profile-CwzO4_RG.js";
22
+ import { A as CodexAppServerStartupError, F as resolveCodexStartupTimeoutMs, G as protectCodexAppServerLiveThread, I as withCodexStartupTimeout, M as TURN_TERMINAL_SETTLEMENT_TIMEOUT_MS, N as isCodexAppServerStartupError, O as getCodexInferenceThread, Q as rememberCodexRateLimitsRead, W as prepareCodexWorkspaceReferences, X as readCodexRateLimitsRevision, Z as readRecentCodexRateLimits, a as clearSharedCodexAppServerClientIfCurrentAndUnclaimed, c as getLeasedSharedCodexAppServerClient, et as resolveCodexAppServerAuthAccountCacheKey, f as readCodexAppServerClientDesktopGenerationFingerprint, h as releaseLeasedSharedCodexAppServerClient, i as clearSharedCodexAppServerClientIfCurrent, j as TURN_FINALIZE_DRAIN_ABORT_GRACE_MS, l as getSharedCodexAppServerClient, s as createIsolatedCodexAppServerClient, tt as resolveCodexAppServerPreparedAuthHandoff, u as isCodexAppServerStartSelectionChangedError, v as retainSharedCodexAppServerClientIfCurrent, z as ensureCodexAppServerClientRuntime } from "./shared-client-CscigXXL.js";
23
+ import { a as closeCodexStartupClientBestEffort, d as unsubscribeCodexThreadBestEffort, f as CODEX_APP_SERVER_NATIVE_TURN_WAIT_TIMEOUT_MS, g as readCodexNotificationThreadId, h as isCodexNotificationForTurn, l as retireUnsafeCodexTurnClientBestEffort, m as CodexProjectionDiagnostics, o as interruptCodexTurnAndWaitBestEffort, p as getCodexAppServerTurnRouter, r as CodexAppServerUnsafeSubscriptionError, u as terminateCodexBackgroundTerminals } from "./attempt-client-cleanup-DKHzbwt5.js";
24
+ import { a as isRawFunctionToolOutputCompletionNotification, c as readNotificationItemId, i as isPendingOpenClawDynamicToolCompletionNotification, l as readRawResponseToolCallId, o as isTerminalTurnStatus, r as isCodexTurnAbortMarkerNotification, s as readCodexNotificationItem, t as codexExecutionToolName, u as updateActiveTurnItemIds } from "./attempt-notifications-C9XufG6l.js";
25
+ import { t as CodexUsageProjection } from "./event-projector-usage-BfXmpOec.js";
26
+ import { $ as codexDynamicToolsFingerprint, A as readCodexMcpToolConnectorId, B as createCodexNativeHookRelay, C as resolveCodexWebSearchPlan, Ct as buildCodexPluginThreadConfigInputFingerprint, Et as mergeCodexThreadConfigs, F as CODEX_NATIVE_HOOK_RELAY_TTL_GRACE_MS, H as resolveCodexNativeHookRelayEvents, J as loadCodexNativeToolCatalog, L as buildCodexNativeHookRelayConfig, N as isCodexAppServerProfilerEnabled, O as resolveCodexAppServerThreadModelSelection, Ot as shouldBuildCodexPluginThreadConfig, R as buildCodexNativeHookRelayDisabledConfig, St as buildCodexPluginThreadConfig, U as resolveCodexNativeHookRelayTtlMs, V as emitCodexNativePreToolUseFailureDiagnostic, W as scheduleCodexNativeHookRelayUnregister, _t as neutralizeCodexExplicitMentionSigils, a as buildCodexUserInput, bt as resolveCodexContextEngineProjectionReserveTokens, c as startOrResumeThread, d as buildScheduledCodexAppAuthorityInputFingerprint, dt as buildContextEngineBinding, et as codexLegacyDynamicToolsFingerprint, f as buildScheduledCodexAppServerConnectionIdentity, g as resolveScheduledCodexAppCreatorCaptureDecision, gt as isCodexDurableCustomMessage, h as readCurrentCodexScheduledAppPolicy$1, ht as fitCodexProjectedContextForTurnStart, i as buildTurnStartParams, j as readCodexMcpToolUiVisibility, l as assertScheduledCodexAppAuthorityRuntime, m as intersectCodexPluginThreadConfigWithScheduledAuthority, mt as buildCodexContinuityCalibration, p as captureScheduledCodexAppAuthority, pt as CodexContextAttachmentError, q as hasCodexNativeToolCatalog, r as buildTurnCollaborationMode, rt as filterCodexDynamicTools, st as isSystemAgentOnlyCodexDynamicToolAllowlist, t as buildCodexParentLocalInstructions, u as buildLegacyScheduledCodexAppRecoveryPrompt, ut as resolveCodexDynamicToolsLoadingForRuntime, vt as projectContextEngineAssemblyForCodex, w as buildDeveloperInstructions, wt as buildCodexPluginThreadConfigTimeoutFallback, xt as resolveCodexContinuityProjectionMaxChars, yt as resolveCodexContextEngineProjectionMaxChars } from "./thread-lifecycle-DXl1-I6b.js";
27
+ import { a as resolveCodexRunSessionBindingAuthority, n as createCodexSessionGenerationSupersededError, o as resolveCodexSessionBinding, s as scopeCodexRunBindingStore } from "./session-binding-CI8UuilT.js";
28
+ import { n as CodexThreadPolicyHandoffError } from "./thread-policy-BuEQfE0g.js";
29
+ import { r as retainCodexAppServerBindingSubscription } from "./thread-ownership-BsDRTsyp.js";
30
+ import { i as mirrorPromptAtTurnStartBestEffort, n as createCodexAppServerUserMessagePersistenceNotifier, o as buildCodexUserPromptMessage, s as promptSnapshot, t as codexTranscriptMirrorRuntime } from "./transcript-mirror-C5CKgNy6.js";
19
31
  import { t as persistCodexContextCompactionActivity } from "./context-compaction-activity-CMla5FPJ.js";
20
- import { i as createAssistantReasoningMessage, n as createAssistantCommentaryMessage, r as createAssistantMessage, t as createAssistantAsyncMessage } from "./event-projector-assistant-message-B9kp6iGC.js";
21
- import { C as shouldRequireCodexSandboxExecServerEnvironment, S as shouldEnableCodexAppServerNativeToolSurface, _ as resolveCodexAppServerHookChannelId, a as emitDynamicToolStartedDiagnostic, c as ensureCodexSandboxExecServerEnvironment, d as CodexNativeToolLifecycleProjector, f as buildDynamicTools, g as resolveCodexAppServerExecutionCwd, h as formatCodexDynamicToolBuildStageSummary, i as emitDynamicToolErrorDiagnostic, l as releaseCodexSandboxExecServerEnvironment, m as disableCodexPluginThreadConfig, n as projectCodexExecutableDynamicTools, o as emitDynamicToolTerminalDiagnostic, p as createCodexDynamicToolBuildStageTracker, r as routeCodexAppServerElicitationRequest, s as handleCodexAppServerApprovalRequest, t as createCodexDynamicToolBridge, u as readBoundedCodexRemoteWorkspaceFile, v as resolveCodexExternalSandboxPolicyForOpenClawSandbox, w as shouldWarnCodexDynamicToolBuildStageSummary, x as resolveCodexSandboxEnvironmentSelection, y as resolveCodexMessageToolProvider } from "./dynamic-tools-BwpvTxaX.js";
22
- import { t as resolveCodexProviderWebSearchSupport } from "./provider-capabilities-BpG9Ltc5.js";
23
- import { a as CodexToolProgressProjection, c as isCodexCommandBearingToolCall, d as sanitizeCodexToolResponse, i as CodexToolTranscriptProjection, l as resolveCodexToolProgressDetailMode, n as CodexEventProjection, o as shouldEmitTranscriptToolProgress, r as emitCodexAgentEvent, s as inferCodexDynamicToolMeta, t as codexNativeSubagentMonitorRuntime, u as sanitizeCodexToolArguments } from "./native-subagent-monitor-B3bvQGcg.js";
24
- import { a as requestPluginApprovalOutcome } from "./plugin-approval-roundtrip-aQVdyL5g.js";
25
- import { a as getCodexWorkspaceMemoryToolNames, c as readContextEngineThreadBootstrapProjection, d as resolveCodexDeliveryHintPreservedInputRange, f as resolveContextEngineBootstrapProjectionDecision, i as buildCodexWorkspaceBootstrapContext, l as readMirroredSessionHistoryMessages, n as buildCodexSystemPromptReport, r as buildCodexWatchedSessionsContext, s as prependCodexOpenClawPromptContext, t as buildCodexOpenClawPromptContext, u as renderCodexSkillsCollaborationInstructions } from "./attempt-context-CSazkWns.js";
26
- import { n as captureCodexSettledTurnFinalizationContext } from "./settled-turn-context-BOM3Y1pl.js";
27
- import { a as runCodexComputerUseLiveTest, n as ensureCodexComputerUse, t as defaultCodexPluginMetadataCache } from "./plugin-metadata-cache-BwCLTY_U.js";
32
+ import { t as CODEX_INFERENCE_GENERATION_KEY } from "./inference-context-Dr_mzvk4.js";
33
+ import { i as createAssistantReasoningMessage, n as createAssistantCommentaryMessage, r as createAssistantMessage, t as createAssistantAsyncMessage } from "./event-projector-assistant-message-BmBM4qBV.js";
34
+ import { _ as sanitizeCodexToolResponse, g as sanitizeCodexToolArguments, h as resolveCodexToolProgressDetailMode, m as isCodexCommandBearingToolCall, p as inferCodexDynamicToolMeta } from "./native-subagent-task-ids-BzTdT0Uw.js";
35
+ import { n as createCodexNativeSubagentHistoryOwner } from "./native-subagent-history-owner-Pcp7JuVF.js";
36
+ import { C as shouldRequireCodexSandboxExecServerEnvironment, S as shouldEnableCodexAppServerNativeToolSurface, _ as resolveCodexAppServerHookChannelId, a as emitDynamicToolStartedDiagnostic, c as ensureCodexSandboxExecServerEnvironment, d as CodexNativeToolLifecycleProjector, f as buildDynamicTools, g as resolveCodexAppServerExecutionCwd, h as formatCodexDynamicToolBuildStageSummary, i as emitDynamicToolErrorDiagnostic, l as releaseCodexSandboxExecServerEnvironment, m as disableCodexPluginThreadConfig, n as projectCodexExecutableDynamicTools, o as emitDynamicToolTerminalDiagnostic, p as createCodexDynamicToolBuildStageTracker, r as routeCodexAppServerElicitationRequest, s as handleCodexAppServerApprovalRequest, t as createCodexDynamicToolBridge, u as readBoundedCodexRemoteWorkspaceFile, v as resolveCodexExternalSandboxPolicyForOpenClawSandbox, w as shouldWarnCodexDynamicToolBuildStageSummary, x as resolveCodexSandboxEnvironmentSelection, y as resolveCodexMessageToolProvider } from "./dynamic-tools-CmN5RAip.js";
37
+ import { t as resolveCodexProviderWebSearchSupport } from "./provider-capabilities-BvCUL69A.js";
38
+ import { a as requestPluginApprovalOutcome } from "./plugin-approval-roundtrip-Bz3FT8W5.js";
39
+ import { a as CodexToolProgressProjection, i as CodexToolTranscriptProjection, n as CodexEventProjection, o as shouldEmitTranscriptToolProgress, r as emitCodexAgentEvent, t as codexNativeSubagentMonitorRuntime } from "./native-subagent-monitor-fQ7eIXEf.js";
40
+ import { a as resolveCodexAppServerForModelProvider, i as resolveCodexSessionPermissionCwd, n as applyCodexSessionPermissionPolicy, r as resolveCodexEffectiveSessionPermissionPolicy } from "./session-permission-policy-BBmXA8Eg.js";
41
+ import { a as getCodexWorkspaceMemoryToolNames, c as readContextEngineThreadBootstrapProjection, d as resolveCodexDeliveryHintPreservedInputRange, f as resolveContextEngineBootstrapProjectionDecision, i as buildCodexWorkspaceBootstrapContext, l as readMirroredSessionHistoryMessages, n as buildCodexSystemPromptReport, r as buildCodexWatchedSessionsContext, s as prependCodexOpenClawPromptContext, t as buildCodexOpenClawPromptContext, u as renderCodexSkillsCollaborationInstructions } from "./attempt-context-D44yeDII.js";
42
+ import { n as captureCodexSettledTurnFinalizationContext } from "./settled-turn-context-Du6gdUDd.js";
43
+ import { a as runCodexComputerUseLiveTest, n as ensureCodexComputerUse, t as defaultCodexPluginMetadataCache } from "./plugin-metadata-cache-ClPJpRio.js";
28
44
  import { asOptionalRecord, normalizeOptionalString, readStringField } from "openclaw/plugin-sdk/string-coerce-runtime";
29
45
  import { createHash } from "node:crypto";
30
46
  import { resolveAgentConfig, resolveSessionAgentIdsStrict } from "openclaw/plugin-sdk/agent-scope-runtime";
31
- import { parseSqliteSessionFileMarker } from "openclaw/plugin-sdk/session-store-runtime";
32
47
  import { MAX_TIMER_TIMEOUT_MS, asDateTimestampMs, resolveTimerTimeoutMs } from "openclaw/plugin-sdk/number-runtime";
33
- import fs from "node:fs/promises";
34
48
  import path from "node:path";
49
+ import fs from "node:fs/promises";
50
+ import { addAbortListener } from "node:events";
51
+ import { truncateUtf16Safe, truncateUtf8Prefix } from "openclaw/plugin-sdk/text-utility-runtime";
52
+ import { Buffer as Buffer$1 } from "node:buffer";
35
53
  import { createDeferred } from "openclaw/plugin-sdk/extension-shared";
36
- import { AgentHarnessPreflightError, CODEX_APP_SERVER_CONTEXT_ENGINE_HOST, FAST_MODE_AUTO_PROGRESS_KIND, agentHarnessAttemptTerminal, agentHarnessStructuredInput, assembleHarnessContextEngine, assertContextEngineHostSupport, awaitAgentEndSideEffects, bootstrapHarnessContextEngine, buildAgentHookContextChannelFields, buildEmbeddedForegroundPromptContext, buildHarnessContextEngineRuntimeContext, cancelPendingAgentQuestionForSession, claimPendingAgentQuestionAnswer, classifyAgentHarnessTerminalOutcome, clearActiveEmbeddedRun, detectAndLoadAgentHarnessPromptImages, embeddedAgentLog, emitAgentEvent, emptyAgentHarnessUserInputAnswers, formatErrorMessage, formatFastModeAutoProgressText, getAgentHarnessHookRunner, hasBeforeToolCallPolicy, isActiveHarnessContextEngine, isHostScopedAgentToolActive, loadCodexBundleMcpThreadConfig, materializeRequesterScopedMcpToolsForHarnessRun, prepareHarnessNativeMcpAppPreview, projectAgentHarnessTranscriptMessageForDisplay, resolveAgentDir as resolveAgentDir$1, resolveAgentHarnessBeforePromptBuildResult, resolveAgentRunAbortLifecycleFields, resolveAttemptFsWorkspaceOnly, resolveContextEngineOwnerPluginId, resolveFastModeForElapsed, resolveSandboxContext, resolveUserPath, runAgentCleanupStep, runAgentEndSideEffects, runAgentHarnessAfterCompactionHook, runAgentHarnessBeforeCompactionHook, runAgentHarnessLlmInputHook, runAgentHarnessLlmOutputHook, runHarnessContextEngineMaintenance, setActiveEmbeddedRun, supportsModelTools } from "openclaw/plugin-sdk/agent-harness-runtime";
37
54
  import { isPathStrictlyInside, root } from "openclaw/plugin-sdk/file-access-runtime";
38
- import { isDeepStrictEqual } from "node:util";
39
- import { markAuthProfileBlockedUntil, resolveAgentDir as resolveAgentDir$2 } from "openclaw/plugin-sdk/agent-runtime";
55
+ import { markAuthProfileBlockedUntil, resolveAgentDir as resolveAgentDir$1 } from "openclaw/plugin-sdk/agent-runtime";
56
+ import { AgentHarnessPreflightError, CODEX_APP_SERVER_CONTEXT_ENGINE_HOST, FAST_MODE_AUTO_PROGRESS_KIND, agentHarnessAttemptTerminal, agentHarnessStructuredInput, assembleHarnessContextEngine, assertContextEngineHostSupport, awaitAgentEndSideEffects, bootstrapHarnessContextEngine, buildAgentHookContextChannelFields, buildEmbeddedForegroundPromptContext, buildHarnessContextEngineRuntimeContext, cancelPendingAgentQuestionForSession, claimPendingAgentQuestionAnswer, classifyAgentHarnessTerminalOutcome, clearActiveEmbeddedRun, detectAndLoadAgentHarnessPromptImages, embeddedAgentLog, emitAgentEvent, emptyAgentHarnessUserInputAnswers, formatErrorMessage, formatFastModeAutoProgressText, getAgentHarnessHookRunner, hasBeforeToolCallPolicy, isActiveHarnessContextEngine, isHostScopedAgentToolActive, loadCodexBundleMcpThreadConfig, materializeRequesterScopedMcpToolsForHarnessRun, prepareHarnessNativeMcpAppPreview, projectAgentHarnessTranscriptMessageForDisplay, projectProgressCardChannelUpdate, resolveAgentDir as resolveAgentDir$2, resolveAgentHarnessBeforePromptBuildResult, resolveAgentRunAbortLifecycleFields, resolveAttemptFsWorkspaceOnly, resolveContextEngineOwnerPluginId, resolveFastModeForElapsed, resolveSandboxContext, resolveUserPath, runAgentCleanupStep, runAgentEndSideEffects, runAgentHarnessAfterCompactionHook, runAgentHarnessBeforeCompactionHook, runAgentHarnessLlmInputHook, runAgentHarnessLlmOutputHook, runHarnessContextEngineMaintenance, setActiveEmbeddedRun, supportsModelTools } from "openclaw/plugin-sdk/agent-harness-runtime";
40
57
  import { loadExecApprovals } from "openclaw/plugin-sdk/exec-approvals-runtime";
41
- import { addAbortListener } from "node:events";
42
- import { truncateUtf16Safe, truncateUtf8Prefix } from "openclaw/plugin-sdk/text-utility-runtime";
58
+ import { isDeepStrictEqual } from "node:util";
59
+ import { getSessionEntry, parseSqliteSessionFileMarker } from "openclaw/plugin-sdk/session-store-runtime";
43
60
  import { createDiagnosticTraceContextFromActiveScope, emitTrustedDiagnosticEvent, emitTrustedDiagnosticEventWithPrivateData, freezeDiagnosticTraceContext, onInternalDiagnosticEvent, resolveDiagnosticModelContentCapturePolicy } from "openclaw/plugin-sdk/diagnostic-runtime";
44
61
  import { captureFinalCodexCronCreatorToolAllowlist, formatMcpCodexApprovalRemedy, materializeStaticMcpToolsForHarnessRun, resolveCodexMcpToolOverridesForAgent, resolveCodexTtsProvenanceTransfer } from "openclaw/plugin-sdk/codex-mcp-projection";
45
- import { hasPromptImageInput } from "openclaw/plugin-sdk/session-transcript-runtime";
46
- import { Buffer as Buffer$1 } from "node:buffer";
47
- import { sleepWithAbort } from "openclaw/plugin-sdk/runtime-env";
62
+ import { appendSessionYieldContext, hasPromptImageInput } from "openclaw/plugin-sdk/session-transcript-runtime";
48
63
  import { getAgentScopedMediaLocalRoots } from "openclaw/plugin-sdk/media-local-roots";
49
64
  import { isSilentReplyPayloadText } from "openclaw/plugin-sdk/reply-chunking";
50
65
  import { generatedImageAssetFromBase64 } from "openclaw/plugin-sdk/image-generation";
@@ -52,6 +67,7 @@ import { resolveGeneratedMediaMaxBytes } from "openclaw/plugin-sdk/media-generat
52
67
  import { saveMediaBuffer } from "openclaw/plugin-sdk/media-store";
53
68
  import { stripInvisibleUnicode } from "openclaw/plugin-sdk/web-content-extractor";
54
69
  import { acknowledgeInternalToolResult } from "openclaw/plugin-sdk/agent-harness-tool-runtime";
70
+ import { sleepWithAbort } from "openclaw/plugin-sdk/runtime-env";
55
71
  //#region extensions/codex/src/app-server/attempt-preparation-timing.ts
56
72
  /** Records startup before the native turn owns inference and tool execution. */
57
73
  function createCodexAttemptPreparationTiming(params) {
@@ -203,6 +219,12 @@ function createCodexSteeringQueue(params) {
203
219
  }
204
220
  liveItems = liveItems.filter(isCurrent);
205
221
  if (liveItems.length === 0) return;
222
+ if (params.beforeSubmit) {
223
+ await params.beforeSubmit(liveItems);
224
+ assertActive();
225
+ liveItems = liveItems.filter(isCurrent);
226
+ if (liveItems.length === 0) return;
227
+ }
206
228
  clientUserMessageId = `openclaw:${params.turnId}:steer:${++batchSequence}`;
207
229
  dispatchedBatches.set(clientUserMessageId, { items: liveItems });
208
230
  const request = {
@@ -303,21 +325,8 @@ function createCodexSteeringQueue(params) {
303
325
  const batch = dispatchedBatches.get(clientUserMessageId);
304
326
  if (!batch) return false;
305
327
  dispatchedBatches.delete(clientUserMessageId);
306
- for (const item of batch.items) reportItemAcceptance(item, true);
307
- const resolveBatch = () => {
308
- for (const item of batch.items) resolveItem(item);
309
- return true;
310
- };
311
- const rejectBatch = (error) => {
312
- for (const item of batch.items) rejectItem(item, error);
313
- return true;
314
- };
315
- if (!params.beforeConfirmConsumed) return resolveBatch();
316
- try {
317
- return params.beforeConfirmConsumed(batch.items).then(resolveBatch, rejectBatch);
318
- } catch (error) {
319
- return rejectBatch(error);
320
- }
328
+ for (const item of batch.items) resolveItem(item);
329
+ return true;
321
330
  },
322
331
  sealAdmission: sealQueueAdmission,
323
332
  cancel: cancelQueue
@@ -328,6 +337,9 @@ function normalizeCodexSteerDebounceMs(value) {
328
337
  return typeof value === "number" && Number.isFinite(value) && value >= 0 ? Math.floor(value) : CODEX_STEER_ALL_DEBOUNCE_MS;
329
338
  }
330
339
  //#endregion
340
+ //#region extensions/codex/src/app-server/attempt-terminal.ts
341
+ const attemptTerminal = agentHarnessAttemptTerminal;
342
+ //#endregion
331
343
  //#region extensions/codex/src/app-server/event-projector-assistant.ts
332
344
  var CodexAssistantProjection = class {
333
345
  constructor(params, emitAgentEvent, matchesToolProgressEcho, nextTranscriptTimestamp, checkpointCommentary) {
@@ -1078,8 +1090,61 @@ function reasoningMethodOrder(method) {
1078
1090
  return method === "item/reasoning/summaryTextDelta" ? 0 : 1;
1079
1091
  }
1080
1092
  //#endregion
1081
- //#region extensions/codex/src/app-server/attempt-terminal.ts
1082
- const attemptTerminal = agentHarnessAttemptTerminal;
1093
+ //#region extensions/codex/src/app-server/event-projector-settlement.ts
1094
+ var CodexProjectionSettlement = class {
1095
+ constructor(params, isActive) {
1096
+ this.turnTainted = false;
1097
+ this.pending = /* @__PURE__ */ new Map();
1098
+ const detach = (stage, callback) => callback ? (...args) => {
1099
+ if (!isActive()) return;
1100
+ const completion = createDeferred();
1101
+ this.pending.set(completion.promise, stage);
1102
+ const settled = () => {
1103
+ this.pending.delete(completion.promise);
1104
+ completion.resolve();
1105
+ };
1106
+ const failed = (error) => {
1107
+ embeddedAgentLog.warn(`codex app-server ${stage} callback failed: ${String(error)}`);
1108
+ settled();
1109
+ };
1110
+ try {
1111
+ Promise.resolve(callback(...args)).then(settled, failed);
1112
+ } catch (error) {
1113
+ failed(error);
1114
+ }
1115
+ } : void 0;
1116
+ this.params = {
1117
+ ...params,
1118
+ onAssistantMessageStart: detach("onAssistantMessageStart", params.onAssistantMessageStart),
1119
+ onPartialReply: detach("onPartialReply", params.onPartialReply),
1120
+ onReasoningStream: detach("onReasoningStream", params.onReasoningStream),
1121
+ onReasoningEnd: detach("onReasoningEnd", params.onReasoningEnd)
1122
+ };
1123
+ }
1124
+ get pendingStage() {
1125
+ return this.stage ?? this.pending.values().next().value;
1126
+ }
1127
+ get completedAnswer() {
1128
+ const turn = this.terminalReceipt;
1129
+ const answer = turn?.items?.findLast((item) => item.type === "agentMessage" && item.phase !== "commentary" && item.delivery !== "async" && typeof item.text === "string" && item.text.trim().length > 0);
1130
+ return turn?.status === "completed" && answer ? {
1131
+ turn,
1132
+ answer
1133
+ } : void 0;
1134
+ }
1135
+ async project(stage, project) {
1136
+ const previous = this.stage;
1137
+ this.stage = stage;
1138
+ try {
1139
+ return await project();
1140
+ } finally {
1141
+ this.stage = previous;
1142
+ }
1143
+ }
1144
+ async drain() {
1145
+ while (this.pending.size > 0) await Promise.all(this.pending.keys());
1146
+ }
1147
+ };
1083
1148
  //#endregion
1084
1149
  //#region extensions/codex/src/app-server/event-projector-snapshot.ts
1085
1150
  function buildCodexMessagesSnapshot(params) {
@@ -1094,7 +1159,10 @@ function buildCodexMessagesSnapshot(params) {
1094
1159
  ...params.toolMessages
1095
1160
  ].toSorted((left, right) => (asDateTimestampMs(left.timestamp) ?? 0) - (asDateTimestampMs(right.timestamp) ?? 0));
1096
1161
  messages.push(...visibleWorkMessages);
1097
- if (params.lastAssistant) messages.push(attachCodexMirrorIdentity(params.lastAssistant, `${params.turnId}:assistant`));
1162
+ if (params.lastAssistant) {
1163
+ const assistant = applyCodexTranscriptTaint(params.lastAssistant, { tainted: params.turnTainted === true });
1164
+ messages.push(attachCodexMirrorIdentity(assistant, `${params.turnId}:assistant`));
1165
+ }
1098
1166
  const taint = { tainted: false };
1099
1167
  return messages.map((message) => projectAgentHarnessTranscriptMessageForDisplay({
1100
1168
  hidden: params.runParams.trigger === "memory",
@@ -1125,116 +1193,6 @@ function buildCodexSteeringMessagesSnapshot(params) {
1125
1193
  };
1126
1194
  }
1127
1195
  //#endregion
1128
- //#region extensions/codex/src/app-server/event-projector-result.ts
1129
- function buildCodexAttemptResult(input) {
1130
- input.nativeToolLifecycleProjection.finalizeActive();
1131
- const assistantTexts = input.assistantProjection.collectAssistantTexts();
1132
- const asyncMessages = input.assistantProjection.collectAsyncMessages();
1133
- const commentaryMessages = input.assistantProjection.collectCommentaryMessages();
1134
- const reasoningText = input.reasoningProjection.reasoningText();
1135
- const planText = input.reasoningProjection.planText();
1136
- const usage = input.usageProjection.usage;
1137
- const projectedUsage = input.aborted && usage ? {
1138
- ...usage,
1139
- contextUsage: { state: "unavailable" }
1140
- } : usage;
1141
- const hasAssistantItemText = input.assistantProjection.hasAssistantItemTextForSynthesis();
1142
- const legacyFailClosed = !input.completedTurn || input.completedTurn.status !== "completed" || hasAssistantItemText;
1143
- const hasDeliverableAssistantOnCompletedTurn = input.completedTurn?.status === "completed" && assistantTexts.some((text) => text.trim().length > 0);
1144
- const synthesizedMissingToolResultError = input.toolTranscriptProjection.synthesizeMissingToolResults({
1145
- synthesize: legacyFailClosed,
1146
- terminalDisposition: input.aborted ? "tool_error" : hasDeliverableAssistantOnCompletedTurn ? "diagnostic_only" : "prompt_error"
1147
- });
1148
- const storedMissingToolResultError = synthesizedMissingToolResultError ?? input.synthesizedMissingToolResultError;
1149
- let promptErrorSource = input.promptErrorSource;
1150
- if (synthesizedMissingToolResultError) {
1151
- input.recordSynthesizedMissingToolResultError(synthesizedMissingToolResultError);
1152
- promptErrorSource = promptErrorSource ?? "prompt";
1153
- }
1154
- const assistantMessageOptions = {
1155
- tokenUsage: projectedUsage,
1156
- aborted: input.aborted,
1157
- promptError: input.promptError,
1158
- providerRefusal: input.providerRefusal
1159
- };
1160
- const lastAssistant = input.providerRefusal ? input.assistantProjection.createAssistantMessage("", assistantMessageOptions) : assistantTexts.length ? input.assistantProjection.createAssistantMessage(assistantTexts.join("\n\n"), assistantMessageOptions) : void 0;
1161
- const currentAttemptAssistant = input.providerRefusal ? lastAssistant : input.assistantProjection.createCurrentAttemptAssistantMessage(assistantMessageOptions);
1162
- const messagesSnapshot = buildCodexMessagesSnapshot({
1163
- runParams: input.runParams,
1164
- turnId: input.turnId,
1165
- upstreamUserText: input.upstreamUserText,
1166
- reasoningText,
1167
- asyncMessages,
1168
- commentaryMessages,
1169
- toolMessages: input.toolTranscriptProjection.transcriptMessages,
1170
- lastAssistant
1171
- });
1172
- const turnFailed = input.completedTurn?.status === "failed";
1173
- const promptError = input.providerRefusal ? null : input.promptError ?? storedMissingToolResultError ?? (turnFailed ? input.completedTurn?.error?.message ?? "codex app-server turn failed" : null);
1174
- const agentHarnessResultClassification = input.providerRefusal ? void 0 : classifyAgentHarnessTerminalOutcome({
1175
- assistantTexts,
1176
- reasoningText,
1177
- planText,
1178
- promptError,
1179
- turnCompleted: Boolean(input.completedTurn)
1180
- });
1181
- const toolMetas = input.toolProgressProjection.toolMetas;
1182
- const hadPotentialSideEffects = input.toolTelemetry.didSendViaMessagingTool || Boolean(input.toolTelemetry.successfulCronAdds || input.toolTelemetry.acceptedSessionSpawns?.length) || input.generatedMediaProjection.hasGeneratedMedia() || input.toolProgressProjection.hasPotentialSideEffects;
1183
- const sentMediaUrls = new Set(input.toolTelemetry.messagingToolSentMediaUrls.map((url) => url.trim()));
1184
- const toolAutoDeliveryMediaUrls = input.toolTelemetry.toolAutoDeliveryMediaUrls?.filter((url) => !sentMediaUrls.has(url.trim()));
1185
- const result = {
1186
- terminal: attemptTerminal.normalize({
1187
- aborted: input.aborted,
1188
- promptError,
1189
- promptErrorSource: promptError ? promptErrorSource || "prompt" : null
1190
- }),
1191
- sessionIdUsed: input.runParams.sessionId,
1192
- terminalTurnId: input.turnId,
1193
- ...agentHarnessResultClassification ? { agentHarnessResultClassification } : {},
1194
- bootstrapPromptWarningSignaturesSeen: input.runParams.bootstrapPromptWarningSignaturesSeen,
1195
- bootstrapPromptWarningSignature: input.runParams.bootstrapPromptWarningSignature,
1196
- ...input.usageProjection.modelIterations > 0 ? { modelIterations: input.usageProjection.modelIterations } : {},
1197
- messagesSnapshot,
1198
- assistantTexts,
1199
- toolMetas,
1200
- lastAssistant,
1201
- currentAttemptAssistant,
1202
- ...input.toolProgressProjection.lastToolError ? { lastToolError: input.toolProgressProjection.lastToolError } : {},
1203
- didSendViaMessagingTool: input.toolTelemetry.didSendViaMessagingTool,
1204
- didDeliverSourceReplyViaMessageTool: input.toolTelemetry.didDeliverSourceReplyViaMessageTool === true,
1205
- sourceReplyDelivered: input.toolTelemetry.sourceReplyDelivered,
1206
- messagingToolSentTexts: input.toolTelemetry.messagingToolSentTexts,
1207
- messagingToolSentMediaUrls: input.toolTelemetry.messagingToolSentMediaUrls,
1208
- messagingToolSentTargets: input.toolTelemetry.messagingToolSentTargets,
1209
- messagingToolSourceReplyPayloads: input.toolTelemetry.messagingToolSourceReplyPayloads ?? [],
1210
- heartbeatToolResponse: input.toolTelemetry.heartbeatToolResponse,
1211
- toolMediaUrls: input.generatedMediaProjection.buildToolMediaUrls(input.toolTelemetry),
1212
- hostOwnedToolMediaUrls: input.generatedMediaProjection.buildHostOwnedMediaUrls(input.toolTelemetry),
1213
- toolAudioAsVoice: input.toolTelemetry.toolAudioAsVoice,
1214
- successfulCronAdds: input.toolTelemetry.successfulCronAdds,
1215
- acceptedSessionSpawns: input.toolTelemetry.acceptedSessionSpawns,
1216
- cloudCodeAssistFormatError: false,
1217
- contextTokens: input.contextTokens,
1218
- contextTokensSource: input.contextTokensSource,
1219
- attemptUsage: projectedUsage,
1220
- ...input.completedCompactionCount > 0 ? { compactionCount: input.completedCompactionCount } : {},
1221
- replayMetadata: {
1222
- hadPotentialSideEffects,
1223
- replaySafe: !hadPotentialSideEffects
1224
- },
1225
- itemLifecycle: {
1226
- startedCount: input.activeItemCount + input.completedItemCount,
1227
- completedCount: input.completedItemCount,
1228
- activeCount: input.activeItemCount
1229
- },
1230
- yieldDetected: input.yieldDetected || false,
1231
- didSendDeterministicApprovalPrompt: input.guardianReviewCount > 0 ? false : void 0
1232
- };
1233
- const transferTtsProvenance = resolveCodexTtsProvenanceTransfer(input.runParams.hostCapabilities);
1234
- for (const toolResult of input.toolTelemetry.coreTtsToolResults ?? []) transferTtsProvenance?.(toolResult, result, toolAutoDeliveryMediaUrls ?? []);
1235
- return result;
1236
- }
1237
- //#endregion
1238
1196
  //#region extensions/codex/src/app-server/usage-limit-error.ts
1239
1197
  /**
1240
1198
  * Enriches Codex usage-limit failures with current rate-limit information and
@@ -1251,7 +1209,7 @@ function resolveCodexPromptError(source) {
1251
1209
  const usageLimitMessage = formatCodexUsageLimitErrorMessage(source);
1252
1210
  if (usageLimitMessage) return new CodexUsageLimitPromptError(usageLimitMessage);
1253
1211
  const info = source.codexErrorInfo;
1254
- let status = info === "serverOverloaded" ? 503 : info === "internalServerError" ? 500 : void 0;
1212
+ let status = info === "rateLimitExceeded" ? 429 : info === "serverOverloaded" ? 503 : info === "internalServerError" ? 500 : void 0;
1255
1213
  if (isJsonObject(info)) for (const variant of [
1256
1214
  "httpConnectionFailed",
1257
1215
  "responseStreamConnectionFailed",
@@ -1423,6 +1381,7 @@ var CodexTranscriptCheckpoint = class {
1423
1381
  this.writing = Promise.resolve();
1424
1382
  this.tainted = false;
1425
1383
  this.closed = false;
1384
+ this.abandoned = false;
1426
1385
  this.nextTimestamp = () => {
1427
1386
  this.lastTimestamp = Math.max(Date.now(), this.lastTimestamp + 1);
1428
1387
  return this.lastTimestamp;
@@ -1442,6 +1401,10 @@ var CodexTranscriptCheckpoint = class {
1442
1401
  if (this.params.sessionTarget && !this.closed) this.pending.push(entry);
1443
1402
  };
1444
1403
  }
1404
+ abandon() {
1405
+ this.closed = this.abandoned = true;
1406
+ this.pending.length = 0;
1407
+ }
1445
1408
  flush(close = false) {
1446
1409
  if (this.closed) return this.writing;
1447
1410
  this.closed = close;
@@ -1459,6 +1422,9 @@ var CodexTranscriptCheckpoint = class {
1459
1422
  });
1460
1423
  try {
1461
1424
  await codexTranscriptMirrorRuntime.mirror({
1425
+ assertWriteCurrent: () => {
1426
+ if (this.abandoned) throw new Error("Codex transcript checkpoint was retired before write");
1427
+ },
1462
1428
  ...this.params.sessionTarget,
1463
1429
  sessionId: this.params.sessionId,
1464
1430
  cwd: this.params.workspaceDir,
@@ -1482,8 +1448,9 @@ var CodexTranscriptCheckpoint = class {
1482
1448
  }
1483
1449
  };
1484
1450
  //#endregion
1485
- //#region extensions/codex/src/app-server/event-projector.ts
1486
- var CodexAppServerEventProjector = class {
1451
+ //#region extensions/codex/src/app-server/event-projector-result.ts
1452
+ /** Owns per-turn projection state and builds results from the same state. */
1453
+ var CodexTurnProjection = class {
1487
1454
  constructor(params, threadId, turnId, options = {}) {
1488
1455
  this.params = params;
1489
1456
  this.threadId = threadId;
@@ -1492,13 +1459,14 @@ var CodexAppServerEventProjector = class {
1492
1459
  this.activeItemIds = /* @__PURE__ */ new Set();
1493
1460
  this.completedItemIds = /* @__PURE__ */ new Set();
1494
1461
  this.activeCompactionItemIds = /* @__PURE__ */ new Set();
1495
- this.projectionClosed = false;
1462
+ this.projectionController = new AbortController();
1496
1463
  this.settledTurnFailureFinalizationAllowed = false;
1497
1464
  this.terminalFailure = new CodexTerminalFailureProjection();
1498
1465
  this.synthesizedMissingToolResultError = null;
1499
1466
  this.aborted = false;
1500
1467
  this.usageProjection = new CodexUsageProjection();
1501
1468
  this.completedCompactionCount = 0;
1469
+ this.settlement = new CodexProjectionSettlement(params, () => !this.projectionClosed);
1502
1470
  this.transcriptCheckpoint = new CodexTranscriptCheckpoint(params, threadId, turnId);
1503
1471
  this.asyncDeliveryProjection = new CodexAsyncDeliveryProjection(params, threadId, turnId, options);
1504
1472
  this.contextTokens = options.initialContextTokens;
@@ -1509,7 +1477,7 @@ var CodexAppServerEventProjector = class {
1509
1477
  remoteWorkspaceRoot: options.remoteWorkspaceRoot,
1510
1478
  readFile: options.readRemoteWorkspaceFile,
1511
1479
  requestTimeoutMs: options.remoteWorkspaceRequestTimeoutMs,
1512
- signal: options.runAbortSignal
1480
+ signal: options.runAbortSignal ? AbortSignal.any([options.runAbortSignal, this.projectionController.signal]) : this.projectionController.signal
1513
1481
  });
1514
1482
  this.toolProgressProjection = new CodexToolProgressProjection(params);
1515
1483
  this.toolTranscriptProjection = new CodexToolTranscriptProjection(params, threadId, turnId, this.toolProgressProjection, this.transcriptCheckpoint.nextTimestamp, {
@@ -1519,12 +1487,151 @@ var CodexAppServerEventProjector = class {
1519
1487
  checkpointMessage: this.transcriptCheckpoint.enqueue
1520
1488
  });
1521
1489
  this.eventProjection = new CodexEventProjection(threadId, turnId, (event) => this.emitAgentEvent(event), this.toolProgressProjection, this.toolTranscriptProjection, options.onNativeToolResultRecorded);
1522
- this.assistantProjection = new CodexAssistantProjection(params, (event) => this.emitAgentEvent(event), (text) => this.toolProgressProjection.matchesEcho(text), this.transcriptCheckpoint.nextTimestamp, this.transcriptCheckpoint.enqueueCommentary);
1523
- this.reasoningProjection = new CodexReasoningProjection(params, (event) => this.emitAgentEvent(event), options.onNativePlanUpdate);
1490
+ this.assistantProjection = new CodexAssistantProjection(this.settlement.params, (event) => this.emitAgentEvent(event), (text) => this.toolProgressProjection.matchesEcho(text), this.transcriptCheckpoint.nextTimestamp, this.transcriptCheckpoint.enqueueCommentary);
1491
+ this.reasoningProjection = new CodexReasoningProjection(this.settlement.params, (event) => this.emitAgentEvent(event), options.onNativePlanUpdate);
1492
+ }
1493
+ get projectionClosed() {
1494
+ return this.projectionController.signal.aborted;
1495
+ }
1496
+ buildResult(toolTelemetry, options) {
1497
+ this.eventProjection.flushPendingGuardianWarning();
1498
+ const { params: runParams, turnId, completedTurn, aborted, contextTokens, contextTokensSource, completedCompactionCount, synthesizedMissingToolResultError: previousMissingToolResultError } = this;
1499
+ const { promptError: initialPromptError, promptErrorSource: initialPromptErrorSource, providerRefusal } = this.terminalFailure;
1500
+ const upstreamUserText = this.options.upstreamUserText;
1501
+ const turnTainted = this.settlement.turnTainted;
1502
+ const activeItemCount = this.activeItemIds.size;
1503
+ const completedItemCount = this.completedItemIds.size;
1504
+ const guardianReviewCount = this.eventProjection.guardianReviewCount;
1505
+ const yieldDetected = options?.yieldDetected;
1506
+ this.nativeToolLifecycleProjector.finalizeActive();
1507
+ const assistantTexts = this.assistantProjection.collectAssistantTexts();
1508
+ const asyncMessages = this.assistantProjection.collectAsyncMessages();
1509
+ const commentaryMessages = this.assistantProjection.collectCommentaryMessages();
1510
+ const reasoningText = this.reasoningProjection.reasoningText();
1511
+ const planText = this.reasoningProjection.planText();
1512
+ const usage = this.usageProjection.usage;
1513
+ const projectedUsage = aborted && usage ? {
1514
+ ...usage,
1515
+ contextUsage: { state: "unavailable" }
1516
+ } : usage;
1517
+ const hasAssistantItemText = this.assistantProjection.hasAssistantItemTextForSynthesis();
1518
+ const legacyFailClosed = !completedTurn || completedTurn.status !== "completed" || hasAssistantItemText;
1519
+ const hasDeliverableAssistantOnCompletedTurn = completedTurn?.status === "completed" && assistantTexts.some((text) => text.trim().length > 0);
1520
+ const synthesizedMissingToolResultError = this.toolTranscriptProjection.synthesizeMissingToolResults({
1521
+ synthesize: legacyFailClosed,
1522
+ terminalDisposition: aborted ? "tool_error" : hasDeliverableAssistantOnCompletedTurn ? "diagnostic_only" : "prompt_error"
1523
+ });
1524
+ const storedMissingToolResultError = synthesizedMissingToolResultError ?? previousMissingToolResultError;
1525
+ let promptErrorSource = initialPromptErrorSource;
1526
+ if (synthesizedMissingToolResultError) {
1527
+ this.synthesizedMissingToolResultError = synthesizedMissingToolResultError;
1528
+ promptErrorSource = promptErrorSource ?? "prompt";
1529
+ }
1530
+ const assistantMessageOptions = {
1531
+ tokenUsage: projectedUsage,
1532
+ aborted,
1533
+ promptError: initialPromptError,
1534
+ providerRefusal
1535
+ };
1536
+ const lastAssistant = providerRefusal ? this.assistantProjection.createAssistantMessage("", assistantMessageOptions) : assistantTexts.length ? this.assistantProjection.createAssistantMessage(assistantTexts.join("\n\n"), assistantMessageOptions) : void 0;
1537
+ const currentAttemptAssistant = providerRefusal ? lastAssistant : this.assistantProjection.createCurrentAttemptAssistantMessage(assistantMessageOptions);
1538
+ const messagesSnapshot = buildCodexMessagesSnapshot({
1539
+ runParams,
1540
+ turnId,
1541
+ upstreamUserText,
1542
+ reasoningText,
1543
+ asyncMessages,
1544
+ commentaryMessages,
1545
+ toolMessages: this.toolTranscriptProjection.transcriptMessages,
1546
+ lastAssistant,
1547
+ turnTainted
1548
+ });
1549
+ const turnFailed = completedTurn?.status === "failed";
1550
+ const promptError = providerRefusal ? null : initialPromptError ?? storedMissingToolResultError ?? (turnFailed ? completedTurn?.error?.message ?? "codex app-server turn failed" : null);
1551
+ const agentHarnessResultClassification = providerRefusal ? void 0 : classifyAgentHarnessTerminalOutcome({
1552
+ assistantTexts,
1553
+ reasoningText,
1554
+ planText,
1555
+ promptError,
1556
+ turnCompleted: Boolean(completedTurn)
1557
+ });
1558
+ const toolMetas = this.toolProgressProjection.toolMetas;
1559
+ const hadPotentialSideEffects = toolTelemetry.didSendViaMessagingTool || Boolean(toolTelemetry.successfulCronAdds || toolTelemetry.acceptedSessionSpawns?.length) || this.generatedMediaProjection.hasGeneratedMedia() || this.toolProgressProjection.hasPotentialSideEffects;
1560
+ const sentMediaUrls = new Set(toolTelemetry.messagingToolSentMediaUrls.map((url) => url.trim()));
1561
+ const toolAutoDeliveryMediaUrls = toolTelemetry.toolAutoDeliveryMediaUrls?.filter((url) => !sentMediaUrls.has(url.trim()));
1562
+ const result = {
1563
+ terminal: attemptTerminal.normalize({
1564
+ aborted,
1565
+ promptError,
1566
+ promptErrorSource: promptError ? promptErrorSource || "prompt" : null
1567
+ }),
1568
+ sessionIdUsed: runParams.sessionId,
1569
+ terminalTurnId: turnId,
1570
+ ...agentHarnessResultClassification ? { agentHarnessResultClassification } : {},
1571
+ bootstrapPromptWarningSignaturesSeen: runParams.bootstrapPromptWarningSignaturesSeen,
1572
+ bootstrapPromptWarningSignature: runParams.bootstrapPromptWarningSignature,
1573
+ ...this.usageProjection.modelIterations > 0 ? { modelIterations: this.usageProjection.modelIterations } : {},
1574
+ messagesSnapshot,
1575
+ assistantTexts,
1576
+ toolMetas,
1577
+ lastAssistant,
1578
+ currentAttemptAssistant,
1579
+ ...this.toolProgressProjection.lastToolError ? { lastToolError: this.toolProgressProjection.lastToolError } : {},
1580
+ didSendViaMessagingTool: toolTelemetry.didSendViaMessagingTool,
1581
+ didDeliverSourceReplyViaMessageTool: toolTelemetry.didDeliverSourceReplyViaMessageTool === true,
1582
+ sourceReplyDelivered: toolTelemetry.sourceReplyDelivered,
1583
+ messagingToolSentTexts: toolTelemetry.messagingToolSentTexts,
1584
+ messagingToolSentMediaUrls: toolTelemetry.messagingToolSentMediaUrls,
1585
+ messagingToolSentTargets: toolTelemetry.messagingToolSentTargets,
1586
+ messagingToolSourceReplyPayloads: toolTelemetry.messagingToolSourceReplyPayloads ?? [],
1587
+ heartbeatToolResponse: toolTelemetry.heartbeatToolResponse,
1588
+ toolMediaUrls: this.generatedMediaProjection.buildToolMediaUrls(toolTelemetry),
1589
+ hostOwnedToolMediaUrls: this.generatedMediaProjection.buildHostOwnedMediaUrls(toolTelemetry),
1590
+ toolAudioAsVoice: toolTelemetry.toolAudioAsVoice,
1591
+ successfulCronAdds: toolTelemetry.successfulCronAdds,
1592
+ acceptedSessionSpawns: toolTelemetry.acceptedSessionSpawns,
1593
+ cloudCodeAssistFormatError: false,
1594
+ contextTokens,
1595
+ contextTokensSource,
1596
+ attemptUsage: projectedUsage,
1597
+ ...completedCompactionCount > 0 ? { compactionCount: completedCompactionCount } : {},
1598
+ replayMetadata: {
1599
+ hadPotentialSideEffects,
1600
+ replaySafe: !hadPotentialSideEffects
1601
+ },
1602
+ itemLifecycle: {
1603
+ startedCount: activeItemCount + completedItemCount,
1604
+ completedCount: completedItemCount,
1605
+ activeCount: activeItemCount
1606
+ },
1607
+ yieldDetected: yieldDetected || false,
1608
+ didSendDeterministicApprovalPrompt: guardianReviewCount > 0 ? false : void 0
1609
+ };
1610
+ const transferTtsProvenance = resolveCodexTtsProvenanceTransfer(runParams.hostCapabilities);
1611
+ for (const toolResult of toolTelemetry.coreTtsToolResults ?? []) transferTtsProvenance?.(toolResult, result, toolAutoDeliveryMediaUrls ?? []);
1612
+ return result;
1613
+ }
1614
+ emitAgentEvent(event) {
1615
+ if (!this.projectionClosed) emitCodexAgentEvent(this.params, event);
1524
1616
  }
1617
+ };
1618
+ //#endregion
1619
+ //#region extensions/codex/src/app-server/event-projector.ts
1620
+ var CodexAppServerEventProjector = class extends CodexTurnProjection {
1525
1621
  getCompletedTurnStatus() {
1526
1622
  return this.completedTurn?.status;
1527
1623
  }
1624
+ /** Native completion owns the answer independently of unfinished host projection. */
1625
+ recoverCompletedAnswer() {
1626
+ const completed = this.settlement.completedAnswer;
1627
+ if (!completed || this.aborted || this.terminalFailure.promptError) return false;
1628
+ this.projectionController.abort();
1629
+ this.transcriptCheckpoint.abandon();
1630
+ this.completedTurn = completed.turn;
1631
+ this.assistantProjection.recordSnapshotItem(completed.answer);
1632
+ this.assistantProjection.finalizeAnswerCandidate(completed.turn);
1633
+ return true;
1634
+ }
1528
1635
  getActiveMcpToolCall(serverName) {
1529
1636
  if (this.projectionClosed || this.aborted) return;
1530
1637
  return this.nativeToolLifecycleProjector.getActiveMcpToolCall(serverName);
@@ -1553,8 +1660,8 @@ var CodexAppServerEventProjector = class {
1553
1660
  }
1554
1661
  /** Fence delayed projections before the turn's final snapshot leaves its owner. */
1555
1662
  closeProjection() {
1556
- this.projectionClosed = true;
1557
- return this.transcriptCheckpoint.flush(true);
1663
+ this.projectionController.abort();
1664
+ return this.settlement.project("transcript/checkpoint", () => this.transcriptCheckpoint.flush(true));
1558
1665
  }
1559
1666
  /** Resolves the shared model-order position for a native tool item. */
1560
1667
  recordNativeToolOutcome(item) {
@@ -1596,11 +1703,9 @@ var CodexAppServerEventProjector = class {
1596
1703
  break;
1597
1704
  case "item/started":
1598
1705
  await this.handleItemStarted(params);
1599
- await this.transcriptCheckpoint.flush();
1600
1706
  break;
1601
1707
  case "item/completed":
1602
1708
  await this.handleItemCompleted(params);
1603
- await this.transcriptCheckpoint.flush();
1604
1709
  break;
1605
1710
  case "item/commandExecution/outputDelta":
1606
1711
  this.toolProgressProjection.handleOutputDelta(params, "bash");
@@ -1643,20 +1748,21 @@ var CodexAppServerEventProjector = class {
1643
1748
  break;
1644
1749
  case "rawResponseItem/completed":
1645
1750
  await this.handleRawResponseItemCompleted(params);
1646
- await this.transcriptCheckpoint.flush();
1647
1751
  break;
1648
1752
  case "model/rerouted":
1649
1753
  this.eventProjection.handleModelRerouted(params);
1650
1754
  break;
1651
1755
  case "error": {
1652
1756
  this.usageProjection.invalidateContext();
1653
- if (params.willRetry === true) break;
1757
+ if (params.willRetry === true) {
1758
+ this.eventProjection.handleRetry(params);
1759
+ break;
1760
+ }
1654
1761
  const codexErrorInfo = isJsonObject(params.error) ? params.error.codexErrorInfo : void 0;
1655
- const message = readCodexErrorNotificationMessage(params);
1656
1762
  const compactionFailure = codexErrorInfo === "other" && this.isCompacting();
1657
1763
  this.settledTurnFailureFinalizationAllowed = codexErrorInfo === "serverOverloaded" || compactionFailure;
1658
1764
  this.terminalFailure.record({
1659
- message,
1765
+ message: readCodexErrorNotificationMessage(params),
1660
1766
  codexErrorInfo,
1661
1767
  rateLimits: this.options.readRecentRateLimits?.(),
1662
1768
  fallbackMessage: "codex app-server error",
@@ -1677,47 +1783,23 @@ var CodexAppServerEventProjector = class {
1677
1783
  case "model/safetyBuffering/updated": break;
1678
1784
  default: this.diagnostics.warnUnknownEvent(notification, params);
1679
1785
  }
1680
- }
1681
- buildResult(toolTelemetry, options) {
1682
- this.eventProjection.flushPendingGuardianWarning();
1683
- return buildCodexAttemptResult({
1684
- runParams: this.params,
1685
- turnId: this.turnId,
1686
- upstreamUserText: this.options.upstreamUserText,
1687
- completedTurn: this.completedTurn,
1688
- promptError: this.terminalFailure.promptError,
1689
- promptErrorSource: this.terminalFailure.promptErrorSource,
1690
- providerRefusal: this.terminalFailure.providerRefusal,
1691
- synthesizedMissingToolResultError: this.synthesizedMissingToolResultError,
1692
- recordSynthesizedMissingToolResultError: (error) => {
1693
- this.synthesizedMissingToolResultError = error;
1694
- this.terminalFailure.promptErrorSource ??= "prompt";
1695
- },
1696
- aborted: this.aborted,
1697
- contextTokens: this.contextTokens,
1698
- contextTokensSource: this.contextTokensSource,
1699
- completedCompactionCount: this.completedCompactionCount,
1700
- activeItemCount: this.activeItemIds.size,
1701
- completedItemCount: this.completedItemIds.size,
1702
- guardianReviewCount: this.eventProjection.guardianReviewCount,
1703
- toolTelemetry,
1704
- yieldDetected: options?.yieldDetected,
1705
- nativeToolLifecycleProjection: this.nativeToolLifecycleProjector,
1706
- assistantProjection: this.assistantProjection,
1707
- reasoningProjection: this.reasoningProjection,
1708
- usageProjection: this.usageProjection,
1709
- toolTranscriptProjection: this.toolTranscriptProjection,
1710
- toolProgressProjection: this.toolProgressProjection,
1711
- generatedMediaProjection: this.generatedMediaProjection
1712
- });
1786
+ if (!this.projectionClosed && [
1787
+ "item/started",
1788
+ "item/completed",
1789
+ "rawResponseItem/completed"
1790
+ ].includes(notification.method)) await this.settlement.project("transcript/checkpoint", () => this.transcriptCheckpoint.flush());
1713
1791
  }
1714
1792
  recordDynamicToolCall(params) {
1715
1793
  this.toolTranscriptProjection.recordDynamicToolCall(params);
1716
1794
  }
1717
1795
  /** Projects a successful OpenClaw progress_card call through the native plan stream. */
1718
1796
  async recordDynamicProgressCardUpdate(params) {
1719
- if (isJsonObject(params)) {
1720
- const projected = { plan: Array.isArray(params.plan) ? params.plan : [] };
1797
+ const update = projectProgressCardChannelUpdate(params);
1798
+ if (update) {
1799
+ const projected = {
1800
+ plan: update.steps,
1801
+ ...update.explanation ? { explanation: update.explanation } : {}
1802
+ };
1721
1803
  await this.reasoningProjection.handleTurnPlanUpdated(projected, "openclaw");
1722
1804
  }
1723
1805
  }
@@ -1805,7 +1887,7 @@ var CodexAppServerEventProjector = class {
1805
1887
  if (asyncMessage) await this.asyncDeliveryProjection.deliver(asyncMessage);
1806
1888
  if (this.projectionClosed) return;
1807
1889
  this.reasoningProjection.recordItem(item);
1808
- await this.generatedMediaProjection.recordNative(item);
1890
+ await this.settlement.project("media_projection", () => this.generatedMediaProjection.recordNative(item));
1809
1891
  if (this.projectionClosed) return;
1810
1892
  if (item?.type === "contextCompaction" && itemId) {
1811
1893
  if (!this.isCompactionProjectionActive()) return;
@@ -1897,11 +1979,16 @@ var CodexAppServerEventProjector = class {
1897
1979
  if (asyncMessage) await this.asyncDeliveryProjection.deliver(asyncMessage);
1898
1980
  if (this.projectionClosed) return;
1899
1981
  this.reasoningProjection.recordItem(item);
1900
- await this.generatedMediaProjection.recordNative(item);
1982
+ await this.settlement.project("media_projection", () => this.generatedMediaProjection.recordNative(item));
1901
1983
  if (this.projectionClosed) return;
1902
1984
  this.toolProgressProjection.recordToolMeta(item);
1903
1985
  this.toolProgressProjection.rememberCommandAggregateOutputEcho(item);
1904
- await this.emitSnapshotOnlyNativeToolProgress(item);
1986
+ await this.eventProjection.emitSnapshotOnlyNativeToolProgress({
1987
+ item,
1988
+ activeItemIds: this.activeItemIds,
1989
+ completedItemIds: this.completedItemIds,
1990
+ isActive: () => !this.projectionClosed
1991
+ });
1905
1992
  if (this.projectionClosed) return;
1906
1993
  this.toolTranscriptProjection.recordNativeToolCall(item);
1907
1994
  const details = await this.toolTranscriptProjection.prepareNativeToolResultDetails(item);
@@ -1921,39 +2008,12 @@ var CodexAppServerEventProjector = class {
1921
2008
  this.activeCompactionItemIds.clear();
1922
2009
  await this.reasoningProjection.maybeEndReasoning();
1923
2010
  }
1924
- async emitSnapshotOnlyNativeToolProgress(item) {
1925
- if (!shouldSynthesizeToolProgressForItem(item) || !matchesCodexSnapshotTurn(item, this.turnId) || this.completedItemIds.has(item.id) || itemStatus(item) === "running") return;
1926
- if (!this.activeItemIds.has(item.id)) {
1927
- this.eventProjection.emitStandardItemEvent({
1928
- phase: "start",
1929
- item
1930
- });
1931
- await this.eventProjection.emitNormalizedToolItemEvent({
1932
- phase: "start",
1933
- item
1934
- });
1935
- }
1936
- if (this.projectionClosed) return;
1937
- this.activeItemIds.delete(item.id);
1938
- this.eventProjection.emitStandardItemEvent({
1939
- phase: "end",
1940
- item
1941
- });
1942
- await this.eventProjection.emitNormalizedToolItemEvent({
1943
- phase: "result",
1944
- item
1945
- });
1946
- this.completedItemIds.add(item.id);
1947
- }
1948
2011
  async handleRawResponseItemCompleted(params) {
1949
2012
  const item = isJsonObject(params.item) ? params.item : void 0;
1950
2013
  if (!item) return;
1951
2014
  this.toolTranscriptProjection.recordRawNativeToolItem(item);
1952
2015
  this.assistantProjection.handleRawResponseItemCompleted(item, this.activeItemIds);
1953
- await this.generatedMediaProjection.recordRaw(item);
1954
- }
1955
- emitAgentEvent(event) {
1956
- if (!this.projectionClosed) emitCodexAgentEvent(this.params, event);
2016
+ await this.settlement.project("media_projection", () => this.generatedMediaProjection.recordRaw(item));
1957
2017
  }
1958
2018
  isHookNotificationForCurrentThread(params) {
1959
2019
  const threadId = readStringField(params, "threadId");
@@ -2064,6 +2124,7 @@ function createNativeMcpRuntime(params) {
2064
2124
  listResourceTemplates: async (serverName) => {
2065
2125
  return { resourceTemplates: (await loadStatuses()).find((entry) => entry.name === serverName)?.resourceTemplates ?? [] };
2066
2126
  },
2127
+ joinCleanup: async () => {},
2067
2128
  dispose: async () => {}
2068
2129
  };
2069
2130
  return runtime;
@@ -2301,9 +2362,9 @@ function createCodexUserInputBridge(params) {
2301
2362
  });
2302
2363
  },
2303
2364
  async handleElicitationRequest(request) {
2304
- if (readRawOwnString(request.params, "threadId") !== params.threadId) return;
2365
+ if (readOwnDataString(request.params, "threadId") !== params.threadId) return;
2305
2366
  const requestSnapshot = agentHarnessStructuredInput.snapshot(request.params);
2306
- if (requestSnapshot === void 0) {
2367
+ if (!agentHarnessStructuredInput.isRecord(requestSnapshot)) {
2307
2368
  const cancelValue = createCodexElicitationResponse("cancel");
2308
2369
  return await enqueue({
2309
2370
  requestId: request.id,
@@ -2319,10 +2380,10 @@ function createCodexUserInputBridge(params) {
2319
2380
  }
2320
2381
  });
2321
2382
  }
2322
- const { compileCodexOrdinaryElicitation } = await import("./elicitation-input-DMkeki8d.js");
2383
+ if (readOwnDataString(requestSnapshot, "threadId") !== params.threadId) return;
2384
+ const { compileCodexOrdinaryElicitation } = await import("./elicitation-input-DPoK8F7w.js");
2323
2385
  const compiled = compileCodexOrdinaryElicitation({
2324
- value: requestSnapshot,
2325
- threadId: params.threadId,
2386
+ snapshot: requestSnapshot,
2326
2387
  turnId: params.turnId
2327
2388
  });
2328
2389
  if (compiled.kind === "ignored") return;
@@ -2348,7 +2409,7 @@ function createCodexUserInputBridge(params) {
2348
2409
  handleNotification(notification) {
2349
2410
  if (notification.method !== "serverRequest/resolved" || !isJsonObject(notification.params)) return;
2350
2411
  const requestId = readRequestId(notification.params);
2351
- if (requestId === void 0 || readOwnString(notification.params, "threadId") !== params.threadId) return;
2412
+ if (requestId === void 0 || readOwnDataString(notification.params, "threadId") !== params.threadId) return;
2352
2413
  const job = jobs.find((candidate) => typeof candidate.requestId === typeof requestId && candidate.requestId === requestId);
2353
2414
  if (job) cancelJob(job);
2354
2415
  },
@@ -2427,11 +2488,7 @@ function readArray(record, key, maximum) {
2427
2488
  const value = readValue(record, key);
2428
2489
  return Array.isArray(value) && value.length <= maximum ? value : void 0;
2429
2490
  }
2430
- function readOwnString(record, key) {
2431
- const descriptor = Object.getOwnPropertyDescriptor(record, key);
2432
- return descriptor && "value" in descriptor && typeof descriptor.value === "string" ? descriptor.value : void 0;
2433
- }
2434
- function readRawOwnString(value, key) {
2491
+ function readOwnDataString(value, key) {
2435
2492
  if (!value || typeof value !== "object" || Array.isArray(value)) return;
2436
2493
  const descriptor = Object.getOwnPropertyDescriptor(value, key);
2437
2494
  return descriptor && "value" in descriptor && typeof descriptor.value === "string" ? descriptor.value : void 0;
@@ -2576,6 +2633,7 @@ function activateCodexAttemptTurn(resources, turnRuntime, lifecycle, notificatio
2576
2633
  }
2577
2634
  });
2578
2635
  if (isTerminalTurnStatus(turn.turn.status)) {
2636
+ projectorRef.current.settlement.terminalReceipt = turn.turn;
2579
2637
  state.terminalTurnNotificationQueued = true;
2580
2638
  deadlines.beginSettlement(Date.now());
2581
2639
  }
@@ -2677,13 +2735,15 @@ function activateCodexAttemptTurn(resources, turnRuntime, lifecycle, notificatio
2677
2735
  if (result.failedMediaCount) throw new Error(`failed to hydrate ${result.failedMediaCount} structured image attachment(s) for Codex steering`);
2678
2736
  return buildCodexUserInput(text, result.images);
2679
2737
  },
2680
- beforeConfirmConsumed: async (items) => {
2738
+ beforeSubmit: async (items) => {
2681
2739
  const transcriptItems = items.filter((item) => item.isInboundUserMessage === true || item.userTurnTranscriptRecorder !== void 0);
2682
2740
  if (transcriptItems.length === 0) return;
2683
2741
  await promptMirrorPromise;
2742
+ assertSteeringActive();
2684
2743
  const messages = activeProjector.buildSteeringTranscriptPrefix();
2685
2744
  if (params.sessionTarget && messages.length > 0) {
2686
2745
  await codexTranscriptMirrorRuntime.mirror({
2746
+ assertCurrent: assertSteeringActive,
2687
2747
  agentId: sessionAgentId,
2688
2748
  sessionKey: contextSessionKey,
2689
2749
  sessionId: params.sessionId,
@@ -2695,13 +2755,15 @@ function activateCodexAttemptTurn(resources, turnRuntime, lifecycle, notificatio
2695
2755
  runMirrorIdentityPrefix: `${activeTurnId}:`,
2696
2756
  config: params.config
2697
2757
  });
2758
+ assertSteeringActive();
2698
2759
  activeProjector.markSteeringTranscriptPersisted();
2699
2760
  }
2700
2761
  for (const item of transcriptItems) {
2701
2762
  const recorder = item.userTurnTranscriptRecorder;
2702
2763
  if (!recorder) continue;
2764
+ assertSteeringActive();
2703
2765
  await recorder.persistApproved();
2704
- if (!recorder.hasPersisted()) throw new Error("Codex consumed steering before its user turn was persisted");
2766
+ if (!recorder.hasPersisted()) throw new Error("Codex steering requires a persisted user turn before submission");
2705
2767
  }
2706
2768
  }
2707
2769
  });
@@ -2721,6 +2783,7 @@ function activateCodexAttemptTurn(resources, turnRuntime, lifecycle, notificatio
2721
2783
  kind: authorityKind,
2722
2784
  assertCurrent: injectionGuard(assertCurrent)
2723
2785
  },
2786
+ sourceRecorder: optionsLocal.userTurnTranscriptRecorder,
2724
2787
  persist: optionsLocal.userTurnTranscriptRecorder ? async () => {
2725
2788
  await optionsLocal.userTurnTranscriptRecorder?.persistApproved();
2726
2789
  } : void 0
@@ -2800,7 +2863,7 @@ function activateCodexAttemptTurn(resources, turnRuntime, lifecycle, notificatio
2800
2863
  abort: () => abortExplicitly("aborted")
2801
2864
  };
2802
2865
  params.replyOperation?.attachBackend(handle);
2803
- setActiveEmbeddedRun(params.sessionId, handle, params.sessionKey, params.sessionFile);
2866
+ setActiveEmbeddedRun(params.sessionId, handle, params.sessionKey, params.sessionFile, sessionAgentId);
2804
2867
  const freezeRunTerminalOutcome = () => {
2805
2868
  if (terminalState.terminalOutcomeFrozen) return;
2806
2869
  terminalState.terminalOutcomeFrozen = true;
@@ -2832,12 +2895,16 @@ async function cleanupCodexAttempt(resources, turnRuntime, lifecycle, requestRun
2832
2895
  const { maybeEmitFastModeAutoResetBestEffort, emitLifecycleTerminal, buildLifecycleTerminalMeta } = lifecycle;
2833
2896
  const { codexModelCallDiagnostics } = requestRuntime;
2834
2897
  const { activeTurnId, abortListener, handle, freezeRunTerminalOutcome } = activeTurn;
2898
+ resourceState.releaseInferenceContext?.();
2899
+ resourceState.releaseInferenceContext = void 0;
2835
2900
  prompt.context.attemptTools.scheduledAppAuthoritySourceRef.current = void 0;
2836
2901
  freezeRunTerminalOutcome();
2837
2902
  const projectionClose = state.projectionClosed ? void 0 : activeTurn.activeProjector.closeProjection();
2838
2903
  state.projectionClosed = true;
2839
2904
  const checkpointCleanup = projectionClose ? runCleanupStep("codex-transcript-checkpoint", () => projectionClose) : void 0;
2840
- await state.abortCleanup.catch(() => void 0);
2905
+ if (params.oneShotCliRun) await runCleanupStep("codex-abort-cleanup", () => state.abortCleanup);
2906
+ else await state.abortCleanup?.catch(() => {});
2907
+ if (params.oneShotCliRun) await runCleanupStep("codex-one-shot-terminals", () => terminateCodexBackgroundTerminals(resourceState.client, resourceState.thread.threadId, true));
2841
2908
  try {
2842
2909
  steeringQueueRef.current?.cancel();
2843
2910
  if (params.isFinalFallbackAttempt !== false) await maybeEmitFastModeAutoResetBestEffort();
@@ -2858,8 +2925,8 @@ async function cleanupCodexAttempt(resources, turnRuntime, lifecycle, requestRun
2858
2925
  aborted: runAbortController.signal.aborted && !state.clientClosedAbort
2859
2926
  });
2860
2927
  await runCleanupStep("codex-trajectory-flush", () => trajectoryRecorder?.flush());
2861
- const retainLiveIncognitoThread = (terminalState.turnSucceeded || state.permissionChangeRestart === "confirmed" && !params.abortSignal?.aborted) && isIncognitoSessionKey(params.sessionKey);
2862
- const retainLiveThread = ((retainLiveIncognitoThread && resourceState.thread.liveThreadEphemeralPolicy !== void 0 || terminalState.turnSucceeded && !isIncognitoSessionKey(params.sessionKey) && params.cleanupBundleMcpOnRunEnd !== true && resourceState.thread.liveThreadConfigFingerprint !== void 0 && resourceState.thread.preserveNativeModel !== true && resourceState.thread.connectionScope !== "supervision" && !resourceState.thread.ringZeroConfigFingerprint) && resourceState.thread.clientId === resolveCodexAppServerClientInstanceId(resourceState.client) ? bindingStore.read(bindingIdentity)?.threadId === resourceState.thread.threadId && await bindingStore.withLease(bindingIdentity, async () => {
2928
+ const retainLiveIncognitoThread = (terminalState.settledTurnStatus === "completed" || state.permissionChangeRestart === "confirmed" && !params.abortSignal?.aborted) && isIncognitoSessionKey(params.sessionKey);
2929
+ const retainLiveThread = ((retainLiveIncognitoThread && resourceState.thread.liveThreadEphemeralPolicy !== void 0 || terminalState.settledTurnStatus !== void 0 && !isIncognitoSessionKey(params.sessionKey) && params.cleanupBundleMcpOnRunEnd !== true && resourceState.thread.liveThreadConfigFingerprint !== void 0 && resourceState.thread.preserveNativeModel !== true && resourceState.thread.connectionScope !== "supervision" && !resourceState.thread.ringZeroConfigFingerprint) && resourceState.thread.clientId === resolveCodexAppServerClientInstanceId(resourceState.client) ? bindingStore.read(bindingIdentity)?.threadId === resourceState.thread.threadId && await bindingStore.withLease(bindingIdentity, async () => {
2863
2930
  if (bindingStore.read(bindingIdentity)?.threadId !== resourceState.thread.threadId) return false;
2864
2931
  return await retainCodexAppServerBindingSubscription(resourceState.client, resourceState.thread.threadId, {
2865
2932
  release: resourceState.thread.liveThreadOwnership?.release,
@@ -2877,16 +2944,22 @@ async function cleanupCodexAttempt(resources, turnRuntime, lifecycle, requestRun
2877
2944
  if (!await unsubscribeCodexThreadBestEffort(resourceState.client, {
2878
2945
  threadId: resourceState.thread.threadId,
2879
2946
  timeoutMs: 5e3
2880
- })) await closeCodexStartupClientBestEffort(resourceState.client);
2947
+ })) {
2948
+ await closeCodexStartupClientBestEffort(resourceState.client);
2949
+ if (params.oneShotCliRun) await runCleanupStep("codex-one-shot-unsubscribe", async () => {
2950
+ throw new Error("Codex one-shot thread unsubscribe was not confirmed");
2951
+ });
2952
+ }
2881
2953
  }
2882
2954
  }
2883
2955
  } finally {
2884
2956
  await runCleanupStep("codex-user-input-cancel", () => userInputBridgeRef.current?.cancelPending());
2885
2957
  await runCleanupStep("codex-turn-deadline-clear", () => deadlines.dispose());
2886
2958
  await runCleanupStep("codex-dynamic-tool-cleanup", async () => {
2887
- const cleanupReason = terminalState.turnSucceeded ? "completion" : state.timeout ? "timeout" : runAbortController.signal.aborted ? "cancel" : "error";
2959
+ const cleanupReason = terminalState.settledTurnStatus === "completed" ? "completion" : state.timeout ? "timeout" : runAbortController.signal.aborted ? "cancel" : "error";
2888
2960
  const cleanups = prompt.context.attemptTools.runCleanups.splice(0);
2889
- await Promise.allSettled(cleanups.map(async (cleanup) => await cleanup(cleanupReason)));
2961
+ const errors = (await Promise.allSettled(cleanups.map(async (cleanup) => await cleanup(cleanupReason)))).filter((result) => result.status === "rejected");
2962
+ if (params.oneShotCliRun && errors.length) throw new AggregateError(errors.map((result) => result.reason), "Codex tool cleanup failed");
2890
2963
  });
2891
2964
  await runCleanupStep("codex-route-release", releaseCurrentRoute);
2892
2965
  await checkpointCleanup;
@@ -2895,7 +2968,7 @@ async function cleanupCodexAttempt(resources, turnRuntime, lifecycle, requestRun
2895
2968
  resourceState.nativeHookRelay = void 0;
2896
2969
  await runCleanupStep("codex-native-hook-relay-release", () => {
2897
2970
  if (!nativeHookRelay) return;
2898
- if (state.shouldDelayNativeHookRelayUnregister) scheduleCodexNativeHookRelayUnregister({
2971
+ if (state.shouldDelayNativeHookRelayUnregister && !params.oneShotCliRun) scheduleCodexNativeHookRelayUnregister({
2899
2972
  relay: nativeHookRelay,
2900
2973
  hookTimeoutSec: options.nativeHookRelay?.hookTimeoutSec
2901
2974
  });
@@ -3326,11 +3399,11 @@ async function prepareCodexAttemptConnection({ params, options }) {
3326
3399
  config: params.config,
3327
3400
  agentId: policyAgentId
3328
3401
  });
3329
- const agentDir = params.agentDir ?? resolveAgentDir$2(params.config ?? {}, sessionAgentId);
3402
+ const agentDir = params.agentDir ?? resolveAgentDir$1(params.config ?? {}, sessionAgentId);
3330
3403
  const preparedEnvironment = params.hostCapabilities.preparedEnvironment?.();
3331
3404
  const remoteExec = isCodexRemoteExecPlacementSandbox(sandbox);
3332
3405
  const assertLocalTargetSupported = (unsupported) => {
3333
- if (preparedEnvironment?.localProcessEnv && unsupported) throw new Error("This runtime cannot target the diagnosed local installation. Use the saved prompt with a suggested external or manual handoff on this machine.");
3406
+ if (preparedEnvironment?.localProcessEnv && unsupported) throw new Error("This runtime cannot target the diagnosed local installation. Use an owned local Codex stdio process, or use the saved prompt with a suggested external or manual handoff on this machine.");
3334
3407
  };
3335
3408
  assertLocalTargetSupported(sandbox?.enabled === true || remoteExec);
3336
3409
  const preparedShellEnvironment = preparedEnvironment ? {
@@ -3341,7 +3414,7 @@ async function prepareCodexAttemptConnection({ params, options }) {
3341
3414
  const shellEnvironment = preparedShellEnvironment && Object.keys(preparedShellEnvironment).length > 0 ? preparedShellEnvironment : void 0;
3342
3415
  const disableLoginShell = remoteExec || preparedEnvironment?.localProcessEnv !== void 0 || preparedEnvironment?.managedLocalIdentity === true || preparedEnvironment !== void 0 && Object.keys(preparedEnvironment.credentialScrubEnv).length > 0;
3343
3416
  const withPreparedProcessEnv = (appServer) => {
3344
- assertLocalTargetSupported(appServer.start.transport === "websocket" || Boolean(appServer.remoteWorkspaceRoot));
3417
+ assertLocalTargetSupported(appServer.start.transport !== "stdio" || Boolean(appServer.remoteWorkspaceRoot));
3345
3418
  return shellEnvironment ? {
3346
3419
  ...appServer,
3347
3420
  start: {
@@ -3518,7 +3591,7 @@ async function prepareCodexAttemptConnection({ params, options }) {
3518
3591
  preDynamicStartupStages.mark("app-server-policy");
3519
3592
  preDynamicStartupStages.mark("native-hook-relay");
3520
3593
  const terminalState = {
3521
- turnSucceeded: false,
3594
+ settledTurnStatus: void 0,
3522
3595
  explicitCancellationObserved: false,
3523
3596
  explicitCancellationReason: void 0,
3524
3597
  terminalOutcomeFrozen: false,
@@ -3730,7 +3803,12 @@ async function prepareCodexAttemptContext(runtime, attemptTools) {
3730
3803
  sessionKey: contextSessionKey,
3731
3804
  sessionId: params.sessionId,
3732
3805
  workspaceDir: params.workspaceDir,
3806
+ ...!usesSupervisionConnection && connection.mutable.startupBinding?.preserveNativeModel !== true ? {
3807
+ modelProviderId: params.provider,
3808
+ modelId: params.modelId
3809
+ } : {},
3733
3810
  trigger: params.trigger,
3811
+ inputProvenance: params.inputProvenance,
3734
3812
  ...buildAgentHookContextChannelFields({
3735
3813
  sessionKey: contextSessionKey,
3736
3814
  messageChannel: params.messageChannel,
@@ -3789,6 +3867,17 @@ async function prepareCodexAttemptContext(runtime, attemptTools) {
3789
3867
  });
3790
3868
  const agentWorkspaceDeveloperInstructions = workspaceBootstrapContext.threadDeveloperInstructions ? connection.mutable.startupBinding?.agentWorkspaceDeveloperInstructions ?? workspaceBootstrapContext.threadDeveloperInstructions : void 0;
3791
3869
  const baseDeveloperInstructions = joinPresentSections(buildDeveloperInstructions(runtimeParams, { dynamicTools: toolBridge.availableSpecs }), agentWorkspaceDeveloperInstructions);
3870
+ const watchedSessionsContext = buildCodexWatchedSessionsContext({
3871
+ attempt: runtimeParams,
3872
+ dynamicTools: toolBridge.availableSpecs,
3873
+ sessionKey: contextSessionKey,
3874
+ sandboxed: sandbox?.enabled === true
3875
+ });
3876
+ const buildOpenClawPromptContext = (includeWorkspaceReferences) => buildCodexOpenClawPromptContext({
3877
+ params: runtimeParams,
3878
+ workspacePromptContext: includeWorkspaceReferences ? workspaceBootstrapContext.promptContext : void 0,
3879
+ watchedSessionsContext
3880
+ });
3792
3881
  return {
3793
3882
  runtime,
3794
3883
  attemptTools,
@@ -3801,16 +3890,7 @@ async function prepareCodexAttemptContext(runtime, attemptTools) {
3801
3890
  workspaceBootstrapContext,
3802
3891
  agentWorkspaceDeveloperInstructions,
3803
3892
  baseDeveloperInstructions,
3804
- openClawPromptContext: buildCodexOpenClawPromptContext({
3805
- params: runtimeParams,
3806
- workspacePromptContext: workspaceBootstrapContext.promptContext,
3807
- watchedSessionsContext: buildCodexWatchedSessionsContext({
3808
- attempt: runtimeParams,
3809
- dynamicTools: toolBridge.availableSpecs,
3810
- sessionKey: contextSessionKey,
3811
- sandboxed: sandbox?.enabled === true
3812
- })
3813
- }),
3893
+ buildOpenClawPromptContext,
3814
3894
  skillsCollaborationInstructions: renderCodexSkillsCollaborationInstructions({
3815
3895
  attempt: runtimeParams,
3816
3896
  skillsPrompt: params.skillsSnapshot?.prompt
@@ -4057,6 +4137,7 @@ function recordCodexTrajectoryCompletion(recorder, params) {
4057
4137
  yieldDetected: params.yieldDetected ?? false,
4058
4138
  aborted: terminal.aborted,
4059
4139
  promptError: normalizeCodexTrajectoryError(terminal.promptError),
4140
+ ...terminal.settlementWarning ? { settlementWarning: terminal.settlementWarning } : {},
4060
4141
  usage: params.result.attemptUsage,
4061
4142
  assistantTexts: params.result.assistantTexts,
4062
4143
  messagesSnapshot: params.result.messagesSnapshot
@@ -4107,25 +4188,25 @@ async function finalizeCodexAttempt(resources, turnRuntime, lifecycle, notificat
4107
4188
  assertCodexBindingMayBeReplaced(resourceState.thread, operation);
4108
4189
  return true;
4109
4190
  };
4110
- const { state, completion, deadlines } = turnRuntime;
4191
+ const { state, completion, deadlines, settlementExpired } = turnRuntime;
4111
4192
  const { emitLifecycleTerminal, buildLifecycleTerminalMeta } = lifecycle;
4112
4193
  const { drainNotificationQueue } = notifications;
4113
4194
  const { codexModelCallDiagnostics } = requestRuntime;
4114
4195
  const { activeTurnId, activeProjector, runtimeModelSelection, streamState, freezeRunTerminalOutcome, notifyUserMessagePersisted } = activeTurn;
4115
4196
  await completion;
4116
- const abortGraceElapsed = createDeferred();
4197
+ const drainGraceElapsed = createDeferred();
4117
4198
  let settlementPhase = "active";
4118
- let abortGraceTimer;
4119
- const beginAbortGrace = () => {
4120
- if (settlementPhase !== "active") return;
4121
- abortGraceTimer = setTimeout(() => {
4199
+ let drainGraceTimer;
4200
+ const beginDrainGrace = () => {
4201
+ if (settlementPhase !== "active" || drainGraceTimer) return;
4202
+ drainGraceTimer = setTimeout(() => {
4122
4203
  settlementPhase = "expired";
4123
- abortGraceElapsed.resolve();
4204
+ drainGraceElapsed.resolve();
4124
4205
  }, TURN_FINALIZE_DRAIN_ABORT_GRACE_MS);
4125
- abortGraceTimer.unref?.();
4206
+ drainGraceTimer.unref?.();
4126
4207
  };
4127
4208
  const abortListener = addAbortListener(runAbortController.signal, () => {
4128
- state.abortCleanup.then(beginAbortGrace, beginAbortGrace);
4209
+ state.abortCleanup.then(beginDrainGrace, beginDrainGrace);
4129
4210
  });
4130
4211
  const closeProjection = () => {
4131
4212
  state.projectionClosed = true;
@@ -4135,14 +4216,24 @@ async function finalizeCodexAttempt(resources, turnRuntime, lifecycle, notificat
4135
4216
  if (settlementPhase === "closed") return;
4136
4217
  settlementPhase = "closed";
4137
4218
  abortListener[Symbol.dispose]();
4138
- clearTimeout(abortGraceTimer);
4219
+ clearTimeout(drainGraceTimer);
4139
4220
  deadlines.dispose();
4140
4221
  };
4141
- const settlement = drainNotificationQueue().then(closeProjection);
4222
+ const settlement = drainNotificationQueue().then(async () => {
4223
+ await closeProjection();
4224
+ await activeProjector.settlement.drain();
4225
+ });
4226
+ const degradedSettlement = settlementExpired.then(() => {
4227
+ beginDrainGrace();
4228
+ });
4142
4229
  let projectionDrained = false;
4143
4230
  try {
4144
4231
  try {
4145
- projectionDrained = await Promise.race([settlement.then(() => true), abortGraceElapsed.promise.then(() => false)]);
4232
+ projectionDrained = await Promise.race([
4233
+ settlement.then(() => true),
4234
+ drainGraceElapsed.promise.then(() => false),
4235
+ degradedSettlement.then(() => false)
4236
+ ]);
4146
4237
  if (runAbortController.signal.aborted) await state.abortCleanup;
4147
4238
  } finally {
4148
4239
  if (!state.projectionClosed) await resources.runCleanupStep("codex-transcript-checkpoint", closeProjection);
@@ -4150,7 +4241,8 @@ async function finalizeCodexAttempt(resources, turnRuntime, lifecycle, notificat
4150
4241
  const result = activeProjector.buildResult(toolBridge.telemetry, { yieldDetected: toolState.yieldDetected });
4151
4242
  const projectedTerminal = attemptTerminal.project(result.terminal);
4152
4243
  const isFinalAborted = () => terminalState.explicitCancellationObserved || !resourceState.executionDisconnectError && (projectedTerminal.aborted || runAbortController.signal.aborted && !state.clientClosedAbort);
4153
- let enrichedPromptError = resourceState.executionDisconnectError ?? state.clientClosedPromptError ?? (state.timeout?.kind === "settlement" ? "codex app-server terminal settlement timed out" : state.timeout?.kind === "execution" ? "codex app-server execution budget timed out" : projectedTerminal.promptError);
4244
+ const currentPromptError = (fallback) => resourceState.executionDisconnectError ?? state.clientClosedPromptError ?? (state.timeout ? `codex app-server ${state.timeout.kind === "execution" ? "execution budget" : "terminal settlement"} timed out` : fallback);
4245
+ let enrichedPromptError = currentPromptError(projectedTerminal.promptError);
4154
4246
  const enrichedPromptErrorMessage = typeof enrichedPromptError === "string" ? enrichedPromptError : enrichedPromptError instanceof Error ? enrichedPromptError.message : enrichedPromptError ? formatErrorMessage(enrichedPromptError) : void 0;
4155
4247
  if (isInvalidCodexImagePayloadError(enrichedPromptErrorMessage)) await clearCodexBindingAfterInvalidImagePayload(bindingStore, bindingIdentity, {
4156
4248
  phase: "turn_completed",
@@ -4194,7 +4286,7 @@ async function finalizeCodexAttempt(resources, turnRuntime, lifecycle, notificat
4194
4286
  const projectTerminalOutcome = () => {
4195
4287
  const effectiveTimedOut = state.timeout !== void 0;
4196
4288
  const clientClosedPromptErrorForFinal = state.clientClosedPromptError;
4197
- const finalPromptError = resourceState.executionDisconnectError ?? clientClosedPromptErrorForFinal ?? (state.timeout?.kind === "settlement" ? "codex app-server terminal settlement timed out" : state.timeout?.kind === "execution" ? "codex app-server execution budget timed out" : enrichedPromptError);
4289
+ const finalPromptError = currentPromptError(enrichedPromptError);
4198
4290
  const finalPromptErrorSource = effectiveTimedOut || clientClosedPromptErrorForFinal ? "prompt" : projectedTerminal.promptErrorSource;
4199
4291
  const codexAppServerFailureKind = clientClosedPromptErrorForFinal ? "client_closed_before_turn_completed" : state.timeout?.kind === "settlement" ? "turn_settlement_timeout" : void 0;
4200
4292
  const replayBlockedReason = codexAppServerFailureKind ? resolveCodexAppServerReplayBlockedReason(result) : void 0;
@@ -4220,6 +4312,7 @@ async function finalizeCodexAttempt(resources, turnRuntime, lifecycle, notificat
4220
4312
  if (toolBridge.telemetry.messagingToolSentTargets.some((target) => target.sourceReplyFinal === true)) result.agentHarnessResultClassification = void 0;
4221
4313
  const attemptSucceeded = turnSucceeded && result.agentHarnessResultClassification === void 0;
4222
4314
  result.terminal = attemptTerminal.normalize({
4315
+ settlementWarning: state.settlementWarning,
4223
4316
  timedOut: effectiveTimedOut,
4224
4317
  aborted: finalAborted,
4225
4318
  promptError: finalPromptError,
@@ -4246,20 +4339,24 @@ async function finalizeCodexAttempt(resources, turnRuntime, lifecycle, notificat
4246
4339
  completedTurnStatus
4247
4340
  };
4248
4341
  };
4249
- const mirrorTerminal = projectTerminalOutcome();
4342
+ projectTerminalOutcome();
4250
4343
  const unavailableMirror = {
4251
4344
  assistantTranscriptOwned: false,
4252
4345
  mirroredMessages: []
4253
4346
  };
4254
4347
  let mirrorOutcome = unavailableMirror;
4255
- try {
4256
- if (projectionDrained && settlementPhase === "active") mirrorOutcome = await Promise.race([codexTranscriptMirrorRuntime.mirrorBestEffort({
4348
+ const mirrorFinal = () => {
4349
+ const warning = state.settlementWarning;
4350
+ const mirrorTerminal = projectTerminalOutcome();
4351
+ state.pendingSettlementStage = "transcript/mirror";
4352
+ return codexTranscriptMirrorRuntime.mirrorBestEffort({
4257
4353
  assertWriteCurrent: () => {
4258
- if (settlementPhase !== "active") throw new Error("Codex transcript settlement is no longer active");
4354
+ if (settlementPhase !== "active" || state.settlementWarning !== warning) throw new Error("Codex transcript settlement is no longer active");
4259
4355
  const current = projectTerminalOutcome();
4260
4356
  if (current.finalAborted !== mirrorTerminal.finalAborted || current.effectiveTimedOut !== mirrorTerminal.effectiveTimedOut || current.finalPromptError !== mirrorTerminal.finalPromptError) throw new Error("Codex transcript terminal outcome changed before write");
4261
4357
  },
4262
4358
  params,
4359
+ settlementWarning: warning,
4263
4360
  agentId: sessionAgentId,
4264
4361
  notifyUserMessagePersisted,
4265
4362
  result,
@@ -4267,13 +4364,47 @@ async function finalizeCodexAttempt(resources, turnRuntime, lifecycle, notificat
4267
4364
  cwd: effectiveCwd,
4268
4365
  threadId: resourceState.thread.threadId,
4269
4366
  turnId: activeTurnId
4270
- }), abortGraceElapsed.promise.then(() => unavailableMirror)]);
4367
+ });
4368
+ };
4369
+ try {
4370
+ if (projectionDrained && settlementPhase === "active" && !state.settlementWarning) mirrorOutcome = await Promise.race([
4371
+ mirrorFinal(),
4372
+ drainGraceElapsed.promise.then(() => unavailableMirror),
4373
+ degradedSettlement.then(() => unavailableMirror)
4374
+ ]);
4375
+ if (state.settlementWarning && !runAbortController.signal.aborted) {
4376
+ mirrorOutcome = await Promise.race([mirrorFinal(), drainGraceElapsed.promise.then(() => unavailableMirror)]);
4377
+ if (mirrorOutcome === unavailableMirror) trajectoryRecorder?.recordEvent("turn.settlement_persistence_unavailable", {
4378
+ pendingStage: "transcript/mirror",
4379
+ threadId: resourceState.thread.threadId,
4380
+ turnId: activeTurnId
4381
+ });
4382
+ }
4383
+ if (toolState.yieldMessage && projectTerminalOutcome().turnSucceeded) {
4384
+ state.pendingSettlementStage = "transcript/yield-context";
4385
+ await Promise.race([
4386
+ appendSessionYieldContext({
4387
+ ...activeTranscriptTarget.sessionTarget,
4388
+ agentId: activeTranscriptTarget.agentId,
4389
+ sessionId: activeTranscriptTarget.sessionId,
4390
+ sessionKey: activeTranscriptTarget.sessionKey,
4391
+ config: params.config,
4392
+ message: toolState.yieldMessage,
4393
+ assertCurrent: () => {
4394
+ connection.assertCurrent();
4395
+ if (settlementPhase !== "active" || !projectTerminalOutcome().turnSucceeded) throw new Error("Codex yield settlement is no longer active");
4396
+ }
4397
+ }),
4398
+ drainGraceElapsed.promise,
4399
+ degradedSettlement
4400
+ ]);
4401
+ }
4271
4402
  if (runAbortController.signal.aborted) await state.abortCleanup;
4272
4403
  } finally {
4273
4404
  closeSettlement();
4274
4405
  }
4275
4406
  const { effectiveTimedOut, finalPromptError, codexAppServerFailure, promptTimeoutOutcome, finalAborted, turnSucceeded, attemptSucceeded, completedTurnStatus } = projectTerminalOutcome();
4276
- terminalState.turnSucceeded = turnSucceeded;
4407
+ terminalState.settledTurnStatus = turnSucceeded ? "completed" : completedTurnStatus === "failed" && !finalAborted && !effectiveTimedOut && !state.clientClosedPromptError && !resourceState.executionDisconnectError ? "failed" : void 0;
4277
4408
  terminalState.sharedAbortAllowedAfterTerminalOutcome = shouldKeepCodexSharedAbortOpen({
4278
4409
  trigger: params.trigger,
4279
4410
  result,
@@ -4326,7 +4457,9 @@ async function finalizeCodexAttempt(resources, turnRuntime, lifecycle, notificat
4326
4457
  ctx: hookContext,
4327
4458
  hookRunner
4328
4459
  });
4460
+ const providerRefusal = result.currentAttemptAssistant?.diagnostics?.some((diagnostic) => diagnostic.type === "provider_refusal");
4329
4461
  await runCodexAgentEndHook(params, {
4462
+ skillExperienceReviewSource: providerRefusal ? void 0 : terminalAnchor,
4330
4463
  event: {
4331
4464
  messages: result.messagesSnapshot,
4332
4465
  success: !finalAborted && !finalPromptError,
@@ -4350,7 +4483,7 @@ async function finalizeCodexAttempt(resources, turnRuntime, lifecycle, notificat
4350
4483
  hookRunner
4351
4484
  });
4352
4485
  state.shouldDelayNativeHookRelayUnregister = completedTurnStatus === "completed" && !effectiveTimedOut && !runAbortController.signal.aborted && !finalAborted && !finalPromptError;
4353
- if (state.shouldDelayNativeHookRelayUnregister) try {
4486
+ if (turnSucceeded && !runAbortController.signal.aborted) try {
4354
4487
  const continuityCalibration = context.promptState.noEngineContinuityProjectionApplied ? buildCodexContinuityCalibration({
4355
4488
  promptChars: prompt.turnState.codexTurnPromptText.length,
4356
4489
  inputTokens: result.attemptUsage?.contextUsage?.state === "available" ? result.attemptUsage.contextUsage.promptTokens ?? 0 : 0
@@ -4699,7 +4832,7 @@ function createCodexAttemptNotificationController(resources, turnRuntime, lifecy
4699
4832
  });
4700
4833
  if (response && !state.projectionClosed && !runAbortController.signal.aborted && turnIdRef.current === turnId && item.success === response.success && isDeepStrictEqual(item.contentItems, response.contentItems)) acknowledgeInternalToolResult(response);
4701
4834
  }
4702
- if (item?.type === "userMessage" && typeof item.clientId === "string") await steeringQueueRef.current?.confirmConsumed(item.clientId);
4835
+ if (item?.type === "userMessage" && typeof item.clientId === "string") steeringQueueRef.current?.confirmConsumed(item.clientId);
4703
4836
  }
4704
4837
  if (isCodexTurnAbortMarkerNotification(notification, { currentPromptTexts: [turnState.codexTurnPromptText] })) state.sawCodexInterruptMarker = true;
4705
4838
  }
@@ -4740,6 +4873,8 @@ function createCodexAttemptNotificationController(resources, turnRuntime, lifecy
4740
4873
  if (!projector || !turnId || state.projectionClosed) return;
4741
4874
  projector.recordMcpToolCallReceipt(notification);
4742
4875
  if (isTerminalTurnNotificationForTurn(notification, turnId)) {
4876
+ const completed = readCodexTurnCompletedNotification(notification.params);
4877
+ if (completed) projector.settlement.terminalReceipt = completed.turn;
4743
4878
  state.terminalTurnNotificationQueued = true;
4744
4879
  steeringQueueRef.current?.sealAdmission();
4745
4880
  deadlines.beginSettlement(receivedAtMs);
@@ -4748,7 +4883,10 @@ function createCodexAttemptNotificationController(resources, turnRuntime, lifecy
4748
4883
  const modelToolCallId = readRawResponseToolCallId(notification);
4749
4884
  if (modelToolCallId) allocateCodexToolOutcomeOrdinal?.(modelToolCallId);
4750
4885
  const nativeItem = readCodexNotificationItem(notification.params);
4751
- if (nativeItem?.type === "webSearch") projector.recordNativeToolOutcome(nativeItem);
4886
+ if (nativeItem?.type === "webSearch") {
4887
+ projector.settlement.turnTainted ||= notification.method === "item/completed";
4888
+ projector.recordNativeToolOutcome(nativeItem);
4889
+ }
4752
4890
  }
4753
4891
  };
4754
4892
  const enqueueNotification = async (notification, scope) => {
@@ -4775,17 +4913,47 @@ function isRestrictivePromptToolsAllow(toolsAllow) {
4775
4913
  return toolsAllow !== void 0 && !toolsAllow.some((name) => name.trim() === "*");
4776
4914
  }
4777
4915
  async function prepareCodexAttemptPrompt(context) {
4778
- const { runtime, attemptTools, historyState, hookContext, workspaceBootstrapContext, buildActiveContextEngineRuntimeContext, baseDeveloperInstructions, openClawPromptContext, skillsCollaborationInstructions, promptState, codexContextProjectionMaxChars, codexContinuityProjectionMaxChars } = context;
4916
+ const { runtime, attemptTools, historyState, hookContext, workspaceBootstrapContext, buildActiveContextEngineRuntimeContext, baseDeveloperInstructions, buildOpenClawPromptContext, skillsCollaborationInstructions, promptState, codexContextProjectionMaxChars, codexContinuityProjectionMaxChars } = context;
4779
4917
  const { connection, buildActiveRunAttemptParams, effectiveContextTokenBudget, effectiveRuntimeModelId, effectiveRuntimeProviderId } = runtime;
4780
4918
  const { params, activeContextEngine, usesSupervisionConnection, mutable, isInactiveThreadBootstrapBinding, bindingStore, bindingIdentity, agentDir, appServer, contextSessionKey, effectiveWorkspace, sandbox } = connection;
4781
4919
  const { toolBridge } = attemptTools;
4782
- const applyFreshThreadContinuityProjection = () => {
4783
- const projection = projectContextEngineAssemblyForCodex({
4784
- assembledMessages: historyState.messages,
4920
+ let contextImages = [];
4921
+ const currentUserTurnIdempotencyKey = params.userTurnTranscriptRecorder?.message?.idempotencyKey;
4922
+ const assertProjectionCurrent = () => {
4923
+ params.hostCapabilities.assertActive();
4924
+ connection.assertCurrent();
4925
+ connection.runAbortController.signal.throwIfAborted();
4926
+ };
4927
+ const prepareFileContext = async (message, maxChars) => {
4928
+ const prepare = params.hostCapabilities.prepareContextMedia;
4929
+ if (!prepare) {
4930
+ const media = asOptionalRecord(Reflect.get(message, "__openclaw"))?.media;
4931
+ if (Array.isArray(media) && media.length || message.role === "user" && Array.isArray(message.content) && message.content.some((part) => part.type === "image")) throw new CodexContextAttachmentError("Saved attachments require a newer OpenClaw host. Update the Gateway and Codex plugin together, then retry.");
4932
+ return { images: [] };
4933
+ }
4934
+ try {
4935
+ const files = await prepare({
4936
+ message,
4937
+ maxChars
4938
+ });
4939
+ assertProjectionCurrent();
4940
+ return files;
4941
+ } catch (error) {
4942
+ assertProjectionCurrent();
4943
+ throw new CodexContextAttachmentError("Saved attachment preparation failed. Retry the request after checking the attachment source.", { cause: error });
4944
+ }
4945
+ };
4946
+ const applyContinuityProjection = async (messages) => {
4947
+ const projection = await projectContextEngineAssemblyForCodex({
4948
+ assembledMessages: messages,
4785
4949
  originalHistoryMessages: historyState.messages,
4786
4950
  prompt: params.prompt,
4787
- maxRenderedContextChars: codexContinuityProjectionMaxChars
4951
+ maxRenderedContextChars: codexContinuityProjectionMaxChars,
4952
+ prepareFileContext,
4953
+ currentUserTurnIdempotencyKey
4788
4954
  });
4955
+ assertProjectionCurrent();
4956
+ contextImages = projection.images ?? [];
4789
4957
  promptState.promptText = projection.promptText;
4790
4958
  promptState.promptContextRange = projection.promptContextRange;
4791
4959
  promptState.prePromptMessageCount = projection.prePromptMessageCount;
@@ -4814,14 +4982,6 @@ async function prepareCodexAttemptPrompt(context) {
4814
4982
  });
4815
4983
  if (!assembled) throw new Error("context engine assemble returned no result");
4816
4984
  const contextEngineProjection = readContextEngineThreadBootstrapProjection(assembled.contextProjection);
4817
- const projection = projectContextEngineAssemblyForCodex({
4818
- assembledMessages: assembled.messages,
4819
- originalHistoryMessages: historyState.messages,
4820
- prompt: params.prompt,
4821
- systemPromptAddition: assembled.systemPromptAddition,
4822
- maxRenderedContextChars: codexContextProjectionMaxChars,
4823
- toolPayloadMode: contextEngineProjection ? "preserve" : "elide"
4824
- });
4825
4985
  const projectionDecision = contextEngineProjection ? resolveContextEngineBootstrapProjectionDecision({
4826
4986
  startupBinding: decisionStartupBinding,
4827
4987
  expectedBinding: buildContextEngineBinding(buildActiveRunAttemptParams(), contextEngineProjection),
@@ -4832,6 +4992,18 @@ async function prepareCodexAttemptPrompt(context) {
4832
4992
  project: true,
4833
4993
  reason: "per-turn-projection"
4834
4994
  };
4995
+ const projection = await projectContextEngineAssemblyForCodex({
4996
+ assembledMessages: assembled.messages,
4997
+ originalHistoryMessages: historyState.messages,
4998
+ prompt: params.prompt,
4999
+ systemPromptAddition: assembled.systemPromptAddition,
5000
+ maxRenderedContextChars: codexContextProjectionMaxChars,
5001
+ toolPayloadMode: contextEngineProjection ? "preserve" : "elide",
5002
+ ...projectionDecision.project ? { prepareFileContext } : {},
5003
+ currentUserTurnIdempotencyKey
5004
+ });
5005
+ assertProjectionCurrent();
5006
+ contextImages = projectionDecision.project ? projection.images ?? [] : [];
4835
5007
  const decisionBinding = decisionStartupBinding;
4836
5008
  embeddedAgentLog.info("codex app-server context-engine projection decision", {
4837
5009
  sessionId: params.sessionId,
@@ -4859,6 +5031,8 @@ async function prepareCodexAttemptPrompt(context) {
4859
5031
  if (activeContextEngine) try {
4860
5032
  await applyActiveContextEngineProjection(runtime.nativeToolSurfaceEnabled ? mutable.startupBinding : void 0);
4861
5033
  } catch (assembleErr) {
5034
+ if (assembleErr instanceof CodexContextAttachmentError) throw assembleErr;
5035
+ assertProjectionCurrent();
4862
5036
  embeddedAgentLog.warn("context engine assemble failed; using Codex baseline prompt", { error: formatErrorMessage(assembleErr) });
4863
5037
  }
4864
5038
  const codexModelInputHistoryMessages = [];
@@ -4905,8 +5079,8 @@ async function prepareCodexAttemptPrompt(context) {
4905
5079
  }
4906
5080
  };
4907
5081
  };
4908
- const decorateCodexTurnPromptText = (promptBuildResult) => {
4909
- const turnPromptText = prependCodexOpenClawPromptContext(promptBuildResult.prompt, openClawPromptContext, { preservePromptWithoutContext: params.bootstrapContextMode === "lightweight" && params.bootstrapContextRunKind === "cron" });
5082
+ const decorateCodexTurnPromptText = (promptBuildResult, includeWorkspaceReferences = true) => {
5083
+ const turnPromptText = prependCodexOpenClawPromptContext(promptBuildResult.prompt, buildOpenClawPromptContext(includeWorkspaceReferences), { preservePromptWithoutContext: params.bootstrapContextMode === "lightweight" && params.bootstrapContextRunKind === "cron" });
4910
5084
  const projectedRanges = resolveShiftedPromptContextRange(promptBuildResult.prompt, promptBuildResult.promptInputRange, turnPromptText);
4911
5085
  const preservedRange = resolveShiftedPromptInputRange(promptBuildResult.prompt, promptBuildResult.promptInputRange, turnPromptText) ?? resolveCodexDeliveryHintPreservedInputRange({
4912
5086
  prompt: promptBuildResult.prompt,
@@ -4925,11 +5099,13 @@ async function prepareCodexAttemptPrompt(context) {
4925
5099
  promptBuild: firstPromptBuild,
4926
5100
  codexTurnPromptText: decorateCodexTurnPromptText(firstPromptBuild)
4927
5101
  };
4928
- const buildRenderedCodexDeveloperInstructions = () => joinPresentSections(turnState.promptBuild.developerInstructions, buildTurnCollaborationMode(params, {
5102
+ let parentLocalEgress = false;
5103
+ const parentLocalContext = {
4929
5104
  turnScopedDeveloperInstructions: workspaceBootstrapContext.turnScopedDeveloperInstructions,
4930
5105
  skillsCollaborationInstructions,
4931
5106
  memoryCollaborationInstructions: workspaceBootstrapContext.memoryCollaborationInstructions
4932
- }).settings.developer_instructions ?? void 0);
5107
+ };
5108
+ const buildRenderedCodexDeveloperInstructions = () => joinPresentSections(turnState.promptBuild.developerInstructions, (parentLocalEgress ? buildCodexParentLocalInstructions(params, parentLocalContext) : buildTurnCollaborationMode(params, parentLocalContext).settings.developer_instructions) ?? void 0);
4933
5109
  const rebuildCodexPromptBuildFromCurrentProjection = async () => {
4934
5110
  turnState.promptBuild = await buildPromptFromCurrentInputs();
4935
5111
  turnState.codexTurnPromptText = decorateCodexTurnPromptText(turnState.promptBuild);
@@ -4946,28 +5122,19 @@ async function prepareCodexAttemptPrompt(context) {
4946
5122
  const selectNewerVisibleHistoryAfterBinding = (binding) => {
4947
5123
  const cutoff = Date.parse(binding.historyCoveredThrough ?? "");
4948
5124
  return historyState.messages.filter((message) => {
4949
- if (message.role !== "user" && message.role !== "assistant") return false;
5125
+ if (message.role !== "user" && message.role !== "assistant" && !isCodexDurableCustomMessage(message)) return false;
4950
5126
  const mirrorIdentity = readMirrorIdentity(message);
4951
5127
  const timestamp = typeof message.timestamp === "number" ? message.timestamp : typeof message.timestamp === "string" ? Date.parse(message.timestamp) : NaN;
4952
5128
  return !("idempotencyKey" in message && typeof message.idempotencyKey === "string" && message.idempotencyKey.startsWith("codex-app-server:")) && !hasCodexMirrorOrigin(message) && !mirrorIdentity?.startsWith("codex-app-server:") && Number.isFinite(timestamp) && timestamp > (Number.isFinite(cutoff) ? cutoff : 0);
4953
5129
  });
4954
5130
  };
4955
- const applyResumeStaleBindingContinuityProjection = (binding) => {
5131
+ const applyResumeStaleBindingContinuityProjection = async (binding) => {
4956
5132
  const newerVisibleMessages = selectNewerVisibleHistoryAfterBinding(binding);
4957
5133
  if (newerVisibleMessages.length === 0) return false;
4958
- const projection = projectContextEngineAssemblyForCodex({
4959
- assembledMessages: newerVisibleMessages,
4960
- originalHistoryMessages: historyState.messages,
4961
- prompt: params.prompt,
4962
- maxRenderedContextChars: codexContinuityProjectionMaxChars
4963
- });
4964
- promptState.promptText = projection.promptText;
4965
- promptState.promptContextRange = projection.promptContextRange;
4966
- promptState.prePromptMessageCount = projection.prePromptMessageCount;
4967
- promptState.noEngineContinuityProjectionApplied = true;
5134
+ await applyContinuityProjection(newerVisibleMessages);
4968
5135
  return true;
4969
5136
  };
4970
- const precomputeNoContextEngineStaleBindingProjection = () => {
5137
+ const precomputeNoContextEngineStaleBindingProjection = async () => {
4971
5138
  promptState.precomputedStaleBindingContinuityProjectionApplied = false;
4972
5139
  promptState.staleBindingContinuityForcedFreshStart = false;
4973
5140
  const binding = mutable.startupBinding;
@@ -4976,24 +5143,24 @@ async function prepareCodexAttemptPrompt(context) {
4976
5143
  promptState.inactiveThreadBootstrapBindingForcedFreshStart = true;
4977
5144
  return false;
4978
5145
  }
4979
- const projected = applyResumeStaleBindingContinuityProjection(binding);
5146
+ const projected = await applyResumeStaleBindingContinuityProjection(binding);
4980
5147
  promptState.precomputedStaleBindingContinuityProjectionApplied = projected;
4981
5148
  return projected;
4982
5149
  };
4983
- const applyNoContextEngineContinuityProjection = (action, binding) => {
4984
- const hasContinuity = historyState.messages.some((message) => message.role === "user" || action === "started" && (message.role === "compactionSummary" || message.role === "branchSummary"));
5150
+ const applyNoContextEngineContinuityProjection = async (action, binding) => {
5151
+ const hasContinuity = historyState.messages.some((message) => message.role === "user" || isCodexDurableCustomMessage(message) || action === "started" && (message.role === "compactionSummary" || message.role === "branchSummary"));
4985
5152
  if (activeContextEngine || !hasContinuity) return false;
4986
5153
  if (action === "resumed" && promptState.precomputedStaleBindingContinuityProjectionApplied) return true;
4987
5154
  if (action === "started" && promptState.staleBindingContinuityForcedFreshStart) return true;
4988
5155
  if (action === "started" && promptState.inactiveThreadBootstrapBindingForcedFreshStart) return false;
4989
5156
  if (action === "resumed" && binding) return applyResumeStaleBindingContinuityProjection(binding);
4990
5157
  if (action === "started") {
4991
- applyFreshThreadContinuityProjection();
5158
+ await applyContinuityProjection(historyState.messages);
4992
5159
  return true;
4993
5160
  }
4994
5161
  return false;
4995
5162
  };
4996
- if (precomputeNoContextEngineStaleBindingProjection()) await rebuildCodexPromptBuildFromCurrentProjection();
5163
+ if (await precomputeNoContextEngineStaleBindingProjection()) await rebuildCodexPromptBuildFromCurrentProjection();
4997
5164
  const rotateStartupBindingForProjectedTurn = async () => {
4998
5165
  const binding = mutable.startupBinding;
4999
5166
  if (!binding?.threadId) return;
@@ -5020,12 +5187,14 @@ async function prepareCodexAttemptPrompt(context) {
5020
5187
  if (mutable.startupBinding?.threadId) return;
5021
5188
  promptState.inactiveThreadBootstrapBindingForcedFreshStart = hadInactiveThreadBootstrapBinding;
5022
5189
  promptState.staleBindingContinuityForcedFreshStart = promptState.precomputedStaleBindingContinuityProjectionApplied && !promptState.inactiveThreadBootstrapBindingForcedFreshStart;
5023
- if (promptState.staleBindingContinuityForcedFreshStart) applyFreshThreadContinuityProjection();
5190
+ if (promptState.staleBindingContinuityForcedFreshStart) await applyContinuityProjection(historyState.messages);
5024
5191
  if (activeContextEngine) {
5025
5192
  promptState.contextEngineProjection = void 0;
5026
5193
  try {
5027
5194
  await applyActiveContextEngineProjection(void 0);
5028
5195
  } catch (assembleErr) {
5196
+ if (assembleErr instanceof CodexContextAttachmentError) throw assembleErr;
5197
+ assertProjectionCurrent();
5029
5198
  embeddedAgentLog.warn("context engine assemble failed; using Codex baseline prompt", { error: formatErrorMessage(assembleErr) });
5030
5199
  }
5031
5200
  }
@@ -5039,22 +5208,40 @@ async function prepareCodexAttemptPrompt(context) {
5039
5208
  });
5040
5209
  };
5041
5210
  await rotateStartupBindingForProjectedTurn();
5211
+ const buildSystemPromptReport = (omitWorkspaceReferences = false) => buildCodexSystemPromptReport({
5212
+ attempt: params,
5213
+ sessionKey: contextSessionKey,
5214
+ workspaceDir: effectiveWorkspace,
5215
+ developerInstructions: buildRenderedCodexDeveloperInstructions(),
5216
+ workspaceBootstrapContext,
5217
+ omitWorkspaceReferences,
5218
+ skillsPrompt: skillsCollaborationInstructions ? params.skillsSnapshot?.prompt ?? "" : "",
5219
+ tools: toolBridge.availableSpecs
5220
+ });
5221
+ const systemPromptReport = buildSystemPromptReport();
5222
+ let workspaceReferencesIncluded = true;
5042
5223
  return {
5043
5224
  context,
5225
+ get contextImages() {
5226
+ return contextImages;
5227
+ },
5044
5228
  codexModelInputHistoryMessages,
5045
5229
  turnState,
5230
+ refreshWorkspaceReferences: (include) => {
5231
+ turnState.codexTurnPromptText = decorateCodexTurnPromptText(turnState.promptBuild, include);
5232
+ if (include !== workspaceReferencesIncluded) {
5233
+ Object.assign(systemPromptReport, buildSystemPromptReport(!include));
5234
+ workspaceReferencesIncluded = include;
5235
+ }
5236
+ },
5237
+ setParentLocalEgress: () => {
5238
+ parentLocalEgress = true;
5239
+ Object.assign(systemPromptReport, buildSystemPromptReport(!workspaceReferencesIncluded));
5240
+ },
5046
5241
  buildRenderedCodexDeveloperInstructions,
5047
5242
  rebuildCodexTurnPromptTextFromCurrentProjection,
5048
5243
  applyNoContextEngineContinuityProjection,
5049
- systemPromptReport: buildCodexSystemPromptReport({
5050
- attempt: params,
5051
- sessionKey: contextSessionKey,
5052
- workspaceDir: effectiveWorkspace,
5053
- developerInstructions: buildRenderedCodexDeveloperInstructions(),
5054
- workspaceBootstrapContext,
5055
- skillsPrompt: skillsCollaborationInstructions ? params.skillsSnapshot?.prompt ?? "" : "",
5056
- tools: toolBridge.availableSpecs
5057
- })
5244
+ systemPromptReport
5058
5245
  };
5059
5246
  }
5060
5247
  //#endregion
@@ -5106,6 +5293,7 @@ function prepareCodexAttemptResources(prompt) {
5106
5293
  sharedCodexClientRetiredForOneShotCleanup: false,
5107
5294
  sandboxExecEnvironment: void 0,
5108
5295
  executionDisconnectError: void 0,
5296
+ releaseInferenceContext: void 0,
5109
5297
  codexEnvironmentSelection: void 0,
5110
5298
  codexExecutionCwd: effectiveCwd,
5111
5299
  codexSandboxPolicy: void 0,
@@ -5153,10 +5341,11 @@ function prepareCodexAttemptResources(prompt) {
5153
5341
  closed: retired.closed,
5154
5342
  matchedSharedClient: retired.found
5155
5343
  });
5156
- if (retired.closed) await state.client.closeAndWait({
5344
+ const result = retired.closed ? await state.client.closeAndWait({
5157
5345
  exitTimeoutMs: 2e3,
5158
5346
  forceKillDelayMs: 250
5159
- });
5347
+ }) : void 0;
5348
+ if (params.oneShotCliRun && result?.cleanup !== "closed") throw new Error("Codex one-shot client cleanup could not be confirmed");
5160
5349
  };
5161
5350
  const releaseSandboxExecEnvironment = async () => {
5162
5351
  if (state.sandboxExecEnvironment) {
@@ -5170,10 +5359,13 @@ function prepareCodexAttemptResources(prompt) {
5170
5359
  await releaseSandboxExecEnvironment();
5171
5360
  const ownedClient = state.releaseSharedClientLease ? state.client : void 0;
5172
5361
  releaseSharedClientLeaseOnce();
5173
- await ownedClient?.closeAndWait({
5174
- exitTimeoutMs: 2e3,
5175
- forceKillDelayMs: 250
5176
- });
5362
+ if (ownedClient) {
5363
+ const result = await ownedClient.closeAndWait({
5364
+ exitTimeoutMs: 2e3,
5365
+ forceKillDelayMs: 250
5366
+ });
5367
+ if (params.oneShotCliRun && result.cleanup !== "closed") throw new Error("Codex isolated client cleanup could not be confirmed");
5368
+ }
5177
5369
  return;
5178
5370
  }
5179
5371
  releaseSharedClientLeaseOnce();
@@ -5194,11 +5386,26 @@ function prepareCodexAttemptResources(prompt) {
5194
5386
  };
5195
5387
  const registerNativeSubagentMonitor = (parentThreadId) => {
5196
5388
  unregisterNativeSubagentMonitor();
5389
+ const sessionKey = params.sessionKey;
5390
+ const storePath = params.sessionTarget?.storePath;
5391
+ const parentSession = sessionKey && storePath ? getSessionEntry({
5392
+ agentId: sessionAgentId,
5393
+ sessionKey,
5394
+ storePath,
5395
+ readConsistency: "latest",
5396
+ hydrateSkillPromptRefs: false
5397
+ }) : void 0;
5197
5398
  state.nativeSubagentMonitor = codexNativeSubagentMonitorRuntime.register({
5198
5399
  client: state.client,
5199
5400
  parentThreadId,
5200
5401
  requesterSessionKey: params.sessionKey,
5201
5402
  taskRuntimeScope: params.agentHarnessTaskRuntimeScope,
5403
+ historyOwner: createCodexNativeSubagentHistoryOwner({
5404
+ parentThreadId,
5405
+ sessionId: params.sessionId,
5406
+ ...parentSession?.sessionId === params.sessionId ? { lifecycleRevision: parentSession.lifecycleRevision } : {},
5407
+ binding: state.thread
5408
+ }),
5202
5409
  agentId: sessionAgentId,
5203
5410
  retainClient: () => retainSharedCodexAppServerClientIfCurrent(state.client),
5204
5411
  retainParentThread: (protectedThreadId) => protectCodexAppServerLiveThread(state.client, protectedThreadId),
@@ -5210,6 +5417,8 @@ function prepareCodexAttemptResources(prompt) {
5210
5417
  });
5211
5418
  };
5212
5419
  const releaseCurrentRoute = () => {
5420
+ state.releaseInferenceContext?.();
5421
+ state.releaseInferenceContext = void 0;
5213
5422
  state.detachRouteAbort();
5214
5423
  state.detachRouteAbort = () => void 0;
5215
5424
  state.turnRoute?.release();
@@ -5646,10 +5855,10 @@ function createCodexDynamicToolExecutionRegistry() {
5646
5855
  }
5647
5856
  };
5648
5857
  }
5649
- function resolveCodexDynamicToolDirectNames(params, hostSystemAgentActive = false) {
5858
+ function resolveCodexDynamicToolDirectNames(params, registeredTools, hostSystemAgentActive = false) {
5650
5859
  const names = [];
5651
5860
  if (hostSystemAgentActive && isSystemAgentOnlyCodexDynamicToolAllowlist(params.toolsAllow)) names.push("openclaw");
5652
- if (params.sourceReplyDeliveryMode === "message_tool_only") names.push("message");
5861
+ if (registeredTools.some((tool) => tool.name === "message")) names.push("message");
5653
5862
  return names;
5654
5863
  }
5655
5864
  //#endregion
@@ -5922,7 +6131,7 @@ function createCodexAttemptServerRequestController(resources, turnRuntime, lifec
5922
6131
  //#region extensions/codex/src/app-server/attempt-runtime-artifact.ts
5923
6132
  async function verifyStartupArtifact(params) {
5924
6133
  if (!params.request) return;
5925
- const { readCodexAppServerClientRuntimeArtifact, validateCodexAppServerRuntimeArtifact } = await import("./runtime-artifact-Bh_gf6-t.js");
6134
+ const { readCodexAppServerClientRuntimeArtifact, validateCodexAppServerRuntimeArtifact } = await import("./runtime-artifact-BJ0rXBZ_.js");
5926
6135
  const runtimeArtifact = readCodexAppServerClientRuntimeArtifact(params.client);
5927
6136
  const expected = params.request.expected;
5928
6137
  const matchesExpected = !expected || runtimeArtifact?.id === expected.id && runtimeArtifact.fingerprint === expected.fingerprint;
@@ -5934,12 +6143,7 @@ async function verifyStartupArtifact(params) {
5934
6143
  }
5935
6144
  //#endregion
5936
6145
  //#region extensions/codex/src/app-server/computer-use-health.ts
5937
- const COMPUTER_USE_HEALTH_MONITOR_STATE = Symbol.for("openclaw.codexComputerUseHealthMonitorState");
5938
- function getComputerUseHealthMonitorState() {
5939
- const globalState = globalThis;
5940
- globalState[COMPUTER_USE_HEALTH_MONITOR_STATE] ??= { monitors: /* @__PURE__ */ new WeakMap() };
5941
- return globalState[COMPUTER_USE_HEALTH_MONITOR_STATE];
5942
- }
6146
+ const getComputerUseHealthMonitorState = defineCodexBuildState("openclaw.codexComputerUseHealthMonitorState", () => ({ monitors: /* @__PURE__ */ new WeakMap() }));
5943
6147
  function startCodexComputerUseHealthMonitor(params) {
5944
6148
  const state = getComputerUseHealthMonitorState();
5945
6149
  const existing = state.monitors.get(params.client);
@@ -6516,7 +6720,7 @@ function shouldRetireCodexStartupClient(error, spawnedBy, signal) {
6516
6720
  //#region extensions/codex/src/app-server/run-attempt-start.ts
6517
6721
  async function startCodexAttemptRuntime(resources) {
6518
6722
  const { prompt, state, trajectoryRecorder, activateNativePreToolUseFailureFallback, releaseSandboxExecEnvironment, releaseSharedClientLeaseAndRetireOneShotClient, releaseCurrentRoute, runCleanupStep, startupTimeoutMs, buildNativeHookRelayFinalConfigPatch } = resources;
6519
- const { context, turnState, buildRenderedCodexDeveloperInstructions, rebuildCodexTurnPromptTextFromCurrentProjection, applyNoContextEngineContinuityProjection } = prompt;
6723
+ const { context, turnState, rebuildCodexTurnPromptTextFromCurrentProjection, applyNoContextEngineContinuityProjection } = prompt;
6520
6724
  const { runtime, attemptTools, promptState } = context;
6521
6725
  const { connection, runtimeParams, preparedAuthBinding, buildActiveRunAttemptParams, startupAuthAccountCacheKey, startupEnvApiKeyCacheKey, bundleMcpThreadConfig, nativeToolSurfaceEnabled, nativeProviderWebSearchSupport, effectiveRuntimeModelId, sandboxExecServerEnabled } = runtime;
6522
6726
  const { toolBridge, toolState } = attemptTools;
@@ -6634,7 +6838,7 @@ async function startCodexAttemptRuntime(resources) {
6634
6838
  clientId: state.client.getInstanceId()
6635
6839
  }
6636
6840
  });
6637
- if (applyNoContextEngineContinuityProjection(state.thread.lifecycle.action, state.thread)) await rebuildCodexTurnPromptTextFromCurrentProjection();
6841
+ if (await applyNoContextEngineContinuityProjection(state.thread.lifecycle.action, state.thread)) await rebuildCodexTurnPromptTextFromCurrentProjection();
6638
6842
  trajectoryRecorder?.recordEvent("session.started", {
6639
6843
  sessionFile: params.sessionFile,
6640
6844
  threadId: state.thread.threadId,
@@ -6642,13 +6846,6 @@ async function startCodexAttemptRuntime(resources) {
6642
6846
  workspaceDir: effectiveWorkspace,
6643
6847
  toolCount: flattenCodexDynamicToolFunctions(toolBridge.specs).length
6644
6848
  });
6645
- recordCodexTrajectoryContext(trajectoryRecorder, {
6646
- attempt: params,
6647
- cwd: effectiveCwd,
6648
- developerInstructions: joinPresentSections(buildRenderedCodexDeveloperInstructions(), attemptTools.configuredMcp?.diagnosticNotice),
6649
- prompt: turnState.codexTurnPromptText,
6650
- tools: toolBridge.availableSpecs
6651
- });
6652
6849
  connection.mutable.pluginAppServer = pluginAppServer;
6653
6850
  } catch (error) {
6654
6851
  await runCleanupStep("codex-start-failure-hook-fallback", activateNativePreToolUseFailureFallback);
@@ -6758,8 +6955,9 @@ async function prepareCodexAttemptTools(runtime) {
6758
6955
  pluginConfig,
6759
6956
  profilerEnabled,
6760
6957
  ...params.cronCreatorAuthorityUnavailableReason === "queued-local-operator" && bundleMcpThreadConfig.staticServerNames.length > 0 ? { cronCreatorAuthorityUnavailableReason: "queued-local-operator-configured-mcp" } : {},
6761
- onYieldDetected: (acknowledgment) => {
6958
+ onYieldDetected: (message, acknowledgment) => {
6762
6959
  toolState.yieldDetected = true;
6960
+ toolState.yieldMessage = message;
6763
6961
  toolState.yieldAcknowledgment = acknowledgment;
6764
6962
  },
6765
6963
  claimYieldCompletion: () => runtimeYieldCompletionClaim.current?.() ?? false,
@@ -6806,9 +7004,13 @@ async function prepareCodexAttemptTools(runtime) {
6806
7004
  releaseLeasedSharedCodexAppServerClient(client);
6807
7005
  }
6808
7006
  }
7007
+ let requireExplicitMessageTarget;
6809
7008
  const tools = await buildDynamicTools({
6810
7009
  ...commonToolParams,
6811
7010
  registerRunCleanup: (cleanup) => runCleanups.push(cleanup),
7011
+ onMessageToolTargetResolved: (required) => {
7012
+ requireExplicitMessageTarget = required;
7013
+ },
6812
7014
  cronCreatorToolAllowlistRef: cronCreatorToolAllowlist,
6813
7015
  cronCreatorToolAllowlistCaptureRef,
6814
7016
  onPersistentWebSearchPolicyResolved: (allowed) => {
@@ -6831,7 +7033,7 @@ async function prepareCodexAttemptTools(runtime) {
6831
7033
  sessionId: params.sessionId,
6832
7034
  runId: params.runId,
6833
7035
  agentId: policyAgentId,
6834
- agentDir: agentDir ?? resolveAgentDir$1(params.config ?? {}, sessionAgentId),
7036
+ agentDir: agentDir ?? resolveAgentDir$2(params.config ?? {}, sessionAgentId),
6835
7037
  agentAccountId: params.agentAccountId,
6836
7038
  messageProvider: params.messageProvider ?? params.messageChannel,
6837
7039
  messageChannel: params.messageChannel,
@@ -6981,7 +7183,7 @@ async function prepareCodexAttemptTools(runtime) {
6981
7183
  signal: runAbortController.signal,
6982
7184
  computerContextEpoch,
6983
7185
  loading: resolveCodexDynamicToolsLoadingForRuntime(pluginConfig, effectiveRuntimeModelId, { connectionClass: connection.appServer.connectionClass }),
6984
- directToolNames: resolveCodexDynamicToolDirectNames(params, isHostScopedAgentToolActive("openclaw")),
7186
+ directToolNames: resolveCodexDynamicToolDirectNames(params, registeredWithScopedMcp, isHostScopedAgentToolActive("openclaw")),
6985
7187
  hookContext
6986
7188
  });
6987
7189
  const captureCronCreatorToolAllowlist = async () => {
@@ -7046,6 +7248,7 @@ async function prepareCodexAttemptTools(runtime) {
7046
7248
  return {
7047
7249
  tools: toolsWithScopedMcp,
7048
7250
  registeredTools: registeredWithScopedMcp,
7251
+ requireExplicitMessageTarget,
7049
7252
  scopedMcpTools,
7050
7253
  configuredMcp,
7051
7254
  disposeMcpTools,
@@ -7148,12 +7351,23 @@ async function prepareCodexAttemptTurnRequest(resources, turnRuntime, ensureCurr
7148
7351
  error.name = "AbortError";
7149
7352
  throw error;
7150
7353
  };
7354
+ const prepareWorkspaceReferences = () => {
7355
+ const references = prepareCodexWorkspaceReferences(resourceState.client, resourceState.thread.threadId, workspaceBootstrapContext.promptContext);
7356
+ prompt.refreshWorkspaceReferences(references.include);
7357
+ return references;
7358
+ };
7151
7359
  const startCodexTurn = async () => {
7152
7360
  const activeTurnRoute = await ensureCurrentThreadRoute();
7153
7361
  assertCodexSessionRuntimeOwnership(resourceState.thread, params.expectedSessionRuntimeOwnership);
7154
7362
  const turnAppServer = withCodexAppServerFastModeServiceTier(connection.mutable.pluginAppServer, runtimeParams);
7155
7363
  connection.mutable.pluginAppServer = turnAppServer;
7156
- const turnStartParams = buildTurnStartParams(runtimeParams, {
7364
+ const references = prepareWorkspaceReferences();
7365
+ const referencesRetained = turnState.codexTurnPromptText.includes(workspaceBootstrapContext.promptContext ?? "");
7366
+ const inferenceRoute = usesSupervisionConnection ? void 0 : getCodexInferenceThread(resourceState.client, resourceState.thread.threadId);
7367
+ const turnStartParams = buildTurnStartParams({
7368
+ ...runtimeParams,
7369
+ images: [...prompt.contextImages, ...runtimeParams.images ?? []]
7370
+ }, {
7157
7371
  threadId: resourceState.thread.threadId,
7158
7372
  cwd: resourceState.codexExecutionCwd,
7159
7373
  appServer: turnAppServer,
@@ -7170,9 +7384,57 @@ async function prepareCodexAttemptTurnRequest(resources, turnRuntime, ensureCurr
7170
7384
  skillsCollaborationInstructions: context.skillsCollaborationInstructions,
7171
7385
  memoryCollaborationInstructions: workspaceBootstrapContext.memoryCollaborationInstructions,
7172
7386
  preserveNativeTurnSettings: usesSupervisionConnection,
7387
+ parentLocalEgress: inferenceRoute !== void 0,
7388
+ messageToolAvailable: toolBridge.availableTools.some((tool) => tool.name === "message"),
7389
+ requireExplicitMessageTarget: attemptTools.requireExplicitMessageTarget,
7173
7390
  sessionStatusAvailable: toolBridge.availableTools.some((tool) => tool.name === "session_status")
7174
7391
  });
7392
+ if (inferenceRoute) {
7393
+ prompt.setParentLocalEgress();
7394
+ resourceState.releaseInferenceContext?.();
7395
+ const inferenceThread = resourceState.thread;
7396
+ const registration = inferenceRoute.context.register({
7397
+ threadId: resourceState.thread.threadId,
7398
+ text: buildCodexParentLocalInstructions(runtimeParams, {
7399
+ turnScopedDeveloperInstructions: workspaceBootstrapContext.turnScopedDeveloperInstructions,
7400
+ skillsCollaborationInstructions: context.skillsCollaborationInstructions,
7401
+ memoryCollaborationInstructions: workspaceBootstrapContext.memoryCollaborationInstructions
7402
+ }) ?? "",
7403
+ signal: runAbortController.signal,
7404
+ assertCurrent: () => {
7405
+ params.hostCapabilities.assertActive();
7406
+ connection.assertCurrent();
7407
+ if (resourceState.thread !== inferenceThread || getCodexInferenceThread(resourceState.client, inferenceThread.threadId) !== inferenceRoute) throw new Error("Codex inference thread ownership changed");
7408
+ inferenceThread.liveThreadOwnership?.assertCurrent();
7409
+ }
7410
+ });
7411
+ resourceState.releaseInferenceContext = registration.release;
7412
+ turnStartParams.responsesapiClientMetadata = {
7413
+ ...turnStartParams.responsesapiClientMetadata,
7414
+ [CODEX_INFERENCE_GENERATION_KEY]: registration.generation
7415
+ };
7416
+ } else if (!usesSupervisionConnection) {
7417
+ embeddedAgentLog.warn("Codex parent-local egress workaround is unavailable for this connection or native network profile; legacy collaboration delivery is not guaranteed.");
7418
+ prompt.systemPromptReport.source = "estimate";
7419
+ prompt.systemPromptReport.injectedWorkspaceFiles = prompt.systemPromptReport.injectedWorkspaceFiles.map((file) => [
7420
+ "SOUL.MD",
7421
+ "IDENTITY.MD",
7422
+ "USER.MD"
7423
+ ].includes(file.name.toUpperCase()) ? {
7424
+ ...file,
7425
+ injectionStatus: "native_unverified",
7426
+ injectedChars: null,
7427
+ truncated: null
7428
+ } : file);
7429
+ }
7175
7430
  codexModelCallDiagnostics.setRequestPayloadBytes(utf8JsonByteLength(turnStartParams));
7431
+ recordCodexTrajectoryContext(resources.trajectoryRecorder, {
7432
+ attempt: params,
7433
+ cwd: connection.effectiveCwd,
7434
+ developerInstructions: joinPresentSections(buildRenderedCodexDeveloperInstructions(), attemptTools.configuredMcp?.diagnosticNotice),
7435
+ prompt: turnState.codexTurnPromptText,
7436
+ tools: toolBridge.availableSpecs
7437
+ });
7176
7438
  state.latestStartupErrorNotification = void 0;
7177
7439
  state.rateLimitsRevisionBeforeLastTurnStart = readCodexRateLimitsRevision(resourceState.client);
7178
7440
  activeTurnRoute.armTurn();
@@ -7196,6 +7458,7 @@ async function prepareCodexAttemptTurnRequest(resources, turnRuntime, ensureCurr
7196
7458
  }));
7197
7459
  acceptedTurnId = startedTurn.turn.id;
7198
7460
  connection.assertCurrent();
7461
+ if (referencesRetained) references.accepted();
7199
7462
  throwIfTurnStartAcceptedAfterAbort();
7200
7463
  return startedTurn;
7201
7464
  } catch (error) {
@@ -7224,6 +7487,7 @@ async function prepareCodexAttemptTurnRequest(resources, turnRuntime, ensureCurr
7224
7487
  if (await waitForActiveNativeTurnCompletion()) await resourceState.turnRoute?.drain();
7225
7488
  else if (!runAbortController.signal.aborted) embeddedAgentLog.warn("codex app-server active native turn did not complete before turn/start wait timed out", { threadId: resourceState.thread.threadId });
7226
7489
  }
7490
+ prepareWorkspaceReferences();
7227
7491
  const buildLlmInputEvent = () => ({
7228
7492
  runId: params.runId,
7229
7493
  sessionId: params.sessionId,
@@ -7232,7 +7496,7 @@ async function prepareCodexAttemptTurnRequest(resources, turnRuntime, ensureCurr
7232
7496
  systemPrompt: buildRenderedCodexDeveloperInstructions(),
7233
7497
  prompt: turnState.codexTurnPromptText,
7234
7498
  historyMessages: prompt.codexModelInputHistoryMessages,
7235
- imagesCount: params.images?.length ?? 0,
7499
+ imagesCount: prompt.contextImages.length + (params.images?.length ?? 0),
7236
7500
  tools
7237
7501
  });
7238
7502
  return {
@@ -7541,6 +7805,8 @@ function createCodexAttemptTurnState(resources) {
7541
7805
  terminalTurnNotificationQueued: false,
7542
7806
  sawCodexInterruptMarker: false,
7543
7807
  timeout: void 0,
7808
+ settlementWarning: void 0,
7809
+ pendingSettlementStage: void 0,
7544
7810
  clientClosedPromptError: void 0,
7545
7811
  clientClosedDiagnostic: void 0,
7546
7812
  clientClosedAbort: false,
@@ -7556,6 +7822,7 @@ function createCodexAttemptTurnState(resources) {
7556
7822
  currentTurnHadNonTerminalDynamicToolResult: false
7557
7823
  };
7558
7824
  const { promise: completion, resolve: resolveCompletion } = createDeferred();
7825
+ const settlementExpired = createDeferred();
7559
7826
  const pendingOpenClawDynamicToolCompletionIds = /* @__PURE__ */ new Set();
7560
7827
  const openClawDynamicToolExecutions = createCodexDynamicToolExecutionRegistry();
7561
7828
  const activeTurnItemIds = /* @__PURE__ */ new Set();
@@ -7616,13 +7883,32 @@ function createCodexAttemptTurnState(resources) {
7616
7883
  signal: runAbortController.signal,
7617
7884
  onDeadlineChanged: params.onAttemptDeadlineChanged,
7618
7885
  onTimeout: (timeout) => {
7886
+ const pendingStage = state.pendingSettlementStage ?? projectorRef.current?.settlement.pendingStage ?? "notification_queue";
7887
+ if (timeout.kind === "settlement" && projectorRef.current?.recoverCompletedAnswer()) {
7888
+ state.settlementWarning = {
7889
+ pendingStage,
7890
+ elapsedMs: timeout.elapsedMs,
7891
+ timeoutMs: timeout.timeoutMs
7892
+ };
7893
+ state.projectionClosed = true;
7894
+ trajectoryRecorder?.recordEvent("turn.settlement_warning", {
7895
+ threadId: resourceState.thread.threadId,
7896
+ turnId: turnIdRef.current,
7897
+ ...state.settlementWarning
7898
+ });
7899
+ embeddedAgentLog.warn("codex app-server retaining completed answer after settlement expiry", state.settlementWarning);
7900
+ completeTurn();
7901
+ settlementExpired.resolve();
7902
+ return;
7903
+ }
7619
7904
  state.timeout = timeout;
7620
7905
  projectorRef.current?.markTimedOut();
7621
7906
  const error = /* @__PURE__ */ new Error(timeout.kind === "execution" ? "codex app-server execution budget timed out" : "codex app-server terminal settlement timed out");
7622
7907
  const fields = {
7623
7908
  threadId: resourceState.thread.threadId,
7624
7909
  turnId: turnIdRef.current,
7625
- ...timeout
7910
+ ...timeout,
7911
+ pendingStage
7626
7912
  };
7627
7913
  trajectoryRecorder?.recordEvent(`turn.${timeout.kind}_timeout`, fields);
7628
7914
  embeddedAgentLog.warn(error.message, fields);
@@ -7633,6 +7919,7 @@ function createCodexAttemptTurnState(resources) {
7633
7919
  return {
7634
7920
  state,
7635
7921
  completion,
7922
+ settlementExpired: settlementExpired.promise,
7636
7923
  pendingOpenClawDynamicToolCompletionIds,
7637
7924
  openClawDynamicToolExecutions,
7638
7925
  activeTurnItemIds,