@openclaw/codex 2026.7.2-beta.2 → 2026.7.2-beta.3

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 (31) hide show
  1. package/dist/{app-server-policy-Scc-Wevo.js → app-server-policy-DUMF2Xyr.js} +1 -1
  2. package/dist/{attempt-notifications-BFmNhqFl.js → attempt-notifications-Ecjyzufe.js} +1 -1
  3. package/dist/cli-metadata.js +1 -1
  4. package/dist/{command-formatters-Dq9InZUK.js → command-formatters-NCTL7A2q.js} +7 -3
  5. package/dist/{command-handlers-IgqmL_kv.js → command-handlers-DtFbZiba.js} +69 -11
  6. package/dist/{compact-DCTmg3id.js → compact-Kgy26gIM.js} +4 -4
  7. package/dist/{computer-use-CPcU8TjG.js → computer-use-C7x4ZaqR.js} +4 -4
  8. package/dist/{conversation-control-CGkBlfc5.js → conversation-control-B0s3aIjT.js} +5 -5
  9. package/dist/doctor-contract-api.js +1 -1
  10. package/dist/{dynamic-tools-C_1tEs34.js → dynamic-tools-D_vSVmv9.js} +253 -114
  11. package/dist/harness.js +8 -7
  12. package/dist/index.js +16 -16
  13. package/dist/{media-understanding-provider-D31dOJwb.js → media-understanding-provider-IPNNQre6.js} +6 -6
  14. package/dist/media-understanding-provider.js +1 -1
  15. package/dist/{models-uh26C8QU.js → models-DD5zBdX5.js} +1 -1
  16. package/dist/{notification-correlation-KmfV4EkP.js → notification-correlation-C8DVQ_Bq.js} +3 -3
  17. package/dist/{plugin-app-cache-key-Ceb-lm2c.js → plugin-app-cache-key-DJbhLYSK.js} +2 -2
  18. package/dist/{rate-limits-DyXaYAxU.js → rate-limits-CqhWQ2R9.js} +3 -1
  19. package/dist/{request-B_oQsCXy.js → request-9yf9pZjf.js} +1 -1
  20. package/dist/{run-attempt-MLzoMe_m.js → run-attempt-BIoO8ISr.js} +158 -76
  21. package/dist/{session-binding-h1mmCGnl.js → session-binding-Bmt20HfB.js} +2 -0
  22. package/dist/{session-catalog-CEvoXWHA.js → session-catalog-CA7R-hX2.js} +43 -22
  23. package/dist/{session-cli-XsEuWb_C.js → session-cli-Bxk3-Wqz.js} +2 -2
  24. package/dist/{shared-client-JiAnW6pc.js → shared-client-CSXLtCLE.js} +52 -3
  25. package/dist/{side-question-DqDvIwSU.js → side-question-DtzquMOb.js} +7 -7
  26. package/dist/{thread-lifecycle-CN_pPtPh.js → thread-lifecycle-CQ_9mAa1.js} +40 -9
  27. package/dist/{usage-D5Rohxoc.js → usage-CuPpFgTc.js} +3 -3
  28. package/dist/{web-search-provider.runtime-CKVBn3fP.js → web-search-provider.runtime-_x5XTeqh.js} +3 -3
  29. package/npm-shrinkwrap.json +30 -30
  30. package/openclaw.plugin.json +11 -1
  31. package/package.json +5 -5
@@ -1,15 +1,15 @@
1
- import { A as isCodexAppServerStartupError, B as isCodexAppServerApprovalRequest, C as resolveCodexAppServerFallbackApiKeyCacheKey, D as resolveCodexAppServerHomeDir, F as resolveCodexTurnCompletionIdleTimeoutMs, H as isCodexAppServerConnectionClosedError, I as resolveCodexTurnTerminalIdleTimeoutMs, K as isCodexAppServerRequestTimeoutError, L as withCodexStartupTimeout, M as resolveCodexPostToolRawAssistantCompletionIdleTimeoutMs, N as resolveCodexStartupTimeoutMs, O as CODEX_POST_REASONING_REPLY_IDLE_TIMEOUT_MS, P as resolveCodexTurnAssistantCompletionIdleTimeoutMs, R as CodexAppServerRpcError, S as resolveCodexAppServerAuthProfileIdForAgent, T as resolveCodexAppServerPreparedAuthHandoff, V as isCodexAppServerBrokenPipeError, X as flattenCodexDynamicToolFunctions, Z as isJsonObject, _ as readCodexRateLimitsRevision, a as getLeasedSharedCodexAppServerClient, b as resolveCodexAppServerAuthAccountCacheKey, c as releaseLeasedSharedCodexAppServerClient, d as retireSharedCodexAppServerClientIfCurrent, g as ensureCodexAppServerClientRuntime, k as CodexAppServerStartupError, n as clearSharedCodexAppServerClientIfCurrentAndUnclaimed, o as isCodexAppServerStartSelectionChangedError, t as clearSharedCodexAppServerClientIfCurrent, u as retainSharedCodexAppServerClientIfCurrent, v as readRecentCodexRateLimits, w as resolveCodexAppServerPreparedApiKeyCacheKey, x as resolveCodexAppServerAuthProfileId } from "./shared-client-JiAnW6pc.js";
2
- import { S as updateActiveTurnItemIds, _ as readCodexNotificationItem, a as isCodexTurnAbortMarkerNotification, b as shouldDisarmAssistantCompletionIdleWatch, c as isPendingOpenClawDynamicToolCompletionNotification, d as isRawReasoningCompletionNotification, f as isRawToolOutputCompletionNotification, g as isTerminalTurnStatus, h as isRetryableErrorNotification, i as isAssistantCompletionReleaseNotification, l as isRawAssistantProgressNotification, m as isReasoningProgressNotification, n as describeNotificationActivity, o as isFileChangePatchUpdatedNotification, p as isReasoningItemCompletionNotification, r as isAssistantCommentaryCompletionNotification, s as isNativeToolProgressNotification, t as codexExecutionToolName, u as isRawFunctionToolOutputCompletionNotification, v as readNotificationItemId, x as updateActiveCompletionBlockerItemIds, y as readRawResponseToolCallId } from "./attempt-notifications-BFmNhqFl.js";
3
- import { C as resolveCodexComputerUseConfig, D as resolveOpenClawExecPolicyForCodexAppServer, O as shouldAutoApproveCodexAppServerApprovals, T as resolveCodexPluginsPolicy, c as sessionBindingIdentity, g as isCodexAppServerApprovalPolicyAllowedByRequirements, k as withMcpElicitationsApprovalPolicy, s as reclaimCurrentCodexSessionGeneration, v as isCodexSandboxExecServerEnabled, w as resolveCodexModelBackedReviewerPolicyContext, y as readCodexPluginConfig } from "./session-binding-h1mmCGnl.js";
1
+ import { A as isCodexAppServerStartupError, B as isCodexAppServerApprovalRequest, C as resolveCodexAppServerFallbackApiKeyCacheKey, D as resolveCodexAppServerHomeDir, F as resolveCodexTurnCompletionIdleTimeoutMs, H as isCodexAppServerConnectionClosedError, I as resolveCodexTurnTerminalIdleTimeoutMs, K as isCodexAppServerRequestTimeoutError, L as withCodexStartupTimeout, M as resolveCodexPostToolRawAssistantCompletionIdleTimeoutMs, N as resolveCodexStartupTimeoutMs, O as CODEX_POST_REASONING_REPLY_IDLE_TIMEOUT_MS, P as resolveCodexTurnAssistantCompletionIdleTimeoutMs, R as CodexAppServerRpcError, S as resolveCodexAppServerAuthProfileIdForAgent, T as resolveCodexAppServerPreparedAuthHandoff, V as isCodexAppServerBrokenPipeError, X as flattenCodexDynamicToolFunctions, Z as isJsonObject, _ as readCodexRateLimitsRevision, a as getLeasedSharedCodexAppServerClient, b as resolveCodexAppServerAuthAccountCacheKey, c as releaseLeasedSharedCodexAppServerClient, d as retireSharedCodexAppServerClientIfCurrent, g as ensureCodexAppServerClientRuntime, k as CodexAppServerStartupError, n as clearSharedCodexAppServerClientIfCurrentAndUnclaimed, o as isCodexAppServerStartSelectionChangedError, t as clearSharedCodexAppServerClientIfCurrent, u as retainSharedCodexAppServerClientIfCurrent, v as readRecentCodexRateLimits, w as resolveCodexAppServerPreparedApiKeyCacheKey, x as resolveCodexAppServerAuthProfileId } from "./shared-client-CSXLtCLE.js";
2
+ import { S as updateActiveTurnItemIds, _ as readCodexNotificationItem, a as isCodexTurnAbortMarkerNotification, b as shouldDisarmAssistantCompletionIdleWatch, c as isPendingOpenClawDynamicToolCompletionNotification, d as isRawReasoningCompletionNotification, f as isRawToolOutputCompletionNotification, g as isTerminalTurnStatus, h as isRetryableErrorNotification, i as isAssistantCompletionReleaseNotification, l as isRawAssistantProgressNotification, m as isReasoningProgressNotification, n as describeNotificationActivity, o as isFileChangePatchUpdatedNotification, p as isReasoningItemCompletionNotification, r as isAssistantCommentaryCompletionNotification, s as isNativeToolProgressNotification, t as codexExecutionToolName, u as isRawFunctionToolOutputCompletionNotification, v as readNotificationItemId, x as updateActiveCompletionBlockerItemIds, y as readRawResponseToolCallId } from "./attempt-notifications-Ecjyzufe.js";
3
+ import { C as resolveCodexComputerUseConfig, D as resolveOpenClawExecPolicyForCodexAppServer, O as shouldAutoApproveCodexAppServerApprovals, T as resolveCodexPluginsPolicy, c as sessionBindingIdentity, g as isCodexAppServerApprovalPolicyAllowedByRequirements, k as withMcpElicitationsApprovalPolicy, s as reclaimCurrentCodexSessionGeneration, v as isCodexSandboxExecServerEnabled, w as resolveCodexModelBackedReviewerPolicyContext, y as readCodexPluginConfig } from "./session-binding-Bmt20HfB.js";
4
4
  import { _ as readCodexTurnCompletedNotification, f as assertCodexTurnStartResponse, i as mirrorPromptAtTurnStartBestEffort, n as createCodexAppServerUserMessagePersistenceNotifier, o as buildCodexUserPromptMessage, p as readCodexDynamicToolCallParams, t as codexTranscriptMirrorRuntime } from "./transcript-mirror-D9rTxx2P.js";
5
- import { i as defaultCodexAppInventoryCache, n as buildCodexAppServerRuntimeFingerprint, r as buildCodexPluginAppCacheKey } from "./plugin-app-cache-key-Ceb-lm2c.js";
6
- import { A as CodexAppServerUnsafeSubscriptionError, B as fitCodexProjectedContextForTurnStart, D as resolveCodexDynamicToolsLoadingForRuntime, F as areCodexDynamicToolFingerprintsCompatible, G as buildCodexPluginThreadConfig, H as resolveCodexContextEngineProjectionMaxChars, I as codexDynamicToolsFingerprint, J as mergeCodexThreadConfigs, K as buildCodexPluginThreadConfigInputFingerprint, L as codexLegacyDynamicToolsFingerprint, M as interruptCodexTurnBestEffort, N as retireCodexAppServerClientAfterTimedOutTurn, O as CODEX_APP_SERVER_INTERRUPT_TIMEOUT_MS, P as unsubscribeCodexThreadBestEffort, Q as resolveRecoverableCodexPluginConfigKeys, R as buildContextEngineBinding, U as resolveCodexContextEngineProjectionReserveTokens, V as projectContextEngineAssemblyForCodex, Y as shouldBuildCodexPluginThreadConfig, b as isCodexAppServerProfilerEnabled, d as resolveCodexWebSearchPlan, f as buildDeveloperInstructions, g as resolveCodexAppServerThreadModelSelection, j as closeCodexStartupClientBestEffort, k as CODEX_APP_SERVER_UNSUBSCRIBE_TIMEOUT_MS, n as buildTurnStartParams, q as buildCodexPluginThreadConfigTimeoutFallback, r as buildCodexUserInput, s as startOrResumeThread, t as buildTurnCollaborationMode, w as isSystemAgentOnlyCodexDynamicToolAllowlist, x as filterCodexDynamicTools, z as isContextEngineBindingCompatible } from "./thread-lifecycle-CN_pPtPh.js";
7
- import { r as formatCodexDisplayText } from "./command-formatters-Dq9InZUK.js";
8
- import { n as resolveCodexAppServerForOpenClawToolPolicy, t as resolveCodexAppServerForModelProvider } from "./app-server-policy-Scc-Wevo.js";
9
- import { a as resolveCodexBindingAppServerConnection, n as readCodexNotificationThreadId, r as readCodexNotificationTurnId, t as isCodexNotificationForTurn } from "./notification-correlation-KmfV4EkP.js";
5
+ import { i as defaultCodexAppInventoryCache, n as buildCodexAppServerRuntimeFingerprint, r as buildCodexPluginAppCacheKey } from "./plugin-app-cache-key-DJbhLYSK.js";
6
+ import { A as CodexAppServerUnsafeSubscriptionError, B as fitCodexProjectedContextForTurnStart, D as resolveCodexDynamicToolsLoadingForRuntime, F as areCodexDynamicToolFingerprintsCompatible, G as buildCodexPluginThreadConfig, H as resolveCodexContextEngineProjectionMaxChars, I as codexDynamicToolsFingerprint, J as mergeCodexThreadConfigs, K as buildCodexPluginThreadConfigInputFingerprint, L as codexLegacyDynamicToolsFingerprint, M as interruptCodexTurnBestEffort, N as retireCodexAppServerClientAfterTimedOutTurn, O as CODEX_APP_SERVER_INTERRUPT_TIMEOUT_MS, P as unsubscribeCodexThreadBestEffort, Q as resolveRecoverableCodexPluginConfigKeys, R as buildContextEngineBinding, U as resolveCodexContextEngineProjectionReserveTokens, V as projectContextEngineAssemblyForCodex, Y as shouldBuildCodexPluginThreadConfig, b as isCodexAppServerProfilerEnabled, d as resolveCodexWebSearchPlan, f as buildDeveloperInstructions, g as resolveCodexAppServerThreadModelSelection, j as closeCodexStartupClientBestEffort, k as CODEX_APP_SERVER_UNSUBSCRIBE_TIMEOUT_MS, n as buildTurnStartParams, q as buildCodexPluginThreadConfigTimeoutFallback, r as buildCodexUserInput, s as startOrResumeThread, t as buildTurnCollaborationMode, w as isSystemAgentOnlyCodexDynamicToolAllowlist, x as filterCodexDynamicTools, z as isContextEngineBindingCompatible } from "./thread-lifecycle-CQ_9mAa1.js";
7
+ import { r as formatCodexDisplayText } from "./command-formatters-NCTL7A2q.js";
8
+ import { n as resolveCodexAppServerForOpenClawToolPolicy, t as resolveCodexAppServerForModelProvider } from "./app-server-policy-DUMF2Xyr.js";
9
+ import { a as resolveCodexBindingAppServerConnection, n as readCodexNotificationThreadId, r as readCodexNotificationTurnId, t as isCodexNotificationForTurn } from "./notification-correlation-C8DVQ_Bq.js";
10
10
  import { n as prepareCodexAppServerAuthBinding } from "./auth-binding-C1czuHPA.js";
11
- import { $ as resolveCodexToolProgressDetailMode, B as hasPendingDynamicToolTerminalDiagnostic, C as CodexAppServerEventProjector, D as markCodexAuthProfileBlockedFromRateLimits, E as isCodexUsageLimitPromptError, F as emitCodexNativePreToolUseFailureDiagnostic, G as shouldBlockTerminalReleaseForNonTerminalDynamicToolResult, H as isMatchingDynamicToolTerminalDiagnostic, I as resolveCodexNativeHookRelayEvents, J as toCodexDynamicToolProtocolResponse, K as shouldReleaseTurnAfterTerminalDynamicTool, L as resolveCodexNativeHookRelayTtlMs, M as buildCodexNativeHookRelayConfig, N as buildCodexNativeHookRelayDisabledConfig, O as refreshCodexUsageLimitPromptError, P as createCodexNativeHookRelay, Q as inferCodexDynamicToolMeta, R as scheduleCodexNativeHookRelayUnregister, T as formatCodexTurnStartUsageLimitError, U as resolveDynamicToolCallTimeoutMs, V as isDynamicToolTerminalDiagnosticEvent, W as resolveTerminalDynamicToolBatchAction, X as readCodexMirroredSessionHistoryMessages, Y as resolveCodexToolAbortTerminalReason, Z as shouldEmitTranscriptToolProgress, _ as resolveCodexMessageToolProvider, a as emitDynamicToolStartedDiagnostic, b as shouldRequireCodexSandboxExecServerEnvironment, d as createCodexDynamicToolBuildStageTracker, et as sanitizeCodexToolArguments, f as disableCodexPluginThreadConfig, g as resolveCodexExternalSandboxPolicyForOpenClawSandbox, h as resolveCodexAppServerHookChannelId, i as emitDynamicToolErrorDiagnostic, j as CODEX_NATIVE_HOOK_RELAY_TTL_GRACE_MS, l as settleCodexSourceReplyFinality, m as resolveCodexAppServerExecutionCwd, n as handleCodexAppServerApprovalRequest, nt as resolveCodexLocalRuntimeAttribution, o as emitDynamicToolTerminalDiagnostic, p as formatCodexDynamicToolBuildStageSummary, q as toCodexDynamicToolProgressResponse, r as handleCodexAppServerElicitationRequest, s as resolveCodexProviderWebSearchSupport, t as createCodexDynamicToolBridge, tt as sanitizeCodexToolResponse, u as buildDynamicTools, v as resolveCodexSandboxEnvironmentSelection, w as createCodexUsageLimitPromptError, x as shouldWarnCodexDynamicToolBuildStageSummary, y as shouldEnableCodexAppServerNativeToolSurface, z as handleDynamicToolCallWithTimeout } from "./dynamic-tools-C_1tEs34.js";
12
- import { a as runCodexComputerUseLiveTest, r as killStaleComputerUseMcpChildren, t as ensureCodexComputerUse } from "./computer-use-CPcU8TjG.js";
11
+ import { $ as resolveCodexToolProgressDetailMode, B as hasPendingDynamicToolTerminalDiagnostic, C as CodexAppServerEventProjector, D as markCodexAuthProfileBlockedFromRateLimits, E as isCodexUsageLimitPromptError, F as emitCodexNativePreToolUseFailureDiagnostic, G as shouldBlockTerminalReleaseForNonTerminalDynamicToolResult, H as isMatchingDynamicToolTerminalDiagnostic, I as resolveCodexNativeHookRelayEvents, J as toCodexDynamicToolProtocolResponse, K as shouldReleaseTurnAfterTerminalDynamicTool, L as resolveCodexNativeHookRelayTtlMs, M as buildCodexNativeHookRelayConfig, N as buildCodexNativeHookRelayDisabledConfig, O as refreshCodexUsageLimitPromptError, P as createCodexNativeHookRelay, Q as inferCodexDynamicToolMeta, R as scheduleCodexNativeHookRelayUnregister, T as formatCodexTurnStartUsageLimitError, U as resolveDynamicToolCallTimeoutMs, V as isDynamicToolTerminalDiagnosticEvent, W as resolveTerminalDynamicToolBatchAction, X as readCodexMirroredSessionHistoryMessages, Y as resolveCodexToolAbortTerminalReason, Z as shouldEmitTranscriptToolProgress, _ as resolveCodexMessageToolProvider, a as emitDynamicToolStartedDiagnostic, b as shouldRequireCodexSandboxExecServerEnvironment, d as createCodexDynamicToolBuildStageTracker, et as sanitizeCodexToolArguments, f as disableCodexPluginThreadConfig, g as resolveCodexExternalSandboxPolicyForOpenClawSandbox, h as resolveCodexAppServerHookChannelId, i as emitDynamicToolErrorDiagnostic, j as CODEX_NATIVE_HOOK_RELAY_TTL_GRACE_MS, l as settleCodexSourceReplyFinality, m as resolveCodexAppServerExecutionCwd, n as handleCodexAppServerApprovalRequest, nt as redactCodexEventKind, o as emitDynamicToolTerminalDiagnostic, p as formatCodexDynamicToolBuildStageSummary, q as toCodexDynamicToolProgressResponse, r as handleCodexAppServerElicitationRequest, rt as resolveCodexLocalRuntimeAttribution, s as resolveCodexProviderWebSearchSupport, t as createCodexDynamicToolBridge, tt as sanitizeCodexToolResponse, u as buildDynamicTools, v as resolveCodexSandboxEnvironmentSelection, w as createCodexUsageLimitPromptError, x as shouldWarnCodexDynamicToolBuildStageSummary, y as shouldEnableCodexAppServerNativeToolSurface, z as handleDynamicToolCallWithTimeout } from "./dynamic-tools-D_vSVmv9.js";
12
+ import { a as runCodexComputerUseLiveTest, r as killStaleComputerUseMcpChildren, t as ensureCodexComputerUse } from "./computer-use-C7x4ZaqR.js";
13
13
  import fs from "node:fs/promises";
14
14
  import path, { posix } from "node:path";
15
15
  import { resolveTimerTimeoutMs } from "openclaw/plugin-sdk/number-runtime";
@@ -18,7 +18,7 @@ import { createHash, randomUUID } from "node:crypto";
18
18
  import { resolveAgentDir, resolveAgentWorkspaceDir } from "openclaw/plugin-sdk/agent-runtime";
19
19
  import { loadExecApprovals } from "openclaw/plugin-sdk/exec-approvals-runtime";
20
20
  import { asFiniteNumber, normalizeOptionalString } from "openclaw/plugin-sdk/string-coerce-runtime";
21
- import { CODEX_APP_SERVER_CONTEXT_ENGINE_HOST, FAST_MODE_AUTO_PROGRESS_KIND, assembleHarnessContextEngine, assertContextEngineHostSupport, awaitAgentEndSideEffects, bootstrapHarnessContextEngine, buildAgentHarnessUserInputAnswers, buildBootstrapContextForFiles, buildHarnessContextEngineRuntimeContext, buildHarnessContextEngineRuntimeContextFromUsage, clearActiveEmbeddedRun, deliverAgentHarnessUserInputPrompt, embeddedAgentLog, emitAgentEvent, emptyAgentHarnessUserInputAnswers, finalizeHarnessContextEngineTurn, formatErrorMessage, formatFastModeAutoProgressText, getAgentHarnessHookRunner, getBeforeToolCallPolicyDiagnosticState, isActiveHarnessContextEngine, isHostScopedAgentToolActive, loadCodexBundleMcpThreadConfig, materializeRequesterScopedMcpToolsForHarnessRun, resolveAgentDir as resolveAgentDir$1, resolveAgentHarnessBeforePromptBuildResult, resolveAgentRunAbortLifecycleFields, resolveBootstrapFilesForRun, resolveContextEngineOwnerPluginId, resolveFastModeForElapsed, resolveSandboxContext, resolveSessionAgentIds as resolveSessionAgentIds$1, resolveUserPath, runAgentCleanupStep, runAgentEndSideEffects, runAgentHarnessLlmInputHook, runAgentHarnessLlmOutputHook, runHarnessContextEngineMaintenance, setActiveEmbeddedRun, supportsModelTools } from "openclaw/plugin-sdk/agent-harness-runtime";
21
+ import { CODEX_APP_SERVER_CONTEXT_ENGINE_HOST, FAST_MODE_AUTO_PROGRESS_KIND, assembleHarnessContextEngine, assertContextEngineHostSupport, awaitAgentEndSideEffects, bootstrapHarnessContextEngine, buildAgentHarnessUserInputAnswers, buildBootstrapContextForFiles, buildHarnessContextEngineRuntimeContext, buildHarnessContextEngineRuntimeContextFromUsage, callGatewayTool, cancelPendingAgentQuestionForSession, claimPendingAgentQuestionAnswer, clearActiveEmbeddedRun, deliverAgentHarnessUserInputPrompt, embeddedAgentLog, emitAgentEvent, emptyAgentHarnessUserInputAnswers, finalizeHarnessContextEngineTurn, formatErrorMessage, formatFastModeAutoProgressText, getAgentHarnessHookRunner, getBeforeToolCallPolicyDiagnosticState, isActiveHarnessContextEngine, isHostScopedAgentToolActive, loadCodexBundleMcpThreadConfig, materializeRequesterScopedMcpToolsForHarnessRun, resolveAgentDir as resolveAgentDir$1, resolveAgentHarnessBeforePromptBuildResult, resolveAgentRunAbortLifecycleFields, resolveBootstrapFilesForRun, resolveContextEngineOwnerPluginId, resolveFastModeForElapsed, resolveSandboxContext, resolveSessionAgentIds as resolveSessionAgentIds$1, resolveUserPath, runAgentCleanupStep, runAgentEndSideEffects, runAgentHarnessGatewayQuestion, runAgentHarnessLlmInputHook, runAgentHarnessLlmOutputHook, runHarnessContextEngineMaintenance, setActiveEmbeddedRun, supportsModelTools } from "openclaw/plugin-sdk/agent-harness-runtime";
22
22
  import { spawn } from "node:child_process";
23
23
  import { once } from "node:events";
24
24
  import { isIP } from "node:net";
@@ -26,7 +26,7 @@ import { WebSocketServer } from "ws";
26
26
  import { parseSqliteSessionFileMarker } from "openclaw/plugin-sdk/session-store-runtime";
27
27
  import { fileURLToPath } from "node:url";
28
28
  import { createDiagnosticTraceContextFromActiveScope, emitTrustedDiagnosticEvent, emitTrustedDiagnosticEventWithPrivateData, freezeDiagnosticTraceContext, onInternalDiagnosticEvent, resolveDiagnosticModelContentCapturePolicy } from "openclaw/plugin-sdk/diagnostic-runtime";
29
- import { buildMemorySystemPromptAddition } from "openclaw/plugin-sdk/core";
29
+ import { prepareMemorySystemPromptAddition } from "openclaw/plugin-sdk/core";
30
30
  import { MESSAGE_TOOL_DELIVERY_HINTS } from "openclaw/plugin-sdk/message-tool-delivery-hints";
31
31
  import { createAgentHarnessTaskRuntime, deliverAgentHarnessTaskCompletion, isDurableAgentHarnessCompletionDelivery } from "openclaw/plugin-sdk/agent-harness-task-runtime";
32
32
  import { SsrFBlockedError, isBlockedHostnameOrIp } from "openclaw/plugin-sdk/ssrf-runtime";
@@ -191,40 +191,42 @@ function normalizeCodexSteerDebounceMs(value) {
191
191
  }
192
192
  //#endregion
193
193
  //#region extensions/codex/src/app-server/user-input-bridge.ts
194
- /**
195
- * Bridges Codex item/tool user-input requests to OpenClaw messaging prompts and
196
- * turns replies into app-server answer payloads.
197
- */
194
+ /** Bridges Codex request_user_input calls to gateway questions and secret text prompts. */
195
+ const DEFAULT_USER_INPUT_TIMEOUT_MS = 15 * 6e4;
198
196
  /** Creates a per-turn bridge for pending Codex user-input requests. */
199
197
  function createCodexUserInputBridge(params) {
200
- let pending;
201
- const resolvePending = (value) => {
202
- const current = pending;
198
+ let sensitiveInput;
199
+ let pendingGateway;
200
+ const gatewayCall = params.gatewayCall ?? callGatewayTool;
201
+ const resolveSecret = (value) => {
202
+ const current = sensitiveInput;
203
203
  if (!current) return;
204
- pending = void 0;
204
+ sensitiveInput = void 0;
205
205
  current.cleanup();
206
206
  current.resolve(value);
207
207
  };
208
- const resolvePendingIfCurrent = (current, value) => {
209
- if (pending !== current) return false;
210
- resolvePending(value);
208
+ const resolveSecretIfCurrent = (current, value) => {
209
+ if (sensitiveInput !== current) return false;
210
+ resolveSecret(value);
211
211
  return true;
212
212
  };
213
+ const cancelGateway = () => {
214
+ pendingGateway?.abort.abort(/* @__PURE__ */ new Error("Codex user input request cancelled"));
215
+ };
213
216
  return {
214
217
  async handleRequest(request) {
215
218
  const requestParams = readUserInputParams(request.params);
216
219
  if (!requestParams) return;
217
220
  if (requestParams.threadId !== params.threadId || requestParams.turnId !== params.turnId) return;
218
221
  if (requestParams.questions.length === 0) return emptyUserInputResponse();
219
- resolvePending(emptyUserInputResponse());
220
- return new Promise((resolve) => {
221
- const abortListener = () => resolvePending(emptyUserInputResponse());
222
+ resolveSecret(emptyUserInputResponse());
223
+ cancelGateway();
224
+ if (requestParams.questions.some((question) => question.isSecret)) return new Promise((resolve) => {
225
+ const abortListener = () => resolveSecret(emptyUserInputResponse());
222
226
  const cleanup = () => params.signal?.removeEventListener("abort", abortListener);
223
- pending = {
227
+ sensitiveInput = {
224
228
  requestId: request.id,
225
229
  threadId: requestParams.threadId,
226
- turnId: requestParams.turnId,
227
- itemId: requestParams.itemId,
228
230
  questions: requestParams.questions,
229
231
  claimed: false,
230
232
  resolve,
@@ -232,37 +234,68 @@ function createCodexUserInputBridge(params) {
232
234
  };
233
235
  params.signal?.addEventListener("abort", abortListener, { once: true });
234
236
  if (params.signal?.aborted) {
235
- resolvePending(emptyUserInputResponse());
237
+ resolveSecret(emptyUserInputResponse());
236
238
  return;
237
239
  }
238
- deliverUserInputPrompt(params.paramsForRun, requestParams.questions).catch((error) => {
239
- embeddedAgentLog.warn("failed to deliver codex user input prompt", { error });
240
+ deliverAgentHarnessUserInputPrompt(params.paramsForRun, requestParams.questions, {
241
+ formatText: formatCodexDisplayText,
242
+ intro: "Codex needs input:"
243
+ }).catch((error) => {
244
+ embeddedAgentLog.warn("failed to deliver secret codex user input prompt", { error });
240
245
  });
241
246
  });
247
+ const abort = new AbortController();
248
+ const abortFromRun = () => abort.abort(params.signal?.reason);
249
+ params.signal?.addEventListener("abort", abortFromRun, { once: true });
250
+ if (params.signal?.aborted) abortFromRun();
251
+ pendingGateway = {
252
+ requestId: request.id,
253
+ threadId: requestParams.threadId,
254
+ abort
255
+ };
256
+ try {
257
+ const result = await runAgentHarnessGatewayQuestion({
258
+ questions: requestParams.questions,
259
+ sessionKey: params.paramsForRun.sessionKey ?? params.paramsForRun.sessionId,
260
+ agentId: params.paramsForRun.agentId,
261
+ timeoutMs: requestParams.autoResolutionMs ?? params.paramsForRun.timeoutMs ?? DEFAULT_USER_INPUT_TIMEOUT_MS,
262
+ gatewayCall,
263
+ delivery: params.paramsForRun,
264
+ promptOptions: {
265
+ formatText: formatCodexDisplayText,
266
+ intro: "Codex needs input:"
267
+ },
268
+ signal: abort.signal
269
+ });
270
+ return result.status === "answered" ? result.answers : emptyUserInputResponse();
271
+ } catch (error) {
272
+ embeddedAgentLog.warn("failed to bridge codex user input through gateway", { error });
273
+ return emptyUserInputResponse();
274
+ } finally {
275
+ params.signal?.removeEventListener("abort", abortFromRun);
276
+ if (pendingGateway?.abort === abort) pendingGateway = void 0;
277
+ }
242
278
  },
243
279
  claimPendingRequest() {
244
- const current = pending;
280
+ const current = sensitiveInput;
245
281
  if (!current || current.claimed) return;
246
282
  current.claimed = true;
247
283
  return {
248
- answer: (text) => resolvePendingIfCurrent(current, buildUserInputResponse(current.questions, text)),
249
- cancel: () => resolvePendingIfCurrent(current, emptyUserInputResponse())
284
+ answer: (text) => resolveSecretIfCurrent(current, buildUserInputResponse(current.questions, text)),
285
+ cancel: () => resolveSecretIfCurrent(current, emptyUserInputResponse())
250
286
  };
251
287
  },
252
- handleQueuedMessage(text) {
253
- const current = pending;
254
- if (!current || current.claimed) return false;
255
- resolvePending(buildUserInputResponse(current.questions, text));
256
- return true;
257
- },
258
288
  handleNotification(notification) {
259
- if (notification.method !== "serverRequest/resolved" || !pending) return;
289
+ if (notification.method !== "serverRequest/resolved") return;
260
290
  const notificationParams = isJsonObject(notification.params) ? notification.params : void 0;
261
291
  const requestId = notificationParams ? readRequestId(notificationParams) : void 0;
262
- if (notificationParams && readString$3(notificationParams, "threadId") === pending.threadId && requestId !== void 0 && String(requestId) === String(pending.requestId)) resolvePending(emptyUserInputResponse());
292
+ if (!notificationParams || requestId === void 0) return;
293
+ if (sensitiveInput && readString$3(notificationParams, "threadId") === sensitiveInput.threadId && String(requestId) === String(sensitiveInput.requestId)) resolveSecret(emptyUserInputResponse());
294
+ if (pendingGateway && readString$3(notificationParams, "threadId") === pendingGateway.threadId && String(requestId) === String(pendingGateway.requestId)) pendingGateway.abort.abort(/* @__PURE__ */ new Error("Codex server request resolved"));
263
295
  },
264
296
  cancelPending() {
265
- resolvePending(emptyUserInputResponse());
297
+ resolveSecret(emptyUserInputResponse());
298
+ cancelGateway();
266
299
  }
267
300
  };
268
301
  }
@@ -277,7 +310,12 @@ function readUserInputParams(value) {
277
310
  threadId,
278
311
  turnId,
279
312
  itemId,
280
- questions: questionsRaw.map(readQuestion).filter((question) => Boolean(question))
313
+ questions: questionsRaw.map((rawQuestion) => {
314
+ const question = readQuestion(rawQuestion);
315
+ if (question && isJsonObject(rawQuestion) && rawQuestion.multiSelect === true) question.multiSelect = true;
316
+ return question;
317
+ }).filter((question) => Boolean(question)),
318
+ autoResolutionMs: typeof value.autoResolutionMs === "number" && value.autoResolutionMs > 0 ? value.autoResolutionMs : void 0
281
319
  };
282
320
  }
283
321
  function readQuestion(value) {
@@ -309,12 +347,6 @@ function readOption(value) {
309
347
  description
310
348
  } : void 0;
311
349
  }
312
- async function deliverUserInputPrompt(params, questions) {
313
- await deliverAgentHarnessUserInputPrompt(params, questions, {
314
- formatText: formatCodexDisplayText,
315
- intro: "Codex needs input:"
316
- });
317
- }
318
350
  function buildUserInputResponse(questions, inputText) {
319
351
  return buildAgentHarnessUserInputAnswers(questions, inputText);
320
352
  }
@@ -421,7 +453,23 @@ async function activateCodexAttemptTurn(resources, turnRuntime, lifecycle, notif
421
453
  const handle = {
422
454
  kind: "embedded",
423
455
  runId: params.runId,
424
- queueMessage: async (text, optionsLocal) => activeSteeringQueue.queue(text, optionsLocal),
456
+ queueMessage: async (text, optionsLocal) => {
457
+ const isInboundUserMessage = optionsLocal?.isInboundUserMessage === true;
458
+ if (isInboundUserMessage && !optionsLocal?.images?.length) {
459
+ if (await claimPendingAgentQuestionAnswer({
460
+ sessionKey: params.sessionKey ?? params.sessionId,
461
+ text
462
+ })) return;
463
+ } else if (isInboundUserMessage) try {
464
+ await cancelPendingAgentQuestionForSession({
465
+ sessionKey: params.sessionKey ?? params.sessionId,
466
+ resolvedBy: "image-reply"
467
+ });
468
+ } catch (error) {
469
+ embeddedAgentLog.warn("failed to cancel codex gateway question before image steering", { error });
470
+ }
471
+ await activeSteeringQueue.queue(text, optionsLocal);
472
+ },
425
473
  isStreaming: () => !state.completed && !runAbortController.signal.aborted,
426
474
  isStopped: () => state.completed || state.timedOut || runAbortController.signal.aborted,
427
475
  isAbortable: () => !terminalState.terminalOutcomeFrozen || terminalState.sharedAbortAllowedAfterTerminalOutcome,
@@ -1295,13 +1343,14 @@ async function buildCodexWorkspaceBootstrapContext(params) {
1295
1343
  promptContext: renderCodexWorkspaceBootstrapPromptContext(promptContextFiles),
1296
1344
  developerInstructions: renderCodexWorkspaceThreadDeveloperInstructions(developerInstructionFiles),
1297
1345
  turnScopedDeveloperInstructions: renderCodexWorkspaceCollaborationDeveloperInstructions(turnScopedDeveloperInstructionFiles),
1298
- memoryCollaborationInstructions: shouldInjectCodexOpenClawPromptContext(params.params) ? renderCodexWorkspaceMemoryCollaborationInstructions({
1346
+ memoryCollaborationInstructions: shouldInjectCodexOpenClawPromptContext(params.params) ? await renderCodexWorkspaceMemoryCollaborationInstructions({
1299
1347
  files: memoryReferenceFiles,
1300
1348
  toolNames: params.memoryToolNames,
1301
1349
  memoryToolRouted: memoryToolsAvailable,
1302
1350
  citationsMode: params.params.config?.memory?.citations,
1303
1351
  agentId: params.params.agentId ?? params.sessionAgentId,
1304
- agentSessionKey: params.sessionKey
1352
+ agentSessionKey: params.sessionKey,
1353
+ sandboxed: params.sandboxed
1305
1354
  }) : void 0,
1306
1355
  heartbeatCollaborationInstructions: renderCodexWorkspaceHeartbeatReference(heartbeatReferenceFiles)
1307
1356
  };
@@ -1656,24 +1705,26 @@ function renderCodexWorkspaceMemoryReference(params) {
1656
1705
  for (const file of params.files) lines.push(`- ${file.path}`);
1657
1706
  return lines.join("\n").trim();
1658
1707
  }
1659
- function renderCodexWorkspaceMemoryCollaborationInstructions(params) {
1660
- const sections = [params.memoryToolRouted ? renderCodexMemoryRecallInstructions({
1708
+ async function renderCodexWorkspaceMemoryCollaborationInstructions(params) {
1709
+ const sections = [params.memoryToolRouted ? await renderCodexMemoryRecallInstructions({
1661
1710
  toolNames: params.toolNames,
1662
1711
  citationsMode: params.citationsMode,
1663
1712
  agentId: params.agentId,
1664
- agentSessionKey: params.agentSessionKey
1713
+ agentSessionKey: params.agentSessionKey,
1714
+ sandboxed: params.sandboxed
1665
1715
  }) : void 0, renderCodexWorkspaceMemoryReference({
1666
1716
  files: params.files,
1667
1717
  toolNames: params.toolNames
1668
1718
  })].filter(isNonEmptyString$1);
1669
1719
  return sections.length > 0 ? sections.join("\n\n") : void 0;
1670
1720
  }
1671
- function renderCodexMemoryRecallInstructions(params) {
1672
- const memoryPrompt = buildMemorySystemPromptAddition({
1721
+ async function renderCodexMemoryRecallInstructions(params) {
1722
+ const memoryPrompt = await prepareMemorySystemPromptAddition({
1673
1723
  availableTools: new Set(params.toolNames),
1674
1724
  citationsMode: params.citationsMode,
1675
1725
  agentId: params.agentId,
1676
- agentSessionKey: params.agentSessionKey
1726
+ agentSessionKey: params.agentSessionKey,
1727
+ sandboxed: params.sandboxed
1677
1728
  });
1678
1729
  if (!memoryPrompt) return;
1679
1730
  return [memoryPrompt, renderCodexMemoryToolSearchBridge(params.toolNames)].filter(isNonEmptyString$1).join("\n").trim();
@@ -1870,7 +1921,7 @@ function buildCodexAppServerTimeoutDiagnostics(params) {
1870
1921
  //#region extensions/codex/src/app-server/run-attempt-context.ts
1871
1922
  async function prepareCodexAttemptContext(runtime, attemptTools) {
1872
1923
  const { connection, runtimeParams, activeSessionId, activeSessionFile, buildActiveRunAttemptParams, effectiveContextWindowInfo, effectiveContextTokenBudget, effectiveRuntimeProviderId, effectiveRuntimeModelId, hookChannelId } = runtime;
1873
- const { params, sessionAgentId, contextSessionKey, activeContextEngine, initialStartupBindingHadInactiveThreadBootstrap, sandboxSessionKey, effectiveWorkspace, effectiveCwd, agentDir, usesSupervisionConnection, resolvedWorkspace, initialInactiveThreadBootstrapBindingForcedFreshStart } = connection;
1924
+ const { params, sessionAgentId, contextSessionKey, activeContextEngine, initialStartupBindingHadInactiveThreadBootstrap, sandboxSessionKey, effectiveWorkspace, effectiveCwd, agentDir, usesSupervisionConnection, resolvedWorkspace, initialInactiveThreadBootstrapBindingForcedFreshStart, sandbox } = connection;
1874
1925
  const { toolBridge } = attemptTools;
1875
1926
  const activeTranscriptTarget = {
1876
1927
  agentId: sessionAgentId,
@@ -1934,7 +1985,8 @@ async function prepareCodexAttemptContext(runtime, attemptTools) {
1934
1985
  effectiveWorkspace,
1935
1986
  sessionKey: contextSessionKey,
1936
1987
  sessionAgentId,
1937
- memoryToolNames: getCodexWorkspaceMemoryToolNames(toolBridge.availableSpecs)
1988
+ memoryToolNames: getCodexWorkspaceMemoryToolNames(toolBridge.availableSpecs),
1989
+ sandboxed: sandbox?.enabled === true
1938
1990
  });
1939
1991
  const baseDeveloperInstructions = joinPresentSections(buildDeveloperInstructions(runtimeParams, { dynamicTools: toolBridge.availableSpecs }), workspaceBootstrapContext.developerInstructions);
1940
1992
  return {
@@ -2851,7 +2903,7 @@ function createCodexAttemptLifecycleController(resources, turnRuntime) {
2851
2903
  startedAt: attemptStartedAt,
2852
2904
  endedAt: Date.now(),
2853
2905
  ...data,
2854
- ...params.deferTerminalLifecycle ?? params.deferTerminalLifecycleEnd ? { phase: "finishing" } : {}
2906
+ ...params.deferTerminalLifecycle ? { phase: "finishing" } : {}
2855
2907
  }
2856
2908
  });
2857
2909
  state.lifecycleTerminalEmitted = true;
@@ -2974,7 +3026,8 @@ var ClientTurnRouter = class {
2974
3026
  gate: "open",
2975
3027
  pending: [],
2976
3028
  notificationTail: Promise.resolve(),
2977
- nativeTurnCompleted: false
3029
+ nativeTurnCompleted: false,
3030
+ ignoredTurnNotificationKeys: /* @__PURE__ */ new Set()
2978
3031
  };
2979
3032
  this.routes.set(threadId, route);
2980
3033
  if (options.onNotification || options.onRequest) this.activateNow(route, options);
@@ -3057,6 +3110,7 @@ var ClientTurnRouter = class {
3057
3110
  this.assertRoute(route);
3058
3111
  if (route.gate !== "open") throw new Error(`codex app-server thread route cannot arm from ${route.gate}`);
3059
3112
  route.gate = "armed";
3113
+ route.ignoredTurnNotificationKeys.clear();
3060
3114
  route.nativeTurnCompleted = false;
3061
3115
  route.binding = deferred();
3062
3116
  }
@@ -3106,7 +3160,10 @@ var ClientTurnRouter = class {
3106
3160
  }
3107
3161
  const handler = route.handlers.onNotification;
3108
3162
  if (!handler) return;
3109
- if (route.gate === "bound" && scope.turnId && scope.turnId !== route.turnId) return;
3163
+ if (route.gate === "bound" && scope.turnId && scope.turnId !== route.turnId) {
3164
+ this.warnDroppedStaleTurnNotification(route, notification, routeScope);
3165
+ return;
3166
+ }
3110
3167
  if (route.gate === "armed") {
3111
3168
  this.bufferNotification(route, notification, routeScope, receivedAtMs);
3112
3169
  return;
@@ -3149,11 +3206,31 @@ var ClientTurnRouter = class {
3149
3206
  flushNotifications(route) {
3150
3207
  const handler = route.handlers?.onNotification;
3151
3208
  if (!handler) return;
3152
- for (const pending of route.pending.splice(0)) if (!pending.scope.turnId || route.gate !== "bound" || pending.scope.turnId === route.turnId) {
3209
+ for (const pending of route.pending.splice(0)) {
3210
+ if (route.gate === "bound" && pending.scope.turnId && pending.scope.turnId !== route.turnId) {
3211
+ this.warnDroppedStaleTurnNotification(route, pending.notification, pending.scope);
3212
+ continue;
3213
+ }
3153
3214
  route.handlers?.onNotificationReceived?.(pending.notification, pending.scope, pending.receivedAtMs);
3154
3215
  this.enqueueNotification(route, handler, pending.notification, pending.scope);
3155
3216
  }
3156
3217
  }
3218
+ warnDroppedStaleTurnNotification(route, notification, scope) {
3219
+ if (notification.method === "turn/completed" || !scope.turnId || !route.turnId) return;
3220
+ const eventKind = redactCodexEventKind(notification.method);
3221
+ const key = JSON.stringify([notification.method, scope.turnId]);
3222
+ if (route.ignoredTurnNotificationKeys.has(key)) return;
3223
+ route.ignoredTurnNotificationKeys.add(key);
3224
+ embeddedAgentLog.warn("codex app-server notification ignored for inactive turn", {
3225
+ eventKind,
3226
+ activeThreadId: route.threadId,
3227
+ activeTurnId: route.turnId,
3228
+ threadId: scope.threadId,
3229
+ turnId: scope.turnId,
3230
+ matchesActiveThread: true,
3231
+ matchesActiveTurn: false
3232
+ });
3233
+ }
3157
3234
  bufferNotification(route, notification, scope, receivedAtMs) {
3158
3235
  if (route.pending.length < DEFAULT_PREBIND_NOTIFICATION_LIMIT) {
3159
3236
  route.pending.push({
@@ -3415,7 +3492,7 @@ function createCodexAttemptNotificationController(resources, turnRuntime, lifecy
3415
3492
  async function prepareCodexAttemptPrompt(context) {
3416
3493
  const { runtime, attemptTools, historyState, hookContext, workspaceBootstrapContext, baseDeveloperInstructions, openClawPromptContext, skillsCollaborationInstructions, promptState, codexContextProjectionMaxChars } = context;
3417
3494
  const { connection, buildActiveRunAttemptParams, effectiveContextTokenBudget, effectiveRuntimeModelId, effectiveRuntimeProviderId } = runtime;
3418
- const { params, activeContextEngine, usesSupervisionConnection, mutable, isInactiveThreadBootstrapBinding, bindingStore, bindingIdentity, agentDir, appServer, contextSessionKey, effectiveWorkspace } = connection;
3495
+ const { params, activeContextEngine, usesSupervisionConnection, mutable, isInactiveThreadBootstrapBinding, bindingStore, bindingIdentity, agentDir, appServer, contextSessionKey, effectiveWorkspace, sandbox } = connection;
3419
3496
  const { toolBridge } = attemptTools;
3420
3497
  const applyFreshThreadContinuityProjection = () => {
3421
3498
  const projection = projectContextEngineAssemblyForCodex({
@@ -3438,6 +3515,7 @@ async function prepareCodexAttemptPrompt(context) {
3438
3515
  tokenBudget: effectiveContextTokenBudget,
3439
3516
  availableTools: new Set(flattenCodexDynamicToolFunctions(toolBridge.availableSpecs).map((tool) => tool.name).filter(isNonEmptyString)),
3440
3517
  citationsMode: params.config?.memory?.citations,
3518
+ sandboxed: sandbox?.enabled === true,
3441
3519
  modelId: effectiveRuntimeModelId,
3442
3520
  contextEngineHostSupport: CODEX_APP_SERVER_CONTEXT_ENGINE_HOST,
3443
3521
  providerId: effectiveRuntimeProviderId,
@@ -3499,7 +3577,7 @@ async function prepareCodexAttemptPrompt(context) {
3499
3577
  const buildPromptFromCurrentInputs = () => resolveAgentHarnessBeforePromptBuildResult({
3500
3578
  prompt: prependCurrentInboundContext(promptState.promptText, params.currentInboundContext),
3501
3579
  developerInstructions: promptState.developerInstructions,
3502
- messages: codexModelInputHistoryMessages,
3580
+ messages: structuredClone(historyState.messages),
3503
3581
  ctx: hookContext,
3504
3582
  bootstrapContextRunKind: params.bootstrapContextRunKind,
3505
3583
  ..."beforeAgentStartResult" in params ? { beforeAgentStartResult: params.beforeAgentStartResult } : {}
@@ -6662,16 +6740,17 @@ function prepareCodexAttemptResources(prompt) {
6662
6740
  const retireSharedCodexClientForOneShotCleanup = async () => {
6663
6741
  if (params.cleanupBundleMcpOnRunEnd !== true || state.sharedCodexClientRetiredForOneShotCleanup) return;
6664
6742
  state.sharedCodexClientRetiredForOneShotCleanup = true;
6665
- const retired = retireSharedCodexAppServerClientIfCurrent(state.client);
6666
- embeddedAgentLog.info("codex app-server one-shot cleanup retired shared client", {
6743
+ const retired = clearSharedCodexAppServerClientIfCurrentAndUnclaimed(state.client);
6744
+ embeddedAgentLog.info("codex app-server one-shot cleanup checked shared client retirement", {
6667
6745
  runId: params.runId,
6668
6746
  sessionId: params.sessionId,
6669
6747
  sessionKey: params.sessionKey,
6670
- activeLeases: retired?.activeLeases ?? null,
6671
- closed: retired?.closed ?? false,
6672
- matchedSharedClient: Boolean(retired)
6748
+ activeLeases: retired.activeLeases,
6749
+ pendingAcquires: retired.pendingAcquires,
6750
+ closed: retired.closed,
6751
+ matchedSharedClient: retired.found
6673
6752
  });
6674
- if (retired?.closed) await state.client.closeAndWait({
6753
+ if (retired.closed) await state.client.closeAndWait({
6675
6754
  exitTimeoutMs: 2e3,
6676
6755
  forceKillDelayMs: 250
6677
6756
  });
@@ -8075,7 +8154,9 @@ async function startCodexAttemptRuntime(resources) {
8075
8154
  stream: "codex_app_server.lifecycle",
8076
8155
  data: {
8077
8156
  phase: "thread_ready",
8078
- threadId: state.thread.threadId
8157
+ threadId: state.thread.threadId,
8158
+ action: state.thread.lifecycle.action,
8159
+ clientId: state.client.getInstanceId()
8079
8160
  }
8080
8161
  });
8081
8162
  } catch (error) {
@@ -8299,6 +8380,7 @@ async function prepareCodexAttemptTurnRequest(resources, turnRuntime, ensureCurr
8299
8380
  model: usesSupervisionConnection ? resourceState.thread.model ?? effectiveRuntimeModelId : params.modelId,
8300
8381
  api: usesSupervisionConnection ? runtimeParams.model.api : params.model.api,
8301
8382
  transport: appServer.start.transport,
8383
+ observationUnit: "turn",
8302
8384
  ...hookContextWindowFields,
8303
8385
  trace: codexModelCallTrace
8304
8386
  },
@@ -9002,7 +9084,7 @@ function createCodexAttemptTurnState(resources) {
9002
9084
  state.resolveCompletion = resolve;
9003
9085
  });
9004
9086
  const turnCompletionIdleTimeoutMs = resolveCodexTurnCompletionIdleTimeoutMs(options.turnCompletionIdleTimeoutMs ?? appServer.turnCompletionIdleTimeoutMs);
9005
- const turnAssistantCompletionIdleTimeoutMs = resolveCodexTurnAssistantCompletionIdleTimeoutMs(options.turnAssistantCompletionIdleTimeoutMs);
9087
+ const turnAssistantCompletionIdleTimeoutMs = resolveCodexTurnAssistantCompletionIdleTimeoutMs(options.turnAssistantCompletionIdleTimeoutMs ?? appServer.turnAssistantCompletionIdleTimeoutMs);
9006
9088
  const postToolRawAssistantCompletionIdleTimeoutMs = resolveCodexPostToolRawAssistantCompletionIdleTimeoutMs(options.postToolRawAssistantCompletionIdleTimeoutMs ?? appServer.postToolRawAssistantCompletionIdleTimeoutMs, turnAssistantCompletionIdleTimeoutMs);
9007
9089
  const turnTerminalIdleTimeoutMs = resolveCodexTurnTerminalIdleTimeoutMs(options.turnTerminalIdleTimeoutMs, params.runTimeoutOverrideMs);
9008
9090
  const turnAttemptIdleTimeoutMs = Math.max(100, Math.floor(params.timeoutMs));
@@ -171,6 +171,7 @@ const codexPluginConfigSchema = z.object({
171
171
  loopDetectionPreToolUseRelay: z.boolean().optional(),
172
172
  requestTimeoutMs: z.number().positive().optional(),
173
173
  turnCompletionIdleTimeoutMs: z.number().positive().optional(),
174
+ turnAssistantCompletionIdleTimeoutMs: z.number().positive().optional(),
174
175
  postToolRawAssistantCompletionIdleTimeoutMs: z.number().positive().optional(),
175
176
  approvalPolicy: codexAppServerApprovalPolicySchema.optional(),
176
177
  sandbox: codexAppServerSandboxSchema.optional(),
@@ -367,6 +368,7 @@ function resolveCodexAppServerRuntimeOptions(params = {}) {
367
368
  loopDetectionPreToolUseRelay: config.loopDetectionPreToolUseRelay !== false,
368
369
  requestTimeoutMs: normalizePositiveNumber(config.requestTimeoutMs, 6e4),
369
370
  turnCompletionIdleTimeoutMs: normalizePositiveNumber(config.turnCompletionIdleTimeoutMs, 6e4),
371
+ turnAssistantCompletionIdleTimeoutMs: normalizePositiveNumber(config.turnAssistantCompletionIdleTimeoutMs, 1e4),
370
372
  ...config.postToolRawAssistantCompletionIdleTimeoutMs !== void 0 ? { postToolRawAssistantCompletionIdleTimeoutMs: normalizePositiveNumber(config.postToolRawAssistantCompletionIdleTimeoutMs, 6e4) } : {},
371
373
  approvalPolicy: forcedPolicy?.approvalPolicy ?? approvalPolicy,
372
374
  approvalPolicySource,
@@ -1,11 +1,11 @@
1
- import { J as CODEX_INTERACTIVE_THREAD_SOURCE_KINDS, R as CodexAppServerRpcError, Z as isJsonObject, a as getLeasedSharedCodexAppServerClient, c as releaseLeasedSharedCodexAppServerClient, q as CODEX_INTERACTIVE_CUSTOM_THREAD_SOURCES } from "./shared-client-JiAnW6pc.js";
2
- import { E as resolveCodexSupervisionAppServerRuntimeOptions, b as resolveCodexAppServerRuntimeOptions, c as sessionBindingIdentity, s as reclaimCurrentCodexSessionGeneration } from "./session-binding-h1mmCGnl.js";
1
+ import { J as CODEX_INTERACTIVE_THREAD_SOURCE_KINDS, R as CodexAppServerRpcError, Z as isJsonObject, a as getLeasedSharedCodexAppServerClient, c as releaseLeasedSharedCodexAppServerClient, m as withTimeout, q as CODEX_INTERACTIVE_CUSTOM_THREAD_SOURCES } from "./shared-client-CSXLtCLE.js";
2
+ import { E as resolveCodexSupervisionAppServerRuntimeOptions, b as resolveCodexAppServerRuntimeOptions, c as sessionBindingIdentity, s as reclaimCurrentCodexSessionGeneration } from "./session-binding-Bmt20HfB.js";
3
3
  import { r as importCodexThreadHistoryToTranscript } from "./transcript-mirror-D9rTxx2P.js";
4
- import { n as listCodexAppServerModels } from "./models-uh26C8QU.js";
5
- import { t as buildCodexAppServerConnectionFingerprint } from "./plugin-app-cache-key-Ceb-lm2c.js";
6
- import { d as CODEX_CONTROL_METHODS, f as describeControlFailure, r as formatCodexDisplayText } from "./command-formatters-Dq9InZUK.js";
4
+ import { n as listCodexAppServerModels } from "./models-DD5zBdX5.js";
5
+ import { t as buildCodexAppServerConnectionFingerprint } from "./plugin-app-cache-key-DJbhLYSK.js";
6
+ import { d as CODEX_CONTROL_METHODS, f as describeControlFailure, r as formatCodexDisplayText } from "./command-formatters-NCTL7A2q.js";
7
7
  import { n as createCodexCliNodeConversationBindingData } from "./conversation-binding-data-BHRpYbX3.js";
8
- import { n as requestCodexAppServerClientJson, r as requestCodexAppServerJson } from "./request-B_oQsCXy.js";
8
+ import { n as requestCodexAppServerClientJson, r as requestCodexAppServerJson } from "./request-9yf9pZjf.js";
9
9
  import fs from "node:fs/promises";
10
10
  import path from "node:path";
11
11
  import { timestampMsToIsoString } from "openclaw/plugin-sdk/number-runtime";
@@ -1063,6 +1063,7 @@ const CODEX_NODE_CONTINUE_COMMANDS = [
1063
1063
  CODEX_APP_SERVER_THREAD_TURNS_LIST_COMMAND,
1064
1064
  CODEX_CLI_SESSION_RESUME_COMMAND
1065
1065
  ];
1066
+ const NODE_CATALOG_LIST_RESPONSE_TIMEOUT_MS = 8e3;
1066
1067
  function nodeLabel(node) {
1067
1068
  return node.displayName?.trim() || node.remoteIp?.trim() || node.nodeId;
1068
1069
  }
@@ -1085,16 +1086,20 @@ async function listPairedNode(params) {
1085
1086
  nodeId: params.node.nodeId,
1086
1087
  canContinueCodex: canContinueCodexOnNode(params.node)
1087
1088
  };
1088
- if (params.node.connected !== true) return {
1089
- ...common,
1090
- connected: false,
1091
- sessions: [],
1092
- error: {
1093
- code: "NODE_OFFLINE",
1094
- message: "Paired node is offline"
1095
- }
1096
- };
1097
- try {
1089
+ if (params.node.connected !== true) {
1090
+ const host = {
1091
+ ...common,
1092
+ connected: false,
1093
+ sessions: [],
1094
+ error: {
1095
+ code: "NODE_OFFLINE",
1096
+ message: "Paired node is offline"
1097
+ }
1098
+ };
1099
+ params.onHost?.(host);
1100
+ return host;
1101
+ }
1102
+ const eventualHost = Promise.resolve().then(async () => {
1098
1103
  const page = filterCatalogPageByTitle(parseCatalogPage(unwrapNodeInvokePayload(await params.runtime.nodes.invoke({
1099
1104
  nodeId: params.node.nodeId,
1100
1105
  command: CODEX_APP_SERVER_THREADS_LIST_COMMAND,
@@ -1115,6 +1120,15 @@ async function listPairedNode(params) {
1115
1120
  return adopted ? Object.assign({}, session, { openClawSessionKey: adopted.key }) : session;
1116
1121
  })
1117
1122
  };
1123
+ }).catch((error) => ({
1124
+ ...common,
1125
+ connected: true,
1126
+ sessions: [],
1127
+ error: catalogError("NODE_INVOKE_FAILED", error)
1128
+ }));
1129
+ if (params.onHost) eventualHost.then(params.onHost).catch(() => void 0);
1130
+ try {
1131
+ return await withTimeout(eventualHost, NODE_CATALOG_LIST_RESPONSE_TIMEOUT_MS, "paired node Codex session catalog timed out");
1118
1132
  } catch (error) {
1119
1133
  return {
1120
1134
  ...common,
@@ -1632,7 +1646,7 @@ function createCodexSessionCatalogControlFromRequests(params) {
1632
1646
  archived: false,
1633
1647
  limit: remaining,
1634
1648
  modelProviders: [],
1635
- sortKey: "recency_at",
1649
+ sortKey: "updated_at",
1636
1650
  sortDirection: "desc",
1637
1651
  ...cwd ? { cwd } : {},
1638
1652
  ...cursor ? { cursor } : {}
@@ -1803,19 +1817,22 @@ async function listCodexSessionCatalog(params) {
1803
1817
  query,
1804
1818
  runtime: params.runtime
1805
1819
  })] : [];
1820
+ for (const host of localHosts) if (params.onHost) host.then(params.onHost).catch(() => void 0);
1806
1821
  if (!(!requestedHostIds || query.hostIds?.some((hostId) => hostId.startsWith("node:")))) return { hosts: await Promise.all(localHosts) };
1807
1822
  let nodes;
1808
1823
  try {
1809
1824
  nodes = (await params.runtime.nodes.list()).nodes.filter((node) => node.commands?.includes("codex.appServer.threads.list.v1") && (!requestedHostIds || requestedHostIds.has(`node:${node.nodeId}`))).slice(0, 100 - localHosts.length);
1810
1825
  } catch (error) {
1811
- return { hosts: [...await Promise.all(localHosts), {
1826
+ const registryHost = {
1812
1827
  hostId: "node:registry",
1813
1828
  label: "Paired nodes",
1814
1829
  kind: "node",
1815
1830
  connected: false,
1816
1831
  sessions: [],
1817
1832
  error: catalogError("NODE_LIST_FAILED", error)
1818
- }] };
1833
+ };
1834
+ params.onHost?.(registryHost);
1835
+ return { hosts: [...await Promise.all(localHosts), registryHost] };
1819
1836
  }
1820
1837
  const adoptedNodeSessions = listNodeAdoptedSessionEntries({
1821
1838
  config: params.config,
@@ -1826,7 +1843,8 @@ async function listCodexSessionCatalog(params) {
1826
1843
  runtime: params.runtime,
1827
1844
  node,
1828
1845
  query,
1829
- adoptedSessions: adoptedNodeSessions
1846
+ adoptedSessions: adoptedNodeSessions,
1847
+ ...params.onHost ? { onHost: params.onHost } : {}
1830
1848
  });
1831
1849
  return Object.assign(host, codexNodeTerminalCapability(node));
1832
1850
  });
@@ -2331,13 +2349,16 @@ function registerCodexSessionCatalog(params) {
2331
2349
  label: "Codex",
2332
2350
  list: async (query) => {
2333
2351
  const localTerminalAvailable = resolveLocalCodexTerminalExecutable() !== void 0;
2352
+ const { onHost, ...gatewayQuery } = query;
2353
+ const mapHost = (host) => toGenericCatalogHost(host, localTerminalAvailable);
2334
2354
  return (await listCodexSessionCatalog({
2335
2355
  bindingStore: params.bindingStore,
2336
2356
  config: params.getRuntimeConfig(),
2337
2357
  runtime: params.api.runtime,
2338
2358
  control: params.control,
2339
- query
2340
- })).hosts.map((host) => toGenericCatalogHost(host, localTerminalAvailable));
2359
+ query: gatewayQuery,
2360
+ ...onHost ? { onHost: (host) => onHost(mapHost(host)) } : {}
2361
+ })).hosts.map(mapHost);
2341
2362
  },
2342
2363
  read: async (request) => {
2343
2364
  const page = await readCodexSessionTranscript({
@@ -1,8 +1,8 @@
1
- import { a as CODEX_LOCAL_SESSION_HOST_ID } from "./session-catalog-CEvoXWHA.js";
1
+ import { a as CODEX_LOCAL_SESSION_HOST_ID } from "./session-catalog-CA7R-hX2.js";
2
2
  import { truncateUtf16Safe } from "openclaw/plugin-sdk/text-utility-runtime";
3
3
  import { isRecord } from "openclaw/plugin-sdk/string-coerce-runtime";
4
- import { addGatewayClientOptions, callGatewayFromCli } from "openclaw/plugin-sdk/gateway-runtime";
5
4
  import { sanitizeTerminalText } from "openclaw/plugin-sdk/text-chunking";
5
+ import { addGatewayClientOptions, callGatewayFromCli } from "openclaw/plugin-sdk/gateway-runtime";
6
6
  //#region extensions/codex/src/session-cli.ts
7
7
  const CODEX_SESSION_CATALOG_CLI_TIMEOUT_MS = 75e3;
8
8
  function writeLine(value = "") {