@openclaw/codex 2026.8.1-beta.3 → 2026.9.1-beta.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (54) hide show
  1. package/dist/api.js +3 -3
  2. package/dist/{attempt-client-cleanup-URjUlCHg.js → attempt-client-cleanup-bfsmcQ6m.js} +21 -2
  3. package/dist/{binding-connection-DAvZwp96.js → binding-connection-BMvPX73o.js} +2 -2
  4. package/dist/{bounded-turn-4BjrZEwW.js → bounded-turn-B7iBUcuP.js} +8 -8
  5. package/dist/{capabilities-CH3K57v4.js → capabilities-BRMh0aIq.js} +1 -1
  6. package/dist/cli-metadata.js +1 -1
  7. package/dist/{command-formatters-D0nZ3qtd.js → command-formatters-DEsIufkt.js} +2 -2
  8. package/dist/{command-handlers-DC86lgT4.js → command-handlers-D_-1_qRp.js} +43 -32
  9. package/dist/{command-rpc-xUIIonsO.js → command-rpc-CCeCkf_v.js} +4 -4
  10. package/dist/{compact-COqgBRny.js → compact-BglNFZrQ.js} +8 -8
  11. package/dist/{config-CpNeo5AE.js → config-giW8X0QA.js} +82 -28
  12. package/dist/doctor-contract-api.js +9 -8
  13. package/dist/{dynamic-tools-fJZhl4CE.js → dynamic-tools-Dnlfa--w.js} +108 -820
  14. package/dist/{effective-mcp-catalog-4YKn51aG.js → effective-mcp-catalog-CTeGrnfO.js} +2 -2
  15. package/dist/{event-projector-assistant-message-BwxV4d6N.js → event-projector-assistant-message-C5-Ds8mA.js} +18 -1
  16. package/dist/{event-projector-usage-CLwNEJqW.js → event-projector-usage-Bk1I90Bg.js} +3 -3
  17. package/dist/{harness-DoKQcF8n.js → harness-Csz0F-DK.js} +11 -11
  18. package/dist/harness.js +1 -1
  19. package/dist/index.js +130 -172
  20. package/dist/{isolated-completion-DPMtlH9r.js → isolated-completion-Cv6FqygM.js} +4 -4
  21. package/dist/{managed-binary-By4FZC6i.js → managed-binary-DFYK4DWq.js} +43 -7
  22. package/dist/media-understanding-provider.js +1 -1
  23. package/dist/{model-catalog-CmGoqVKB.js → model-catalog-i9rNBthX.js} +4 -4
  24. package/dist/{models-CZw1wClT.js → models-TS3HBU-q.js} +4 -3
  25. package/dist/{native-subagent-monitor-GGq3RnOo.js → native-subagent-monitor-4Mfq2HDs.js} +176 -19
  26. package/dist/{node-exec-server.runtime-Bsu1LdFZ.js → node-exec-server.runtime-BpWqJO1V.js} +2 -2
  27. package/dist/{plugin-app-cache-key-DMNQ8Zi8.js → plugin-app-cache-key-C1CAdfcP.js} +6 -3
  28. package/dist/{plugin-approval-roundtrip-C75Yiiwc.js → plugin-approval-roundtrip-bUm777tR.js} +1 -1
  29. package/dist/{plugin-marketplace-discovery-CSWDkMrP.js → plugin-marketplace-discovery-B9DvaAG-.js} +29 -38
  30. package/dist/{plugin-metadata-cache-BXH5NF-4.js → plugin-metadata-cache-CTCT3w5L.js} +162 -135
  31. package/dist/{protocol-validators-VAVyEnDp.js → protocol-validators-VeJxxJ0U.js} +25 -3
  32. package/dist/{rate-limits-BI1dMHDG.js → rate-limits-C5_D8Gmb.js} +1 -1
  33. package/dist/{request-DSK0W6YI.js → request-DXXGHko0.js} +2 -2
  34. package/dist/{run-attempt-BV3HzuCf.js → run-attempt-DYc0QCBF.js} +346 -267
  35. package/dist/{sandbox-guard-C1qEeZ5C.js → sandbox-guard-kuWTn9C5.js} +1 -1
  36. package/dist/{session-binding-BTrLf9Qm.js → session-binding-Bcynfd-_.js} +1 -1
  37. package/dist/{session-catalog-ezP_UcRM.js → session-catalog-DaLKVtpH.js} +17 -16
  38. package/dist/{session-cli-B1hKvfkI.js → session-cli-DMc4oS2w.js} +1 -1
  39. package/dist/session-permission-policy-BrNH1bjy.js +160 -0
  40. package/dist/{session-retirement-CE4iMiLh.js → session-retirement-CcNC3YSY.js} +3 -3
  41. package/dist/{session-upstream-marker-D_2npHlA.js → session-upstream-marker-BIkusb95.js} +1 -1
  42. package/dist/{settled-turn-finalizer-Dx1onIqg.js → settled-turn-finalizer-Dc3ApjU4.js} +4 -4
  43. package/dist/{shared-client-Dw-rzii0.js → shared-client-DKz23hHY.js} +1026 -248
  44. package/dist/{side-question-DbXkJZzg.js → side-question-DjA_jsNe.js} +65 -36
  45. package/dist/{thread-lifecycle-DKdrnTMX.js → thread-lifecycle-L7oEkTlq.js} +850 -35
  46. package/dist/{thread-ownership-i2NBwDUL.js → thread-ownership-DZeuKH1j.js} +2 -2
  47. package/dist/{thread-resume-CdJk2Ehf.js → thread-resume-BE9qNEW0.js} +3 -3
  48. package/dist/{transcript-mirror-BU0_LKAL.js → transcript-mirror-DsCMWBca.js} +91 -10
  49. package/dist/{upstream-session-fork-BDVJCLAD.js → upstream-session-fork-DlaHxSLC.js} +3 -3
  50. package/dist/{usage-9dKJCgcy.js → usage-ROIaW3wo.js} +3 -3
  51. package/dist/{web-search-provider.runtime-DCdx4DGu.js → web-search-provider.runtime-ClaNPV7N.js} +3 -3
  52. package/openclaw.plugin.json +18 -1
  53. package/package.json +8 -8
  54. package/dist/app-server-policy-bg5QPSVP.js +0 -25
@@ -1,41 +1,42 @@
1
- import { A as resolveOpenClawExecPolicyForCodexAppServer, C as parseAllowedApprovalPoliciesFromCodexRequirements, D as selectGuardianApprovalPolicy, E as readCodexRequirementsToml, O as selectGuardianApprovalsReviewer, S as resolveCodexModelBackedReviewerPolicyContext, T as parseAllowedSandboxModesFromCodexRequirements, b as canUseCodexModelBackedApprovalsReviewerForModel, d as withMcpElicitationsApprovalPolicy, f as isCodexPairedNodeRemoteExecPlacementSandbox, g as resolveCodexPluginsPolicy, h as readCodexPluginConfig, j as selectGuardianSandbox, k as selectUserApprovalsReviewer, l as resolveCodexAppServerNetworkProxy, m as isCodexSandboxExecServerEnabled, o as resolveCodexComputerUseConfig, p as isCodexRemoteExecPlacementSandbox, r as resolveCodexAppServerHomeScope, u as shouldAutoApproveCodexAppServerApprovals, w as parseAllowedApprovalsReviewersFromCodexRequirements } from "./config-CpNeo5AE.js";
2
- import { $ as rememberCodexRateLimitsRead, A as isCodexAppServerApprovalRequest, B as CodexAppServerRpcError, C as resolveCodexPostToolRawAssistantCompletionIdleTimeoutMs, D as resolveCodexTurnTerminalIdleTimeoutMs, E as resolveCodexTurnCompletionIdleTimeoutMs, I as isCodexAppServerRequestTimeoutError, M as isCodexAppServerConnectionClosedError, N as isCodexAppServerIndeterminateRequestCancellationError, O as withCodexStartupTimeout, P as isCodexAppServerIndeterminateTransportError, Q as readRecentCodexRateLimits, R as resolveCodexAppServerClientInstanceId, T as resolveCodexTurnAssistantCompletionIdleTimeoutMs, V as createCodexElicitationResponse, W as ensureCodexAppServerClientRuntime, Y as retainCodexAppServerLiveThread, Z as readCodexRateLimitsRevision, a as getLeasedSharedCodexAppServerClient, at as resolveCodexAppServerPreparedAuthHandoff, b as CodexAppServerStartupError, et as resolveCodexAppServerAuthAccountCacheKey, f as retainSharedCodexAppServerClientIfCurrent, ft as resolveCodexAppServerHomeDir, g as withAbortableTimeout, i as createIsolatedCodexAppServerClient, it as resolveCodexAppServerPreparedApiKeyCacheKey, j as isCodexAppServerBrokenPipeError, k as getCodexAppServerClientInstanceId, l as releaseLeasedSharedCodexAppServerClient, lt as flattenCodexDynamicToolFunctions, n as clearSharedCodexAppServerClientIfCurrentAndUnclaimed, nt as resolveCodexAppServerAuthProfileIdForAgent, o as getSharedCodexAppServerClient, p as retireSharedCodexAppServerClientIfCurrent, q as protectCodexAppServerLiveThread, rt as resolveCodexAppServerFallbackApiKeyCacheKey, s as isCodexAppServerStartSelectionChangedError, t as clearSharedCodexAppServerClientIfCurrent, tt as resolveCodexAppServerAuthProfileId, ut as isJsonObject, w as resolveCodexStartupTimeoutMs, x as isCodexAppServerStartupError, y as CODEX_POST_REASONING_REPLY_IDLE_TIMEOUT_MS } from "./shared-client-Dw-rzii0.js";
3
- import { c as reclaimCurrentCodexSessionGeneration, d as sessionBindingIdentity, i as createCodexSessionGenerationSupersededError, l as resolveCodexRunSessionBindingAuthority, u as scopeCodexRunBindingStore } from "./session-binding-BTrLf9Qm.js";
4
- import { A as shouldSynthesizeToolProgressForItem, B as readNullableString, E as itemStatus, F as readItem, I as readItemString, N as readCodexErrorNotificationMessage, O as shouldClearTerminalPresentationForNativeItem, T as itemName, V as splitPlanText, a as closeCodexStartupClientBestEffort, d as unsubscribeCodexThreadBestEffort, f as CODEX_APP_SERVER_NATIVE_TURN_WAIT_TIMEOUT_MS, g as readCodexNotificationThreadId, h as isCodexNotificationForTurn, j as extractRawAssistantText, l as retireCodexAppServerClientAfterTimedOutTurn, m as CodexProjectionDiagnostics, o as interruptCodexTurnAndWaitBestEffort, p as getCodexAppServerTurnRouter, r as CodexAppServerUnsafeSubscriptionError, t as CODEX_APP_SERVER_INTERRUPT_TIMEOUT_MS, u as retireUnsafeCodexTurnClientBestEffort, z as readNonNegativeInteger } from "./attempt-client-cleanup-URjUlCHg.js";
5
- import { C as readRawResponseToolCallId, E as updateActiveTurnItemIds, S as readNotificationItemId, T as updateActiveCompletionBlockerItemIds, _ as isReasoningItemCompletionNotification, a as codexExecutionToolName, b as isTerminalTurnStatus, c as isAssistantCompletionReleaseNotification, d as isNativeToolProgressNotification, f as isPendingOpenClawDynamicToolCompletionNotification, g as isRawToolOutputCompletionNotification, h as isRawReasoningCompletionNotification, l as isCodexTurnAbortMarkerNotification, m as isRawFunctionToolOutputCompletionNotification, o as describeNotificationActivity, p as isRawAssistantProgressNotification, r as projectCodexThreadUsageUpdate, s as isAssistantCommentaryCompletionNotification, t as CodexResponseCompletionProjection, u as isFileChangePatchUpdatedNotification, v as isReasoningProgressNotification, w as shouldDisarmAssistantCompletionIdleWatch, x as readCodexNotificationItem, y as isRetryableErrorNotification } from "./event-projector-usage-CLwNEJqW.js";
6
- import { l as readCodexTurn, o as assertCodexTurnStartResponse, s as readCodexDynamicToolCallParams, u as readCodexTurnCompletedNotification } from "./protocol-validators-VAVyEnDp.js";
7
- import { n as buildCodexAppServerRuntimeFingerprint, o as defaultCodexAppInventoryCache, r as buildCodexPluginAppCacheKey } from "./plugin-app-cache-key-DMNQ8Zi8.js";
8
- import { B as neutralizeCodexExplicitMentionSigils, D as codexLegacyDynamicToolsFingerprint, E as codexDynamicToolsFingerprint, F as resolveCodexDynamicToolsLoadingForRuntime, G as buildCodexPluginAppsConfigPatchFromPolicyContext, H as resolveCodexContextEngineProjectionMaxChars, I as buildContextEngineBinding, J as buildCodexPluginThreadConfigTimeoutFallback, K as buildCodexPluginThreadConfig, L as isContextEngineBindingCompatible, M as isSystemAgentOnlyCodexDynamicToolAllowlist, O as filterCodexDynamicTools, Q as shouldBuildCodexPluginThreadConfig, R as buildCodexContinuityCalibration, T as areCodexDynamicToolFingerprintsCompatible, U as resolveCodexContextEngineProjectionReserveTokens, V as projectContextEngineAssemblyForCodex, W as resolveCodexContinuityProjectionMaxChars, X as buildPluginAppPolicyContext, Z as mergeCodexThreadConfigs, a as isCodexAppServerProfilerEnabled, f as resolveCodexWebSearchPlan, i as startOrResumeThread, it as resolveRecoverableCodexPluginConfigKeys, j as isMessageOnlyCodexSourceReply, n as buildTurnStartParams, p as buildDeveloperInstructions, q as buildCodexPluginThreadConfigInputFingerprint, r as buildCodexUserInput, t as buildTurnCollaborationMode, v as resolveCodexAppServerThreadModelSelection, z as fitCodexProjectedContextForTurnStart } from "./thread-lifecycle-DKdrnTMX.js";
1
+ import { C as resolveCodexModelBackedReviewerPolicyContext, D as readCodexRequirementsToml, d as withMcpElicitationsApprovalPolicy, f as isCodexPairedNodeRemoteExecPlacementSandbox, g as resolveCodexPluginsPolicy, h as readCodexPluginConfig, j as resolveOpenClawExecPolicyForCodexAppServer, m as isCodexSandboxExecServerEnabled, o as resolveCodexComputerUseConfig, p as isCodexRemoteExecPlacementSandbox, r as resolveCodexAppServerHomeScope, u as shouldAutoApproveCodexAppServerApprovals, x as canUseCodexModelBackedApprovalsReviewerForModel } from "./config-giW8X0QA.js";
2
+ import { A as resolveCodexTurnAssistantCompletionIdleTimeoutMs, E as isCodexAppServerStartupError, F as isCodexAppServerApprovalRequest, G as CodexAppServerRpcError, I as isCodexAppServerBrokenPipeError, K as createCodexElicitationResponse, L as isCodexAppServerConnectionClosedError, M as resolveCodexTurnTerminalIdleTimeoutMs, N as withCodexStartupTimeout, O as resolveCodexPostToolRawAssistantCompletionIdleTimeoutMs, P as getCodexAppServerClientInstanceId, Q as protectCodexAppServerLiveThread, R as isCodexAppServerIndeterminateRequestCancellationError, T as CodexAppServerStartupError, U as resolveCodexAppServerClientInstanceId, V as isCodexAppServerRequestTimeoutError, Y as ensureCodexAppServerClientRuntime, _ as retireSharedCodexAppServerClientIfCurrent, _t as flattenCodexDynamicToolFunctions, a as createIsolatedCodexAppServerClient, at as readRecentCodexRateLimits, c as isCodexAppServerStartSelectionChangedError, ct as resolveCodexAppServerAuthAccountCacheKey, dt as resolveCodexAppServerFallbackApiKeyCacheKey, et as retainCodexAppServerLiveThread, ft as resolveCodexAppServerPreparedApiKeyCacheKey, g as retainSharedCodexAppServerClientIfCurrent, it as readCodexRateLimitsRevision, j as resolveCodexTurnCompletionIdleTimeoutMs, k as resolveCodexStartupTimeoutMs, lt as resolveCodexAppServerAuthProfileId, n as clearSharedCodexAppServerClientIfCurrent, nt as withAbortableTimeout, o as getLeasedSharedCodexAppServerClient, ot as rememberCodexRateLimitsRead, p as releaseLeasedSharedCodexAppServerClient, pt as resolveCodexAppServerPreparedAuthHandoff, r as clearSharedCodexAppServerClientIfCurrentAndUnclaimed, s as getSharedCodexAppServerClient, u as readCodexAppServerClientDesktopGenerationFingerprint, ut as resolveCodexAppServerAuthProfileIdForAgent, vt as isJsonObject, w as CODEX_POST_REASONING_REPLY_IDLE_TIMEOUT_MS, xt as resolveCodexAppServerHomeDir, z as isCodexAppServerIndeterminateTransportError } from "./shared-client-DKz23hHY.js";
3
+ import { c as reclaimCurrentCodexSessionGeneration, d as sessionBindingIdentity, i as createCodexSessionGenerationSupersededError, l as resolveCodexRunSessionBindingAuthority, u as scopeCodexRunBindingStore } from "./session-binding-Bcynfd-_.js";
4
+ import { A as shouldSynthesizeToolProgressForItem, B as readNullableString, E as itemStatus, F as readItem, I as readItemString, N as readCodexErrorNotificationMessage, O as shouldClearTerminalPresentationForNativeItem, T as itemName, V as splitPlanText, a as closeCodexStartupClientBestEffort, d as unsubscribeCodexThreadBestEffort, f as CODEX_APP_SERVER_NATIVE_TURN_WAIT_TIMEOUT_MS, g as readCodexNotificationThreadId, h as isCodexNotificationForTurn, j as extractRawAssistantText, l as retireCodexAppServerClientAfterTimedOutTurn, m as CodexProjectionDiagnostics, o as interruptCodexTurnAndWaitBestEffort, p as getCodexAppServerTurnRouter, r as CodexAppServerUnsafeSubscriptionError, t as CODEX_APP_SERVER_INTERRUPT_TIMEOUT_MS, u as retireUnsafeCodexTurnClientBestEffort, z as readNonNegativeInteger } from "./attempt-client-cleanup-bfsmcQ6m.js";
5
+ import { C as readRawResponseToolCallId, E as updateActiveTurnItemIds, S as readNotificationItemId, T as updateActiveCompletionBlockerItemIds, _ as isReasoningItemCompletionNotification, a as codexExecutionToolName, b as isTerminalTurnStatus, c as isAssistantCompletionReleaseNotification, d as isNativeToolProgressNotification, f as isPendingOpenClawDynamicToolCompletionNotification, g as isRawToolOutputCompletionNotification, h as isRawReasoningCompletionNotification, l as isCodexTurnAbortMarkerNotification, m as isRawFunctionToolOutputCompletionNotification, o as describeNotificationActivity, p as isRawAssistantProgressNotification, r as projectCodexThreadUsageUpdate, s as isAssistantCommentaryCompletionNotification, t as CodexResponseCompletionProjection, u as isFileChangePatchUpdatedNotification, v as isReasoningProgressNotification, w as shouldDisarmAssistantCompletionIdleWatch, x as readCodexNotificationItem, y as isRetryableErrorNotification } from "./event-projector-usage-Bk1I90Bg.js";
6
+ import { l as readCodexTurn, o as assertCodexTurnStartResponse, s as readCodexDynamicToolCallParams, u as readCodexTurnCompletedNotification } from "./protocol-validators-VeJxxJ0U.js";
7
+ import { n as buildCodexAppServerRuntimeFingerprint, o as defaultCodexAppInventoryCache, r as buildCodexPluginAppCacheKey } from "./plugin-app-cache-key-C1CAdfcP.js";
8
+ import { C as toCodexDynamicToolProgressResponse, Dt as resolveRecoverableCodexPluginConfigKeys, F as resolveCodexWebSearchPlan, I as buildDeveloperInstructions, J as areCodexDynamicToolFingerprintsCompatible, S as shouldReleaseTurnAfterTerminalDynamicTool, T as resolveCodexToolAbortTerminalReason, V as resolveCodexAppServerThreadModelSelection, X as codexLegacyDynamicToolsFingerprint, Y as codexDynamicToolsFingerprint, Z as filterCodexDynamicTools, _ as isDynamicToolTerminalDiagnosticEvent, _t as buildCodexPluginThreadConfigTimeoutFallback, a as isCodexAppServerProfilerEnabled, at as buildContextEngineBinding, b as resolveTerminalDynamicToolBatchAction, bt as mergeCodexThreadConfigs, c as buildCodexNativeHookRelayConfig, ct as fitCodexProjectedContextForTurnStart, d as emitCodexNativePreToolUseFailureDiagnostic, dt as resolveCodexContextEngineProjectionMaxChars, et as isMessageOnlyCodexSourceReply, f as resolveCodexNativeHookRelayEvents, ft as resolveCodexContextEngineProjectionReserveTokens, g as hasPendingDynamicToolTerminalDiagnostic, gt as buildCodexPluginThreadConfigInputFingerprint, h as handleDynamicToolCallWithTimeout, ht as buildCodexPluginThreadConfig, i as startOrResumeThread, it as resolveCodexDynamicToolsLoadingForRuntime, l as buildCodexNativeHookRelayDisabledConfig, lt as neutralizeCodexExplicitMentionSigils, m as scheduleCodexNativeHookRelayUnregister, mt as buildCodexPluginAppsConfigPatchFromPolicyContext, n as buildTurnStartParams, ot as isContextEngineBindingCompatible, p as resolveCodexNativeHookRelayTtlMs, pt as resolveCodexContinuityProjectionMaxChars, r as buildCodexUserInput, s as CODEX_NATIVE_HOOK_RELAY_TTL_GRACE_MS, st as buildCodexContinuityCalibration, t as buildTurnCollaborationMode, tt as isSystemAgentOnlyCodexDynamicToolAllowlist, u as createCodexNativeHookRelay, ut as projectContextEngineAssemblyForCodex, v as isMatchingDynamicToolTerminalDiagnostic, w as toCodexDynamicToolProtocolResponse, x as shouldBlockTerminalReleaseForNonTerminalDynamicToolResult, xt as shouldBuildCodexPluginThreadConfig, y as resolveDynamicToolCallTimeoutMs, yt as buildPluginAppPolicyContext } from "./thread-lifecycle-L7oEkTlq.js";
9
9
  import { t as isIncognitoSessionKey } from "./incognito-session-ET_ufDH-.js";
10
10
  import { i as readUpstreamUserText, n as attachUpstreamUserText, r as readMirrorIdentity, t as attachCodexMirrorIdentity } from "./upstream-prompt-provenance-CFmsKwr9.js";
11
- import { a as buildCodexUserPromptMessage, c as readCodexMirrorSourceFingerprint, i as mirrorPromptAtTurnStartBestEffort, l as serializeCodexMirrorSourceEvidence, n as createCodexAppServerUserMessagePersistenceNotifier, o as promptSnapshot, t as codexTranscriptMirrorRuntime } from "./transcript-mirror-BU0_LKAL.js";
12
- import { t as CODEX_CONTROL_METHODS } from "./capabilities-CH3K57v4.js";
13
- import { a as shouldRefreshCodexRateLimitsForUsageLimitMessage, i as resolveCodexUsageLimitResetAtMs, n as formatCodexUsageLimitErrorMessage } from "./rate-limits-BI1dMHDG.js";
14
- import { r as formatCodexDisplayText } from "./command-formatters-D0nZ3qtd.js";
15
- import { t as resolveCodexAppServerForModelProvider } from "./app-server-policy-bg5QPSVP.js";
16
- import { n as resolveCodexBindingAppServerConnection } from "./binding-connection-DAvZwp96.js";
11
+ import { a as buildCodexUserPromptMessage, c as readCodexMirrorSourceFingerprint, i as mirrorPromptAtTurnStartBestEffort, l as serializeCodexMirrorSourceEvidence, n as createCodexAppServerUserMessagePersistenceNotifier, o as promptSnapshot, t as codexTranscriptMirrorRuntime } from "./transcript-mirror-DsCMWBca.js";
12
+ import { t as CODEX_CONTROL_METHODS } from "./capabilities-BRMh0aIq.js";
13
+ import { a as shouldRefreshCodexRateLimitsForUsageLimitMessage, i as resolveCodexUsageLimitResetAtMs, n as formatCodexUsageLimitErrorMessage } from "./rate-limits-C5_D8Gmb.js";
14
+ import { r as formatCodexDisplayText } from "./command-formatters-DEsIufkt.js";
15
+ import { a as resolveCodexAppServerForModelProvider, i as resolveCodexSessionPermissionCwd, n as applyCodexSessionPermissionPolicy, r as resolveCodexEffectiveSessionPermissionPolicy } from "./session-permission-policy-BrNH1bjy.js";
16
+ import { n as resolveCodexBindingAppServerConnection } from "./binding-connection-BMvPX73o.js";
17
17
  import { n as prepareCodexAppServerAuthBinding } from "./auth-binding-B4FfbcCg.js";
18
18
  import { t as persistCodexContextCompactionActivity } from "./context-compaction-activity-BOeJf7yo.js";
19
- import { n as createAssistantMessage, r as createAssistantMirrorMessage, t as createAssistantCommentaryMessage } from "./event-projector-assistant-message-BwxV4d6N.js";
20
- import { a as CodexToolProgressProjection, c as isCodexCommandBearingToolCall, d as sanitizeCodexToolResponse, i as readCodexMirroredSessionHistoryMessages, l as resolveCodexToolProgressDetailMode, n as CodexEventProjection, o as shouldEmitTranscriptToolProgress, r as CodexToolTranscriptProjection, s as inferCodexDynamicToolMeta, t as codexNativeSubagentMonitorRuntime, u as sanitizeCodexToolArguments } from "./native-subagent-monitor-GGq3RnOo.js";
21
- import { A as buildCodexNativeHookRelayConfig, B as isMatchingDynamicToolTerminalDiagnostic, C as shouldRequireCodexSandboxExecServerEnvironment, D as CodexNativeToolLifecycleProjector, E as readBoundedCodexRemoteWorkspaceFile, F as resolveCodexNativeHookRelayTtlMs, G as toCodexDynamicToolProgressResponse, H as resolveTerminalDynamicToolBatchAction, I as scheduleCodexNativeHookRelayUnregister, K as toCodexDynamicToolProtocolResponse, L as handleDynamicToolCallWithTimeout, M as createCodexNativeHookRelay, N as emitCodexNativePreToolUseFailureDiagnostic, P as resolveCodexNativeHookRelayEvents, R as hasPendingDynamicToolTerminalDiagnostic, S as shouldEnableCodexAppServerNativeToolSurface, U as shouldBlockTerminalReleaseForNonTerminalDynamicToolResult, V as resolveDynamicToolCallTimeoutMs, W as shouldReleaseTurnAfterTerminalDynamicTool, _ as resolveCodexAppServerHookChannelId, a as emitDynamicToolStartedDiagnostic, c as resolveCodexProviderWebSearchSupport, d as releaseCodexSandboxExecServerEnvironment, f as buildDynamicTools, g as resolveCodexAppServerExecutionCwd, h as formatCodexDynamicToolBuildStageSummary, i as emitDynamicToolErrorDiagnostic, j as buildCodexNativeHookRelayDisabledConfig, k as CODEX_NATIVE_HOOK_RELAY_TTL_GRACE_MS, m as disableCodexPluginThreadConfig, n as projectCodexExecutableDynamicTools, o as emitDynamicToolTerminalDiagnostic, p as createCodexDynamicToolBuildStageTracker, q as resolveCodexToolAbortTerminalReason, r as routeCodexAppServerElicitationRequest, s as handleCodexAppServerApprovalRequest, t as createCodexDynamicToolBridge, u as ensureCodexSandboxExecServerEnvironment, v as resolveCodexExternalSandboxPolicyForOpenClawSandbox, w as shouldWarnCodexDynamicToolBuildStageSummary, x as resolveCodexSandboxEnvironmentSelection, y as resolveCodexMessageToolProvider, z as isDynamicToolTerminalDiagnosticEvent } from "./dynamic-tools-fJZhl4CE.js";
22
- import { a as runCodexComputerUseLiveTest, n as ensureCodexComputerUse, o as killStaleComputerUseMcpChildren, t as defaultCodexPluginMetadataCache } from "./plugin-metadata-cache-BXH5NF-4.js";
19
+ import { i as createAssistantMirrorMessage, n as createAssistantCommentaryMessage, r as createAssistantMessage, t as createAssistantAsyncMessage } from "./event-projector-assistant-message-C5-Ds8mA.js";
20
+ import { a as readCodexMirroredSessionHistoryMessages, c as inferCodexDynamicToolMeta, d as sanitizeCodexToolArguments, f as sanitizeCodexToolResponse, i as CodexToolTranscriptProjection, l as isCodexCommandBearingToolCall, n as CodexEventProjection, o as CodexToolProgressProjection, r as emitCodexAgentEvent, s as shouldEmitTranscriptToolProgress, t as codexNativeSubagentMonitorRuntime, u as resolveCodexToolProgressDetailMode } from "./native-subagent-monitor-4Mfq2HDs.js";
21
+ import { C as shouldRequireCodexSandboxExecServerEnvironment, D as CodexNativeToolLifecycleProjector, E as readBoundedCodexRemoteWorkspaceFile, S as shouldEnableCodexAppServerNativeToolSurface, _ as resolveCodexAppServerHookChannelId, a as emitDynamicToolStartedDiagnostic, c as resolveCodexProviderWebSearchSupport, d as releaseCodexSandboxExecServerEnvironment, f as buildDynamicTools, g as resolveCodexAppServerExecutionCwd, h as formatCodexDynamicToolBuildStageSummary, i as emitDynamicToolErrorDiagnostic, m as disableCodexPluginThreadConfig, n as projectCodexExecutableDynamicTools, o as emitDynamicToolTerminalDiagnostic, p as createCodexDynamicToolBuildStageTracker, r as routeCodexAppServerElicitationRequest, s as handleCodexAppServerApprovalRequest, t as createCodexDynamicToolBridge, u as ensureCodexSandboxExecServerEnvironment, v as resolveCodexExternalSandboxPolicyForOpenClawSandbox, w as shouldWarnCodexDynamicToolBuildStageSummary, x as resolveCodexSandboxEnvironmentSelection, y as resolveCodexMessageToolProvider } from "./dynamic-tools-Dnlfa--w.js";
22
+ import { a as runCodexComputerUseLiveTest, n as ensureCodexComputerUse, t as defaultCodexPluginMetadataCache } from "./plugin-metadata-cache-CTCT3w5L.js";
23
23
  import { asBoolean, asFiniteNumber, asOptionalRecord, hasNonEmptyString, normalizeOptionalString, readNonBlankString, readStringField } from "openclaw/plugin-sdk/string-coerce-runtime";
24
24
  import fs from "node:fs/promises";
25
25
  import path from "node:path";
26
26
  import { createDeferred } from "openclaw/plugin-sdk/extension-shared";
27
27
  import { asDateTimestampMs, resolveTimerTimeoutMs } from "openclaw/plugin-sdk/number-runtime";
28
- import { AgentHarnessPreflightError, CODEX_APP_SERVER_CONTEXT_ENGINE_HOST, FAST_MODE_AUTO_PROGRESS_KIND, agentHarnessAttemptTerminal, agentHarnessStructuredInput, assembleHarnessContextEngine, assertContextEngineHostSupport, awaitAgentEndSideEffects, bootstrapHarnessContextEngine, buildBootstrapContextForFiles, buildHarnessContextEngineRuntimeContext, buildWatchedSessionsHarnessContext, callGatewayTool, cancelPendingAgentQuestionForSession, claimPendingAgentQuestionAnswer, classifyAgentHarnessTerminalOutcome, clearActiveEmbeddedRun, embeddedAgentLog, emitAgentEvent, emptyAgentHarnessUserInputAnswers, formatErrorMessage, formatFastModeAutoProgressText, getAgentHarnessHookRunner, isActiveHarnessContextEngine, isHostScopedAgentToolActive, loadCodexBundleMcpThreadConfig, materializeRequesterScopedMcpToolsForHarnessRun, prepareHarnessNativeMcpAppPreview, projectAgentHarnessTranscriptMessageForDisplay, resolveAgentDir, resolveAgentHarnessBeforePromptBuildResult, resolveAgentRunAbortLifecycleFields, resolveBootstrapFilesForRun, resolveContextEngineOwnerPluginId, resolveFastModeForElapsed, resolveSandboxContext, resolveSessionAgentIds, resolveUserPath, runAgentCleanupStep, runAgentEndSideEffects, runAgentHarnessAfterCompactionHook, runAgentHarnessBeforeCompactionHook, runAgentHarnessLlmInputHook, runAgentHarnessLlmOutputHook, runHarnessContextEngineMaintenance, setActiveEmbeddedRun, supportsModelTools } from "openclaw/plugin-sdk/agent-harness-runtime";
28
+ import { AgentHarnessPreflightError, CODEX_APP_SERVER_CONTEXT_ENGINE_HOST, FAST_MODE_AUTO_PROGRESS_KIND, agentHarnessAttemptTerminal, agentHarnessStructuredInput, assembleHarnessContextEngine, assertContextEngineHostSupport, awaitAgentEndSideEffects, bootstrapHarnessContextEngine, buildBootstrapContextForFiles, buildEmbeddedForegroundPromptContext, buildHarnessContextEngineRuntimeContext, buildWatchedSessionsHarnessContext, callGatewayTool, cancelPendingAgentQuestionForSession, claimPendingAgentQuestionAnswer, classifyAgentHarnessTerminalOutcome, clearActiveEmbeddedRun, embeddedAgentLog, emitAgentEvent, emptyAgentHarnessUserInputAnswers, formatErrorMessage, formatFastModeAutoProgressText, getAgentHarnessHookRunner, hasBeforeToolCallPolicy, isActiveHarnessContextEngine, isHostScopedAgentToolActive, loadCodexBundleMcpThreadConfig, materializeRequesterScopedMcpToolsForHarnessRun, prepareHarnessNativeMcpAppPreview, projectAgentHarnessTranscriptMessageForDisplay, resolveAgentDir, resolveAgentHarnessBeforePromptBuildResult, resolveAgentRunAbortLifecycleFields, resolveBootstrapFilesForRun, resolveContextEngineOwnerPluginId, resolveFastModeForElapsed, resolveSandboxContext, resolveSessionAgentIds, resolveUserPath, runAgentCleanupStep, runAgentEndSideEffects, runAgentHarnessAfterCompactionHook, runAgentHarnessBeforeCompactionHook, runAgentHarnessLlmInputHook, runAgentHarnessLlmOutputHook, runHarnessContextEngineMaintenance, setActiveEmbeddedRun, supportsModelTools } from "openclaw/plugin-sdk/agent-harness-runtime";
29
29
  import crypto, { createHash } from "node:crypto";
30
- import { hostname } from "node:os";
31
30
  import { markAuthProfileBlockedUntil, resolveAgentDir as resolveAgentDir$1, resolveAgentWorkspaceDir } from "openclaw/plugin-sdk/agent-runtime";
31
+ import { resolveAgentConfig as resolveAgentConfig$1 } from "openclaw/plugin-sdk/agent-scope-runtime";
32
32
  import { loadExecApprovals } from "openclaw/plugin-sdk/exec-approvals-runtime";
33
33
  import { parseSqliteSessionFileMarker } from "openclaw/plugin-sdk/session-store-runtime";
34
34
  import { truncateUtf16Safe, truncateUtf8Prefix } from "openclaw/plugin-sdk/text-utility-runtime";
35
- import { isPathInside, isPathStrictlyInside, root } from "openclaw/plugin-sdk/file-access-runtime";
35
+ import { isPathStrictlyInside, root } from "openclaw/plugin-sdk/file-access-runtime";
36
36
  import { captureFinalCodexCronCreatorToolAllowlist, materializeStaticMcpToolsForScheduledHarnessRun, resolveCodexMcpToolOverridesForAgent } from "openclaw/plugin-sdk/codex-mcp-projection";
37
37
  import { createDiagnosticTraceContextFromActiveScope, emitTrustedDiagnosticEvent, emitTrustedDiagnosticEventWithPrivateData, freezeDiagnosticTraceContext, onInternalDiagnosticEvent, resolveDiagnosticModelContentCapturePolicy } from "openclaw/plugin-sdk/diagnostic-runtime";
38
38
  import { Buffer as Buffer$1 } from "node:buffer";
39
+ import { sleepWithAbort } from "openclaw/plugin-sdk/runtime-env";
39
40
  import { prepareMemorySystemPromptAddition } from "openclaw/plugin-sdk/core";
40
41
  import { isSilentReplyPayloadText } from "openclaw/plugin-sdk/reply-chunking";
41
42
  import { generatedImageAssetFromBase64 } from "openclaw/plugin-sdk/image-generation";
@@ -251,6 +252,7 @@ var CodexAssistantProjection = class {
251
252
  this.assistantItemOrder = [];
252
253
  this.assistantTimestampByItem = /* @__PURE__ */ new Map();
253
254
  this.assistantPhaseByItem = /* @__PURE__ */ new Map();
255
+ this.assistantDeliveryByItem = /* @__PURE__ */ new Map();
254
256
  this.latestTerminalAssistantCandidateSuperseded = false;
255
257
  this.latestTerminalAssistantCandidateCanReleaseAfterToolHandoff = false;
256
258
  this.terminalAssistantCandidateEarlierActiveItemIds = /* @__PURE__ */ new Set();
@@ -261,6 +263,7 @@ var CodexAssistantProjection = class {
261
263
  this.assistantStarted = false;
262
264
  this.streamedPartialAssistantItemReplaceable = false;
263
265
  this.persistableAssistantBarrier = 0;
266
+ this.persistedAssistantBoundary = false;
264
267
  this.persistableAssistantBarrierItemIds = /* @__PURE__ */ new Set();
265
268
  }
266
269
  hasCompletedTerminalAssistantText(completedItemIds) {
@@ -293,7 +296,8 @@ var CodexAssistantProjection = class {
293
296
  if (!delta) return;
294
297
  if (itemId !== this.pendingRawTerminalAssistantEchoItemId) this.pendingRawTerminalAssistantEchoItemId = void 0;
295
298
  const isCommentary = this.isCommentaryAssistantItem(itemId);
296
- if (!isCommentary && itemId !== this.latestTerminalAssistantCandidateItemId) this.markTerminalAssistantCandidateSupersededBy();
299
+ const isAsync = this.isAsyncAssistantItem(itemId);
300
+ if (!isCommentary && !isAsync && itemId !== this.latestTerminalAssistantCandidateItemId) this.markTerminalAssistantCandidateSupersededBy();
297
301
  if (!this.assistantStarted) {
298
302
  this.assistantStarted = true;
299
303
  await this.params.onAssistantMessageStart?.();
@@ -301,6 +305,7 @@ var CodexAssistantProjection = class {
301
305
  this.rememberAssistantItem(itemId);
302
306
  const text = `${this.assistantTextByItem.get(itemId) ?? ""}${delta}`;
303
307
  this.assistantTextByItem.set(itemId, text);
308
+ if (isAsync) return;
304
309
  if (isCommentary) {
305
310
  this.emitCommentaryProgress({
306
311
  itemId,
@@ -332,24 +337,24 @@ var CodexAssistantProjection = class {
332
337
  }
333
338
  recordItemStarted(item, itemId) {
334
339
  this.noteNativeWorkBarrier(item);
335
- if (item?.type === "agentMessage" && itemId && itemId !== this.pendingRawTerminalAssistantEchoItemId) this.pendingRawTerminalAssistantEchoItemId = void 0;
336
340
  this.rememberAssistantPhase(item);
341
+ if (item?.type === "agentMessage" && itemId && !this.isNonTerminalAssistantItem(itemId) && itemId !== this.pendingRawTerminalAssistantEchoItemId) this.pendingRawTerminalAssistantEchoItemId = void 0;
337
342
  if (item?.type === "agentMessage" && itemId) this.rememberAssistantItem(itemId);
338
- if (itemId && itemId !== this.latestTerminalAssistantCandidateItemId) {
343
+ if (itemId && !this.isNonTerminalAssistantItem(itemId) && itemId !== this.latestTerminalAssistantCandidateItemId) {
339
344
  this.markTerminalAssistantCandidateSupersededBy(itemId, { preserveEarlierActiveItem: true });
340
345
  if (this.latestTerminalAssistantCandidateSuperseded) this.pendingRawTerminalAssistantEchoItemId = void 0;
341
346
  }
342
347
  }
343
348
  recordItemCompleted(item, itemId, activeItemIds) {
344
349
  this.noteNativeWorkBarrier(item);
345
- if (item?.type === "agentMessage" && itemId && itemId !== this.pendingRawTerminalAssistantEchoItemId) this.pendingRawTerminalAssistantEchoItemId = void 0;
346
- if (itemId) this.latestCompletedItemId = itemId;
347
350
  this.rememberAssistantPhase(item);
348
- if (item?.type === "agentMessage" && !this.isCommentaryAssistantItem(item.id)) {
351
+ if (item?.type === "agentMessage" && itemId && !this.isNonTerminalAssistantItem(itemId) && itemId !== this.pendingRawTerminalAssistantEchoItemId) this.pendingRawTerminalAssistantEchoItemId = void 0;
352
+ if (itemId && !this.isNonTerminalAssistantItem(itemId)) this.latestCompletedItemId = itemId;
353
+ if (item?.type === "agentMessage" && !this.isNonTerminalAssistantItem(item.id)) {
349
354
  this.latestCompletedTerminalAssistantItemId = item.id;
350
355
  this.markLatestTerminalAssistantCandidate(item.id, activeItemIds);
351
356
  this.pendingRawTerminalAssistantEchoItemId = item.id;
352
- } else if (itemId) {
357
+ } else if (itemId && !this.isNonTerminalAssistantItem(itemId)) {
353
358
  this.markTerminalAssistantCandidateSupersededBy(itemId, { preserveEarlierActiveItem: true });
354
359
  if (this.latestTerminalAssistantCandidateSuperseded) this.pendingRawTerminalAssistantEchoItemId = void 0;
355
360
  }
@@ -362,7 +367,8 @@ var CodexAssistantProjection = class {
362
367
  text: item.text
363
368
  });
364
369
  this.pendingRawCommentaryEchoes += 1;
365
- } else if (item.text && this.isFinalAnswerAssistantItem(item.id)) this.emitAnswerCandidate(item.id, "candidate");
370
+ } else if (item.text && !this.isAsyncAssistantItem(item.id) && this.isFinalAnswerAssistantItem(item.id)) this.emitAnswerCandidate(item.id, "candidate");
371
+ return this.createAsyncDelivery(item.id);
366
372
  }
367
373
  }
368
374
  recordSnapshotItem(item) {
@@ -370,6 +376,7 @@ var CodexAssistantProjection = class {
370
376
  if (item.type === "agentMessage" && typeof item.text === "string") {
371
377
  this.rememberAssistantItem(item.id);
372
378
  this.assistantTextByItem.set(item.id, item.text);
379
+ return this.createAsyncDelivery(item.id);
373
380
  }
374
381
  }
375
382
  handleRawResponseItemCompleted(item, activeItemIds) {
@@ -418,6 +425,7 @@ var CodexAssistantProjection = class {
418
425
  const audibleAfterHandoff = afterHandoff.filter((text) => !isSilentReplyPayloadText(text));
419
426
  if (audibleAfterHandoff.length > 0) return audibleAfterHandoff;
420
427
  if (afterHandoff.length > 0) return afterHandoff.slice(-1);
428
+ if (this.persistedAssistantBoundary) return [];
421
429
  const recoveredAudible = this.collectPersistableAssistantTexts(0).filter((text) => !isSilentReplyPayloadText(text));
422
430
  if (recoveredAudible.length > 0) return recoveredAudible.slice(-1);
423
431
  const recovered = this.resolveFinalAssistantTextItem()?.text;
@@ -435,6 +443,39 @@ var CodexAssistantProjection = class {
435
443
  }];
436
444
  });
437
445
  }
446
+ collectAsyncMessages() {
447
+ return this.assistantItemOrder.flatMap((itemId) => {
448
+ if (!this.isAsyncAssistantItem(itemId)) return [];
449
+ const text = this.assistantTextByItem.get(itemId)?.trim();
450
+ const timestamp = this.assistantTimestampByItem.get(itemId);
451
+ if (!text || timestamp === void 0) return [];
452
+ return [{
453
+ itemId,
454
+ message: createAssistantAsyncMessage(this.params, text, itemId, timestamp)
455
+ }];
456
+ });
457
+ }
458
+ createCompletedAssistantBoundaryMessage(completedItemIds, options) {
459
+ const itemId = this.latestCompletedTerminalAssistantItemId;
460
+ const text = itemId ? this.assistantTextByItem.get(itemId)?.trim() : void 0;
461
+ const itemIndex = itemId ? this.assistantItemOrder.indexOf(itemId) : -1;
462
+ if (!itemId || !completedItemIds.has(itemId) || itemIndex < this.persistableAssistantBarrier || !text || isSilentReplyPayloadText(text) || this.isToolProgressEchoText(itemId, text)) return;
463
+ const message = this.createAssistantMessage(text, options);
464
+ return {
465
+ itemId,
466
+ message: {
467
+ ...message,
468
+ timestamp: this.assistantTimestampByItem.get(itemId) ?? message.timestamp
469
+ }
470
+ };
471
+ }
472
+ markAssistantBoundaryPersisted(itemId) {
473
+ const index = this.assistantItemOrder.indexOf(itemId);
474
+ if (index >= 0) {
475
+ this.persistableAssistantBarrier = Math.max(this.persistableAssistantBarrier, index + 1);
476
+ this.persistedAssistantBoundary = true;
477
+ }
478
+ }
438
479
  finalizeAnswerCandidate(turn) {
439
480
  if (turn.status !== "completed") {
440
481
  this.supersedeVisibleAnswerCandidate();
@@ -444,7 +485,7 @@ var CodexAssistantProjection = class {
444
485
  const authoritativeIndex = turnItems.findLastIndex((item) => {
445
486
  if (item.type !== "agentMessage" || typeof item.text !== "string" || item.text.trim().length === 0) return false;
446
487
  const phase = readItemString(item, "phase");
447
- return phase === "final_answer" || phase === void 0;
488
+ return readItemString(item, "delivery") !== "async" && (phase === "final_answer" || phase === void 0);
448
489
  });
449
490
  const authoritative = authoritativeIndex >= 0 ? turnItems[authoritativeIndex] : void 0;
450
491
  if (turnItems.slice(authoritativeIndex + 1).some(shouldClearTerminalPresentationForNativeItem) || authoritative?.id === this.latestTerminalAssistantCandidateItemId && this.latestTerminalAssistantCandidateSuperseded) {
@@ -462,7 +503,7 @@ var CodexAssistantProjection = class {
462
503
  hasAssistantItemTextForSynthesis() {
463
504
  for (let i = this.assistantItemOrder.length - 1; i >= 0; i -= 1) {
464
505
  const itemId = this.assistantItemOrder[i];
465
- if (!itemId || this.assistantPhaseByItem.get(itemId) === "commentary") continue;
506
+ if (!itemId || this.isNonTerminalAssistantItem(itemId)) continue;
466
507
  const text = this.assistantTextByItem.get(itemId);
467
508
  if (text && text.length > 0) return true;
468
509
  }
@@ -471,7 +512,7 @@ var CodexAssistantProjection = class {
471
512
  createCurrentAttemptAssistantMessage(options) {
472
513
  for (let i = this.assistantItemOrder.length - 1; i >= 0; i -= 1) {
473
514
  const itemId = this.assistantItemOrder[i];
474
- if (!itemId || this.isCommentaryAssistantItem(itemId) || !this.assistantTextByItem.has(itemId)) continue;
515
+ if (!itemId || this.isNonTerminalAssistantItem(itemId) || !this.assistantTextByItem.has(itemId)) continue;
475
516
  const text = this.assistantTextByItem.get(itemId) ?? "";
476
517
  const normalizedText = text.trim();
477
518
  if (normalizedText && this.isToolProgressEchoText(itemId, normalizedText)) continue;
@@ -492,10 +533,18 @@ var CodexAssistantProjection = class {
492
533
  if (item?.type !== "agentMessage") return;
493
534
  const phase = readItemString(item, "phase");
494
535
  if (phase) this.assistantPhaseByItem.set(item.id, phase);
536
+ const delivery = readItemString(item, "delivery");
537
+ if (delivery) this.assistantDeliveryByItem.set(item.id, delivery);
495
538
  }
496
539
  isCommentaryAssistantItem(itemId) {
497
540
  return this.assistantPhaseByItem.get(itemId) === "commentary";
498
541
  }
542
+ isAsyncAssistantItem(itemId) {
543
+ return this.assistantDeliveryByItem.get(itemId) === "async";
544
+ }
545
+ isNonTerminalAssistantItem(itemId) {
546
+ return this.isCommentaryAssistantItem(itemId) || this.isAsyncAssistantItem(itemId);
547
+ }
499
548
  isFinalAnswerAssistantItem(itemId) {
500
549
  return this.assistantPhaseByItem.get(itemId) === "final_answer";
501
550
  }
@@ -503,7 +552,7 @@ var CodexAssistantProjection = class {
503
552
  return this.assistantPhaseByItem.get(itemId) === "final_answer";
504
553
  }
505
554
  emitCommentaryProgress(params) {
506
- const progressText = params.text.replace(/\s+/g, " ").trim();
555
+ const progressText = params.text.trim();
507
556
  if (!progressText || this.lastCommentaryProgressTextByItem.get(params.itemId) === progressText) return;
508
557
  this.lastCommentaryProgressTextByItem.set(params.itemId, progressText);
509
558
  this.emitAgentEvent({
@@ -570,7 +619,7 @@ var CodexAssistantProjection = class {
570
619
  const itemId = this.assistantItemOrder[i];
571
620
  if (!itemId) continue;
572
621
  const text = this.assistantTextByItem.get(itemId)?.trim();
573
- if (this.assistantPhaseByItem.get(itemId) === "commentary") continue;
622
+ if (this.isNonTerminalAssistantItem(itemId)) continue;
574
623
  if (text && !this.isToolProgressEchoText(itemId, text)) return {
575
624
  itemId,
576
625
  text
@@ -582,7 +631,7 @@ var CodexAssistantProjection = class {
582
631
  let replaceable = false;
583
632
  for (let index = minIndex; index < this.assistantItemOrder.length; index += 1) {
584
633
  const itemId = this.assistantItemOrder[index];
585
- if (!itemId || this.assistantPhaseByItem.get(itemId) === "commentary") continue;
634
+ if (!itemId || this.isNonTerminalAssistantItem(itemId)) continue;
586
635
  const text = this.assistantTextByItem.get(itemId)?.trim();
587
636
  if (!text || this.isToolProgressEchoText(itemId, text)) continue;
588
637
  if (isSilentReplyPayloadText(text)) {
@@ -610,6 +659,17 @@ var CodexAssistantProjection = class {
610
659
  this.assistantItemOrder.push(itemId);
611
660
  this.assistantTimestampByItem.set(itemId, this.nextTranscriptTimestamp());
612
661
  }
662
+ createAsyncDelivery(itemId) {
663
+ if (!this.isAsyncAssistantItem(itemId)) return;
664
+ const text = this.assistantTextByItem.get(itemId);
665
+ const timestamp = this.assistantTimestampByItem.get(itemId);
666
+ if (!text?.trim() || timestamp === void 0) return;
667
+ return {
668
+ itemId,
669
+ message: createAssistantAsyncMessage(this.params, text, itemId, timestamp),
670
+ text
671
+ };
672
+ }
613
673
  isToolProgressEchoText(itemId, text) {
614
674
  return this.rawPromotedAssistantItemIds.has(itemId) && this.matchesToolProgressEcho(text);
615
675
  }
@@ -618,6 +678,40 @@ function shouldAdvancePersistableAssistantBarrier(item) {
618
678
  return shouldClearTerminalPresentationForNativeItem(item) || item.type === "dynamicToolCall" || item.type === "sleep";
619
679
  }
620
680
  //#endregion
681
+ //#region extensions/codex/src/app-server/event-projector-async-delivery.ts
682
+ /** Owns authorization, exactly-once settlement, and terminal retry for async user messages. */
683
+ var CodexAsyncDeliveryProjection = class {
684
+ constructor(params, threadId, turnId, options) {
685
+ this.params = params;
686
+ this.threadId = threadId;
687
+ this.turnId = turnId;
688
+ this.options = options;
689
+ this.settledItemIds = /* @__PURE__ */ new Set();
690
+ this.pendingDeliveries = /* @__PURE__ */ new Map();
691
+ }
692
+ allows(item, reportUnauthorized = false) {
693
+ if (item?.type !== "agentMessage" || item.delivery !== "async") return true;
694
+ const allowed = this.params.disableTools !== true && (this.options.asyncUserMessageAllowed ?? (this.params.toolsAllow === void 0 || this.params.toolsAllow.some((name) => name === "*" || name === "message")));
695
+ if (!allowed && reportUnauthorized) embeddedAgentLog.warn("blocked unauthorized codex async user message", {
696
+ itemId: item.id,
697
+ threadId: this.threadId,
698
+ turnId: this.turnId
699
+ });
700
+ return allowed;
701
+ }
702
+ pending() {
703
+ return [...this.pendingDeliveries.values()];
704
+ }
705
+ async deliver(delivery) {
706
+ if (this.settledItemIds.has(delivery.itemId)) return;
707
+ const settlement = await this.options.onAsyncDelivery?.(delivery);
708
+ if (settlement === "settled") {
709
+ this.settledItemIds.add(delivery.itemId);
710
+ this.pendingDeliveries.delete(delivery.itemId);
711
+ } else if (settlement === "retry") this.pendingDeliveries.set(delivery.itemId, delivery);
712
+ }
713
+ };
714
+ //#endregion
621
715
  //#region extensions/codex/src/app-server/event-projector-media.ts
622
716
  const GENERATED_IMAGE_MEDIA_SUBDIR = "tool-image-generation";
623
717
  var CodexGeneratedMediaProjection = class {
@@ -936,20 +1030,50 @@ function applyStickyTurnTaint(messages) {
936
1030
  function buildCodexMessagesSnapshot(params) {
937
1031
  const messages = promptSnapshot(params.runParams, params.turnId, params.upstreamUserText);
938
1032
  if (params.reasoningText) messages.push(attachCodexMirrorIdentity(params.createAssistantMirrorMessage("Codex reasoning", params.reasoningText), `${params.turnId}:reasoning`));
939
- if (params.planText) messages.push(attachCodexMirrorIdentity(params.createAssistantMirrorMessage("Codex plan", params.planText), `${params.turnId}:plan`));
940
- const visibleWorkMessages = [...params.runParams.config?.ui?.prefs?.chatPersistCommentary === false ? [] : params.commentaryMessages.map(({ itemId, message }) => attachCodexMirrorIdentity(message, `${params.turnId}:commentary:${itemId}`)), ...params.toolMessages].toSorted((left, right) => (asDateTimestampMs(left.timestamp) ?? 0) - (asDateTimestampMs(right.timestamp) ?? 0));
1033
+ const commentaryMessages = params.runParams.config?.ui?.prefs?.chatPersistCommentary === false ? [] : params.commentaryMessages.map(({ itemId, message }) => attachCodexMirrorIdentity(message, `${params.turnId}:commentary:${itemId}`));
1034
+ const asyncMessages = params.asyncMessages.map(({ itemId, message }) => attachCodexMirrorIdentity(message, `${params.turnId}:async:${itemId}`));
1035
+ const visibleWorkMessages = [
1036
+ ...commentaryMessages,
1037
+ ...asyncMessages,
1038
+ ...params.toolMessages
1039
+ ].toSorted((left, right) => (asDateTimestampMs(left.timestamp) ?? 0) - (asDateTimestampMs(right.timestamp) ?? 0));
941
1040
  messages.push(...visibleWorkMessages);
942
- if (params.lastAssistant) messages.push(attachCodexMirrorIdentity(params.lastAssistant, `${params.turnId}:assistant`));
1041
+ if (params.lastAssistant) messages.push(attachCodexMirrorIdentity(params.lastAssistant, params.lastAssistantIdentity ?? `${params.turnId}:assistant`));
943
1042
  return applyStickyTurnTaint(messages).map((message) => projectAgentHarnessTranscriptMessageForDisplay({
944
1043
  hidden: params.runParams.trigger === "memory",
945
1044
  message
946
1045
  }));
947
1046
  }
1047
+ function buildCodexSteeringMessagesSnapshot(params) {
1048
+ const asyncMessages = params.assistantProjection.collectAsyncMessages().filter(({ itemId }) => params.completedItemIds.has(itemId));
1049
+ const commentaryMessages = params.assistantProjection.collectCommentaryMessages().filter(({ itemId }) => params.completedItemIds.has(itemId));
1050
+ const assistantBoundary = params.assistantProjection.createCompletedAssistantBoundaryMessage(params.completedItemIds, {
1051
+ tokenUsage: void 0,
1052
+ aborted: false,
1053
+ promptError: void 0
1054
+ });
1055
+ return {
1056
+ messages: buildCodexMessagesSnapshot({
1057
+ runParams: params.runParams,
1058
+ turnId: params.turnId,
1059
+ upstreamUserText: params.upstreamUserText,
1060
+ reasoningText: void 0,
1061
+ asyncMessages,
1062
+ commentaryMessages,
1063
+ toolMessages: params.toolMessages,
1064
+ lastAssistant: assistantBoundary?.message,
1065
+ ...assistantBoundary ? { lastAssistantIdentity: `${params.turnId}:assistant:${assistantBoundary.itemId}` } : {},
1066
+ createAssistantMirrorMessage: (title, text) => params.assistantProjection.createAssistantMirrorMessage(title, text)
1067
+ }).filter((message) => message.role !== "user"),
1068
+ ...assistantBoundary ? { assistantBoundaryItemId: assistantBoundary.itemId } : {}
1069
+ };
1070
+ }
948
1071
  //#endregion
949
1072
  //#region extensions/codex/src/app-server/event-projector-result.ts
950
1073
  function buildCodexAttemptResult(input) {
951
1074
  input.nativeToolLifecycleProjection.finalizeActive();
952
1075
  const assistantTexts = input.assistantProjection.collectAssistantTexts();
1076
+ const asyncMessages = input.assistantProjection.collectAsyncMessages();
953
1077
  const commentaryMessages = input.assistantProjection.collectCommentaryMessages();
954
1078
  const reasoningText = input.reasoningProjection.reasoningText();
955
1079
  const planText = input.reasoningProjection.planText();
@@ -984,7 +1108,7 @@ function buildCodexAttemptResult(input) {
984
1108
  turnId: input.turnId,
985
1109
  upstreamUserText: input.upstreamUserText,
986
1110
  reasoningText,
987
- planText,
1111
+ asyncMessages,
988
1112
  commentaryMessages,
989
1113
  toolMessages: input.toolTranscriptProjection.transcriptMessages,
990
1114
  lastAssistant,
@@ -1205,6 +1329,7 @@ var CodexAppServerEventProjector = class {
1205
1329
  this.responseCompletions = new CodexResponseCompletionProjection();
1206
1330
  this.completedCompactionCount = 0;
1207
1331
  this.lastTranscriptTimestamp = 0;
1332
+ this.asyncDeliveryProjection = new CodexAsyncDeliveryProjection(params, threadId, turnId, options);
1208
1333
  this.contextTokens = options.initialContextTokens;
1209
1334
  this.contextTokensSource = options.initialContextTokens === void 0 ? void 0 : "resolved";
1210
1335
  this.diagnostics = new CodexProjectionDiagnostics(threadId, turnId);
@@ -1233,18 +1358,23 @@ var CodexAppServerEventProjector = class {
1233
1358
  return this.completedTurn?.status;
1234
1359
  }
1235
1360
  buildSteeringTranscriptPrefix() {
1236
- const commentaryMessages = this.assistantProjection.collectCommentaryMessages().filter(({ itemId }) => this.completedItemIds.has(itemId));
1237
- return buildCodexMessagesSnapshot({
1361
+ const snapshot = buildCodexSteeringMessagesSnapshot({
1238
1362
  runParams: this.params,
1239
1363
  turnId: this.turnId,
1240
1364
  upstreamUserText: this.options.upstreamUserText,
1241
- reasoningText: void 0,
1242
- planText: void 0,
1243
- commentaryMessages,
1244
- toolMessages: this.toolTranscriptProjection.transcriptMessages,
1245
- lastAssistant: void 0,
1246
- createAssistantMirrorMessage: (title, text) => this.assistantProjection.createAssistantMirrorMessage(title, text)
1247
- }).filter((message) => message.role !== "user");
1365
+ completedItemIds: this.completedItemIds,
1366
+ assistantProjection: this.assistantProjection,
1367
+ toolMessages: this.toolTranscriptProjection.transcriptMessages
1368
+ });
1369
+ this.pendingSteeringAssistantBoundaryItemId = snapshot.assistantBoundaryItemId;
1370
+ return snapshot.messages;
1371
+ }
1372
+ markSteeringTranscriptPersisted() {
1373
+ const itemId = this.pendingSteeringAssistantBoundaryItemId;
1374
+ if (itemId) {
1375
+ this.assistantProjection.markAssistantBoundaryPersisted(itemId);
1376
+ this.pendingSteeringAssistantBoundaryItemId = void 0;
1377
+ }
1248
1378
  }
1249
1379
  hasCompletedTerminalAssistantText() {
1250
1380
  return this.assistantProjection.hasCompletedTerminalAssistantText(this.completedItemIds);
@@ -1284,8 +1414,9 @@ var CodexAppServerEventProjector = class {
1284
1414
  if (!params) return;
1285
1415
  if (notification.method === "hook/started" || notification.method === "hook/completed") {
1286
1416
  if (!this.isHookNotificationForCurrentThread(params)) return;
1287
- } else if (notification.method === "guardianWarning") {
1288
- if (readCodexNotificationThreadId(params) !== this.threadId) return;
1417
+ } else if (notification.method === "guardianWarning" || notification.method === "warning" || notification.method === "configWarning") {
1418
+ const warningThreadId = readCodexNotificationThreadId(params);
1419
+ if (notification.method === "guardianWarning" && warningThreadId !== this.threadId || warningThreadId && warningThreadId !== this.threadId) return;
1289
1420
  } else if (!isCodexNotificationForTurn(params, this.threadId, this.turnId)) return;
1290
1421
  if (notification.method !== "guardianWarning" && notification.method !== "item/autoApprovalReview/started" && notification.method !== "item/autoApprovalReview/completed") this.eventProjection.flushPendingGuardianWarning();
1291
1422
  this.nativeToolLifecycleProjector.handleNotification(notification);
@@ -1317,9 +1448,16 @@ var CodexAppServerEventProjector = class {
1317
1448
  case "item/autoApprovalReview/completed":
1318
1449
  this.eventProjection.handleGuardianReview(notification.method, params);
1319
1450
  break;
1451
+ case "autoApprovalReview/strictReviewRequired":
1452
+ this.eventProjection.handleStrictReviewRequired(params);
1453
+ break;
1320
1454
  case "guardianWarning":
1321
1455
  this.eventProjection.handleGuardianWarning(params);
1322
1456
  break;
1457
+ case "warning":
1458
+ case "configWarning":
1459
+ this.eventProjection.handleWarning(params);
1460
+ break;
1323
1461
  case "hook/started":
1324
1462
  case "hook/completed":
1325
1463
  this.eventProjection.handleHook(notification.method, params);
@@ -1331,7 +1469,7 @@ var CodexAppServerEventProjector = class {
1331
1469
  this.contextTokensSource = this.params.authoredContextTokenCap === void 0 ? "runtime" : "runtime-configured";
1332
1470
  }
1333
1471
  this.emitAgentEvent({
1334
- stream: "codex_app_server.usage",
1472
+ stream: "usage",
1335
1473
  data
1336
1474
  });
1337
1475
  });
@@ -1345,6 +1483,9 @@ var CodexAppServerEventProjector = class {
1345
1483
  case "rawResponseItem/completed":
1346
1484
  await this.handleRawResponseItemCompleted(params);
1347
1485
  break;
1486
+ case "model/rerouted":
1487
+ this.eventProjection.handleModelRerouted(params);
1488
+ break;
1348
1489
  case "error": {
1349
1490
  this.responseCompletions.clear();
1350
1491
  if (params.willRetry === true) break;
@@ -1363,7 +1504,6 @@ var CodexAppServerEventProjector = class {
1363
1504
  case "item/fileChange/outputDelta":
1364
1505
  case "item/fileChange/patchUpdated":
1365
1506
  case "item/mcpToolCall/progress":
1366
- case "model/rerouted":
1367
1507
  case "model/verification":
1368
1508
  case "turn/moderationMetadata":
1369
1509
  case "model/safetyBuffering/updated": break;
@@ -1495,7 +1635,9 @@ var CodexAppServerEventProjector = class {
1495
1635
  this.activeItemIds.delete(itemId);
1496
1636
  this.completedItemIds.add(itemId);
1497
1637
  }
1498
- this.assistantProjection.recordItemCompleted(item, itemId, this.activeItemIds);
1638
+ if (!this.asyncDeliveryProjection.allows(item, true)) return;
1639
+ const asyncMessage = this.assistantProjection.recordItemCompleted(item, itemId, this.activeItemIds);
1640
+ if (asyncMessage) await this.asyncDeliveryProjection.deliver(asyncMessage);
1499
1641
  this.reasoningProjection.recordItem(item);
1500
1642
  await this.generatedMediaProjection.recordNative(item);
1501
1643
  if (item?.type === "contextCompaction" && itemId) {
@@ -1527,7 +1669,7 @@ var CodexAppServerEventProjector = class {
1527
1669
  itemId,
1528
1670
  timestamp: this.nextTranscriptTimestamp()
1529
1671
  });
1530
- this.emitCompactionEnd(itemId, true);
1672
+ this.eventProjection.emitCompactionEnd(itemId, true);
1531
1673
  }
1532
1674
  this.toolProgressProjection.recordToolMeta(item);
1533
1675
  this.toolProgressProjection.rememberCommandAggregateOutputEcho(item);
@@ -1573,10 +1715,11 @@ var CodexAppServerEventProjector = class {
1573
1715
  for (const itemId of failedCompactionItemIds) {
1574
1716
  this.activeItemIds.delete(itemId);
1575
1717
  this.activeCompactionItemIds.delete(itemId);
1576
- this.emitCompactionEnd(itemId, false);
1718
+ this.eventProjection.emitCompactionEnd(itemId, false);
1577
1719
  }
1578
1720
  }
1579
1721
  const turnItems = turn.items ?? [];
1722
+ const unsettledAsyncDeliveries = this.asyncDeliveryProjection.pending();
1580
1723
  for (let index = turnItems.length - 1; index >= 0; index -= 1) {
1581
1724
  const item = turnItems[index];
1582
1725
  if (!item || !this.isCurrentTurnSnapshotItem(item)) continue;
@@ -1587,8 +1730,10 @@ var CodexAppServerEventProjector = class {
1587
1730
  }
1588
1731
  }
1589
1732
  for (const item of turnItems) {
1733
+ if (!this.asyncDeliveryProjection.allows(item)) continue;
1590
1734
  this.diagnostics.warnUnknownItemStatus(item);
1591
- this.assistantProjection.recordSnapshotItem(item);
1735
+ const asyncMessage = this.assistantProjection.recordSnapshotItem(item);
1736
+ if (asyncMessage) await this.asyncDeliveryProjection.deliver(asyncMessage);
1592
1737
  this.reasoningProjection.recordItem(item);
1593
1738
  await this.generatedMediaProjection.recordNative(item);
1594
1739
  this.toolProgressProjection.recordToolMeta(item);
@@ -1601,23 +1746,11 @@ var CodexAppServerEventProjector = class {
1601
1746
  this.toolProgressProjection.emitToolResultOutput(item);
1602
1747
  }
1603
1748
  this.toolProgressProjection.approvalTimeoutKinds.clear();
1749
+ for (const delivery of unsettledAsyncDeliveries) await this.asyncDeliveryProjection.deliver(delivery);
1604
1750
  this.assistantProjection.finalizeAnswerCandidate(turn);
1605
1751
  this.activeCompactionItemIds.clear();
1606
1752
  await this.reasoningProjection.maybeEndReasoning();
1607
1753
  }
1608
- emitCompactionEnd(itemId, completed) {
1609
- this.emitAgentEvent({
1610
- stream: "compaction",
1611
- data: {
1612
- phase: "end",
1613
- backend: "codex-app-server",
1614
- completed,
1615
- threadId: this.threadId,
1616
- turnId: this.turnId,
1617
- itemId
1618
- }
1619
- });
1620
- }
1621
1754
  async emitSnapshotOnlyNativeToolProgress(item) {
1622
1755
  if (!shouldSynthesizeToolProgressForItem(item) || !this.isCurrentTurnSnapshotItem(item) || this.completedItemIds.has(item.id) || itemStatus(item) === "running") return;
1623
1756
  if (!this.activeItemIds.has(item.id)) {
@@ -1675,24 +1808,7 @@ var CodexAppServerEventProjector = class {
1675
1808
  return usageLimitMessage ? createCodexUsageLimitPromptError(usageLimitMessage) : readCodexErrorNotificationMessage(params);
1676
1809
  }
1677
1810
  emitAgentEvent(event) {
1678
- try {
1679
- emitAgentEvent({
1680
- runId: this.params.runId,
1681
- stream: event.stream,
1682
- data: event.data,
1683
- ...this.params.sessionKey ? { sessionKey: this.params.sessionKey } : {}
1684
- });
1685
- } catch (error) {
1686
- embeddedAgentLog.debug("codex app-server global agent event emit failed", { error });
1687
- }
1688
- try {
1689
- const maybePromise = this.params.onAgentEvent?.(event);
1690
- Promise.resolve(maybePromise).catch((error) => {
1691
- embeddedAgentLog.debug("codex app-server agent event handler rejected", { error });
1692
- });
1693
- } catch (error) {
1694
- embeddedAgentLog.debug("codex app-server agent event handler threw", { error });
1695
- }
1811
+ emitCodexAgentEvent(this.params, event);
1696
1812
  }
1697
1813
  isHookNotificationForCurrentThread(params) {
1698
1814
  const threadId = readStringField(params, "threadId");
@@ -1701,11 +1817,28 @@ var CodexAppServerEventProjector = class {
1701
1817
  }
1702
1818
  };
1703
1819
  //#endregion
1820
+ //#region extensions/codex/src/app-server/mcp-tool-metadata.ts
1821
+ /** Hosted app ownership is authoritative only on metadata supplied by Codex. */
1822
+ function readCodexMcpToolConnectorId(tool) {
1823
+ const metadata = asOptionalRecord(asOptionalRecord(tool)?.["_meta"]);
1824
+ return normalizeOptionalString(metadata?.connector_id) ?? normalizeOptionalString(metadata?.connectorId);
1825
+ }
1826
+ /** Preserve MCP App visibility so model-only tools cannot become widget authority. */
1827
+ function readCodexMcpToolUiVisibility(tool) {
1828
+ const visibility = asOptionalRecord(asOptionalRecord(asOptionalRecord(tool)?.["_meta"])?.ui)?.visibility;
1829
+ if (!Array.isArray(visibility)) return;
1830
+ return [...new Set(visibility.filter((value) => value === "app" || value === "model"))].toSorted();
1831
+ }
1832
+ //#endregion
1704
1833
  //#region extensions/codex/src/app-server/native-mcp-app.ts
1834
+ const CODEX_APPS_MCP_SERVER$1 = "codex_apps";
1705
1835
  function readMcpAppResourceUri(item) {
1706
1836
  const uri = normalizeOptionalString(asOptionalRecord(item.appContext)?.resourceUri) ?? normalizeOptionalString(item.mcpAppResourceUri);
1707
1837
  return uri?.startsWith("ui://") ? uri : void 0;
1708
1838
  }
1839
+ function readMcpAppConnectorId(item) {
1840
+ return normalizeOptionalString(asOptionalRecord(item.appContext)?.connectorId);
1841
+ }
1709
1842
  function readMcpToolResult(item) {
1710
1843
  const result = asOptionalRecord(item.result);
1711
1844
  if (!result || !Array.isArray(result.content)) return;
@@ -1743,13 +1876,16 @@ function createNativeMcpRuntime(params) {
1743
1876
  launchSummary: "Codex native MCP connection",
1744
1877
  toolCount: Object.keys(status.tools).length
1745
1878
  }])),
1746
- tools: loaded.flatMap((status) => statusTools(status).map((tool) => ({
1747
- serverName: status.name,
1748
- safeServerName: status.name,
1749
- toolName: String(tool.name),
1750
- inputSchema: asOptionalRecord(tool.inputSchema) ?? { type: "object" },
1751
- fallbackDescription: normalizeOptionalString(tool.description) ?? String(tool.name)
1752
- })))
1879
+ tools: loaded.flatMap((status) => statusTools(status).map((tool) => {
1880
+ const uiVisibility = readCodexMcpToolUiVisibility(tool);
1881
+ return Object.assign({
1882
+ serverName: status.name,
1883
+ safeServerName: status.name,
1884
+ toolName: String(tool.name),
1885
+ inputSchema: asOptionalRecord(tool.inputSchema) ?? { type: "object" },
1886
+ fallbackDescription: normalizeOptionalString(tool.description) ?? String(tool.name)
1887
+ }, uiVisibility ? { uiVisibility } : {});
1888
+ }))
1753
1889
  };
1754
1890
  return catalog;
1755
1891
  };
@@ -1777,11 +1913,18 @@ function createNativeMcpRuntime(params) {
1777
1913
  const status = (await loadStatuses()).find((entry) => entry.name === serverName);
1778
1914
  return { tools: status ? statusTools(status) : [] };
1779
1915
  },
1780
- readResource: async (serverName, uri) => await params.client.request("mcpServer/resource/read", {
1781
- threadId: params.threadId,
1782
- server: serverName,
1783
- uri
1784
- }),
1916
+ readResource: async (serverName, uri) => {
1917
+ const isCodexAppsServer = serverName === CODEX_APPS_MCP_SERVER$1;
1918
+ const response = await params.client.request("mcpServer/resource/read", {
1919
+ threadId: params.threadId,
1920
+ ...isCodexAppsServer ? { originCallId: params.originCallId } : {},
1921
+ server: serverName,
1922
+ uri,
1923
+ ...params.connectorId ? { connectorId: params.connectorId } : {}
1924
+ });
1925
+ if (isCodexAppsServer && response.originCallId !== params.originCallId) throw new Error(`Codex MCP resource response originCallId mismatch: expected ${params.originCallId}, received ${response.originCallId}`);
1926
+ return response;
1927
+ },
1785
1928
  listResources: async (serverName) => {
1786
1929
  return { resources: (await loadStatuses()).find((entry) => entry.name === serverName)?.resources ?? [] };
1787
1930
  },
@@ -1794,15 +1937,25 @@ function createNativeMcpRuntime(params) {
1794
1937
  }
1795
1938
  function createCodexNativeMcpAppResultDetailsPreparer(params) {
1796
1939
  if (params.attempt.config?.mcp?.apps?.enabled !== true) return;
1797
- const runtime = createNativeMcpRuntime(params);
1798
1940
  return async (item) => {
1799
1941
  const serverName = normalizeOptionalString(item.server);
1800
1942
  const toolName = normalizeOptionalString(item.tool);
1801
1943
  const uiResourceUri = readMcpAppResourceUri(item);
1944
+ const connectorId = readMcpAppConnectorId(item);
1802
1945
  const toolResult = readMcpToolResult(item);
1803
1946
  if (!serverName || !toolName || !uiResourceUri || !toolResult) return;
1804
- const allowedAppToolNames = new Set((await runtime.getCatalog()).tools.filter((tool) => tool.serverName === serverName).map((tool) => tool.toolName));
1805
- if (allowedAppToolNames.size === 0) return;
1947
+ if (serverName === CODEX_APPS_MCP_SERVER$1 && !connectorId) return;
1948
+ const runtime = createNativeMcpRuntime({
1949
+ ...params,
1950
+ originCallId: item.id,
1951
+ ...connectorId ? { connectorId } : {}
1952
+ });
1953
+ const tools = (await runtime.listTools?.(serverName))?.tools ?? [];
1954
+ const allowedAppToolNames = new Set(tools.filter((tool) => {
1955
+ const uiVisibility = readCodexMcpToolUiVisibility(tool);
1956
+ return (uiVisibility === void 0 || uiVisibility.includes("app")) && (serverName !== CODEX_APPS_MCP_SERVER$1 || readCodexMcpToolConnectorId(tool) === connectorId);
1957
+ }).map((tool) => tool.name));
1958
+ if (!allowedAppToolNames.has(toolName)) return;
1806
1959
  return await prepareHarnessNativeMcpAppPreview({
1807
1960
  runtime,
1808
1961
  serverName,
@@ -2208,6 +2361,16 @@ async function activateCodexAttemptTurn(resources, turnRuntime, lifecycle, notif
2208
2361
  }, resourceState.thread.threadId, activeTurnId, {
2209
2362
  initialContextTokens: connection.mutable.startupContextTokens,
2210
2363
  nativePostToolUseRelayEnabled: resourceState.nativeHookRelay?.allowedEvents.includes("post_tool_use") === true && resourceState.nativeHookRelay.shouldRelayEvent("post_tool_use"),
2364
+ asyncUserMessageAllowed: params.disableTools !== true && (params.toolsAllow === void 0 || toolBridge.availableTools.some((tool) => tool.name === "message")),
2365
+ onAsyncDelivery: async (delivery) => {
2366
+ return await codexTranscriptMirrorRuntime.deliverAsyncMessageBestEffort({
2367
+ params: dynamicToolParams,
2368
+ cwd: effectiveCwd,
2369
+ threadId: resourceState.thread.threadId,
2370
+ turnId: activeTurnId,
2371
+ ...delivery
2372
+ });
2373
+ },
2211
2374
  readRecentRateLimits: () => readRecentCodexRateLimits(resourceState.client),
2212
2375
  runAbortSignal: runAbortController.signal,
2213
2376
  remoteWorkspaceRoot: connection.appServer.remoteWorkspaceRoot,
@@ -2265,6 +2428,18 @@ async function activateCodexAttemptTurn(resources, turnRuntime, lifecycle, notif
2265
2428
  turnWatches.armAttemptIdleWatch();
2266
2429
  turnWatches.touchActivity("turn:start", { attemptProgress: true });
2267
2430
  for (const failure of pendingNativePreToolUseFailures.splice(0)) activeProjector.recordNativeToolPreToolUseFailure(failure);
2431
+ const notifyUserMessagePersisted = createCodexAppServerUserMessagePersistenceNotifier(params);
2432
+ const promptMirrorPromise = mirrorPromptAtTurnStartBestEffort({
2433
+ params,
2434
+ agentId: sessionAgentId,
2435
+ notifyUserMessagePersisted,
2436
+ sessionKey: sandboxSessionKey,
2437
+ cwd: effectiveCwd,
2438
+ threadId: resourceState.thread.threadId,
2439
+ turnId: activeTurnId,
2440
+ upstreamUserText: turnState.codexTurnPromptText
2441
+ });
2442
+ await promptMirrorPromise;
2268
2443
  if (resourceState.turnRoute) try {
2269
2444
  await resourceState.turnRoute.bindTurn(activeTurnId);
2270
2445
  } catch (error) {
@@ -2289,17 +2464,6 @@ async function activateCodexAttemptTurn(resources, turnRuntime, lifecycle, notif
2289
2464
  turnId: activeTurnId
2290
2465
  });
2291
2466
  }
2292
- const notifyUserMessagePersisted = createCodexAppServerUserMessagePersistenceNotifier(params);
2293
- const promptMirrorPromise = mirrorPromptAtTurnStartBestEffort({
2294
- params,
2295
- agentId: sessionAgentId,
2296
- notifyUserMessagePersisted,
2297
- sessionKey: sandboxSessionKey,
2298
- cwd: effectiveCwd,
2299
- threadId: resourceState.thread.threadId,
2300
- turnId: activeTurnId,
2301
- upstreamUserText: turnState.codexTurnPromptText
2302
- });
2303
2467
  const activeSteeringQueue = createCodexSteeringQueue({
2304
2468
  client: resourceState.client,
2305
2469
  threadId: resourceState.thread.threadId,
@@ -2311,18 +2475,21 @@ async function activateCodexAttemptTurn(resources, turnRuntime, lifecycle, notif
2311
2475
  if (inboundItems.length === 0) return;
2312
2476
  await promptMirrorPromise;
2313
2477
  const messages = activeProjector.buildSteeringTranscriptPrefix();
2314
- if (params.sessionTarget && messages.length > 0) await codexTranscriptMirrorRuntime.mirror({
2315
- agentId: sessionAgentId,
2316
- sessionKey: contextSessionKey,
2317
- sessionId: params.sessionId,
2318
- storePath: params.sessionTarget.storePath,
2319
- cwd: effectiveCwd,
2320
- messages,
2321
- idempotencyScope: `codex-app-server:${resourceState.thread.threadId}`,
2322
- runId: params.runId,
2323
- runMirrorIdentityPrefix: `${activeTurnId}:`,
2324
- config: params.config
2325
- });
2478
+ if (params.sessionTarget && messages.length > 0) {
2479
+ await codexTranscriptMirrorRuntime.mirror({
2480
+ agentId: sessionAgentId,
2481
+ sessionKey: contextSessionKey,
2482
+ sessionId: params.sessionId,
2483
+ storePath: params.sessionTarget.storePath,
2484
+ cwd: effectiveCwd,
2485
+ messages,
2486
+ idempotencyScope: `codex-app-server:${resourceState.thread.threadId}`,
2487
+ runId: params.runId,
2488
+ runMirrorIdentityPrefix: `${activeTurnId}:`,
2489
+ config: params.config
2490
+ });
2491
+ activeProjector.markSteeringTranscriptPersisted();
2492
+ }
2326
2493
  for (const item of inboundItems) {
2327
2494
  const recorder = item.userTurnTranscriptRecorder;
2328
2495
  if (!recorder) continue;
@@ -2579,105 +2746,6 @@ async function runCodexAgentEndHook(params, hookParams) {
2579
2746
  runAgentEndSideEffects(sideEffectParams);
2580
2747
  }
2581
2748
  //#endregion
2582
- //#region extensions/codex/src/app-server/session-permission-policy.ts
2583
- function tupleForMode(mode, canUseAutoReview) {
2584
- switch (mode) {
2585
- case "read-only": return {
2586
- sandbox: "read-only",
2587
- approvalPolicy: "on-request",
2588
- approvalsReviewer: "user"
2589
- };
2590
- case "guarded": return {
2591
- sandbox: "workspace-write",
2592
- approvalPolicy: "on-request",
2593
- approvalsReviewer: "user"
2594
- };
2595
- case "workspace": return {
2596
- sandbox: "workspace-write",
2597
- approvalPolicy: "on-request",
2598
- approvalsReviewer: canUseAutoReview ? "auto_review" : "user"
2599
- };
2600
- case "full": return {
2601
- sandbox: "danger-full-access",
2602
- approvalPolicy: "never",
2603
- approvalsReviewer: "user"
2604
- };
2605
- }
2606
- return mode;
2607
- }
2608
- function requirementsAllowTuple(tuple, allowed) {
2609
- return (allowed.sandboxes === void 0 || allowed.sandboxes.has(tuple.sandbox)) && (allowed.approvalPolicies === void 0 || allowed.approvalPolicies.has(tuple.approvalPolicy)) && (allowed.reviewers === void 0 || allowed.reviewers.has(tuple.approvalsReviewer));
2610
- }
2611
- function tightenTupleForExecMode(tuple, execMode) {
2612
- switch (execMode) {
2613
- case "deny":
2614
- case "allowlist": return {
2615
- sandbox: "read-only",
2616
- approvalPolicy: "on-request",
2617
- approvalsReviewer: "user"
2618
- };
2619
- case "ask": return {
2620
- ...tuple,
2621
- approvalPolicy: "on-request",
2622
- approvalsReviewer: "user"
2623
- };
2624
- case "auto":
2625
- case "full":
2626
- case void 0: return tuple;
2627
- }
2628
- return execMode;
2629
- }
2630
- function clampSessionPermissionTuple(params) {
2631
- if (!params.requirementsToml) return params.requested;
2632
- const allowed = {
2633
- sandboxes: parseAllowedSandboxModesFromCodexRequirements(params.requirementsToml, params.hostName ?? hostname()),
2634
- approvalPolicies: parseAllowedApprovalPoliciesFromCodexRequirements(params.requirementsToml),
2635
- reviewers: parseAllowedApprovalsReviewersFromCodexRequirements(params.requirementsToml)
2636
- };
2637
- if (requirementsAllowTuple(params.requested, allowed)) return params.requested;
2638
- const userReviewRequired = params.mode === "read-only" || params.mode === "guarded" || params.mode === "workspace" && !params.canUseAutoReview;
2639
- return {
2640
- sandbox: selectGuardianSandbox(allowed.sandboxes),
2641
- approvalPolicy: selectGuardianApprovalPolicy(allowed.approvalPolicies, userReviewRequired ? "ask" : "auto"),
2642
- approvalsReviewer: userReviewRequired ? selectUserApprovalsReviewer(allowed.reviewers) : selectGuardianApprovalsReviewer(allowed.reviewers, "auto")
2643
- };
2644
- }
2645
- /** Applies one complete session-mode tuple without mixing requirements-clamped fields. */
2646
- function applyCodexSessionPermissionPolicy(params) {
2647
- if (!params.permissionMode) return params.appServer;
2648
- const sessionRoot = params.sessionRoot?.trim();
2649
- if (!sessionRoot) throw new Error("Codex session permission mode requires a recorded session root");
2650
- if (params.policyLocked) return {
2651
- ...params.appServer,
2652
- sessionRoot
2653
- };
2654
- const requested = tightenTupleForExecMode(tupleForMode(params.permissionMode, params.canUseAutoReview), params.execMode);
2655
- const tuple = params.appServer.start.transport === "stdio" ? clampSessionPermissionTuple({
2656
- mode: params.permissionMode,
2657
- requested,
2658
- requirementsToml: params.requirementsToml,
2659
- hostName: params.hostName,
2660
- canUseAutoReview: params.canUseAutoReview
2661
- }) : requested;
2662
- const networkProxy = params.appServer.networkProxy ? resolveCodexAppServerNetworkProxy(params.pluginConfig.appServer?.networkProxy, tuple.sandbox).networkProxy : void 0;
2663
- const resolved = {
2664
- ...params.appServer,
2665
- ...tuple,
2666
- sessionRoot
2667
- };
2668
- if (networkProxy) resolved.networkProxy = networkProxy;
2669
- else delete resolved.networkProxy;
2670
- return resolved;
2671
- }
2672
- /** Keeps relative execution inside the prepared root without filesystem rediscovery. */
2673
- function resolveCodexSessionPermissionCwd(params) {
2674
- if (!params.permissionMode) return params.requestedCwd ?? params.fallbackCwd;
2675
- const sessionRoot = params.sessionRoot?.trim();
2676
- if (!sessionRoot) throw new Error("Codex session permission mode requires a recorded session root");
2677
- const requestedCwd = params.requestedCwd?.trim();
2678
- return requestedCwd && isPathInside(sessionRoot, requestedCwd) ? requestedCwd : sessionRoot;
2679
- }
2680
- //#endregion
2681
2749
  //#region extensions/codex/src/app-server/startup-binding.ts
2682
2750
  const CODEX_APP_SERVER_NATIVE_THREAD_FALLBACK_MAX_TOKENS = 3e5;
2683
2751
  const CODEX_APP_SERVER_NATIVE_THREAD_DEFAULT_RESERVE_TOKENS = 2e4;
@@ -3150,6 +3218,7 @@ async function prepareCodexAttemptConnection({ params, options }) {
3150
3218
  const sessionPermissionCwd = resolveCodexSessionPermissionCwd({
3151
3219
  permissionMode: params.permissionMode,
3152
3220
  sessionRoot: params.sessionRoot,
3221
+ defaultRoot: effectiveWorkspace,
3153
3222
  requestedCwd,
3154
3223
  fallbackCwd: effectiveWorkspace
3155
3224
  });
@@ -3160,14 +3229,20 @@ async function prepareCodexAttemptConnection({ params, options }) {
3160
3229
  appServer,
3161
3230
  permissionMode: params.permissionMode,
3162
3231
  sessionRoot: params.sessionRoot,
3232
+ defaultRoot: effectiveWorkspace,
3163
3233
  pluginConfig,
3164
3234
  canUseAutoReview: canUseCodexModelBackedApprovalsReviewerForModel({
3165
3235
  modelProvider: selection.modelProvider,
3166
3236
  model: selection.model,
3167
3237
  config: params.config,
3168
- env: process.env,
3238
+ env: {
3239
+ ...process.env,
3240
+ ...appServer.start.env,
3241
+ ...shellEnvironment
3242
+ },
3169
3243
  agentDir,
3170
- homeScope: appServer.start.homeScope
3244
+ homeScope: appServer.start.homeScope,
3245
+ codexArgs: appServer.start.args
3171
3246
  }),
3172
3247
  requirementsToml,
3173
3248
  policyLocked: startupBinding?.connectionScope === "supervision",
@@ -3180,7 +3255,11 @@ async function prepareCodexAttemptConnection({ params, options }) {
3180
3255
  provider: selection.modelProvider,
3181
3256
  model: selection.model,
3182
3257
  config: params.config,
3183
- env: process.env,
3258
+ env: {
3259
+ ...process.env,
3260
+ ...session.start.env,
3261
+ ...shellEnvironment
3262
+ },
3184
3263
  agentDir
3185
3264
  });
3186
3265
  return {
@@ -3244,6 +3323,17 @@ async function prepareCodexAttemptConnection({ params, options }) {
3244
3323
  resolvedAppServer = resolveFinalAppServer(configuredAppServer, reviewerPolicyContext);
3245
3324
  appServer = resolvedAppServer.appServer;
3246
3325
  }
3326
+ const sessionPermissionPolicy = resolveCodexEffectiveSessionPermissionPolicy({
3327
+ appServer,
3328
+ permissionMode: params.permissionMode,
3329
+ sessionRoot: params.sessionRoot,
3330
+ defaultRoot: effectiveWorkspace
3331
+ });
3332
+ if (sessionPermissionPolicy) {
3333
+ params.permissionMode = sessionPermissionPolicy.mode;
3334
+ params.sessionRoot = sessionPermissionPolicy.root;
3335
+ (params.execOverrides ??= {}).mode = sessionPermissionPolicy.execMode;
3336
+ }
3247
3337
  const nativeHookRelayEvents = resolveCodexNativeHookRelayEvents({
3248
3338
  configuredEvents: options.nativeHookRelay?.events,
3249
3339
  appServer
@@ -3290,6 +3380,7 @@ async function prepareCodexAttemptConnection({ params, options }) {
3290
3380
  effectiveWorkspace,
3291
3381
  effectiveCwd,
3292
3382
  appServer,
3383
+ sessionPermissionPolicy,
3293
3384
  nativeHookRelayEvents,
3294
3385
  runAbortController,
3295
3386
  terminalState,
@@ -4501,7 +4592,7 @@ async function finalizeCodexAttempt(resources, turnRuntime, lifecycle, notificat
4501
4592
  const { hookContextWindowFields, hookRunner } = context;
4502
4593
  const { connection, preparedAuthBinding } = runtime;
4503
4594
  const { effectiveRuntimeProviderId, effectiveRuntimeModelId } = runtime;
4504
- const { params, terminalState, runAbortController, activeContextEngine, bindingStore, bindingIdentity, appServer, usesSupervisionConnection, sessionAgentId, contextSessionKey, effectiveCwd, attemptStartedAt, startupAuthProfileId } = connection;
4595
+ const { params, terminalState, runAbortController, activeContextEngine, bindingStore, bindingIdentity, appServer, usesSupervisionConnection, sessionAgentId, contextSessionKey, effectiveCwd, agentDir, attemptStartedAt, startupAuthProfileId } = connection;
4505
4596
  const { toolBridge, toolState } = attemptTools;
4506
4597
  const { state, completion, pendingOpenClawDynamicToolCompletionIds, activeTurnItemIds, activeCompletionBlockerItemIds, activeFinalizationHookRunIds, turnWatches } = turnRuntime;
4507
4598
  const { emitLifecycleTerminal, buildLifecycleTerminalMeta } = lifecycle;
@@ -4680,20 +4771,11 @@ async function finalizeCodexAttempt(resources, turnRuntime, lifecycle, notificat
4680
4771
  modelIterations: result.modelIterations ?? 0,
4681
4772
  skillWorkshopAvailable: flattenCodexDynamicToolFunctions(attemptTools.toolBridge.availableSpecs).some((tool) => tool.name === "skill_workshop"),
4682
4773
  compacted: (result.compactionCount ?? 0) > 0,
4683
- messageChannel: params.messageChannel,
4684
- messageProvider: params.messageProvider,
4685
- chatType: params.chatType,
4686
- agentAccountId: params.agentAccountId,
4687
- groupId: params.groupId,
4688
- groupChannel: params.groupChannel,
4689
- groupSpace: params.groupSpace,
4690
- memberRoleIds: params.memberRoleIds,
4691
- spawnedBy: params.spawnedBy,
4692
4774
  senderId: params.senderId ?? void 0,
4693
- senderName: params.senderName,
4694
- senderUsername: params.senderUsername,
4695
- senderE164: params.senderE164,
4696
- senderIsOwner: params.senderIsOwner
4775
+ foregroundPromptContext: buildEmbeddedForegroundPromptContext({
4776
+ ...params,
4777
+ agentId: sessionAgentId
4778
+ }, agentDir)
4697
4779
  },
4698
4780
  hookRunner
4699
4781
  });
@@ -5854,10 +5936,6 @@ function resolveScheduledCodexAppCreatorCaptureDecision(params) {
5854
5936
  ...unavailableReason ? { unavailableReason } : {}
5855
5937
  };
5856
5938
  }
5857
- function readConnectorId(tool) {
5858
- const meta = asOptionalRecord(asOptionalRecord(tool)?.["_meta"]);
5859
- return normalizeOptionalString(meta?.connector_id) ?? normalizeOptionalString(meta?.connectorId);
5860
- }
5861
5939
  function normalizeApprovalMode(value) {
5862
5940
  return value === "allow" || value === "deny" || value === "auto" || value === "ask" ? value : void 0;
5863
5941
  }
@@ -5924,7 +6002,7 @@ async function readCodexScheduledAppToolNamesByApp(params) {
5924
6002
  if (!isJsonObject(status) || !isJsonObject(status.tools)) throw new Error("Codex scheduled app inventory contained an invalid server status");
5925
6003
  if (status.name !== CODEX_APPS_MCP_SERVER) continue;
5926
6004
  for (const [toolName, tool] of Object.entries(status.tools)) {
5927
- const connectorId = readConnectorId(tool);
6005
+ const connectorId = readCodexMcpToolConnectorId(tool);
5928
6006
  if (connectorId) {
5929
6007
  const names = toolNamesByApp.get(connectorId) ?? /* @__PURE__ */ new Set();
5930
6008
  names.add(toolName);
@@ -6711,19 +6789,17 @@ function startCodexComputerUseHealthMonitor(params) {
6711
6789
  }
6712
6790
  const fingerprint = buildComputerUseHealthMonitorFingerprint(params.config);
6713
6791
  const intervalMs = params.config.healthCheckIntervalMinutes * 6e4;
6714
- if (existing?.fingerprint === fingerprint && existing.repairComputerUseMcpChildren === params.repairComputerUseMcpChildren) return {
6792
+ if (existing?.fingerprint === fingerprint) return {
6715
6793
  started: false,
6716
6794
  intervalMs,
6717
6795
  reason: "already_started"
6718
6796
  };
6719
6797
  if (existing) clearComputerUseHealthMonitor(params.client, existing);
6720
- const repairComputerUseMcpChildren = params.repairComputerUseMcpChildren ?? (() => killStaleComputerUseMcpChildren({ ancestorPid: params.client.getTransportPid() }));
6721
6798
  const monitor = {
6722
6799
  fingerprint,
6723
6800
  intervalMs,
6724
- repairComputerUseMcpChildren: params.repairComputerUseMcpChildren,
6725
6801
  timer: setInterval(() => {
6726
- runCodexComputerUseHealthProbe(params.client, params.config, monitor, { repairComputerUseMcpChildren });
6802
+ runCodexComputerUseHealthProbe(params.client, params.config, monitor);
6727
6803
  }, intervalMs),
6728
6804
  disposeCloseHandler: () => void 0,
6729
6805
  running: false
@@ -6748,13 +6824,12 @@ function buildComputerUseHealthMonitorFingerprint(config) {
6748
6824
  toolCallTimeoutMs: config.toolCallTimeoutMs
6749
6825
  });
6750
6826
  }
6751
- async function runCodexComputerUseHealthProbe(client, config, monitor, options) {
6827
+ async function runCodexComputerUseHealthProbe(client, config, monitor) {
6752
6828
  if (monitor.running) return;
6753
6829
  monitor.running = true;
6754
6830
  try {
6755
6831
  const { liveTest, repair } = await runCodexComputerUseLiveTest({
6756
6832
  config,
6757
- repairComputerUseMcpChildren: options.repairComputerUseMcpChildren,
6758
6833
  request: async (method, requestParams, requestOptions) => await client.request(method, requestParams, { timeoutMs: requestOptions?.timeoutMs ?? config.liveTestTimeoutMs })
6759
6834
  });
6760
6835
  if (!liveTest.ok) {
@@ -6767,10 +6842,7 @@ async function runCodexComputerUseHealthProbe(client, config, monitor, options)
6767
6842
  });
6768
6843
  return;
6769
6844
  }
6770
- if (repair?.killedPids.length) embeddedAgentLog.info("codex computer-use periodic health repaired stale children", {
6771
- mcpServerName: config.mcpServerName,
6772
- killedPids: repair.killedPids
6773
- });
6845
+ if (repair?.attempted && repair.warnings.length === 0) embeddedAgentLog.info("codex computer-use periodic health reloaded MCP servers", { mcpServerName: config.mcpServerName });
6774
6846
  } catch (error) {
6775
6847
  embeddedAgentLog.warn("codex computer-use periodic health probe crashed", {
6776
6848
  mcpServerName: config.mcpServerName,
@@ -6865,6 +6937,7 @@ function createCodexPluginThreadConfigStartupProvider(params) {
6865
6937
  build: async (buildOptions) => {
6866
6938
  const config = await buildCodexPluginThreadConfigWithinDeadline({
6867
6939
  ...buildParams,
6940
+ threadId: buildOptions?.threadId,
6868
6941
  appCache: appCache ?? defaultCodexAppInventoryCache,
6869
6942
  metadataCache,
6870
6943
  failClosedOnTimeout: Boolean(params.scheduledRuntimeAuthority),
@@ -6897,7 +6970,7 @@ function isCodexPluginThreadConfigTimeoutError(error) {
6897
6970
  * Startup orchestration for Codex app-server attempts, including shared-client
6898
6971
  * leasing, plugin thread config, sandbox environment, and thread lifecycle binding.
6899
6972
  */
6900
- const CODEX_APP_SERVER_STARTUP_CONNECTION_CLOSE_MAX_ATTEMPTS = 3;
6973
+ const CODEX_APP_SERVER_STARTUP_MAX_ATTEMPTS = 3;
6901
6974
  const CODEX_APP_SERVER_CONTEXT_RESTART_SELECTION_CHANGED = "CODEX_APP_SERVER_CONTEXT_RESTART_SELECTION_CHANGED";
6902
6975
  /** True when a pre-write context restart must replay on the newly selected owner. */
6903
6976
  function isCodexContextRestartSelectionChangedError(error) {
@@ -7009,7 +7082,7 @@ async function startCodexAttemptThread(params) {
7009
7082
  signal: startupAbandonController.signal
7010
7083
  });
7011
7084
  } catch (error) {
7012
- if (startupAbandonController.signal.aborted) throw error;
7085
+ if (startupAbandonController.signal.aborted || isCodexAppServerStartSelectionChangedError(error)) throw error;
7013
7086
  throw new AgentHarnessPreflightError(`Codex Computer Use readiness failed: ${formatErrorMessage(error)}`, {
7014
7087
  cause: error,
7015
7088
  scope: "harness"
@@ -7023,7 +7096,8 @@ async function startCodexAttemptThread(params) {
7023
7096
  accountId: params.startupAuthAccountCacheKey,
7024
7097
  envApiKeyFingerprint: params.startupEnvApiKeyCacheKey,
7025
7098
  appServerVersion: activeStartupClient.getServerVersion(),
7026
- runtimeIdentity: startupRuntimeIdentity
7099
+ runtimeIdentity: startupRuntimeIdentity,
7100
+ desktopGenerationFingerprint: readCodexAppServerClientDesktopGenerationFingerprint(activeStartupClient)
7027
7101
  });
7028
7102
  const appServerRuntimeFingerprint = buildCodexAppServerRuntimeFingerprint({
7029
7103
  appServer: params.appServer,
@@ -7127,6 +7201,7 @@ async function startCodexAttemptThread(params) {
7127
7201
  finalConfigPatch: params.finalConfigPatch,
7128
7202
  buildFinalConfigPatch: params.buildFinalConfigPatch,
7129
7203
  nativeHookRelayGeneration: params.nativeHookRelayGeneration,
7204
+ nativeHookRelayRequired: params.nativeHookRelayRequired,
7130
7205
  nativeCodeModeEnabled: params.nativeToolSurfaceEnabled,
7131
7206
  nativeProviderWebSearchSupport: params.nativeProviderWebSearchSupport,
7132
7207
  nativeCodeModeOnlyEnabled: params.appServer.codeModeOnly,
@@ -7221,30 +7296,31 @@ async function startCodexAttemptThread(params) {
7221
7296
  }
7222
7297
  }
7223
7298
  };
7224
- for (let attempt = 1; attempt <= CODEX_APP_SERVER_STARTUP_CONNECTION_CLOSE_MAX_ATTEMPTS; attempt += 1) try {
7299
+ for (let attempt = 1; attempt <= CODEX_APP_SERVER_STARTUP_MAX_ATTEMPTS; attempt += 1) try {
7225
7300
  return await startupAttempt();
7226
7301
  } catch (error) {
7227
7302
  const selectionChanged = isCodexAppServerStartSelectionChangedError(error);
7228
7303
  if (startupAbandoned || params.signal.aborted || !selectionChanged && !isCodexAppServerConnectionClosedError(error)) throw error;
7229
- const failedClient = attemptedClient;
7230
- const refreshedSharedClient = selectionChanged ? retireSharedCodexAppServerClientIfCurrent(failedClient) : clearSharedCodexAppServerClientIfCurrent(failedClient);
7231
- if (startupClientForAbandonedRequestCleanup === failedClient) startupClientForAbandonedRequestCleanup = void 0;
7232
- if (attempt >= CODEX_APP_SERVER_STARTUP_CONNECTION_CLOSE_MAX_ATTEMPTS) {
7304
+ const refreshedSharedClient = selectionChanged ? retireSharedCodexAppServerClientIfCurrent(attemptedClient) : clearSharedCodexAppServerClientIfCurrent(attemptedClient);
7305
+ if (startupClientForAbandonedRequestCleanup === attemptedClient) startupClientForAbandonedRequestCleanup = void 0;
7306
+ if (attempt >= CODEX_APP_SERVER_STARTUP_MAX_ATTEMPTS) {
7233
7307
  embeddedAgentLog.warn(selectionChanged ? "codex app-server executable selection kept changing during startup; retries exhausted" : "codex app-server connection closed during startup; retries exhausted", {
7234
7308
  attempt,
7235
- maxAttempts: CODEX_APP_SERVER_STARTUP_CONNECTION_CLOSE_MAX_ATTEMPTS,
7309
+ maxAttempts: CODEX_APP_SERVER_STARTUP_MAX_ATTEMPTS,
7236
7310
  refreshedSharedClient,
7237
7311
  error: formatErrorMessage(error)
7238
7312
  });
7239
7313
  throw error;
7240
7314
  }
7315
+ const retryDelayMs = selectionChanged ? 0 : 1e3 * 2 ** (attempt - 1);
7241
7316
  embeddedAgentLog.warn(selectionChanged ? "codex app-server executable selection changed during startup; restarting app-server and retrying" : "codex app-server connection closed during startup; restarting app-server and retrying", {
7242
7317
  attempt,
7243
7318
  nextAttempt: attempt + 1,
7244
- maxAttempts: CODEX_APP_SERVER_STARTUP_CONNECTION_CLOSE_MAX_ATTEMPTS,
7319
+ maxAttempts: CODEX_APP_SERVER_STARTUP_MAX_ATTEMPTS,
7245
7320
  refreshedSharedClient,
7246
7321
  error: formatErrorMessage(error)
7247
7322
  });
7323
+ await sleepWithAbort(retryDelayMs, startupAbandonController.signal);
7248
7324
  }
7249
7325
  throw new Error("codex app-server startup retry loop exited unexpectedly");
7250
7326
  }
@@ -7296,6 +7372,7 @@ async function startCodexAttemptRuntime(resources) {
7296
7372
  const developerInstructions = joinPresentSections(turnState.promptBuild.developerInstructions, attemptTools.scheduledConfiguredMcp?.diagnosticNotice);
7297
7373
  const { params, attemptClientFactory, bindingStore, appServer, pluginConfig, computerUseConfig, startupClientAuthProfileId, runtimeArtifactRequest, startupPreparedAuth, agentDir, sessionAgentId, effectiveWorkspace, effectiveCwd, sandbox, runAbortController, usesSupervisionConnection, resolveReviewerPolicyContext, resolveRuntimeOptionsForCurrentBinding, startupAuthProfileId, startupAuthRequirement, abortFromUpstream } = connection;
7298
7374
  let pluginAppServer = withCodexAppServerFastModeServiceTier(appServer, runtimeParams);
7375
+ const loopDetectionEnabled = (sessionAgentId && params.config ? resolveAgentConfig$1(params.config, sessionAgentId)?.tools?.loopDetection?.enabled : void 0) ?? params.config?.tools?.loopDetection?.enabled ?? false;
7299
7376
  try {
7300
7377
  emitCodexAppServerEvent(params, {
7301
7378
  stream: "codex_app_server.lifecycle",
@@ -7330,6 +7407,7 @@ async function startCodexAttemptRuntime(resources) {
7330
7407
  developerInstructions,
7331
7408
  agentWorkspaceDeveloperInstructions: context.agentWorkspaceDeveloperInstructions,
7332
7409
  buildFinalConfigPatch: buildNativeHookRelayFinalConfigPatch,
7410
+ nativeHookRelayRequired: connection.options.nativeHookRelay?.enabled !== false && params.pluginHarnessToolPolicyRestricted !== true && connection.nativeHookRelayEvents.includes("pre_tool_use") && (hasBeforeToolCallPolicy() || appServer.loopDetectionPreToolUseRelay && Boolean(connection.sandboxSessionKey) && loopDetectionEnabled),
7333
7411
  bundleMcpThreadConfig,
7334
7412
  configuredMcpOwnershipVersion: attemptTools.configuredMcpOwnershipVersion,
7335
7413
  nativeToolSurfaceEnabled,
@@ -7436,7 +7514,7 @@ function isAuthorityResolutionOperationAbort(error, signal) {
7436
7514
  }
7437
7515
  async function prepareCodexAttemptTools(runtime) {
7438
7516
  const { connection, bundleMcpThreadConfig, bundleManifestRegistry, runtimeParams, effectiveRuntimeModelId, nativeToolSurfaceEnabled, nativeProviderWebSearchSupport, hookChannelId, codexMcpToolOverrides, authenticatedScheduledMode, ownsScheduledConfiguredMcpSurface, canResolveScheduledConfiguredMcpCreatorAuthority } = runtime;
7439
- const { params, preDynamicStartupStages, mutable, startupAuthProfileId, resolvedWorkspace, effectiveWorkspace, effectiveCwd, sandboxSessionKey, sandbox, runAbortController, sessionAgentId, pluginConfig, profilerEnabled, agentDir } = connection;
7517
+ const { params, preDynamicStartupStages, mutable, startupAuthProfileId, resolvedWorkspace, effectiveWorkspace, effectiveCwd, sandboxSessionKey, sandbox, sessionPermissionPolicy, runAbortController, sessionAgentId, pluginConfig, profilerEnabled, agentDir } = connection;
7440
7518
  const preDynamicSummary = preDynamicStartupStages.snapshot();
7441
7519
  if (shouldWarnCodexDynamicToolBuildStageSummary(preDynamicSummary)) embeddedAgentLog.warn(`codex app-server pre-dynamic startup timings runId=${params.runId} sessionId=${params.sessionId} totalMs=${preDynamicSummary.totalMs} stages=${formatCodexDynamicToolBuildStageSummary(preDynamicSummary)}`, {
7442
7520
  runId: params.runId,
@@ -7509,6 +7587,7 @@ async function prepareCodexAttemptTools(runtime) {
7509
7587
  effectiveCwd,
7510
7588
  sandboxSessionKey,
7511
7589
  sandbox,
7590
+ sessionPermissionPolicy,
7512
7591
  nativeToolSurfaceEnabled,
7513
7592
  nativeProviderWebSearchSupport,
7514
7593
  runAbortController,