@openclaw/codex 2026.7.1-beta.1 → 2026.7.1-beta.2

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 (23) hide show
  1. package/dist/{app-server-policy-xi0ZmBGO.js → app-server-policy-B7hqD3Xj.js} +1 -1
  2. package/dist/{attempt-notifications-l9LElGOU.js → attempt-notifications-tqyQ_Tdn.js} +1 -1
  3. package/dist/{client-factory-CwjdQQ4j.js → client-factory-DfFu9JH_.js} +2 -5
  4. package/dist/{command-handlers-vZy8xX5X.js → command-handlers-C9K-KRU-.js} +6 -6
  5. package/dist/{compact-BzB9AqN1.js → compact-CILptrPS.js} +1 -1
  6. package/dist/{computer-use-FPGG-mtX.js → computer-use-CpurU-G9.js} +1 -1
  7. package/dist/{conversation-binding-CEE2UyYb.js → conversation-binding-DOJtUxOy.js} +4 -4
  8. package/dist/harness.js +4 -4
  9. package/dist/index.js +10 -17
  10. package/dist/{media-understanding-provider-C5yYzx_6.js → media-understanding-provider-BOeoBhEw.js} +4 -4
  11. package/dist/media-understanding-provider.js +1 -1
  12. package/dist/{models-Ccy1_7nN.js → models-DpzY1xpp.js} +1 -1
  13. package/dist/{plugin-app-cache-key-CDioyur-.js → plugin-app-cache-key-BrZUG9jj.js} +1 -1
  14. package/dist/{protocol-validators-CB4mtyrs.js → protocol-validators-CJiWigAJ.js} +1 -3
  15. package/dist/{provider-capabilities-CE5k8cmO.js → provider-capabilities-wqedK49Z.js} +7 -3
  16. package/dist/{provider-DosqwRb6.js → provider-nmtMDcGH.js} +1 -1
  17. package/dist/provider.js +1 -1
  18. package/dist/{run-attempt-O3Zs32KI.js → run-attempt-DikbXia_.js} +319 -85
  19. package/dist/{side-question-DDVgFmpv.js → side-question-Ca9wqmd0.js} +5 -5
  20. package/dist/{thread-lifecycle-DeSMZSXr.js → thread-lifecycle-D6R40plk.js} +2 -2
  21. package/dist/{web-search-provider.runtime-Q89rQhsL.js → web-search-provider.runtime-B6eZEFmd.js} +2 -2
  22. package/npm-shrinkwrap.json +2 -2
  23. package/package.json +4 -4
@@ -1,6 +1,6 @@
1
1
  import { n as isJsonObject } from "./protocol-dh-ETiNd.js";
2
2
  import { n as canUseCodexModelBackedApprovalsReviewerForModel } from "./config-C_whBx3M.js";
3
- import { c as hasCodexRateLimitSnapshots, d as summarizeCodexAccountRateLimits, p as summarizeCodexRateLimits } from "./provider-DosqwRb6.js";
3
+ import { c as hasCodexRateLimitSnapshots, d as summarizeCodexAccountRateLimits, p as summarizeCodexRateLimits } from "./provider-nmtMDcGH.js";
4
4
  //#region extensions/codex/src/command-formatters.ts
5
5
  /** Formats the combined `/codex status` probe result. */
6
6
  function formatCodexStatus(probes) {
@@ -1,5 +1,5 @@
1
1
  import { n as isJsonObject } from "./protocol-dh-ETiNd.js";
2
- import { V as isCodexNotificationForTurn } from "./thread-lifecycle-DeSMZSXr.js";
2
+ import { V as isCodexNotificationForTurn } from "./thread-lifecycle-D6R40plk.js";
3
3
  import { asBoolean } from "openclaw/plugin-sdk/string-coerce-runtime";
4
4
  //#region extensions/codex/src/app-server/attempt-notifications.ts
5
5
  /**
@@ -1,9 +1,6 @@
1
+ import { createLazyRuntimeModule } from "openclaw/plugin-sdk/lazy-runtime";
1
2
  //#region extensions/codex/src/app-server/client-factory.ts
2
- let sharedClientModulePromise = null;
3
- const loadSharedClientModule = async () => {
4
- sharedClientModulePromise ??= import("./shared-client-rR6TDJA3.js").then((n) => n.c);
5
- return await sharedClientModulePromise;
6
- };
3
+ const loadSharedClientModule = createLazyRuntimeModule(() => import("./shared-client-rR6TDJA3.js").then((n) => n.c));
7
4
  /** Returns a leased shared client so startup can release ownership explicitly. */
8
5
  const defaultLeasedCodexAppServerClientFactory = (startOptions, authProfileId, agentDir, config, options) => loadSharedClientModule().then(({ getLeasedSharedCodexAppServerClient }) => getLeasedSharedCodexAppServerClient({
9
6
  startOptions,
@@ -1,14 +1,14 @@
1
1
  import { n as isJsonObject } from "./protocol-dh-ETiNd.js";
2
2
  import { d as resolveCodexAppServerRuntimeOptions, o as isCodexFastServiceTier } from "./config-C_whBx3M.js";
3
- import { n as listCodexAppServerModels, t as listAllCodexAppServerModels } from "./models-Ccy1_7nN.js";
4
- import { f as summarizeCodexAccountUsage } from "./provider-DosqwRb6.js";
3
+ import { n as listCodexAppServerModels, t as listAllCodexAppServerModels } from "./models-DpzY1xpp.js";
4
+ import { f as summarizeCodexAccountUsage } from "./provider-nmtMDcGH.js";
5
5
  import { l as writeCodexAppServerBinding, n as clearCodexAppServerBinding, o as readCodexAppServerBinding } from "./session-binding-Cm0Gg7Z1.js";
6
- import { i as describeControlFailure, r as CODEX_CONTROL_METHODS } from "./plugin-app-cache-key-CDioyur-.js";
7
- import { a as formatCodexDisplayText, c as formatList, d as formatThreads, f as readString$1, i as formatAccount, l as formatModels, o as formatCodexStatus, r as buildHelp, s as formatComputerUseStatus, u as formatSkills } from "./app-server-policy-xi0ZmBGO.js";
6
+ import { i as describeControlFailure, r as CODEX_CONTROL_METHODS } from "./plugin-app-cache-key-BrZUG9jj.js";
7
+ import { a as formatCodexDisplayText, c as formatList, d as formatThreads, f as readString$1, i as formatAccount, l as formatModels, o as formatCodexStatus, r as buildHelp, s as formatComputerUseStatus, u as formatSkills } from "./app-server-policy-B7hqD3Xj.js";
8
8
  import { n as resolveCodexNativeExecutionBlock, r as resolveCodexNativeSandboxBlock } from "./sandbox-guard-pTY2COoC.js";
9
- import { C as canMutateCodexHost, S as CODEX_NATIVE_EXECUTION_AUTH_ERROR, _ as steerCodexConversationTurn, b as readCodexConversationBindingData, d as parseCodexFastModeArg, f as parseCodexPermissionsModeArg, g as setCodexConversationPermissions, h as setCodexConversationModel, m as setCodexConversationFastMode, o as formatCodexCliSessions, p as readCodexConversationActiveTurn, r as startCodexConversationThread, u as formatPermissionsMode, v as stopCodexConversationTurn, x as resolveCodexDefaultWorkspaceDir, y as createCodexCliNodeConversationBindingData } from "./conversation-binding-CEE2UyYb.js";
9
+ import { C as canMutateCodexHost, S as CODEX_NATIVE_EXECUTION_AUTH_ERROR, _ as steerCodexConversationTurn, b as readCodexConversationBindingData, d as parseCodexFastModeArg, f as parseCodexPermissionsModeArg, g as setCodexConversationPermissions, h as setCodexConversationModel, m as setCodexConversationFastMode, o as formatCodexCliSessions, p as readCodexConversationActiveTurn, r as startCodexConversationThread, u as formatPermissionsMode, v as stopCodexConversationTurn, x as resolveCodexDefaultWorkspaceDir, y as createCodexCliNodeConversationBindingData } from "./conversation-binding-DOJtUxOy.js";
10
10
  import { t as requestCodexAppServerJson } from "./request-BQuSQF29.js";
11
- import { n as installCodexComputerUse, r as readCodexComputerUseStatus } from "./computer-use-FPGG-mtX.js";
11
+ import { n as installCodexComputerUse, r as readCodexComputerUseStatus } from "./computer-use-CpurU-G9.js";
12
12
  import { n as rememberCodexRateLimits } from "./rate-limit-cache-C7qmZ0Jh.js";
13
13
  import { parseStrictPositiveInteger } from "openclaw/plugin-sdk/number-runtime";
14
14
  import { normalizeOptionalString, normalizeUniqueStringEntries } from "openclaw/plugin-sdk/string-coerce-runtime";
@@ -2,7 +2,7 @@ import { d as resolveCodexAppServerRuntimeOptions } from "./config-C_whBx3M.js";
2
2
  import { c as withCodexAppServerBindingLock, l as writeCodexAppServerBinding, o as readCodexAppServerBinding, t as CODEX_APP_SERVER_BINDING_GUARDED_REQUEST_TIMEOUT_MS } from "./session-binding-Cm0Gg7Z1.js";
3
3
  import { o as releaseLeasedSharedCodexAppServerClient } from "./shared-client-rR6TDJA3.js";
4
4
  import { n as resolveCodexNativeExecutionBlock } from "./sandbox-guard-pTY2COoC.js";
5
- import { t as defaultLeasedCodexAppServerClientFactory } from "./client-factory-CwjdQQ4j.js";
5
+ import { t as defaultLeasedCodexAppServerClientFactory } from "./client-factory-DfFu9JH_.js";
6
6
  import { embeddedAgentLog } from "openclaw/plugin-sdk/agent-harness-runtime";
7
7
  //#region extensions/codex/src/app-server/compact.ts
8
8
  /**
@@ -1,5 +1,5 @@
1
1
  import { d as resolveCodexAppServerRuntimeOptions, f as resolveCodexComputerUseConfig } from "./config-C_whBx3M.js";
2
- import { i as describeControlFailure } from "./plugin-app-cache-key-CDioyur-.js";
2
+ import { i as describeControlFailure } from "./plugin-app-cache-key-BrZUG9jj.js";
3
3
  import { t as requestCodexAppServerJson } from "./request-BQuSQF29.js";
4
4
  import { existsSync } from "node:fs";
5
5
  //#region extensions/codex/src/app-server/computer-use.ts
@@ -1,10 +1,10 @@
1
1
  import { n as isJsonObject } from "./protocol-dh-ETiNd.js";
2
- import { H as readCodexNotificationThreadId, U as readCodexNotificationTurnId, d as resolveCodexAppServerRequestModelSelection, p as resolveCodexBindingModelProviderFallback, t as CODEX_NATIVE_PERSONALITY_NONE } from "./thread-lifecycle-DeSMZSXr.js";
2
+ import { H as readCodexNotificationThreadId, U as readCodexNotificationTurnId, d as resolveCodexAppServerRequestModelSelection, p as resolveCodexBindingModelProviderFallback, t as CODEX_NATIVE_PERSONALITY_NONE } from "./thread-lifecycle-D6R40plk.js";
3
3
  import { d as resolveCodexAppServerRuntimeOptions, h as resolveOpenClawExecPolicyForCodexAppServer, i as codexSandboxPolicyForTurn, n as canUseCodexModelBackedApprovalsReviewerForModel, o as isCodexFastServiceTier, p as resolveCodexModelBackedReviewerPolicyContext } from "./config-C_whBx3M.js";
4
- import { r as assertCodexThreadStartResponse } from "./protocol-validators-CB4mtyrs.js";
4
+ import { r as assertCodexThreadStartResponse } from "./protocol-validators-CJiWigAJ.js";
5
5
  import { a as normalizeCodexAppServerBindingModelProvider, i as isCodexAppServerNativeAuthProfile, l as writeCodexAppServerBinding, n as clearCodexAppServerBinding, o as readCodexAppServerBinding } from "./session-binding-Cm0Gg7Z1.js";
6
- import { r as CODEX_CONTROL_METHODS } from "./plugin-app-cache-key-CDioyur-.js";
7
- import { a as formatCodexDisplayText, t as resolveCodexAppServerForModelProvider } from "./app-server-policy-xi0ZmBGO.js";
6
+ import { r as CODEX_CONTROL_METHODS } from "./plugin-app-cache-key-BrZUG9jj.js";
7
+ import { a as formatCodexDisplayText, t as resolveCodexAppServerForModelProvider } from "./app-server-policy-B7hqD3Xj.js";
8
8
  import { a as getLeasedSharedCodexAppServerClient, o as releaseLeasedSharedCodexAppServerClient, p as resolveCodexAppServerAuthProfileIdForAgent } from "./shared-client-rR6TDJA3.js";
9
9
  import { n as resolveCodexNativeExecutionBlock, r as resolveCodexNativeSandboxBlock } from "./sandbox-guard-pTY2COoC.js";
10
10
  import fs from "node:fs/promises";
package/dist/harness.js CHANGED
@@ -32,25 +32,25 @@ function createCodexAppServerAgentHarness(options) {
32
32
  };
33
33
  },
34
34
  runAttempt: async (params) => {
35
- const { runCodexAppServerAttempt } = await import("./run-attempt-O3Zs32KI.js");
35
+ const { runCodexAppServerAttempt } = await import("./run-attempt-DikbXia_.js");
36
36
  return runCodexAppServerAttempt(params, {
37
37
  pluginConfig: options?.resolvePluginConfig?.() ?? options?.pluginConfig,
38
38
  nativeHookRelay: { enabled: true }
39
39
  });
40
40
  },
41
41
  runSideQuestion: async (params) => {
42
- const { runCodexAppServerSideQuestion } = await import("./side-question-DDVgFmpv.js");
42
+ const { runCodexAppServerSideQuestion } = await import("./side-question-Ca9wqmd0.js");
43
43
  return runCodexAppServerSideQuestion(params, {
44
44
  pluginConfig: options?.resolvePluginConfig?.() ?? options?.pluginConfig,
45
45
  nativeHookRelay: { enabled: true }
46
46
  });
47
47
  },
48
48
  compact: async (params) => {
49
- const { maybeCompactCodexAppServerSession } = await import("./compact-BzB9AqN1.js");
49
+ const { maybeCompactCodexAppServerSession } = await import("./compact-CILptrPS.js");
50
50
  return maybeCompactCodexAppServerSession(params, { pluginConfig: options?.resolvePluginConfig?.() ?? options?.pluginConfig });
51
51
  },
52
52
  compactAfterContextEngine: async (params) => {
53
- const { maybeCompactCodexAppServerSession } = await import("./compact-BzB9AqN1.js");
53
+ const { maybeCompactCodexAppServerSession } = await import("./compact-CILptrPS.js");
54
54
  return maybeCompactCodexAppServerSession(params, {
55
55
  pluginConfig: options?.resolvePluginConfig?.() ?? options?.pluginConfig,
56
56
  allowNonManualNativeRequest: true
package/dist/index.js CHANGED
@@ -1,12 +1,12 @@
1
1
  import { createCodexAppServerAgentHarness } from "./harness.js";
2
- import { I as ensureCodexPluginActivation, L as pluginReadParams, z as defaultCodexAppInventoryCache } from "./thread-lifecycle-DeSMZSXr.js";
2
+ import { I as ensureCodexPluginActivation, L as pluginReadParams, z as defaultCodexAppInventoryCache } from "./thread-lifecycle-D6R40plk.js";
3
3
  import { d as resolveCodexAppServerRuntimeOptions, t as CODEX_PLUGINS_MARKETPLACE_NAME, u as readCodexPluginConfig } from "./config-C_whBx3M.js";
4
- import { t as buildCodexProvider } from "./provider-DosqwRb6.js";
5
- import { t as buildCodexMediaUnderstandingProvider } from "./media-understanding-provider-C5yYzx_6.js";
6
- import { i as describeControlFailure, n as buildCodexPluginAppCacheKey } from "./plugin-app-cache-key-CDioyur-.js";
7
- import { a as formatCodexDisplayText } from "./app-server-policy-xi0ZmBGO.js";
4
+ import { t as buildCodexProvider } from "./provider-nmtMDcGH.js";
5
+ import { t as buildCodexMediaUnderstandingProvider } from "./media-understanding-provider-BOeoBhEw.js";
6
+ import { i as describeControlFailure, n as buildCodexPluginAppCacheKey } from "./plugin-app-cache-key-BrZUG9jj.js";
7
+ import { a as formatCodexDisplayText } from "./app-server-policy-B7hqD3Xj.js";
8
8
  import { a as getLeasedSharedCodexAppServerClient, d as resolveCodexAppServerAuthAccountCacheKey, m as resolveCodexAppServerFallbackApiKeyCacheKey, o as releaseLeasedSharedCodexAppServerClient, p as resolveCodexAppServerAuthProfileIdForAgent, r as clearSharedCodexAppServerClientIfCurrentAndWait } from "./shared-client-rR6TDJA3.js";
9
- import { a as createCodexCliSessionNodeInvokePolicies, c as resolveCodexCliSessionForBindingOnNode, i as createCodexCliSessionNodeHostCommands, l as resumeCodexCliSessionOnNode, n as handleCodexConversationInboundClaim, s as listCodexCliSessionsOnNode, t as handleCodexConversationBindingResolved } from "./conversation-binding-CEE2UyYb.js";
9
+ import { a as createCodexCliSessionNodeInvokePolicies, c as resolveCodexCliSessionForBindingOnNode, i as createCodexCliSessionNodeHostCommands, l as resumeCodexCliSessionOnNode, n as handleCodexConversationInboundClaim, s as listCodexCliSessionsOnNode, t as handleCodexConversationBindingResolved } from "./conversation-binding-DOJtUxOy.js";
10
10
  import { t as requestCodexAppServerJson } from "./request-BQuSQF29.js";
11
11
  import { t as createCodexWebSearchProviderBase } from "./web-search-provider.shared-BrZmlqyR.js";
12
12
  import { mutateConfigFile } from "openclaw/plugin-sdk/config-mutation";
@@ -22,7 +22,9 @@ import { applyAuthProfileConfig, buildApiKeyCredential, buildOauthProviderAuthRe
22
22
  import { pathExists } from "openclaw/plugin-sdk/security-runtime";
23
23
  import { MIGRATION_REASON_TARGET_EXISTS, applyMigrationManualItem, createMigrationItem, createMigrationManualItem, hasMigrationConfigPatchConflict, markMigrationItemConflict, markMigrationItemError, markMigrationItemSkipped, readMigrationConfigPath, summarizeMigrationItems, writeMigrationConfigPath } from "openclaw/plugin-sdk/migration";
24
24
  import { archiveMigrationItem, copyMigrationFileItem, withCachedMigrationConfigRuntime, writeMigrationReport } from "openclaw/plugin-sdk/migration-runtime";
25
+ import { sleep } from "openclaw/plugin-sdk/runtime-env";
25
26
  import { readJsonFileWithFallback } from "openclaw/plugin-sdk/json-store";
27
+ import { createLazyRuntimeModule } from "openclaw/plugin-sdk/lazy-runtime";
26
28
  //#region extensions/codex/src/commands.ts
27
29
  /** Creates the reserved `/codex` command definition exposed by the plugin. */
28
30
  function createCodexCommand(options) {
@@ -52,7 +54,7 @@ async function handleCodexCommand(ctx, options = {}) {
52
54
  }
53
55
  }
54
56
  async function loadDefaultCodexSubcommandHandler() {
55
- const { handleCodexSubcommand } = await import("./command-handlers-vZy8xX5X.js");
57
+ const { handleCodexSubcommand } = await import("./command-handlers-C9K-KRU-.js");
56
58
  return handleCodexSubcommand;
57
59
  }
58
60
  //#endregion
@@ -1405,11 +1407,6 @@ function targetCodexMarketplaceDiscoveryTimeoutMs(env = process.env) {
1405
1407
  function isCodexPluginLoadWarningItem(item) {
1406
1408
  return item.kind === "plugin" && item.action === "install" && item.status === "warning" && item.details?.warningReason === CODEX_PLUGIN_LOAD_WARNING;
1407
1409
  }
1408
- async function sleep(ms) {
1409
- await new Promise((resolve) => {
1410
- setTimeout(resolve, ms);
1411
- });
1412
- }
1413
1410
  async function buildTargetCodexPluginAppCacheKey(ctx) {
1414
1411
  const targets = resolveCodexMigrationTargets(ctx);
1415
1412
  const appServer = resolveTargetCodexAppServer(ctx);
@@ -1548,11 +1545,7 @@ function buildCodexMigrationProvider(params = {}) {
1548
1545
  }
1549
1546
  //#endregion
1550
1547
  //#region extensions/codex/src/web-search-provider.ts
1551
- let codexWebSearchRuntimePromise;
1552
- function loadCodexWebSearchRuntime() {
1553
- codexWebSearchRuntimePromise ??= import("./web-search-provider.runtime-Q89rQhsL.js");
1554
- return codexWebSearchRuntimePromise;
1555
- }
1548
+ const loadCodexWebSearchRuntime = createLazyRuntimeModule(() => import("./web-search-provider.runtime-B6eZEFmd.js"));
1556
1549
  const CodexWebSearchSchema = {
1557
1550
  type: "object",
1558
1551
  properties: { query: {
@@ -1,10 +1,10 @@
1
1
  import { CODEX_PROVIDER_ID, FALLBACK_CODEX_MODELS } from "./provider-catalog.js";
2
2
  import { n as isJsonObject } from "./protocol-dh-ETiNd.js";
3
- import { P as mergeCodexThreadConfigs, r as buildCodexRuntimeThreadConfig } from "./thread-lifecycle-DeSMZSXr.js";
4
- import { C as readCodexNotificationItem } from "./attempt-notifications-l9LElGOU.js";
3
+ import { P as mergeCodexThreadConfigs, r as buildCodexRuntimeThreadConfig } from "./thread-lifecycle-D6R40plk.js";
4
+ import { C as readCodexNotificationItem } from "./attempt-notifications-tqyQ_Tdn.js";
5
5
  import { d as resolveCodexAppServerRuntimeOptions } from "./config-C_whBx3M.js";
6
- import { i as assertCodexTurnStartResponse, l as readCodexTurnCompletedNotification, o as readCodexErrorNotification, r as assertCodexThreadStartResponse } from "./protocol-validators-CB4mtyrs.js";
7
- import { i as readModelListResult } from "./models-Ccy1_7nN.js";
6
+ import { i as assertCodexTurnStartResponse, l as readCodexTurnCompletedNotification, o as readCodexErrorNotification, r as assertCodexThreadStartResponse } from "./protocol-validators-CJiWigAJ.js";
7
+ import { i as readModelListResult } from "./models-DpzY1xpp.js";
8
8
  import { validateJsonSchemaValue } from "openclaw/plugin-sdk/json-schema-runtime";
9
9
  import fs from "node:fs/promises";
10
10
  import path from "node:path";
@@ -1,2 +1,2 @@
1
- import { t as buildCodexMediaUnderstandingProvider } from "./media-understanding-provider-C5yYzx_6.js";
1
+ import { t as buildCodexMediaUnderstandingProvider } from "./media-understanding-provider-BOeoBhEw.js";
2
2
  export { buildCodexMediaUnderstandingProvider };
@@ -1,5 +1,5 @@
1
1
  import { t as __exportAll } from "./rolldown-runtime-8H4AJuhK.js";
2
- import { s as readCodexModelListResponse } from "./protocol-validators-CB4mtyrs.js";
2
+ import { s as readCodexModelListResponse } from "./protocol-validators-CJiWigAJ.js";
3
3
  import { uniqueStrings } from "openclaw/plugin-sdk/string-coerce-runtime";
4
4
  //#region extensions/codex/src/app-server/models.ts
5
5
  /**
@@ -1,4 +1,4 @@
1
- import { R as buildCodexAppInventoryCacheKey } from "./thread-lifecycle-DeSMZSXr.js";
1
+ import { R as buildCodexAppInventoryCacheKey } from "./thread-lifecycle-D6R40plk.js";
2
2
  import { n as CodexAppServerRpcError } from "./client-IcTBKEqA.js";
3
3
  import { h as resolveCodexAppServerHomeDir } from "./shared-client-rR6TDJA3.js";
4
4
  import { createRequire } from "node:module";
@@ -1,3 +1,4 @@
1
+ import { isRecord } from "openclaw/plugin-sdk/string-coerce-runtime";
1
2
  import { Compile } from "typebox/compile";
2
3
  //#region extensions/codex/src/app-server/protocol-generated/json/DynamicToolCallParams.json
3
4
  var DynamicToolCallParams_default = {
@@ -5816,9 +5817,6 @@ function compileCodexSchema(schema) {
5816
5817
  errors: (value) => [...validator.Errors(value)]
5817
5818
  };
5818
5819
  }
5819
- function isRecord(value) {
5820
- return Boolean(value && typeof value === "object" && !Array.isArray(value));
5821
- }
5822
5820
  const schemaMapKeywords = new Set([
5823
5821
  "$defs",
5824
5822
  "definitions",
@@ -1,7 +1,7 @@
1
1
  import { n as isJsonObject } from "./protocol-dh-ETiNd.js";
2
- import { C as isForcedPrivateQaCodexRuntime, S as filterCodexDynamicTools, _ as resolveCodexWebSearchPlan, w as normalizeCodexDynamicToolName, x as sanitizeInlineImageDataUrl, y as invalidInlineImageText } from "./thread-lifecycle-DeSMZSXr.js";
2
+ import { C as isForcedPrivateQaCodexRuntime, S as filterCodexDynamicTools, _ as resolveCodexWebSearchPlan, w as normalizeCodexDynamicToolName, x as sanitizeInlineImageDataUrl, y as invalidInlineImageText } from "./thread-lifecycle-D6R40plk.js";
3
3
  import { c as isTrustedCodexModelBackedOpenAIProvider, u as readCodexPluginConfig } from "./config-C_whBx3M.js";
4
- import { a as formatCodexDisplayText } from "./app-server-policy-xi0ZmBGO.js";
4
+ import { a as formatCodexDisplayText } from "./app-server-policy-B7hqD3Xj.js";
5
5
  import { o as releaseLeasedSharedCodexAppServerClient } from "./shared-client-rR6TDJA3.js";
6
6
  import { i as resolveCodexNativeExecutionPolicy } from "./sandbox-guard-pTY2COoC.js";
7
7
  import { addTimerTimeoutGraceMs, finiteSecondsToTimerSafeMilliseconds, resolveTimerTimeoutMs } from "openclaw/plugin-sdk/number-runtime";
@@ -1784,7 +1784,11 @@ function hasExplicitNonSourceMessageRoute(args, hookContext, messagingTarget) {
1784
1784
  }
1785
1785
  /** Namespace attached to OpenClaw-owned dynamic tools exposed to Codex. */
1786
1786
  const CODEX_OPENCLAW_DYNAMIC_TOOL_NAMESPACE = "openclaw";
1787
- const ALWAYS_DIRECT_DYNAMIC_TOOL_NAMES = new Set(["sessions_yield"]);
1787
+ const ALWAYS_DIRECT_DYNAMIC_TOOL_NAMES = new Set([
1788
+ "agents_list",
1789
+ "sessions_spawn",
1790
+ "sessions_yield"
1791
+ ]);
1788
1792
  const EXPLICIT_MESSAGE_PROVIDER_KEYS = ["channel", "provider"];
1789
1793
  const EXPLICIT_MESSAGE_TARGET_KEYS = [
1790
1794
  "target",
@@ -545,7 +545,7 @@ async function listModelsBestEffort(params) {
545
545
  }
546
546
  }
547
547
  async function listCodexAppServerModelsLazy(options) {
548
- const { listCodexAppServerModels } = await import("./models-Ccy1_7nN.js").then((n) => n.r);
548
+ const { listCodexAppServerModels } = await import("./models-DpzY1xpp.js").then((n) => n.r);
549
549
  return listCodexAppServerModels(options);
550
550
  }
551
551
  async function requestCodexAppServerRateLimitsLazy(options) {
package/dist/provider.js CHANGED
@@ -1,2 +1,2 @@
1
- import { a as readCodexSupportedReasoningEfforts, i as isModernCodexModel, n as buildCodexProviderCatalog, o as resolveCodexSupportedReasoningEffort, r as isMaxReasoningCodexModel, t as buildCodexProvider } from "./provider-DosqwRb6.js";
1
+ import { a as readCodexSupportedReasoningEfforts, i as isModernCodexModel, n as buildCodexProviderCatalog, o as resolveCodexSupportedReasoningEffort, r as isMaxReasoningCodexModel, t as buildCodexProvider } from "./provider-nmtMDcGH.js";
2
2
  export { buildCodexProvider, buildCodexProviderCatalog, isMaxReasoningCodexModel, isModernCodexModel, readCodexSupportedReasoningEfforts, resolveCodexSupportedReasoningEffort };
@@ -1,17 +1,17 @@
1
1
  import { n as isJsonObject, t as flattenCodexDynamicToolFunctions } from "./protocol-dh-ETiNd.js";
2
- import { A as resolveCodexContextEngineProjectionReserveTokens, B as describeCodexNotificationCorrelation, D as fitCodexProjectedContextForTurnStart, E as resolveCodexDynamicToolsLoadingForRuntime, F as shouldBuildCodexPluginThreadConfig, H as readCodexNotificationThreadId, M as buildCodexPluginThreadConfig, N as buildCodexPluginThreadConfigInputFingerprint, O as projectContextEngineAssemblyForCodex, P as mergeCodexThreadConfigs, U as readCodexNotificationTurnId, _ as resolveCodexWebSearchPlan, a as buildDeveloperInstructions, b as sanitizeCodexHistoryImagePayloads, c as codexDynamicToolsFingerprint, f as resolveCodexAppServerThreadModelSelection, h as startOrResumeThread, i as buildContextEngineBinding, k as resolveCodexContextEngineProjectionMaxChars, l as isContextEngineBindingCompatible, n as areCodexDynamicToolFingerprintsCompatible, o as buildTurnCollaborationMode, s as buildTurnStartParams, v as isCodexAppServerProfilerEnabled, z as defaultCodexAppInventoryCache } from "./thread-lifecycle-DeSMZSXr.js";
3
- import { C as readCodexNotificationItem, D as updateActiveCompletionBlockerItemIds, E as shouldDisarmAssistantCompletionIdleWatch, O as updateActiveTurnItemIds, S as isTurnNotification, T as readRawResponseToolCallId, _ as isRawToolOutputCompletionNotification, a as isCodexNotificationOutsideActiveRun, b as isRetryableErrorNotification, c as isCurrentThreadOptionalTurnRequestParams, d as isNativeResponseStreamDeltaNotification, f as isNativeToolProgressNotification, g as isRawReasoningCompletionNotification, h as isRawFunctionToolOutputCompletionNotification, i as isAssistantCompletionReleaseNotification, l as isCurrentThreadTurnRequestParams, m as isRawAssistantProgressNotification, n as describeNotificationActivity, o as isCodexTurnAbortMarkerNotification, p as isPendingOpenClawDynamicToolCompletionNotification, r as isAssistantCommentaryCompletionNotification, s as isCurrentApprovalTurnRequestParams, t as codexExecutionToolName, u as isFileChangePatchUpdatedNotification, v as isReasoningItemCompletionNotification, w as readNotificationItemId, x as isTerminalTurnStatus, y as isReasoningProgressNotification } from "./attempt-notifications-l9LElGOU.js";
2
+ import { A as resolveCodexContextEngineProjectionReserveTokens, B as describeCodexNotificationCorrelation, D as fitCodexProjectedContextForTurnStart, E as resolveCodexDynamicToolsLoadingForRuntime, F as shouldBuildCodexPluginThreadConfig, H as readCodexNotificationThreadId, M as buildCodexPluginThreadConfig, N as buildCodexPluginThreadConfigInputFingerprint, O as projectContextEngineAssemblyForCodex, P as mergeCodexThreadConfigs, U as readCodexNotificationTurnId, _ as resolveCodexWebSearchPlan, a as buildDeveloperInstructions, b as sanitizeCodexHistoryImagePayloads, c as codexDynamicToolsFingerprint, f as resolveCodexAppServerThreadModelSelection, h as startOrResumeThread, i as buildContextEngineBinding, k as resolveCodexContextEngineProjectionMaxChars, l as isContextEngineBindingCompatible, n as areCodexDynamicToolFingerprintsCompatible, o as buildTurnCollaborationMode, s as buildTurnStartParams, v as isCodexAppServerProfilerEnabled, z as defaultCodexAppInventoryCache } from "./thread-lifecycle-D6R40plk.js";
3
+ import { C as readCodexNotificationItem, D as updateActiveCompletionBlockerItemIds, E as shouldDisarmAssistantCompletionIdleWatch, O as updateActiveTurnItemIds, S as isTurnNotification, T as readRawResponseToolCallId, _ as isRawToolOutputCompletionNotification, a as isCodexNotificationOutsideActiveRun, b as isRetryableErrorNotification, c as isCurrentThreadOptionalTurnRequestParams, d as isNativeResponseStreamDeltaNotification, f as isNativeToolProgressNotification, g as isRawReasoningCompletionNotification, h as isRawFunctionToolOutputCompletionNotification, i as isAssistantCompletionReleaseNotification, l as isCurrentThreadTurnRequestParams, m as isRawAssistantProgressNotification, n as describeNotificationActivity, o as isCodexTurnAbortMarkerNotification, p as isPendingOpenClawDynamicToolCompletionNotification, r as isAssistantCommentaryCompletionNotification, s as isCurrentApprovalTurnRequestParams, t as codexExecutionToolName, u as isFileChangePatchUpdatedNotification, v as isReasoningItemCompletionNotification, w as readNotificationItemId, x as isTerminalTurnStatus, y as isReasoningProgressNotification } from "./attempt-notifications-tqyQ_Tdn.js";
4
4
  import { _ as withMcpElicitationsApprovalPolicy, a as isCodexAppServerApprovalPolicyAllowedByRequirements, d as resolveCodexAppServerRuntimeOptions, f as resolveCodexComputerUseConfig, g as shouldAutoApproveCodexAppServerApprovals, h as resolveOpenClawExecPolicyForCodexAppServer, m as resolveCodexPluginsPolicy, p as resolveCodexModelBackedReviewerPolicyContext, s as isCodexSandboxExecServerEnabled, u as readCodexPluginConfig } from "./config-C_whBx3M.js";
5
- import { a as readCodexDynamicToolCallParams, c as readCodexTurn, i as assertCodexTurnStartResponse } from "./protocol-validators-CB4mtyrs.js";
6
- import { l as resolveCodexUsageLimitResetAtMs, s as formatCodexUsageLimitErrorMessage, u as shouldRefreshCodexRateLimitsForUsageLimitMessage } from "./provider-DosqwRb6.js";
5
+ import { a as readCodexDynamicToolCallParams, c as readCodexTurn, i as assertCodexTurnStartResponse } from "./protocol-validators-CJiWigAJ.js";
6
+ import { l as resolveCodexUsageLimitResetAtMs, s as formatCodexUsageLimitErrorMessage, u as shouldRefreshCodexRateLimitsForUsageLimitMessage } from "./provider-nmtMDcGH.js";
7
7
  import { a as isCodexAppServerConnectionClosedError, c as MIN_CODEX_SANDBOX_EXEC_SERVER_APP_SERVER_VERSION, i as isCodexAppServerApprovalRequest, n as CodexAppServerRpcError, r as compareCodexAppServerVersions } from "./client-IcTBKEqA.js";
8
8
  import { i as isCodexAppServerNativeAuthProfile, l as writeCodexAppServerBinding, n as clearCodexAppServerBinding, o as readCodexAppServerBinding, r as clearCodexAppServerBindingForThread } from "./session-binding-Cm0Gg7Z1.js";
9
- import { n as buildCodexPluginAppCacheKey, r as CODEX_CONTROL_METHODS, t as buildCodexAppServerRuntimeFingerprint } from "./plugin-app-cache-key-CDioyur-.js";
10
- import { a as formatCodexDisplayText, n as resolveCodexAppServerForOpenClawToolPolicy, t as resolveCodexAppServerForModelProvider } from "./app-server-policy-xi0ZmBGO.js";
9
+ import { n as buildCodexPluginAppCacheKey, r as CODEX_CONTROL_METHODS, t as buildCodexAppServerRuntimeFingerprint } from "./plugin-app-cache-key-BrZUG9jj.js";
10
+ import { a as formatCodexDisplayText, n as resolveCodexAppServerForOpenClawToolPolicy, t as resolveCodexAppServerForModelProvider } from "./app-server-policy-B7hqD3Xj.js";
11
11
  import { d as resolveCodexAppServerAuthAccountCacheKey, f as resolveCodexAppServerAuthProfileId, h as resolveCodexAppServerHomeDir, m as resolveCodexAppServerFallbackApiKeyCacheKey, n as clearSharedCodexAppServerClientIfCurrentAndUnclaimed, o as releaseLeasedSharedCodexAppServerClient, p as resolveCodexAppServerAuthProfileIdForAgent, s as retireSharedCodexAppServerClientIfCurrent, t as clearSharedCodexAppServerClientIfCurrent, u as refreshCodexAppServerAuthTokens } from "./shared-client-rR6TDJA3.js";
12
- import { t as defaultLeasedCodexAppServerClientFactory } from "./client-factory-CwjdQQ4j.js";
13
- import { A as CODEX_POST_REASONING_REPLY_IDLE_TIMEOUT_MS, C as resolveCodexMessageToolProvider, D as shouldWarnCodexDynamicToolBuildStageSummary, E as shouldRequireCodexSandboxExecServerEnvironment, F as resolveCodexTurnTerminalIdleTimeoutMs, I as withCodexStartupTimeout, M as resolveCodexStartupTimeoutMs, N as resolveCodexTurnAssistantCompletionIdleTimeoutMs, P as resolveCodexTurnCompletionIdleTimeoutMs, S as resolveCodexExternalSandboxPolicyForOpenClawSandbox, T as shouldEnableCodexAppServerNativeToolSurface, _ as createCodexDynamicToolBuildStageTracker, a as buildCodexNativeHookRelayConfig, b as resolveCodexAppServerExecutionCwd, c as resolveCodexNativeHookRelayEvents, d as handleCodexAppServerElicitationRequest, f as createCodexDynamicToolBridge, g as buildDynamicTools, h as emitDynamicToolTerminalDiagnostic, i as CODEX_NATIVE_HOOK_RELAY_TTL_GRACE_MS, j as resolveCodexPostToolRawAssistantCompletionIdleTimeoutMs, k as handleCodexAppServerApprovalRequest, l as resolveCodexNativeHookRelayTtlMs, m as emitDynamicToolStartedDiagnostic, o as buildCodexNativeHookRelayDisabledConfig, p as emitDynamicToolErrorDiagnostic, s as createCodexNativeHookRelay, t as resolveCodexProviderWebSearchSupport, u as scheduleCodexNativeHookRelayUnregister, v as disableCodexPluginThreadConfig, w as resolveCodexSandboxEnvironmentSelection, x as resolveCodexAppServerHookChannelId, y as formatCodexDynamicToolBuildStageSummary } from "./provider-capabilities-CE5k8cmO.js";
14
- import { t as ensureCodexComputerUse } from "./computer-use-FPGG-mtX.js";
12
+ import { t as defaultLeasedCodexAppServerClientFactory } from "./client-factory-DfFu9JH_.js";
13
+ import { A as CODEX_POST_REASONING_REPLY_IDLE_TIMEOUT_MS, C as resolveCodexMessageToolProvider, D as shouldWarnCodexDynamicToolBuildStageSummary, E as shouldRequireCodexSandboxExecServerEnvironment, F as resolveCodexTurnTerminalIdleTimeoutMs, I as withCodexStartupTimeout, M as resolveCodexStartupTimeoutMs, N as resolveCodexTurnAssistantCompletionIdleTimeoutMs, P as resolveCodexTurnCompletionIdleTimeoutMs, S as resolveCodexExternalSandboxPolicyForOpenClawSandbox, T as shouldEnableCodexAppServerNativeToolSurface, _ as createCodexDynamicToolBuildStageTracker, a as buildCodexNativeHookRelayConfig, b as resolveCodexAppServerExecutionCwd, c as resolveCodexNativeHookRelayEvents, d as handleCodexAppServerElicitationRequest, f as createCodexDynamicToolBridge, g as buildDynamicTools, h as emitDynamicToolTerminalDiagnostic, i as CODEX_NATIVE_HOOK_RELAY_TTL_GRACE_MS, j as resolveCodexPostToolRawAssistantCompletionIdleTimeoutMs, k as handleCodexAppServerApprovalRequest, l as resolveCodexNativeHookRelayTtlMs, m as emitDynamicToolStartedDiagnostic, o as buildCodexNativeHookRelayDisabledConfig, p as emitDynamicToolErrorDiagnostic, s as createCodexNativeHookRelay, t as resolveCodexProviderWebSearchSupport, u as scheduleCodexNativeHookRelayUnregister, v as disableCodexPluginThreadConfig, w as resolveCodexSandboxEnvironmentSelection, x as resolveCodexAppServerHookChannelId, y as formatCodexDynamicToolBuildStageSummary } from "./provider-capabilities-wqedK49Z.js";
14
+ import { t as ensureCodexComputerUse } from "./computer-use-CpurU-G9.js";
15
15
  import { n as rememberCodexRateLimits, t as readRecentCodexRateLimits } from "./rate-limit-cache-C7qmZ0Jh.js";
16
16
  import fs from "node:fs/promises";
17
17
  import path, { posix } from "node:path";
@@ -2912,7 +2912,7 @@ function createCodexAttemptTurnWatchController(params) {
2912
2912
  }
2913
2913
  function scheduleAssistantCompletionIdleWatch() {
2914
2914
  clearAssistantCompletionIdleTimer();
2915
- if (params.isCompleted() || params.signal.aborted || !assistantCompletionIdleWatchArmed) return;
2915
+ if (params.isCompleted() || params.signal.aborted || !assistantCompletionIdleWatchArmed || params.getActiveFinalizationHookCount() > 0) return;
2916
2916
  const elapsedMs = Math.max(0, Date.now() - assistantCompletionLastActivityAt);
2917
2917
  const delayMs = Math.max(1, turnAssistantCompletionIdleTimeoutMs - elapsedMs);
2918
2918
  assistantCompletionIdleTimer = setTimeout(fireAssistantCompletionIdleRelease, delayMs);
@@ -2955,10 +2955,16 @@ function createCodexAttemptTurnWatchController(params) {
2955
2955
  }
2956
2956
  function fireAssistantCompletionIdleRelease() {
2957
2957
  if (params.isCompleted() || params.signal.aborted || !assistantCompletionIdleWatchArmed) return;
2958
- if (params.getActiveAppServerTurnRequests() > 0 || params.getActiveTurnItemCount() > 0) {
2958
+ if (params.getActiveAppServerTurnRequests() > 0 || params.getActiveTurnItemCount() > 0 || params.getActiveFinalizationHookCount() > 0) {
2959
2959
  scheduleAssistantCompletionIdleWatch();
2960
2960
  return;
2961
2961
  }
2962
+ if (!params.canReleaseAssistantCompletionIdle()) {
2963
+ assistantCompletionIdleWatchArmed = false;
2964
+ assistantCompletionLastActivityDetails = void 0;
2965
+ clearAssistantCompletionIdleTimer();
2966
+ return;
2967
+ }
2962
2968
  const idleMs = Math.max(0, Date.now() - assistantCompletionLastActivityAt);
2963
2969
  if (idleMs < turnAssistantCompletionIdleTimeoutMs) {
2964
2970
  scheduleAssistantCompletionIdleWatch();
@@ -3807,6 +3813,9 @@ var CodexAppServerEventProjector = class {
3807
3813
  this.assistantTextByItem = /* @__PURE__ */ new Map();
3808
3814
  this.assistantItemOrder = [];
3809
3815
  this.assistantPhaseByItem = /* @__PURE__ */ new Map();
3816
+ this.latestTerminalAssistantCandidateSuperseded = false;
3817
+ this.latestTerminalAssistantCandidateCanReleaseAfterToolHandoff = false;
3818
+ this.terminalAssistantCandidateEarlierActiveItemIds = /* @__PURE__ */ new Set();
3810
3819
  this.lastCommentaryProgressTextByItem = /* @__PURE__ */ new Map();
3811
3820
  this.pendingRawCommentaryEchoes = 0;
3812
3821
  this.reasoningTextByGroup = /* @__PURE__ */ new Map();
@@ -3855,8 +3864,33 @@ var CodexAppServerEventProjector = class {
3855
3864
  return this.completedTurn?.status;
3856
3865
  }
3857
3866
  hasCompletedTerminalAssistantText() {
3867
+ const latestCompletedItemId = this.latestCompletedTerminalAssistantItemId;
3868
+ if (!latestCompletedItemId) return false;
3858
3869
  const finalItem = this.resolveFinalAssistantTextItem();
3859
- return finalItem !== void 0 && this.completedItemIds.has(finalItem.itemId);
3870
+ return this.latestCompletedItemId === latestCompletedItemId && finalItem?.itemId === latestCompletedItemId && this.completedItemIds.has(latestCompletedItemId);
3871
+ }
3872
+ getLatestTerminalAssistantCandidate() {
3873
+ const itemId = this.latestTerminalAssistantCandidateItemId;
3874
+ if (!itemId) return;
3875
+ const text = this.assistantTextByItem.get(itemId)?.trim();
3876
+ return {
3877
+ itemId,
3878
+ hasText: Boolean(text && !this.toolProgressTexts.has(text))
3879
+ };
3880
+ }
3881
+ hasLatestTerminalAssistantCandidateText() {
3882
+ return !this.latestTerminalAssistantCandidateSuperseded && this.getLatestTerminalAssistantCandidate()?.hasText === true;
3883
+ }
3884
+ canReleaseLatestTerminalAssistantAfterToolHandoff() {
3885
+ return this.latestTerminalAssistantCandidateCanReleaseAfterToolHandoff && this.hasLatestTerminalAssistantCandidateText();
3886
+ }
3887
+ /** Restores a completed final item after only the enclosing turn timeout fired. */
3888
+ recoverCompletedTerminalAssistantAfterTurnWatchTimeout() {
3889
+ if (!this.aborted || this.promptError !== "codex app-server attempt timed out" || !this.hasCompletedTerminalAssistantText()) return false;
3890
+ this.aborted = false;
3891
+ this.promptError = void 0;
3892
+ this.promptErrorSource = null;
3893
+ return true;
3860
3894
  }
3861
3895
  /** Resolves the shared model-order position for a native tool item. */
3862
3896
  recordNativeToolOutcome(item) {
@@ -4047,9 +4081,12 @@ var CodexAppServerEventProjector = class {
4047
4081
  const itemId = readString$5(params, "itemId") ?? readString$5(params, "id") ?? "assistant";
4048
4082
  const delta = readString$5(params, "delta") ?? "";
4049
4083
  if (!delta) return;
4084
+ if (itemId !== this.pendingRawTerminalAssistantEchoItemId) this.pendingRawTerminalAssistantEchoItemId = void 0;
4050
4085
  this.rememberAssistantPhase(readItem(params.item));
4051
4086
  const phase = readString$5(params, "phase");
4052
4087
  if (phase) this.assistantPhaseByItem.set(itemId, phase);
4088
+ const isCommentary = this.isCommentaryAssistantItem(itemId);
4089
+ if (!isCommentary && itemId !== this.latestTerminalAssistantCandidateItemId) this.markTerminalAssistantCandidateSupersededBy();
4053
4090
  if (!this.assistantStarted) {
4054
4091
  this.assistantStarted = true;
4055
4092
  await this.params.onAssistantMessageStart?.();
@@ -4057,7 +4094,7 @@ var CodexAppServerEventProjector = class {
4057
4094
  this.rememberAssistantItem(itemId);
4058
4095
  const text = `${this.assistantTextByItem.get(itemId) ?? ""}${delta}`;
4059
4096
  this.assistantTextByItem.set(itemId, text);
4060
- if (this.isCommentaryAssistantItem(itemId)) this.emitCommentaryProgress({
4097
+ if (isCommentary) this.emitCommentaryProgress({
4061
4098
  itemId,
4062
4099
  text
4063
4100
  });
@@ -4131,8 +4168,15 @@ var CodexAppServerEventProjector = class {
4131
4168
  async handleItemStarted(params) {
4132
4169
  const item = readItem(params.item);
4133
4170
  const itemId = item?.id ?? readString$5(params, "itemId") ?? readString$5(params, "id");
4171
+ if (item?.type === "agentMessage" && itemId && itemId !== this.pendingRawTerminalAssistantEchoItemId) this.pendingRawTerminalAssistantEchoItemId = void 0;
4134
4172
  this.rememberAssistantPhase(item);
4135
- if (itemId) this.activeItemIds.add(itemId);
4173
+ if (itemId) {
4174
+ this.activeItemIds.add(itemId);
4175
+ if (itemId !== this.latestTerminalAssistantCandidateItemId) {
4176
+ this.markTerminalAssistantCandidateSupersededBy(itemId, { preserveEarlierActiveItem: true });
4177
+ if (this.latestTerminalAssistantCandidateSuperseded) this.pendingRawTerminalAssistantEchoItemId = void 0;
4178
+ }
4179
+ }
4136
4180
  this.recordNativeToolOutcome(item);
4137
4181
  if (item?.type === "contextCompaction" && itemId) {
4138
4182
  this.activeCompactionItemIds.add(itemId);
@@ -4186,11 +4230,21 @@ var CodexAppServerEventProjector = class {
4186
4230
  this.recordNativeToolOutcome(item);
4187
4231
  this.clearTerminalPresentationForNativeItem(item);
4188
4232
  const itemId = item?.id ?? readString$5(params, "itemId") ?? readString$5(params, "id");
4233
+ if (item?.type === "agentMessage" && itemId && itemId !== this.pendingRawTerminalAssistantEchoItemId) this.pendingRawTerminalAssistantEchoItemId = void 0;
4189
4234
  if (itemId) {
4190
4235
  this.activeItemIds.delete(itemId);
4191
4236
  this.completedItemIds.add(itemId);
4237
+ this.latestCompletedItemId = itemId;
4192
4238
  }
4193
4239
  this.rememberAssistantPhase(item);
4240
+ if (item?.type === "agentMessage" && !this.isCommentaryAssistantItem(item.id)) {
4241
+ this.latestCompletedTerminalAssistantItemId = item.id;
4242
+ this.markLatestTerminalAssistantCandidate(item.id);
4243
+ this.pendingRawTerminalAssistantEchoItemId = item.id;
4244
+ } else if (itemId) {
4245
+ this.markTerminalAssistantCandidateSupersededBy(itemId, { preserveEarlierActiveItem: true });
4246
+ if (this.latestTerminalAssistantCandidateSuperseded) this.pendingRawTerminalAssistantEchoItemId = void 0;
4247
+ }
4194
4248
  if (item?.type === "agentMessage" && typeof item.text === "string") {
4195
4249
  this.rememberAssistantItem(item.id);
4196
4250
  this.assistantTextByItem.set(item.id, item.text);
@@ -4428,16 +4482,36 @@ var CodexAppServerEventProjector = class {
4428
4482
  async handleRawResponseItemCompleted(params) {
4429
4483
  const item = isJsonObject(params.item) ? params.item : void 0;
4430
4484
  if (!item) return;
4431
- await this.recordRawGeneratedImageMedia(item);
4432
- if (readString$5(item, "role") !== "assistant") return;
4485
+ const role = readString$5(item, "role");
4433
4486
  const phase = readString$5(item, "phase");
4487
+ const rawItemId = readString$5(item, "id");
4488
+ const candidateWasSupersededBeforeRaw = this.latestTerminalAssistantCandidateSuperseded;
4489
+ const pendingTerminalAssistantEchoItemId = this.pendingRawTerminalAssistantEchoItemId;
4490
+ const isPendingTerminalAssistantEcho = role === "assistant" && phase !== "commentary" && pendingTerminalAssistantEchoItemId !== void 0 && (rawItemId === void 0 || rawItemId === pendingTerminalAssistantEchoItemId);
4491
+ if (pendingTerminalAssistantEchoItemId !== void 0 && !isPendingTerminalAssistantEcho) this.pendingRawTerminalAssistantEchoItemId = void 0;
4492
+ if (!isPendingTerminalAssistantEcho) {
4493
+ this.latestCompletedItemId = void 0;
4494
+ this.markTerminalAssistantCandidateSupersededBy(rawItemId);
4495
+ }
4496
+ await this.recordRawGeneratedImageMedia(item);
4497
+ if (role !== "assistant") return;
4434
4498
  if (phase === "commentary" && this.pendingRawCommentaryEchoes > 0) {
4435
4499
  this.pendingRawCommentaryEchoes -= 1;
4436
4500
  return;
4437
4501
  }
4438
4502
  const text = extractRawAssistantText(item);
4503
+ if (isPendingTerminalAssistantEcho) {
4504
+ const typedItemId = pendingTerminalAssistantEchoItemId;
4505
+ this.pendingRawTerminalAssistantEchoItemId = void 0;
4506
+ if (this.assistantTextByItem.get(typedItemId)?.trim() || !text) return;
4507
+ this.rememberAssistantItem(typedItemId);
4508
+ this.assistantTextByItem.set(typedItemId, text);
4509
+ return;
4510
+ }
4439
4511
  if (!text) return;
4440
- const itemId = readString$5(item, "id") ?? `raw-assistant-${this.assistantItemOrder.length + 1}`;
4512
+ const itemId = rawItemId ?? `raw-assistant-${this.assistantItemOrder.length + 1}`;
4513
+ const isIdlessTerminalAssistantAfterCompletedWork = candidateWasSupersededBeforeRaw && rawItemId === void 0 && pendingTerminalAssistantEchoItemId === void 0 && this.activeItemIds.size === 0;
4514
+ if (phase !== "commentary" && candidateWasSupersededBeforeRaw && itemId !== this.streamedPartialAssistantItemId && !isIdlessTerminalAssistantAfterCompletedWork) return;
4441
4515
  if (phase) this.assistantPhaseByItem.set(itemId, phase);
4442
4516
  this.rememberAssistantItem(itemId);
4443
4517
  this.assistantTextByItem.set(itemId, text);
@@ -4445,6 +4519,23 @@ var CodexAppServerEventProjector = class {
4445
4519
  itemId,
4446
4520
  text
4447
4521
  });
4522
+ else this.markLatestTerminalAssistantCandidate(itemId, { canReleaseAfterToolHandoff: isIdlessTerminalAssistantAfterCompletedWork });
4523
+ }
4524
+ markLatestTerminalAssistantCandidate(itemId, options) {
4525
+ this.latestTerminalAssistantCandidateItemId = itemId;
4526
+ this.latestTerminalAssistantCandidateSuperseded = false;
4527
+ this.latestTerminalAssistantCandidateCanReleaseAfterToolHandoff = options?.canReleaseAfterToolHandoff === true;
4528
+ this.terminalAssistantCandidateEarlierActiveItemIds = new Set(this.activeItemIds);
4529
+ }
4530
+ markTerminalAssistantCandidateSupersededBy(itemId, options) {
4531
+ if (!this.latestTerminalAssistantCandidateItemId) return;
4532
+ if (itemId && this.terminalAssistantCandidateEarlierActiveItemIds.has(itemId)) {
4533
+ if (!options?.preserveEarlierActiveItem) this.terminalAssistantCandidateEarlierActiveItemIds.delete(itemId);
4534
+ return;
4535
+ }
4536
+ this.latestTerminalAssistantCandidateSuperseded = true;
4537
+ this.latestTerminalAssistantCandidateCanReleaseAfterToolHandoff = false;
4538
+ this.terminalAssistantCandidateEarlierActiveItemIds.clear();
4448
4539
  }
4449
4540
  recordNativeGeneratedMedia(item) {
4450
4541
  if (item?.type !== "imageGeneration") return;
@@ -7614,6 +7705,10 @@ function readRequestId(record) {
7614
7705
  const CODEX_NATIVE_HOOK_RELAY_RENEW_INTERVAL_MS = 6e4;
7615
7706
  const CODEX_APP_SERVER_PROJECTED_CHARS_PER_TOKEN = 4;
7616
7707
  const CODEX_APP_SERVER_ACTIVE_NATIVE_TURN_WAIT_TIMEOUT_MS = 3e4;
7708
+ function shouldKeepCodexSharedAbortOpen(params) {
7709
+ if (params.explicitCancellationObserved || params.result.aborted || params.result.externalAbort) return false;
7710
+ return params.trigger === "memory" || !params.attemptSucceeded;
7711
+ }
7617
7712
  const ensuredCodexWorkspaceDirs = /* @__PURE__ */ new Set();
7618
7713
  function withCodexAppServerFastModeServiceTier(appServer, params) {
7619
7714
  const fastMode = typeof params.fastMode === "function" ? params.fastMode() : params.fastMode;
@@ -7831,8 +7926,28 @@ async function runCodexAppServerAttempt(params, options = {}) {
7831
7926
  });
7832
7927
  preDynamicStartupStages.mark("native-hook-relay");
7833
7928
  const runAbortController = new AbortController();
7929
+ let explicitCancellationObserved = false;
7930
+ let explicitCancellationReason;
7931
+ let terminalOutcomeFrozen = false;
7932
+ let sharedAbortAllowedAfterTerminalOutcome = false;
7933
+ let attemptAbortNotified = false;
7934
+ const notifyAttemptAbort = () => {
7935
+ if (attemptAbortNotified) return;
7936
+ attemptAbortNotified = true;
7937
+ params.onAttemptAbort?.();
7938
+ };
7939
+ const abortExplicitly = (reason) => {
7940
+ if (terminalOutcomeFrozen) {
7941
+ if (sharedAbortAllowedAfterTerminalOutcome) notifyAttemptAbort();
7942
+ return;
7943
+ }
7944
+ notifyAttemptAbort();
7945
+ explicitCancellationObserved = true;
7946
+ explicitCancellationReason ??= reason;
7947
+ runAbortController.abort(reason);
7948
+ };
7834
7949
  const abortFromUpstream = () => {
7835
- runAbortController.abort(params.abortSignal?.reason ?? "upstream_abort");
7950
+ abortExplicitly(params.abortSignal?.reason ?? "upstream_abort");
7836
7951
  };
7837
7952
  if (params.abortSignal?.aborted) abortFromUpstream();
7838
7953
  else params.abortSignal?.addEventListener("abort", abortFromUpstream, { once: true });
@@ -8625,6 +8740,10 @@ async function runCodexAppServerAttempt(params, options = {}) {
8625
8740
  const pendingOpenClawDynamicToolCompletionIds = /* @__PURE__ */ new Set();
8626
8741
  const activeTurnItemIds = /* @__PURE__ */ new Set();
8627
8742
  const activeCompletionBlockerItemIds = /* @__PURE__ */ new Set();
8743
+ const activeFinalizationHookRunIds = /* @__PURE__ */ new Set();
8744
+ const finalizationHookBatchStatuses = /* @__PURE__ */ new Map();
8745
+ let unsettledFinalizationHookCount = 0;
8746
+ let rejectedFinalizationHookAssistant;
8628
8747
  let turnCrossedToolHandoff = false;
8629
8748
  let pendingTerminalDynamicToolRelease;
8630
8749
  let terminalDynamicToolReleaseCheckScheduled = false;
@@ -8656,6 +8775,8 @@ async function runCodexAppServerAttempt(params, options = {}) {
8656
8775
  getActiveAppServerTurnRequests: () => activeAppServerTurnRequests,
8657
8776
  getActiveTurnItemCount: () => activeTurnItemIds.size,
8658
8777
  getActiveCompletionBlockerItemCount: () => activeCompletionBlockerItemIds.size,
8778
+ getActiveFinalizationHookCount: () => unsettledFinalizationHookCount,
8779
+ canReleaseAssistantCompletionIdle: () => projectorRef.current?.hasLatestTerminalAssistantCandidateText() === true,
8659
8780
  turnCompletionIdleTimeoutMs,
8660
8781
  turnAssistantCompletionIdleTimeoutMs,
8661
8782
  turnAttemptIdleTimeoutMs,
@@ -8876,10 +8997,23 @@ async function runCodexAppServerAttempt(params, options = {}) {
8876
8997
  onReportExecutionNotification: reportExecutionNotification
8877
8998
  });
8878
8999
  turnCrossedToolHandoff = notificationState.turnCrossedToolHandoff;
9000
+ const finalizationHookNotification = readCodexFinalizationHookNotification(notification, thread.threadId, turnId);
9001
+ if (finalizationHookNotification?.phase === "started") {
9002
+ if (activeFinalizationHookRunIds.size === 0) finalizationHookBatchStatuses.clear();
9003
+ activeFinalizationHookRunIds.add(finalizationHookNotification.runId);
9004
+ turnWatches.disarmAssistantCompletionIdleWatch();
9005
+ }
8879
9006
  if (notificationState.isTurnTerminal) terminalTurnNotificationQueued = true;
8880
9007
  try {
8881
9008
  await waitForCodexNotificationDispatchTurn();
8882
9009
  await projector.handleNotification(notification);
9010
+ const projectedAssistantCompletionCanRelease = isAssistantCompletionReleaseNotification(notification, turnCrossedToolHandoff) || notificationState.isCurrentTurnNotification && turnCrossedToolHandoff && notification.method === "rawResponseItem/completed" && projector.canReleaseLatestTerminalAssistantAfterToolHandoff();
9011
+ if (notificationState.isCurrentTurnNotification && projectedAssistantCompletionCanRelease) {
9012
+ const completedAssistantItemId = projector.getLatestTerminalAssistantCandidate()?.itemId;
9013
+ if (rejectedFinalizationHookAssistant !== void 0 && completedAssistantItemId !== void 0 && completedAssistantItemId !== rejectedFinalizationHookAssistant.itemId) rejectedFinalizationHookAssistant = void 0;
9014
+ else if (rejectedFinalizationHookAssistant !== void 0) turnWatches.disarmAssistantCompletionIdleWatch();
9015
+ else if (activeFinalizationHookRunIds.size === 0 && !terminalTurnNotificationQueued && activeAppServerTurnRequests === 0 && activeTurnItemIds.size === 0 && activeCompletionBlockerItemIds.size === 0 && pendingOpenClawDynamicToolCompletionIds.size === 0 && projector.hasLatestTerminalAssistantCandidateText()) turnWatches.armAssistantCompletionIdleWatch(describeNotificationActivity(notification));
9016
+ }
8883
9017
  if (notificationState.isCurrentTurnNotification && activeTurnItemIds.size === 0 && isRawFunctionToolOutputCompletionNotification(notification)) await maybeAnnounceFastModeAutoOff();
8884
9018
  } catch (error) {
8885
9019
  embeddedAgentLog.debug("codex app-server projector notification threw", {
@@ -8887,6 +9021,24 @@ async function runCodexAppServerAttempt(params, options = {}) {
8887
9021
  error
8888
9022
  });
8889
9023
  } finally {
9024
+ if (finalizationHookNotification?.phase === "completed") {
9025
+ unsettledFinalizationHookCount = Math.max(0, unsettledFinalizationHookCount - 1);
9026
+ activeFinalizationHookRunIds.delete(finalizationHookNotification.runId);
9027
+ finalizationHookBatchStatuses.set(finalizationHookNotification.runId, finalizationHookNotification.status);
9028
+ if (activeFinalizationHookRunIds.size === 0) {
9029
+ const statuses = new Set(finalizationHookBatchStatuses.values());
9030
+ if (statuses.has("blocked") && !statuses.has("stopped")) {
9031
+ const itemId = projector.getLatestTerminalAssistantCandidate()?.itemId;
9032
+ rejectedFinalizationHookAssistant = itemId ? { itemId } : {};
9033
+ turnWatches.disarmAssistantCompletionIdleWatch();
9034
+ } else rejectedFinalizationHookAssistant = void 0;
9035
+ }
9036
+ if (activeFinalizationHookRunIds.size === 0 && rejectedFinalizationHookAssistant === void 0 && !terminalTurnNotificationQueued && activeAppServerTurnRequests === 0 && activeTurnItemIds.size === 0 && activeCompletionBlockerItemIds.size === 0 && pendingOpenClawDynamicToolCompletionIds.size === 0 && projector.hasLatestTerminalAssistantCandidateText()) turnWatches.armAssistantCompletionIdleWatch({
9037
+ lastNotificationMethod: notification.method,
9038
+ hookRunId: finalizationHookNotification.runId,
9039
+ hookStatus: finalizationHookNotification.status
9040
+ });
9041
+ }
8890
9042
  if (notificationState.isTurnTerminal) {
8891
9043
  if (notificationState.isTurnAbortMarker) projector.markAborted();
8892
9044
  if (!timedOut && !runAbortController.signal.aborted) await steeringQueue?.flushPending();
@@ -8954,14 +9106,27 @@ async function runCodexAppServerAttempt(params, options = {}) {
8954
9106
  const nativeItem = readCodexNotificationItem(notification.params);
8955
9107
  if (nativeItem?.type === "webSearch") projector.recordNativeToolOutcome(nativeItem);
8956
9108
  }
8957
- if (notificationMatchesActiveTurn) turnWatches.noteNotificationReceived(notification.method, isNativeResponseStreamDelta ? {
8958
- attemptProgress: true,
8959
- ...turnCrossedToolHandoff ? { attemptTimeoutMs: postToolRawAssistantCompletionIdleTimeoutMs } : {},
8960
- details: { lastNotificationMethod: notification.method }
8961
- } : void 0);
9109
+ if (notificationMatchesActiveTurn) {
9110
+ if (readCodexFinalizationHookNotification(notification, thread.threadId, turnId)?.phase === "started") {
9111
+ unsettledFinalizationHookCount += 1;
9112
+ turnWatches.disarmAssistantCompletionIdleWatch();
9113
+ }
9114
+ turnWatches.noteNotificationReceived(notification.method, isNativeResponseStreamDelta ? {
9115
+ attemptProgress: true,
9116
+ ...turnCrossedToolHandoff ? { attemptTimeoutMs: postToolRawAssistantCompletionIdleTimeoutMs } : {},
9117
+ details: { lastNotificationMethod: notification.method }
9118
+ } : void 0);
9119
+ }
8962
9120
  notificationQueue = notificationQueue.then(() => handleNotification(notification), () => handleNotification(notification));
8963
9121
  return notificationQueue;
8964
9122
  };
9123
+ const drainNotificationQueue = async () => {
9124
+ while (true) {
9125
+ const queued = notificationQueue;
9126
+ await queued;
9127
+ if (queued === notificationQueue) return;
9128
+ }
9129
+ };
8965
9130
  const nativeSubagentCodexHome = appServer.start.transport === "stdio" ? appServer.start.env?.CODEX_HOME ?? resolveCodexAppServerHomeDir(agentDir) : void 0;
8966
9131
  registerCodexNativeSubagentMonitor({
8967
9132
  client,
@@ -9579,15 +9744,23 @@ async function runCodexAppServerAttempt(params, options = {}) {
9579
9744
  steeringQueueRef.current = activeSteeringQueue;
9580
9745
  const handle = {
9581
9746
  kind: "embedded",
9747
+ runId: params.runId,
9582
9748
  queueMessage: async (text, optionsLocal) => activeSteeringQueue.queue(text, optionsLocal),
9583
9749
  isStreaming: () => !completed && !runAbortController.signal.aborted,
9584
9750
  isStopped: () => completed || timedOut || runAbortController.signal.aborted,
9751
+ isAbortable: () => !terminalOutcomeFrozen || sharedAbortAllowedAfterTerminalOutcome,
9585
9752
  isCompacting: () => projectorRef.current?.isCompacting() ?? false,
9586
9753
  sourceReplyDeliveryMode: params.sourceReplyDeliveryMode,
9587
- cancel: () => runAbortController.abort("cancelled"),
9588
- abort: () => runAbortController.abort("aborted")
9754
+ cancel: () => abortExplicitly("cancelled"),
9755
+ abort: () => abortExplicitly("aborted")
9589
9756
  };
9757
+ params.replyOperation?.attachBackend(handle);
9590
9758
  setActiveEmbeddedRun(params.sessionId, handle, params.sessionKey, params.sessionFile);
9759
+ const freezeRunTerminalOutcome = () => {
9760
+ if (terminalOutcomeFrozen) return;
9761
+ terminalOutcomeFrozen = true;
9762
+ params.abortSignal?.removeEventListener("abort", abortFromUpstream);
9763
+ };
9591
9764
  const notifyUserMessagePersisted = createCodexAppServerUserMessagePersistenceNotifier(params);
9592
9765
  mirrorPromptAtTurnStartBestEffort({
9593
9766
  params,
@@ -9622,12 +9795,32 @@ async function runCodexAppServerAttempt(params, options = {}) {
9622
9795
  if (runAbortController.signal.aborted) abortListener();
9623
9796
  try {
9624
9797
  await completion;
9625
- await notificationQueue;
9798
+ await drainNotificationQueue();
9799
+ const hasQuiescentCompletedAssistant = activeProjector.hasCompletedTerminalAssistantText() && activeAppServerTurnRequests === 0 && activeTurnItemIds.size === 0 && activeCompletionBlockerItemIds.size === 0 && pendingOpenClawDynamicToolCompletionIds.size === 0 && activeFinalizationHookRunIds.size === 0 && unsettledFinalizationHookCount === 0 && rejectedFinalizationHookAssistant === void 0;
9800
+ const hasRecoverableCompletedAssistant = !turnWatches.isCompletionIdleWatchPinnedByTerminalError() && turnWatches.isAssistantCompletionIdleWatchArmed() && hasQuiescentCompletedAssistant;
9801
+ const recoveredTurnWatchTimeout = turnCompletionIdleTimedOut && !explicitCancellationObserved && !terminalTurnNotificationQueued && hasRecoverableCompletedAssistant && activeProjector.recoverCompletedTerminalAssistantAfterTurnWatchTimeout();
9802
+ if (recoveredTurnWatchTimeout) {
9803
+ embeddedAgentLog.warn("codex app-server recovered completed assistant output after missing turn completion", {
9804
+ threadId: thread.threadId,
9805
+ turnId: activeTurnId,
9806
+ timeoutKind: turnWatchTimeoutKind,
9807
+ idleMs: turnWatchTimeoutIdleMs,
9808
+ timeoutMs: turnWatchTimeoutMs
9809
+ });
9810
+ trajectoryRecorder?.recordEvent("turn.watch_timeout_recovered", {
9811
+ threadId: thread.threadId,
9812
+ turnId: activeTurnId,
9813
+ timeoutKind: turnWatchTimeoutKind,
9814
+ idleMs: turnWatchTimeoutIdleMs,
9815
+ timeoutMs: turnWatchTimeoutMs
9816
+ });
9817
+ }
9626
9818
  const result = activeProjector.buildResult(toolBridge.telemetry, { yieldDetected });
9627
- const finalAborted = result.aborted || runAbortController.signal.aborted && !clientClosedAbort;
9628
- const canUseCompletedAssistantTextAfterClientClose = activeProjector.hasCompletedTerminalAssistantText() && activeAppServerTurnRequests === 0 && activeTurnItemIds.size === 0 && pendingOpenClawDynamicToolCompletionIds.size === 0;
9629
- const clientClosedPromptErrorForFinal = clientClosedPromptError && canUseCompletedAssistantTextAfterClientClose ? void 0 : clientClosedPromptError;
9630
- let finalPromptError = clientClosedPromptErrorForFinal ?? (turnCompletionIdleTimedOut ? turnCompletionIdleTimeoutMessage : timedOut ? "codex app-server attempt timed out" : result.promptError);
9819
+ const effectiveTimedOut = timedOut && !recoveredTurnWatchTimeout;
9820
+ const effectiveTurnCompletionIdleTimedOut = turnCompletionIdleTimedOut && !recoveredTurnWatchTimeout;
9821
+ const isFinalAborted = () => result.aborted || explicitCancellationObserved || runAbortController.signal.aborted && !clientClosedAbort && !recoveredTurnWatchTimeout;
9822
+ const clientClosedPromptErrorForFinal = clientClosedPromptError && hasRecoverableCompletedAssistant ? void 0 : clientClosedPromptError;
9823
+ let finalPromptError = clientClosedPromptErrorForFinal ?? (effectiveTurnCompletionIdleTimedOut ? turnCompletionIdleTimeoutMessage : effectiveTimedOut ? "codex app-server attempt timed out" : result.promptError);
9631
9824
  const finalPromptErrorMessage = typeof finalPromptError === "string" ? finalPromptError : finalPromptError ? formatErrorMessage(finalPromptError) : void 0;
9632
9825
  if (isInvalidCodexImagePayloadError(finalPromptErrorMessage)) await clearCodexBindingAfterInvalidImagePayload(activeSessionFile, {
9633
9826
  phase: "turn_completed",
@@ -9656,12 +9849,12 @@ async function runCodexAppServerAttempt(params, options = {}) {
9656
9849
  signal: runAbortController.signal
9657
9850
  });
9658
9851
  if (refreshedUsageLimitPromptError) finalPromptError = refreshedUsageLimitPromptError;
9659
- const finalPromptErrorSource = timedOut || clientClosedPromptErrorForFinal ? "prompt" : result.promptErrorSource;
9660
- const codexAppServerFailureKind = clientClosedPromptErrorForFinal ? "client_closed_before_turn_completed" : turnCompletionIdleTimedOut ? "turn_completion_idle_timeout" : void 0;
9852
+ const finalPromptErrorSource = effectiveTimedOut || clientClosedPromptErrorForFinal ? "prompt" : result.promptErrorSource;
9853
+ const codexAppServerFailureKind = clientClosedPromptErrorForFinal ? "client_closed_before_turn_completed" : effectiveTurnCompletionIdleTimedOut ? "turn_completion_idle_timeout" : void 0;
9661
9854
  const codexAppServerReplayBlockedReason = codexAppServerFailureKind ? resolveCodexAppServerReplayBlockedReason(result) : void 0;
9662
9855
  const promptTimeoutOutcome = buildCodexAppServerPromptTimeoutOutcome({
9663
9856
  result,
9664
- turnCompletionIdleTimedOut,
9857
+ turnCompletionIdleTimedOut: effectiveTurnCompletionIdleTimedOut,
9665
9858
  turnWatchTimeoutKind
9666
9859
  });
9667
9860
  const codexAppServerFailureDiagnostics = codexAppServerFailureKind === "turn_completion_idle_timeout" && turnWatchTimeoutKind === "completion" ? buildCodexAppServerTimeoutDiagnostics({
@@ -9670,35 +9863,39 @@ async function runCodexAppServerAttempt(params, options = {}) {
9670
9863
  lastActivityReason: turnWatchTimeoutLastActivityReason,
9671
9864
  details: turnWatchTimeoutDetails
9672
9865
  }) : void 0;
9866
+ const codexAppServerFailure = codexAppServerFailureKind ? {
9867
+ kind: codexAppServerFailureKind,
9868
+ ...codexAppServerFailureKind === "turn_completion_idle_timeout" && turnWatchTimeoutKind ? { turnWatchTimeoutKind } : {},
9869
+ transport: appServer.start.transport,
9870
+ threadId: thread.threadId,
9871
+ turnId: activeTurnId,
9872
+ replaySafe: codexAppServerReplayBlockedReason === void 0,
9873
+ ...codexAppServerReplayBlockedReason ? { replayBlockedReason: codexAppServerReplayBlockedReason } : {},
9874
+ ...codexAppServerFailureDiagnostics ? { diagnostics: codexAppServerFailureDiagnostics } : {}
9875
+ } : void 0;
9876
+ const finalAborted = isFinalAborted();
9877
+ const completedTurnStatus = activeProjector.getCompletedTurnStatus();
9878
+ const completedWithoutTerminalNotification = completed && !terminalTurnNotificationQueued && !timedOut && clientClosedPromptErrorForFinal === void 0;
9879
+ const attemptSucceeded = !finalAborted && !effectiveTimedOut && (finalPromptError === null || finalPromptError === void 0) && result.agentHarnessResultClassification === void 0 && (completedTurnStatus === "completed" || recoveredTurnWatchTimeout || completedWithoutTerminalNotification);
9880
+ sharedAbortAllowedAfterTerminalOutcome = shouldKeepCodexSharedAbortOpen({
9881
+ trigger: params.trigger,
9882
+ result,
9883
+ attemptSucceeded,
9884
+ explicitCancellationObserved
9885
+ });
9886
+ freezeRunTerminalOutcome();
9673
9887
  const modelCallFailureKind = classifyCodexModelCallFailureKind({
9674
9888
  error: finalPromptError,
9675
- timedOut,
9676
- turnCompletionIdleTimedOut,
9677
- runAborted: runAbortController.signal.aborted,
9678
- abortReason: runAbortController.signal.reason,
9889
+ timedOut: effectiveTimedOut,
9890
+ turnCompletionIdleTimedOut: effectiveTurnCompletionIdleTimedOut,
9891
+ runAborted: finalAborted,
9892
+ abortReason: explicitCancellationReason ?? runAbortController.signal.reason,
9679
9893
  clientClosedAbort,
9680
9894
  formatError: formatErrorMessage
9681
9895
  }) ?? (finalAborted ? "aborted" : void 0);
9682
9896
  if (modelCallFailureKind) codexModelCallDiagnostics.emitError(finalPromptError ?? "codex app-server attempt interrupted", { failureKind: modelCallFailureKind });
9683
9897
  else if (finalPromptError) codexModelCallDiagnostics.emitError(finalPromptError);
9684
9898
  else codexModelCallDiagnostics.emitCompleted(result);
9685
- recordCodexTrajectoryCompletion(trajectoryRecorder, {
9686
- attempt: params,
9687
- result,
9688
- threadId: thread.threadId,
9689
- turnId: activeTurnId,
9690
- timedOut,
9691
- yieldDetected
9692
- });
9693
- trajectoryRecorder?.recordEvent("session.ended", {
9694
- status: finalPromptError ? "error" : finalAborted || timedOut ? "interrupted" : "success",
9695
- threadId: thread.threadId,
9696
- turnId: activeTurnId,
9697
- timedOut,
9698
- yieldDetected,
9699
- promptError: normalizeCodexTrajectoryError(finalPromptError)
9700
- });
9701
- markTrajectoryEndRecorded();
9702
9899
  await mirrorTranscriptBestEffort({
9703
9900
  params,
9704
9901
  agentId: sessionAgentId,
@@ -9709,19 +9906,6 @@ async function runCodexAppServerAttempt(params, options = {}) {
9709
9906
  threadId: thread.threadId,
9710
9907
  turnId: activeTurnId
9711
9908
  });
9712
- const terminalAssistantText = collectTerminalAssistantText(result);
9713
- if (terminalAssistantText && (!assistantStreamEventEmitted || assistantStreamNeedsTerminalSnapshot) && !finalAborted && !finalPromptError) emitCodexAppServerEvent(params, {
9714
- stream: "assistant",
9715
- data: { text: terminalAssistantText }
9716
- });
9717
- if (finalPromptError) emitLifecycleTerminal({
9718
- phase: "error",
9719
- error: formatErrorMessage(finalPromptError)
9720
- });
9721
- else emitLifecycleTerminal({
9722
- phase: "end",
9723
- ...finalAborted ? { aborted: true } : {}
9724
- });
9725
9909
  if (activeContextEngine) {
9726
9910
  const activeContextEnginePluginIdLocal = resolveContextEngineOwnerPluginId(activeContextEngine);
9727
9911
  const isHeartbeatLifecycleRun = params.bootstrapContextRunKind === "heartbeat" || params.bootstrapContextRunKind === "commitment-only";
@@ -9786,30 +9970,64 @@ async function runCodexAppServerAttempt(params, options = {}) {
9786
9970
  ctx: hookContext,
9787
9971
  hookRunner
9788
9972
  });
9789
- shouldDelayNativeHookRelayUnregister = activeProjector.getCompletedTurnStatus() === "completed" && !timedOut && !runAbortController.signal.aborted && !finalAborted && !finalPromptError;
9790
- if (shouldDelayNativeHookRelayUnregister) await markCodexAppServerBindingCoveredThroughTurn({
9791
- sessionFile: params.sessionFile,
9973
+ shouldDelayNativeHookRelayUnregister = completedTurnStatus === "completed" && !effectiveTimedOut && !runAbortController.signal.aborted && !finalAborted && !finalPromptError;
9974
+ if (shouldDelayNativeHookRelayUnregister) try {
9975
+ await markCodexAppServerBindingCoveredThroughTurn({
9976
+ sessionFile: params.sessionFile,
9977
+ threadId: thread.threadId,
9978
+ authProfileStore: params.authProfileStore,
9979
+ agentDir: params.agentDir,
9980
+ config: params.config
9981
+ });
9982
+ } catch (error) {
9983
+ if (!await clearCodexAppServerBindingForThread(params.sessionFile, thread.threadId, {
9984
+ authProfileStore: params.authProfileStore,
9985
+ agentDir: params.agentDir,
9986
+ config: params.config
9987
+ })) throw error;
9988
+ embeddedAgentLog.warn("codex app-server binding coverage update failed after completed turn; cleared stale binding", {
9989
+ threadId: thread.threadId,
9990
+ turnId: activeTurnId,
9991
+ error
9992
+ });
9993
+ }
9994
+ recordCodexTrajectoryCompletion(trajectoryRecorder, {
9995
+ attempt: params,
9996
+ result,
9792
9997
  threadId: thread.threadId,
9793
- authProfileStore: params.authProfileStore,
9794
- agentDir: params.agentDir,
9795
- config: params.config
9998
+ turnId: activeTurnId,
9999
+ timedOut: effectiveTimedOut,
10000
+ yieldDetected
10001
+ });
10002
+ trajectoryRecorder?.recordEvent("session.ended", {
10003
+ status: finalPromptError ? "error" : finalAborted || effectiveTimedOut ? "interrupted" : "success",
10004
+ threadId: thread.threadId,
10005
+ turnId: activeTurnId,
10006
+ timedOut: effectiveTimedOut,
10007
+ yieldDetected,
10008
+ promptError: normalizeCodexTrajectoryError(finalPromptError)
10009
+ });
10010
+ markTrajectoryEndRecorded();
10011
+ const terminalAssistantText = collectTerminalAssistantText(result);
10012
+ if (terminalAssistantText && (!assistantStreamEventEmitted || assistantStreamNeedsTerminalSnapshot) && !finalAborted && !finalPromptError) emitCodexAppServerEvent(params, {
10013
+ stream: "assistant",
10014
+ data: { text: terminalAssistantText }
10015
+ });
10016
+ if (finalPromptError) emitLifecycleTerminal({
10017
+ phase: "error",
10018
+ error: formatErrorMessage(finalPromptError)
10019
+ });
10020
+ else emitLifecycleTerminal({
10021
+ phase: "end",
10022
+ ...finalAborted ? { aborted: true } : {}
9796
10023
  });
9797
10024
  return {
9798
10025
  ...result,
9799
- timedOut,
10026
+ timedOut: effectiveTimedOut,
9800
10027
  aborted: finalAborted,
9801
10028
  promptError: finalPromptError,
9802
10029
  promptErrorSource: finalPromptErrorSource,
9803
- ...codexAppServerFailureKind ? { codexAppServerFailure: {
9804
- kind: codexAppServerFailureKind,
9805
- ...codexAppServerFailureKind === "turn_completion_idle_timeout" && turnWatchTimeoutKind ? { turnWatchTimeoutKind } : {},
9806
- transport: appServer.start.transport,
9807
- threadId: thread.threadId,
9808
- turnId: activeTurnId,
9809
- replaySafe: codexAppServerReplayBlockedReason === void 0,
9810
- ...codexAppServerReplayBlockedReason ? { replayBlockedReason: codexAppServerReplayBlockedReason } : {},
9811
- ...codexAppServerFailureDiagnostics ? { diagnostics: codexAppServerFailureDiagnostics } : {}
9812
- } } : {},
10030
+ ...codexAppServerFailure ? { codexAppServerFailure } : {},
9813
10031
  ...promptTimeoutOutcome ? { promptTimeoutOutcome } : {},
9814
10032
  systemPromptReport
9815
10033
  };
@@ -9854,8 +10072,9 @@ async function runCodexAppServerAttempt(params, options = {}) {
9854
10072
  else nativeHookRelay.unregister();
9855
10073
  await releaseSandboxExecEnvironment();
9856
10074
  runAbortController.signal.removeEventListener("abort", abortListener);
9857
- params.abortSignal?.removeEventListener("abort", abortFromUpstream);
9858
10075
  steeringQueueRef.current?.cancel();
10076
+ freezeRunTerminalOutcome();
10077
+ params.replyOperation?.detachBackend(handle);
9859
10078
  clearActiveEmbeddedRun(params.sessionId, handle, params.sessionKey, params.sessionFile);
9860
10079
  }
9861
10080
  }
@@ -9919,6 +10138,21 @@ function isCodexThreadTurnCompletedNotification(notification, threadId, turnIds)
9919
10138
  const turnId = correlation.turnId ?? correlation.nestedTurnId;
9920
10139
  return !turnIds || turnId !== void 0 && turnIds.has(turnId);
9921
10140
  }
10141
+ function readCodexFinalizationHookNotification(notification, threadId, turnId) {
10142
+ if (notification.method !== "hook/started" && notification.method !== "hook/completed") return;
10143
+ const params = isJsonObject(notification.params) ? notification.params : void 0;
10144
+ const run = params && isJsonObject(params.run) ? params.run : void 0;
10145
+ if (params?.threadId !== threadId || params.turnId !== turnId || run?.eventName !== "stop" && run?.eventName !== "subagentStop" || typeof run.id !== "string" || !run.id) return;
10146
+ if (notification.method === "hook/started") return {
10147
+ phase: "started",
10148
+ runId: run.id
10149
+ };
10150
+ return {
10151
+ phase: "completed",
10152
+ runId: run.id,
10153
+ status: typeof run.status === "string" ? run.status : void 0
10154
+ };
10155
+ }
9922
10156
  function joinPresentSections(...sections) {
9923
10157
  return sections.filter((section) => Boolean(section?.trim())).join("\n\n");
9924
10158
  }
@@ -1,14 +1,14 @@
1
1
  import { n as isJsonObject } from "./protocol-dh-ETiNd.js";
2
- import { H as readCodexNotificationThreadId, P as mergeCodexThreadConfigs, S as filterCodexDynamicTools, T as resolveCodexDynamicToolsLoading, U as readCodexNotificationTurnId, _ as resolveCodexWebSearchPlan, d as resolveCodexAppServerRequestModelSelection, j as buildCodexPluginAppsConfigPatchFromPolicyContext, m as resolveReasoningEffort, p as resolveCodexBindingModelProviderFallback, r as buildCodexRuntimeThreadConfig, t as CODEX_NATIVE_PERSONALITY_NONE, u as resolveCodexAppServerModelProvider } from "./thread-lifecycle-DeSMZSXr.js";
2
+ import { H as readCodexNotificationThreadId, P as mergeCodexThreadConfigs, S as filterCodexDynamicTools, T as resolveCodexDynamicToolsLoading, U as readCodexNotificationTurnId, _ as resolveCodexWebSearchPlan, d as resolveCodexAppServerRequestModelSelection, j as buildCodexPluginAppsConfigPatchFromPolicyContext, m as resolveReasoningEffort, p as resolveCodexBindingModelProviderFallback, r as buildCodexRuntimeThreadConfig, t as CODEX_NATIVE_PERSONALITY_NONE, u as resolveCodexAppServerModelProvider } from "./thread-lifecycle-D6R40plk.js";
3
3
  import { d as resolveCodexAppServerRuntimeOptions, g as shouldAutoApproveCodexAppServerApprovals, h as resolveOpenClawExecPolicyForCodexAppServer, n as canUseCodexModelBackedApprovalsReviewerForModel, p as resolveCodexModelBackedReviewerPolicyContext, u as readCodexPluginConfig } from "./config-C_whBx3M.js";
4
- import { a as readCodexDynamicToolCallParams, c as readCodexTurn, i as assertCodexTurnStartResponse, t as assertCodexThreadForkResponse } from "./protocol-validators-CB4mtyrs.js";
5
- import { a as readCodexSupportedReasoningEfforts, s as formatCodexUsageLimitErrorMessage } from "./provider-DosqwRb6.js";
4
+ import { a as readCodexDynamicToolCallParams, c as readCodexTurn, i as assertCodexTurnStartResponse, t as assertCodexThreadForkResponse } from "./protocol-validators-CJiWigAJ.js";
5
+ import { a as readCodexSupportedReasoningEfforts, s as formatCodexUsageLimitErrorMessage } from "./provider-nmtMDcGH.js";
6
6
  import { i as isCodexAppServerApprovalRequest } from "./client-IcTBKEqA.js";
7
7
  import { i as isCodexAppServerNativeAuthProfile, o as readCodexAppServerBinding } from "./session-binding-Cm0Gg7Z1.js";
8
- import { t as resolveCodexAppServerForModelProvider } from "./app-server-policy-xi0ZmBGO.js";
8
+ import { t as resolveCodexAppServerForModelProvider } from "./app-server-policy-B7hqD3Xj.js";
9
9
  import { a as getLeasedSharedCodexAppServerClient, o as releaseLeasedSharedCodexAppServerClient, u as refreshCodexAppServerAuthTokens } from "./shared-client-rR6TDJA3.js";
10
10
  import { n as resolveCodexNativeExecutionBlock } from "./sandbox-guard-pTY2COoC.js";
11
- import { C as resolveCodexMessageToolProvider, O as filterToolsForVisionInputs, T as shouldEnableCodexAppServerNativeToolSurface, a as buildCodexNativeHookRelayConfig, d as handleCodexAppServerElicitationRequest, f as createCodexDynamicToolBridge, h as emitDynamicToolTerminalDiagnostic, k as handleCodexAppServerApprovalRequest, m as emitDynamicToolStartedDiagnostic, n as resolveCodexProviderWebSearchSupportForClient, o as buildCodexNativeHookRelayDisabledConfig, p as emitDynamicToolErrorDiagnostic, r as CODEX_NATIVE_HOOK_RELAY_EVENTS } from "./provider-capabilities-CE5k8cmO.js";
11
+ import { C as resolveCodexMessageToolProvider, O as filterToolsForVisionInputs, T as shouldEnableCodexAppServerNativeToolSurface, a as buildCodexNativeHookRelayConfig, d as handleCodexAppServerElicitationRequest, f as createCodexDynamicToolBridge, h as emitDynamicToolTerminalDiagnostic, k as handleCodexAppServerApprovalRequest, m as emitDynamicToolStartedDiagnostic, n as resolveCodexProviderWebSearchSupportForClient, o as buildCodexNativeHookRelayDisabledConfig, p as emitDynamicToolErrorDiagnostic, r as CODEX_NATIVE_HOOK_RELAY_EVENTS } from "./provider-capabilities-wqedK49Z.js";
12
12
  import { n as rememberCodexRateLimits, t as readRecentCodexRateLimits } from "./rate-limit-cache-C7qmZ0Jh.js";
13
13
  import { loadExecApprovals } from "openclaw/plugin-sdk/exec-approvals-runtime";
14
14
  import { buildAgentHookContextChannelFields, embeddedAgentLog, formatErrorMessage, registerNativeHookRelay, resolveAgentDir, resolveAttemptSpawnWorkspaceDir, resolveModelAuthMode, resolveSandboxContext, resolveSessionAgentIds, supportsModelTools } from "openclaw/plugin-sdk/agent-harness-runtime";
@@ -1,8 +1,8 @@
1
1
  import { n as isJsonObject, t as flattenCodexDynamicToolFunctions } from "./protocol-dh-ETiNd.js";
2
2
  import { i as codexSandboxPolicyForTurn, m as resolveCodexPluginsPolicy, t as CODEX_PLUGINS_MARKETPLACE_NAME } from "./config-C_whBx3M.js";
3
- import { n as assertCodexThreadResumeResponse, r as assertCodexThreadStartResponse } from "./protocol-validators-CB4mtyrs.js";
3
+ import { n as assertCodexThreadResumeResponse, r as assertCodexThreadStartResponse } from "./protocol-validators-CJiWigAJ.js";
4
4
  import { CODEX_GPT5_HEARTBEAT_PROMPT_OVERLAY } from "./prompt-overlay.js";
5
- import { a as readCodexSupportedReasoningEfforts, i as isModernCodexModel, o as resolveCodexSupportedReasoningEffort, r as isMaxReasoningCodexModel } from "./provider-DosqwRb6.js";
5
+ import { a as readCodexSupportedReasoningEfforts, i as isModernCodexModel, o as resolveCodexSupportedReasoningEffort, r as isMaxReasoningCodexModel } from "./provider-nmtMDcGH.js";
6
6
  import { a as isCodexAppServerConnectionClosedError, n as CodexAppServerRpcError } from "./client-IcTBKEqA.js";
7
7
  import { i as isCodexAppServerNativeAuthProfile, l as writeCodexAppServerBinding, n as clearCodexAppServerBinding, o as readCodexAppServerBinding } from "./session-binding-Cm0Gg7Z1.js";
8
8
  import "node:fs/promises";
@@ -1,6 +1,6 @@
1
1
  import { n as isJsonObject } from "./protocol-dh-ETiNd.js";
2
- import { g as buildCodexNativeWebSearchThreadConfig } from "./thread-lifecycle-DeSMZSXr.js";
3
- import { n as runBoundedCodexAppServerTurn } from "./media-understanding-provider-C5yYzx_6.js";
2
+ import { g as buildCodexNativeWebSearchThreadConfig } from "./thread-lifecycle-D6R40plk.js";
3
+ import { n as runBoundedCodexAppServerTurn } from "./media-understanding-provider-BOeoBhEw.js";
4
4
  import { readStringParam, resolveSearchTimeoutSeconds, wrapWebContent } from "openclaw/plugin-sdk/provider-web-search";
5
5
  //#region extensions/codex/src/web-search-provider.runtime.ts
6
6
  async function executeCodexWebSearchProviderTool(ctx, args, executionContext, options) {
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "@openclaw/codex",
3
- "version": "2026.7.1-beta.1",
3
+ "version": "2026.7.1-beta.2",
4
4
  "lockfileVersion": 3,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "@openclaw/codex",
9
- "version": "2026.7.1-beta.1",
9
+ "version": "2026.7.1-beta.2",
10
10
  "dependencies": {
11
11
  "@openai/codex": "0.142.4",
12
12
  "typebox": "1.1.39",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@openclaw/codex",
3
- "version": "2026.7.1-beta.1",
3
+ "version": "2026.7.1-beta.2",
4
4
  "description": "OpenClaw Codex app-server harness and model provider plugin with a Codex-managed GPT catalog.",
5
5
  "repository": {
6
6
  "type": "git",
@@ -34,10 +34,10 @@
34
34
  ]
35
35
  },
36
36
  "compat": {
37
- "pluginApi": ">=2026.7.1-beta.1"
37
+ "pluginApi": ">=2026.7.1-beta.2"
38
38
  },
39
39
  "build": {
40
- "openclawVersion": "2026.7.1-beta.1"
40
+ "openclawVersion": "2026.7.1-beta.2"
41
41
  },
42
42
  "release": {
43
43
  "publishToClawHub": true,
@@ -55,7 +55,7 @@
55
55
  "README.md"
56
56
  ],
57
57
  "peerDependencies": {
58
- "openclaw": ">=2026.7.1-beta.1"
58
+ "openclaw": ">=2026.7.1-beta.2"
59
59
  },
60
60
  "peerDependenciesMeta": {
61
61
  "openclaw": {