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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (54) hide show
  1. package/dist/api.js +3 -3
  2. package/dist/{attempt-client-cleanup-URjUlCHg.js → attempt-client-cleanup-bfsmcQ6m.js} +21 -2
  3. package/dist/{binding-connection-DAvZwp96.js → binding-connection-BMvPX73o.js} +2 -2
  4. package/dist/{bounded-turn-4BjrZEwW.js → bounded-turn-B7iBUcuP.js} +8 -8
  5. package/dist/{capabilities-CH3K57v4.js → capabilities-BRMh0aIq.js} +1 -1
  6. package/dist/cli-metadata.js +1 -1
  7. package/dist/{command-formatters-D0nZ3qtd.js → command-formatters-DEsIufkt.js} +2 -2
  8. package/dist/{command-handlers-DC86lgT4.js → command-handlers-D_-1_qRp.js} +43 -32
  9. package/dist/{command-rpc-xUIIonsO.js → command-rpc-CCeCkf_v.js} +4 -4
  10. package/dist/{compact-COqgBRny.js → compact-BglNFZrQ.js} +8 -8
  11. package/dist/{config-CpNeo5AE.js → config-giW8X0QA.js} +82 -28
  12. package/dist/doctor-contract-api.js +9 -8
  13. package/dist/{dynamic-tools-fJZhl4CE.js → dynamic-tools-Dnlfa--w.js} +108 -820
  14. package/dist/{effective-mcp-catalog-4YKn51aG.js → effective-mcp-catalog-CTeGrnfO.js} +2 -2
  15. package/dist/{event-projector-assistant-message-BwxV4d6N.js → event-projector-assistant-message-C5-Ds8mA.js} +18 -1
  16. package/dist/{event-projector-usage-CLwNEJqW.js → event-projector-usage-Bk1I90Bg.js} +3 -3
  17. package/dist/{harness-DoKQcF8n.js → harness-Csz0F-DK.js} +11 -11
  18. package/dist/harness.js +1 -1
  19. package/dist/index.js +130 -172
  20. package/dist/{isolated-completion-DPMtlH9r.js → isolated-completion-Cv6FqygM.js} +4 -4
  21. package/dist/{managed-binary-By4FZC6i.js → managed-binary-DFYK4DWq.js} +43 -7
  22. package/dist/media-understanding-provider.js +1 -1
  23. package/dist/{model-catalog-CmGoqVKB.js → model-catalog-i9rNBthX.js} +4 -4
  24. package/dist/{models-CZw1wClT.js → models-TS3HBU-q.js} +4 -3
  25. package/dist/{native-subagent-monitor-GGq3RnOo.js → native-subagent-monitor-4Mfq2HDs.js} +176 -19
  26. package/dist/{node-exec-server.runtime-Bsu1LdFZ.js → node-exec-server.runtime-BpWqJO1V.js} +2 -2
  27. package/dist/{plugin-app-cache-key-DMNQ8Zi8.js → plugin-app-cache-key-C1CAdfcP.js} +6 -3
  28. package/dist/{plugin-approval-roundtrip-C75Yiiwc.js → plugin-approval-roundtrip-bUm777tR.js} +1 -1
  29. package/dist/{plugin-marketplace-discovery-CSWDkMrP.js → plugin-marketplace-discovery-B9DvaAG-.js} +29 -38
  30. package/dist/{plugin-metadata-cache-BXH5NF-4.js → plugin-metadata-cache-CTCT3w5L.js} +162 -135
  31. package/dist/{protocol-validators-VAVyEnDp.js → protocol-validators-VeJxxJ0U.js} +25 -3
  32. package/dist/{rate-limits-BI1dMHDG.js → rate-limits-C5_D8Gmb.js} +1 -1
  33. package/dist/{request-DSK0W6YI.js → request-DXXGHko0.js} +2 -2
  34. package/dist/{run-attempt-BV3HzuCf.js → run-attempt-DYc0QCBF.js} +346 -267
  35. package/dist/{sandbox-guard-C1qEeZ5C.js → sandbox-guard-kuWTn9C5.js} +1 -1
  36. package/dist/{session-binding-BTrLf9Qm.js → session-binding-Bcynfd-_.js} +1 -1
  37. package/dist/{session-catalog-ezP_UcRM.js → session-catalog-DaLKVtpH.js} +17 -16
  38. package/dist/{session-cli-B1hKvfkI.js → session-cli-DMc4oS2w.js} +1 -1
  39. package/dist/session-permission-policy-BrNH1bjy.js +160 -0
  40. package/dist/{session-retirement-CE4iMiLh.js → session-retirement-CcNC3YSY.js} +3 -3
  41. package/dist/{session-upstream-marker-D_2npHlA.js → session-upstream-marker-BIkusb95.js} +1 -1
  42. package/dist/{settled-turn-finalizer-Dx1onIqg.js → settled-turn-finalizer-Dc3ApjU4.js} +4 -4
  43. package/dist/{shared-client-Dw-rzii0.js → shared-client-DKz23hHY.js} +1026 -248
  44. package/dist/{side-question-DbXkJZzg.js → side-question-DjA_jsNe.js} +65 -36
  45. package/dist/{thread-lifecycle-DKdrnTMX.js → thread-lifecycle-L7oEkTlq.js} +850 -35
  46. package/dist/{thread-ownership-i2NBwDUL.js → thread-ownership-DZeuKH1j.js} +2 -2
  47. package/dist/{thread-resume-CdJk2Ehf.js → thread-resume-BE9qNEW0.js} +3 -3
  48. package/dist/{transcript-mirror-BU0_LKAL.js → transcript-mirror-DsCMWBca.js} +91 -10
  49. package/dist/{upstream-session-fork-BDVJCLAD.js → upstream-session-fork-DlaHxSLC.js} +3 -3
  50. package/dist/{usage-9dKJCgcy.js → usage-ROIaW3wo.js} +3 -3
  51. package/dist/{web-search-provider.runtime-DCdx4DGu.js → web-search-provider.runtime-ClaNPV7N.js} +3 -3
  52. package/openclaw.plugin.json +18 -1
  53. package/package.json +8 -8
  54. package/dist/app-server-policy-bg5QPSVP.js +0 -25
@@ -4,14 +4,51 @@ import path from "node:path";
4
4
  import { constants, existsSync, readFileSync, realpathSync } from "node:fs";
5
5
  import { fileURLToPath } from "node:url";
6
6
  import { expectDefined } from "openclaw/plugin-sdk/expect-runtime";
7
+ //#region extensions/codex/src/app-server/desktop-app-paths.ts
8
+ /** Shared path candidates for Codex's macOS desktop app bundle. */
9
+ const MACOS_DESKTOP_CODEX_APP_PATH_CANDIDATES = [{
10
+ appName: "ChatGPT.app",
11
+ appBundlePath: "/Applications/ChatGPT.app",
12
+ appServerCommandPath: "/Applications/ChatGPT.app/Contents/Resources/codex",
13
+ bundledMarketplacePath: "/Applications/ChatGPT.app/Contents/Resources/plugins/openai-bundled",
14
+ computerUseServiceAppPaths: ["/Applications/ChatGPT.app/Contents/Resources/cua_node/lib/node_modules/@oai/sky/Codex Computer Use.app", "/Applications/ChatGPT.app/Contents/Resources/plugins/openai-bundled/plugins/computer-use/Codex Computer Use.app"]
15
+ }, {
16
+ appName: "Codex.app",
17
+ appBundlePath: "/Applications/Codex.app",
18
+ appServerCommandPath: "/Applications/Codex.app/Contents/Resources/codex",
19
+ bundledMarketplacePath: "/Applications/Codex.app/Contents/Resources/plugins/openai-bundled",
20
+ computerUseServiceAppPaths: ["/Applications/Codex.app/Contents/Resources/plugins/openai-bundled/plugins/computer-use/Codex Computer Use.app", "/Applications/Codex.app/Contents/Resources/cua_node/lib/node_modules/@oai/sky/Codex Computer Use.app"]
21
+ }];
22
+ function resolveMacOSDesktopCodexAppPathCandidates(platform = process.platform) {
23
+ return platform === "darwin" ? MACOS_DESKTOP_CODEX_APP_PATH_CANDIDATES : [];
24
+ }
25
+ function resolveMacOSDesktopCodexAppServerCommandCandidates(platform = process.platform) {
26
+ return resolveMacOSDesktopCodexAppPathCandidates(platform).map((candidate) => candidate.appServerCommandPath);
27
+ }
28
+ function resolveMacOSDesktopCodexBundledMarketplaceCandidates(platform = process.platform) {
29
+ return resolveMacOSDesktopCodexAppPathCandidates(platform).map((candidate) => candidate.bundledMarketplacePath);
30
+ }
31
+ function resolveMacOSDesktopCodexComputerUseServiceAppCandidates(platform = process.platform, appServerCommand) {
32
+ if (platform !== "darwin") return [];
33
+ const candidates = resolveMacOSDesktopCodexAppPathCandidates(platform);
34
+ const matchingCandidate = appServerCommand ? candidates.find((candidate) => path.resolve(candidate.appServerCommandPath) === path.resolve(appServerCommand)) : void 0;
35
+ const orderedCandidates = matchingCandidate ? [matchingCandidate, ...candidates.filter((candidate) => candidate !== matchingCandidate)] : candidates;
36
+ return [...new Set(orderedCandidates.flatMap((candidate) => candidate.computerUseServiceAppPaths))];
37
+ }
38
+ function resolveFirstExistingMacOSDesktopCodexBundledMarketplacePath(params = {}) {
39
+ const candidates = params.candidates ?? resolveMacOSDesktopCodexBundledMarketplaceCandidates(params.platform);
40
+ const pathExists = params.pathExists ?? existsSync;
41
+ return candidates.find((candidate) => pathExists(candidate));
42
+ }
43
+ //#endregion
7
44
  //#region extensions/codex/src/app-server/version.ts
8
45
  /**
9
46
  * Version and package pins for the managed Codex app-server runtime.
10
47
  */
11
48
  /** Exact Codex app-server version shipped by the OpenClaw Codex bridge. */
12
- const CODEX_APP_SERVER_VERSION = "0.149.1";
49
+ const CODEX_APP_SERVER_VERSION = "0.150.1";
13
50
  /** Inclusive runtime compatibility floor for external app-server binaries. */
14
- const MIN_SUPPORTED_CODEX_APP_SERVER_VERSION = "0.147.0";
51
+ const MIN_SUPPORTED_CODEX_APP_SERVER_VERSION = "0.149.0";
15
52
  /** npm package name for the managed Codex app-server binary. */
16
53
  const MANAGED_CODEX_APP_SERVER_PACKAGE = "@openai/codex";
17
54
  //#endregion
@@ -22,7 +59,6 @@ const MANAGED_CODEX_APP_SERVER_PACKAGE = "@openai/codex";
22
59
  */
23
60
  const CODEX_PLUGIN_ROOT = resolveDefaultCodexPluginRoot(path.dirname(fileURLToPath(import.meta.url)));
24
61
  let registeredCodexPluginRoot;
25
- const MACOS_DESKTOP_CODEX_APP_SERVER_COMMANDS = ["/Applications/ChatGPT.app/Contents/Resources/codex", "/Applications/Codex.app/Contents/Resources/codex"];
26
62
  /** Records the process-stable plugin root prepared by OpenClaw's plugin loader. */
27
63
  function setManagedCodexPluginRoot(pluginRoot) {
28
64
  registeredCodexPluginRoot = pluginRoot;
@@ -62,9 +98,9 @@ function resolveManagedCodexNativeCommand(command, options = {}) {
62
98
  if (pathExists(candidate)) return candidate;
63
99
  }
64
100
  }
65
- /** Returns whether a resolved managed command is owned by the macOS desktop app. */
101
+ /** Returns whether a command is one of the standard macOS desktop app executables. */
66
102
  function isManagedCodexDesktopCommand(command, platform = process.platform) {
67
- return platform === "darwin" && MACOS_DESKTOP_CODEX_APP_SERVER_COMMANDS.some((candidate) => candidate === command);
103
+ return platform === "darwin" && resolveMacOSDesktopCodexAppServerCommandCandidates(platform).some((candidate) => candidate === command);
68
104
  }
69
105
  function resolveManagedCodexPackageRootForCommand(command, platform) {
70
106
  const pathApi = pathForPlatform(platform);
@@ -126,7 +162,7 @@ function resolveManagedCodexAppServerCommandCandidates(pluginRoot, platform, man
126
162
  return [...new Set(orderedCommandPaths)];
127
163
  }
128
164
  function resolveDesktopCodexAppServerCommandCandidates(platform) {
129
- return platform === "darwin" ? [...MACOS_DESKTOP_CODEX_APP_SERVER_COMMANDS] : [];
165
+ return resolveMacOSDesktopCodexAppServerCommandCandidates(platform);
130
166
  }
131
167
  function resolveDefaultCodexPluginRoot(moduleDir) {
132
168
  const moduleBaseName = path.basename(moduleDir);
@@ -209,4 +245,4 @@ async function commandPathExists(filePath, platform) {
209
245
  }
210
246
  }
211
247
  //#endregion
212
- export { CODEX_APP_SERVER_VERSION as a, setManagedCodexPluginRoot as i, resolveManagedCodexAppServerStartOptions as n, MIN_SUPPORTED_CODEX_APP_SERVER_VERSION as o, resolveManagedCodexNativeCommand as r, isManagedCodexDesktopCommand as t };
248
+ export { CODEX_APP_SERVER_VERSION as a, resolveMacOSDesktopCodexAppPathCandidates as c, setManagedCodexPluginRoot as i, resolveMacOSDesktopCodexBundledMarketplaceCandidates as l, resolveManagedCodexAppServerStartOptions as n, MIN_SUPPORTED_CODEX_APP_SERVER_VERSION as o, resolveManagedCodexNativeCommand as r, resolveFirstExistingMacOSDesktopCodexBundledMarketplacePath as s, isManagedCodexDesktopCommand as t, resolveMacOSDesktopCodexComputerUseServiceAppCandidates as u };
@@ -1,4 +1,4 @@
1
- import { t as runBoundedCodexAppServerTurn } from "./bounded-turn-4BjrZEwW.js";
1
+ import { t as runBoundedCodexAppServerTurn } from "./bounded-turn-B7iBUcuP.js";
2
2
  import { isRecord } from "openclaw/plugin-sdk/string-coerce-runtime";
3
3
  import { validateJsonSchemaValue } from "openclaw/plugin-sdk/json-schema-runtime";
4
4
  //#region extensions/codex/media-understanding-provider.ts
@@ -1,7 +1,7 @@
1
- import { r as buildCodexRuntimeModelParams } from "./harness-DoKQcF8n.js";
2
- import { h as readCodexPluginConfig } from "./config-CpNeo5AE.js";
3
- import { t as listAllCodexAppServerModels } from "./models-CZw1wClT.js";
4
- import { r as requestOptions } from "./command-rpc-xUIIonsO.js";
1
+ import { r as buildCodexRuntimeModelParams } from "./harness-Csz0F-DK.js";
2
+ import { h as readCodexPluginConfig } from "./config-giW8X0QA.js";
3
+ import { t as listAllCodexAppServerModels } from "./models-TS3HBU-q.js";
4
+ import { r as requestOptions } from "./command-rpc-CCeCkf_v.js";
5
5
  //#region extensions/codex/src/app-server/model-catalog.ts
6
6
  const OPENAI_CODEX_BASE_URL = "https://chatgpt.com/backend-api/codex";
7
7
  const DEFAULT_MODEL_DISCOVERY_TIMEOUT_MS = 2500;
@@ -1,4 +1,4 @@
1
- import { t as assertCodexModelListResponse } from "./protocol-validators-VAVyEnDp.js";
1
+ import { t as assertCodexModelListResponse } from "./protocol-validators-VeJxxJ0U.js";
2
2
  import { normalizeOptionalString, uniqueStrings } from "openclaw/plugin-sdk/string-coerce-runtime";
3
3
  //#region extensions/codex/src/app-server/models.ts
4
4
  /**
@@ -40,7 +40,7 @@ async function listAllCodexAppServerModels(options = {}) {
40
40
  async function withCodexAppServerModelClient(options, run) {
41
41
  const timeoutMs = options.timeoutMs ?? 2500;
42
42
  const useSharedClient = options.sharedClient !== false;
43
- const { createIsolatedCodexAppServerClient, getLeasedSharedCodexAppServerClient, releaseLeasedSharedCodexAppServerClient } = await import("./shared-client-Dw-rzii0.js").then((n) => n.m);
43
+ const { createIsolatedCodexAppServerClient, getLeasedSharedCodexAppServerClient, releaseLeasedSharedCodexAppServerClient } = await import("./shared-client-DKz23hHY.js").then((n) => n.y);
44
44
  const client = useSharedClient ? await getLeasedSharedCodexAppServerClient({
45
45
  startOptions: options.startOptions,
46
46
  timeoutMs,
@@ -96,7 +96,8 @@ function readCodexModel(value) {
96
96
  isDefault: value.isDefault,
97
97
  inputModalities: value.inputModalities,
98
98
  supportedReasoningEfforts: readReasoningEfforts(value.supportedReasoningEfforts),
99
- ...normalizeOptionalString(value.defaultReasoningEffort) ? { defaultReasoningEffort: normalizeOptionalString(value.defaultReasoningEffort) } : {}
99
+ ...normalizeOptionalString(value.defaultReasoningEffort) ? { defaultReasoningEffort: normalizeOptionalString(value.defaultReasoningEffort) } : {},
100
+ ...value.multiAgentVersion !== void 0 ? { multiAgentVersion: value.multiAgentVersion } : {}
100
101
  };
101
102
  }
102
103
  function readReasoningEfforts(value) {
@@ -1,9 +1,9 @@
1
- import { H as claimCodexAppServerLiveThread, J as releaseCodexAppServerLiveThread, Y as retainCodexAppServerLiveThread, ut as isJsonObject } from "./shared-client-Dw-rzii0.js";
2
- import { A as shouldSynthesizeToolProgressForItem, B as readNullableString$1, C as isSideEffectingNativeToolItem, D as itemTitle, E as itemStatus, F as readItem, L as readNonEmptyString, M as normalizeOptionalString$1, P as readHookOutputEntries, R as readNonEmptyStringArray, S as isNonSuccessItemStatus, T as itemName, k as shouldRecordNativeToolTranscript, w as itemKind, x as isMutatingNativeToolItem, y as auditNativeToolTerminalStatus } from "./attempt-client-cleanup-URjUlCHg.js";
1
+ import { $ as releaseCodexAppServerLiveThread, et as retainCodexAppServerLiveThread, q as claimCodexAppServerLiveThread, vt as isJsonObject } from "./shared-client-DKz23hHY.js";
2
+ import { A as shouldSynthesizeToolProgressForItem, B as readNullableString$1, C as isSideEffectingNativeToolItem, D as itemTitle, E as itemStatus, F as readItem, L as readNonEmptyString, M as normalizeOptionalString$1, P as readHookOutputEntries, R as readNonEmptyStringArray, S as isNonSuccessItemStatus, T as itemName, k as shouldRecordNativeToolTranscript, w as itemKind, x as isMutatingNativeToolItem, y as auditNativeToolTerminalStatus } from "./attempt-client-cleanup-bfsmcQ6m.js";
3
3
  import { t as attachCodexMirrorIdentity } from "./upstream-prompt-provenance-CFmsKwr9.js";
4
4
  import { n as sanitizeCodexHistoryImagePayloads } from "./image-payload-sanitizer-CnfoUPCE.js";
5
5
  import { t as resolveCodexLocalRuntimeAttribution } from "./local-runtime-attribution-B_2mnqhb.js";
6
- import { n as codexApprovalTimeoutText } from "./plugin-approval-roundtrip-C75Yiiwc.js";
6
+ import { n as codexApprovalTimeoutText } from "./plugin-approval-roundtrip-bUm777tR.js";
7
7
  import { asFiniteNumber, asNonArrayRecord, normalizeOptionalString, readStringField } from "openclaw/plugin-sdk/string-coerce-runtime";
8
8
  import fs from "node:fs/promises";
9
9
  import path from "node:path";
@@ -1253,10 +1253,34 @@ function resolveStartedAtFromDurationMs(durationMs) {
1253
1253
  }
1254
1254
  //#endregion
1255
1255
  //#region extensions/codex/src/app-server/event-projector-events.ts
1256
+ /** Downstream event consumers must never corrupt the canonical Codex turn projection. */
1257
+ function emitCodexAgentEvent(params, event) {
1258
+ try {
1259
+ emitAgentEvent({
1260
+ runId: params.runId,
1261
+ stream: event.stream,
1262
+ data: event.data,
1263
+ ...params.sessionKey ? { sessionKey: params.sessionKey } : {}
1264
+ });
1265
+ } catch (error) {
1266
+ embeddedAgentLog.debug("codex app-server global agent event emit failed", { error });
1267
+ }
1268
+ try {
1269
+ const maybePromise = params.onAgentEvent?.(event);
1270
+ Promise.resolve(maybePromise).catch((error) => {
1271
+ embeddedAgentLog.debug("codex app-server agent event handler rejected", { error });
1272
+ });
1273
+ } catch (error) {
1274
+ embeddedAgentLog.debug("codex app-server agent event handler threw", { error });
1275
+ }
1276
+ }
1256
1277
  function guardianActionCommand(action) {
1257
1278
  if (!action) return;
1258
- const command = readStringField(action, "command");
1259
- if (command) return command;
1279
+ const directLabel = readStringField(action, "command") ?? readStringField(action, "target") ?? readStringField(action, "toolTitle") ?? readStringField(action, "reason");
1280
+ if (directLabel) return directLabel;
1281
+ const server = readStringField(action, "connectorName") ?? readStringField(action, "server");
1282
+ const tool = readStringField(action, "toolName");
1283
+ if (server && tool) return `${server}/${tool}`;
1260
1284
  const argv = Array.isArray(action.argv) ? action.argv.filter((value) => typeof value === "string") : [];
1261
1285
  return argv.length > 0 ? argv.join(" ") : readStringField(action, "program");
1262
1286
  }
@@ -1310,12 +1334,26 @@ var CodexEventProjection = class {
1310
1334
  get guardianReviewCount() {
1311
1335
  return this.reviewCount;
1312
1336
  }
1337
+ emitCompactionEnd(itemId, completed) {
1338
+ this.emitAgentEvent({
1339
+ stream: "compaction",
1340
+ data: {
1341
+ phase: "end",
1342
+ backend: "codex-app-server",
1343
+ completed,
1344
+ threadId: this.threadId,
1345
+ turnId: this.turnId,
1346
+ itemId
1347
+ }
1348
+ });
1349
+ }
1313
1350
  handleGuardianReview(method, params) {
1314
1351
  this.reviewCount += 1;
1315
1352
  const review = isJsonObject(params.review) ? params.review : void 0;
1316
1353
  const action = isJsonObject(params.action) ? params.action : void 0;
1317
1354
  const reviewId = readStringField(params, "reviewId");
1318
1355
  const targetItemId = readNullableString$1(params, "targetItemId");
1356
+ const command = guardianActionCommand(action);
1319
1357
  const reviewStatus = review ? readStringField(review, "status") : void 0;
1320
1358
  const status = normalizeApprovalReviewStatus(reviewStatus);
1321
1359
  const riskLevel = review ? readStringField(review, "riskLevel") : void 0;
@@ -1324,11 +1362,22 @@ var CodexEventProjection = class {
1324
1362
  const expectedWarning = status === "timed_out" ? GUARDIAN_TIMEOUT_WARNING : rationale && riskLevel && userAuthorization && (status === "approved" || status === "denied") ? `Automatic approval review ${status} (risk: ${riskLevel}, authorization: ${userAuthorization}): ${rationale}` : void 0;
1325
1363
  if (Boolean(targetItemId) && Boolean(reviewId) && this.pendingGuardianWarning === expectedWarning) this.pendingGuardianWarning = void 0;
1326
1364
  else this.flushPendingGuardianWarning();
1365
+ const threadId = readStringField(params, "threadId") ?? this.threadId;
1366
+ const turnId = readStringField(params, "turnId") ?? this.turnId;
1367
+ if (method.endsWith("/started")) this.activeGuardianReview = {
1368
+ reviewId,
1369
+ targetItemId,
1370
+ command,
1371
+ threadId,
1372
+ turnId
1373
+ };
1327
1374
  this.emitAgentEvent({
1328
1375
  stream: "codex_app_server.guardian",
1329
1376
  data: {
1330
1377
  method,
1331
1378
  phase: method.endsWith("/started") ? "started" : "completed",
1379
+ threadId,
1380
+ turnId,
1332
1381
  reviewId,
1333
1382
  targetItemId,
1334
1383
  decisionSource: readStringField(params, "decisionSource"),
@@ -1337,7 +1386,7 @@ var CodexEventProjection = class {
1337
1386
  userAuthorization,
1338
1387
  rationale,
1339
1388
  actionType: action ? readStringField(action, "type") : void 0,
1340
- command: guardianActionCommand(action)
1389
+ command
1341
1390
  }
1342
1391
  });
1343
1392
  if (reviewId && targetItemId && status) {
@@ -1361,6 +1410,7 @@ var CodexEventProjection = class {
1361
1410
  }
1362
1411
  });
1363
1412
  }
1413
+ if (method.endsWith("/completed") && this.activeGuardianReview?.reviewId === reviewId) this.activeGuardianReview = void 0;
1364
1414
  }
1365
1415
  handleGuardianWarning(params) {
1366
1416
  this.flushPendingGuardianWarning();
@@ -1377,6 +1427,29 @@ var CodexEventProjection = class {
1377
1427
  }
1378
1428
  });
1379
1429
  }
1430
+ handleWarning(params) {
1431
+ const message = [readStringField(params, "summary") ?? readStringField(params, "message"), readStringField(params, "details")].filter(Boolean).join("\n");
1432
+ if (message) this.emitAgentEvent({
1433
+ stream: "notice",
1434
+ data: {
1435
+ phase: "warning",
1436
+ message
1437
+ }
1438
+ });
1439
+ }
1440
+ handleModelRerouted(params) {
1441
+ const fromModel = readStringField(params, "fromModel");
1442
+ const toModel = readStringField(params, "toModel");
1443
+ const reason = readStringField(params, "reason");
1444
+ if (fromModel && toModel && fromModel !== toModel) this.emitAgentEvent({
1445
+ stream: "fallback",
1446
+ data: {
1447
+ fromModel,
1448
+ toModel,
1449
+ ...reason ? { reason } : {}
1450
+ }
1451
+ });
1452
+ }
1380
1453
  flushPendingGuardianWarning() {
1381
1454
  const pending = this.pendingGuardianWarning;
1382
1455
  if (!pending) return;
@@ -1389,6 +1462,21 @@ var CodexEventProjection = class {
1389
1462
  }
1390
1463
  });
1391
1464
  }
1465
+ handleStrictReviewRequired(params) {
1466
+ this.emitAgentEvent({
1467
+ stream: "codex_app_server.guardian",
1468
+ data: {
1469
+ method: "autoApprovalReview/strictReviewRequired",
1470
+ phase: "strict_review_required",
1471
+ threadId: readStringField(params, "threadId") ?? this.activeGuardianReview?.threadId ?? this.threadId,
1472
+ turnId: readStringField(params, "turnId") ?? this.activeGuardianReview?.turnId ?? this.turnId,
1473
+ reviewId: this.activeGuardianReview?.reviewId,
1474
+ targetItemId: this.activeGuardianReview?.targetItemId,
1475
+ command: this.activeGuardianReview?.command,
1476
+ startedAtMs: asFiniteNumber(params.startedAtMs)
1477
+ }
1478
+ });
1479
+ }
1392
1480
  handleHook(method, params) {
1393
1481
  const run = isJsonObject(params.run) ? params.run : void 0;
1394
1482
  if (!run) return;
@@ -1513,8 +1601,23 @@ function extractCodexNativeSubagentCompletionsFromText(text) {
1513
1601
  }
1514
1602
  const codexNativeSubagentNotifications = {
1515
1603
  fromNotification: extractCodexNativeSubagentCompletions,
1516
- fromText: extractCodexNativeSubagentCompletionsFromText
1604
+ fromText: extractCodexNativeSubagentCompletionsFromText,
1605
+ deliveredAgentPaths: readDeliveredNativeCompletionPaths
1517
1606
  };
1607
+ /** Reads native delivery receipts, leaving status and result ownership with the child lifecycle. */
1608
+ function readDeliveredNativeCompletionPaths(notification) {
1609
+ if (notification.method !== "rawResponseItem/completed") return [];
1610
+ const params = isJsonObject(notification.params) ? notification.params : void 0;
1611
+ const item = isJsonObject(params?.item) ? params.item : void 0;
1612
+ if (!item || readStringField(item, "type") !== "agent_message") return extractCodexNativeSubagentCompletions(notification).map((completion) => completion.agentPath);
1613
+ const author = readStringField(item, "author");
1614
+ const recipient = readStringField(item, "recipient");
1615
+ const content = item.content;
1616
+ if (!author || !recipient || !Array.isArray(content) || content.length !== 1) return [];
1617
+ const part = content[0];
1618
+ if (!isJsonObject(part) || readStringField(part, "type") !== "input_text") return [];
1619
+ return readStringField(part, "text")?.startsWith(`Message Type: FINAL_ANSWER\nTask name: ${recipient}\nSender: ${author}\nPayload:\n`) ? [author] : [];
1620
+ }
1518
1621
  function parseCodexNativeSubagentNotificationBody(body) {
1519
1622
  let payload;
1520
1623
  try {
@@ -2113,7 +2216,11 @@ var Monitor = class {
2113
2216
  this.releaseRetainedClient();
2114
2217
  for (const release of this.parentThreadRetentions.values()) release();
2115
2218
  this.parentThreadRetentions.clear();
2116
- for (const state of this.parentStates.values()) state.owners.clear();
2219
+ for (const state of this.parentStates.values()) {
2220
+ state.owners.clear();
2221
+ state.turnIds.clear();
2222
+ this.deliverDetachedCompletions(state);
2223
+ }
2117
2224
  this.pendingDirectSpawnEvidence.clear();
2118
2225
  for (const [parentThreadId] of this.parentStates) if (![...this.childStates.values()].some((childState) => childState.parentThreadId === parentThreadId)) this.parentStates.delete(parentThreadId);
2119
2226
  }
@@ -2126,7 +2233,9 @@ var Monitor = class {
2126
2233
  if (!state) {
2127
2234
  state = {
2128
2235
  parentThreadId,
2129
- owners: /* @__PURE__ */ new Map()
2236
+ owners: /* @__PURE__ */ new Map(),
2237
+ turnIds: /* @__PURE__ */ new Set(),
2238
+ nativeCompletionReceipts: /* @__PURE__ */ new Set()
2130
2239
  };
2131
2240
  this.parentStates.set(parentThreadId, state);
2132
2241
  }
@@ -2156,6 +2265,7 @@ var Monitor = class {
2156
2265
  const current = registeredState.owners.get(owner);
2157
2266
  if (!current || [...registeredState.owners.values()].some((other) => other !== current && other.turnId === turnId)) return;
2158
2267
  current.turnId = turnId;
2268
+ registeredState.turnIds.add(turnId);
2159
2269
  this.drainPendingDirectSpawnEvidence(registeredState, current, turnId);
2160
2270
  this.clearUnconsumablePendingDirectSpawnEvidence();
2161
2271
  },
@@ -2164,8 +2274,15 @@ var Monitor = class {
2164
2274
  registered = false;
2165
2275
  const current = this.parentStates.get(parentThreadId);
2166
2276
  if (current === registeredState) {
2277
+ const turnId = current.owners.get(owner)?.turnId;
2167
2278
  current.owners.delete(owner);
2279
+ if (turnId) current.turnIds.delete(turnId);
2280
+ if (current.owners.size === 0) {
2281
+ current.turnIds.clear();
2282
+ current.nativeCompletionReceipts = /* @__PURE__ */ new Set();
2283
+ }
2168
2284
  this.clearUnconsumablePendingDirectSpawnEvidence();
2285
+ this.deliverDetachedCompletions(current);
2169
2286
  this.pruneParentIfUnused(current);
2170
2287
  }
2171
2288
  }
@@ -2203,6 +2320,11 @@ var Monitor = class {
2203
2320
  const startedThread = isJsonObject(params?.thread) ? params.thread : void 0;
2204
2321
  const threadId = readStringField(params, "threadId")?.trim() ?? readStringField(startedThread, "id")?.trim();
2205
2322
  const threadStatus = isJsonObject(params?.status) ? normalizeIdentifier(readStringField(params.status, "type")) : void 0;
2323
+ const parent = threadId ? this.parentStates.get(threadId) : void 0;
2324
+ if (parent && parent.owners.size > 0 && notification.method === "turn/started") {
2325
+ const turnId = isJsonObject(params?.turn) ? readStringField(params.turn, "id") : void 0;
2326
+ if (turnId) parent.turnIds.add(turnId);
2327
+ }
2206
2328
  const tracksRecoveryRevision = Boolean(threadId && this.threadStatusRevisions.has(threadId));
2207
2329
  if (RECOVERY_REVISION_NOTIFICATION_METHODS.has(notification.method) && threadId && tracksRecoveryRevision) this.threadStatusRevisions.get(threadId).value += 1;
2208
2330
  if (!state && (!threadId || !this.parentStates.has(threadId) && !this.childStates.has(threadId) && !tracksRecoveryRevision)) return;
@@ -2216,7 +2338,12 @@ var Monitor = class {
2216
2338
  }
2217
2339
  if (state) this.handleClosedChild(notification, state);
2218
2340
  const childState = threadId ? this.childStates.get(threadId) : void 0;
2219
- if (notification.method === "turn/started" && childState) this.resumeChild(childState);
2341
+ if (notification.method === "turn/started" && childState) {
2342
+ childState.nativeCompletionDelivered = false;
2343
+ for (const key of childState.agentPathKeys) state?.nativeCompletionReceipts.delete(key);
2344
+ this.resumeChild(childState);
2345
+ }
2346
+ if (parent && parent.turnIds.has(readStringField(params, "turnId") ?? "")) this.recordNativeCompletionDelivery(parent, notification);
2220
2347
  if (childState && !childState.terminal) this.emitChildTaskActivity(notification, childState);
2221
2348
  this.captureChildAssistantMessage(notification);
2222
2349
  await this.handleChildTurnCompletion(notification);
@@ -2528,6 +2655,7 @@ var Monitor = class {
2528
2655
  this.unregisterChild(childState);
2529
2656
  return false;
2530
2657
  }
2658
+ if (recovery.agentPath) this.registerAgentPath(childState, recovery.agentPath);
2531
2659
  if (recovery.threadState === "active") {
2532
2660
  this.observeActiveChild(childState);
2533
2661
  return false;
@@ -2593,6 +2721,7 @@ var Monitor = class {
2593
2721
  }
2594
2722
  return {
2595
2723
  parentThreadId: readThreadParentThreadId(thread),
2724
+ agentPath: normalizeOptionalString(readStringField(readThreadSpawnSource(thread), "agent_path")),
2596
2725
  completion,
2597
2726
  fallbackCompletion,
2598
2727
  resumable,
@@ -2624,6 +2753,10 @@ var Monitor = class {
2624
2753
  this.unregisterChild(childState);
2625
2754
  return;
2626
2755
  }
2756
+ if (childState.nativeCompletionDelivered) {
2757
+ this.finishCompletionDelivery(state, childState);
2758
+ return;
2759
+ }
2627
2760
  childState.pendingCompletion = completion;
2628
2761
  state.taskRuntime?.setDetachedTaskDeliveryStatusByRunId({
2629
2762
  runId: codexNativeSubagentRunId(completion.childThreadId),
@@ -2635,6 +2768,7 @@ var Monitor = class {
2635
2768
  async deliverPendingCompletion(state, childState) {
2636
2769
  const completion = childState.pendingCompletion;
2637
2770
  if (!completion || !state.requesterSessionKey || !state.taskRuntimeScope) return;
2771
+ if (state.owners.size > 0) return;
2638
2772
  if (childState.deliveringCompletion || childState.completionDeliveryTimer) return;
2639
2773
  childState.deliveringCompletion = true;
2640
2774
  try {
@@ -2652,13 +2786,7 @@ var Monitor = class {
2652
2786
  });
2653
2787
  if (this.childStates.get(childState.childThreadId) !== childState || this.parentStates.get(state.parentThreadId) !== state) return;
2654
2788
  if (isDurableAgentHarnessCompletionDelivery(delivery)) {
2655
- childState.pendingCompletion = void 0;
2656
- childState.completionDeliveryAttempt = 0;
2657
- state.taskRuntime?.setDetachedTaskDeliveryStatusByRunId({
2658
- runId: codexNativeSubagentRunId(completion.childThreadId),
2659
- deliveryStatus: "delivered"
2660
- });
2661
- this.unregisterChild(childState);
2789
+ this.finishCompletionDelivery(state, childState);
2662
2790
  return;
2663
2791
  }
2664
2792
  const error = delivery.error ?? "completion delivery did not produce a parent response";
@@ -2686,6 +2814,29 @@ var Monitor = class {
2686
2814
  childState.deliveringCompletion = false;
2687
2815
  }
2688
2816
  }
2817
+ recordNativeCompletionDelivery(state, notification) {
2818
+ for (const agentPath of codexNativeSubagentNotifications.deliveredAgentPaths(notification)) {
2819
+ const key = buildParentAgentPathKey(state.parentThreadId, agentPath);
2820
+ state.nativeCompletionReceipts.add(key);
2821
+ const childThreadId = this.childThreadIdsByAgentPath.get(key);
2822
+ const child = childThreadId ? this.childStates.get(childThreadId) : void 0;
2823
+ if (!child || child.parentThreadId !== state.parentThreadId) continue;
2824
+ child.nativeCompletionDelivered = true;
2825
+ if (child.pendingCompletion && !child.deliveringCompletion) this.finishCompletionDelivery(state, child);
2826
+ }
2827
+ }
2828
+ finishCompletionDelivery(state, child) {
2829
+ child.pendingCompletion = void 0;
2830
+ child.completionDeliveryAttempt = 0;
2831
+ state.taskRuntime?.setDetachedTaskDeliveryStatusByRunId({
2832
+ runId: codexNativeSubagentRunId(child.childThreadId),
2833
+ deliveryStatus: "delivered"
2834
+ });
2835
+ this.unregisterChild(child);
2836
+ }
2837
+ deliverDetachedCompletions(state) {
2838
+ for (const child of this.childStates.values()) if (child.parentThreadId === state.parentThreadId && child.pendingCompletion) this.deliverPendingCompletion(state, child);
2839
+ }
2689
2840
  scheduleCompletionDeliveryRetry(childState, error) {
2690
2841
  if (!childState.pendingCompletion || childState.completionDeliveryTimer || this.childStates.get(childState.childThreadId) !== childState) return;
2691
2842
  if (childState.completionDeliveryAttempt >= this.completionDeliveryMaxRetries) {
@@ -2735,6 +2886,7 @@ var Monitor = class {
2735
2886
  assistantMessagesByTurn: /* @__PURE__ */ new Map(),
2736
2887
  recoveryAttempt: 0,
2737
2888
  terminal: false,
2889
+ nativeCompletionDelivered: false,
2738
2890
  settledWithoutCompletion: false,
2739
2891
  completionDeliveryAttempt: 0,
2740
2892
  deliveringCompletion: false
@@ -2821,6 +2973,7 @@ var Monitor = class {
2821
2973
  }
2822
2974
  this.childThreadIdsByAgentPath.set(key, childState.childThreadId);
2823
2975
  childState.agentPathKeys.add(key);
2976
+ if (this.parentStates.get(childState.parentThreadId)?.nativeCompletionReceipts.has(key)) childState.nativeCompletionDelivered = true;
2824
2977
  }
2825
2978
  unregisterChild(childState, options = {}) {
2826
2979
  this.releaseDirectChild(childState);
@@ -2970,6 +3123,7 @@ var Monitor = class {
2970
3123
  const childThreadId = task.runId.slice(13).trim();
2971
3124
  candidates.set(childThreadId, {
2972
3125
  parentState: state,
3126
+ nativeCompletionReceipts: state.nativeCompletionReceipts,
2973
3127
  requesterSessionKey: state.requesterSessionKey,
2974
3128
  childThreadId,
2975
3129
  recoveryAttempt: 0,
@@ -3046,6 +3200,8 @@ var Monitor = class {
3046
3200
  state = {
3047
3201
  parentThreadId,
3048
3202
  owners: /* @__PURE__ */ new Map(),
3203
+ turnIds: /* @__PURE__ */ new Set(),
3204
+ nativeCompletionReceipts: /* @__PURE__ */ new Set(),
3049
3205
  requesterSessionKey: candidate.requesterSessionKey,
3050
3206
  taskRuntimeScope: candidate.taskRuntimeScope,
3051
3207
  agentId: candidate.agentId,
@@ -3054,11 +3210,12 @@ var Monitor = class {
3054
3210
  this.prepareParentTaskRuntime(state);
3055
3211
  this.parentStates.set(parentThreadId, state);
3056
3212
  }
3057
- const childState = this.registerChildThread(state, candidate.childThreadId);
3213
+ const childState = this.registerChildThread(state, candidate.childThreadId, recovery.agentPath ? { agentPath: recovery.agentPath } : {});
3058
3214
  if (!childState) {
3059
3215
  this.pruneParentIfUnused(state);
3060
3216
  return;
3061
3217
  }
3218
+ if ([...childState.agentPathKeys].some((key) => candidate.nativeCompletionReceipts.has(key))) childState.nativeCompletionDelivered = true;
3062
3219
  if (recovery.threadState === "active") this.observeActiveChild(childState);
3063
3220
  if (recovery.threadState === "other") this.clearSystemErrorFallback(childState);
3064
3221
  if (recovery.resumable) {
@@ -3222,4 +3379,4 @@ function unrefTimer(timer) {
3222
3379
  if (typeof timer === "object" && timer && "unref" in timer) timer.unref();
3223
3380
  }
3224
3381
  //#endregion
3225
- export { CodexToolProgressProjection as a, isCodexCommandBearingToolCall as c, sanitizeCodexToolResponse as d, readCodexMirroredSessionHistoryMessages as i, resolveCodexToolProgressDetailMode as l, CodexEventProjection as n, shouldEmitTranscriptToolProgress as o, CodexToolTranscriptProjection as r, inferCodexDynamicToolMeta as s, codexNativeSubagentMonitorRuntime as t, sanitizeCodexToolArguments as u };
3382
+ export { readCodexMirroredSessionHistoryMessages as a, inferCodexDynamicToolMeta as c, sanitizeCodexToolArguments as d, sanitizeCodexToolResponse as f, CodexToolTranscriptProjection as i, isCodexCommandBearingToolCall as l, CodexEventProjection as n, CodexToolProgressProjection as o, emitCodexAgentEvent as r, shouldEmitTranscriptToolProgress as s, codexNativeSubagentMonitorRuntime as t, resolveCodexToolProgressDetailMode as u };
@@ -1,6 +1,6 @@
1
- import { z as closeCodexAppServerTransportAndWait } from "./shared-client-Dw-rzii0.js";
1
+ import { W as closeCodexAppServerTransportAndWait } from "./shared-client-DKz23hHY.js";
2
+ import { n as resolveManagedCodexAppServerStartOptions, r as resolveManagedCodexNativeCommand, t as isManagedCodexDesktopCommand } from "./managed-binary-DFYK4DWq.js";
2
3
  import { t as createStdioTransport } from "./transport-stdio-DhoGy33Z.js";
3
- import { n as resolveManagedCodexAppServerStartOptions, r as resolveManagedCodexNativeCommand, t as isManagedCodexDesktopCommand } from "./managed-binary-By4FZC6i.js";
4
4
  import { isRecord } from "openclaw/plugin-sdk/string-coerce-runtime";
5
5
  import { mkdir } from "node:fs/promises";
6
6
  import path from "node:path";
@@ -1,5 +1,5 @@
1
- import { x as resolveCodexAppServerUserHomeDir } from "./config-CpNeo5AE.js";
2
- import { ft as resolveCodexAppServerHomeDir, pt as resolveCodexAppServerLocalHomeDir } from "./shared-client-Dw-rzii0.js";
1
+ import { S as resolveCodexAppServerUserHomeDir } from "./config-giW8X0QA.js";
2
+ import { St as resolveCodexAppServerLocalHomeDir, xt as resolveCodexAppServerHomeDir } from "./shared-client-DKz23hHY.js";
3
3
  import { createRequire } from "node:module";
4
4
  import { isRecord } from "openclaw/plugin-sdk/string-coerce-runtime";
5
5
  import { readPluginPackageVersion } from "openclaw/plugin-sdk/extension-shared";
@@ -348,7 +348,10 @@ function buildCodexPluginAppCacheKey(params) {
348
348
  accountId: params.accountId,
349
349
  envApiKeyFingerprint: params.envApiKeyFingerprint,
350
350
  appServerVersion: params.appServerVersion ?? params.runtimeIdentity?.serverVersion,
351
- runtimeIdentity: params.runtimeIdentity
351
+ runtimeIdentity: params.desktopGenerationFingerprint ? {
352
+ ...params.runtimeIdentity,
353
+ desktopGeneration: params.desktopGenerationFingerprint
354
+ } : params.runtimeIdentity
352
355
  }, OPENCLAW_VERSION, CODEX_PLUGIN_VERSION);
353
356
  }
354
357
  /** Builds a durable thread-binding fingerprint for one initialized app-server runtime. */
@@ -1,4 +1,4 @@
1
- import { S as resolveCodexGatewayTimeoutWithGraceMs } from "./shared-client-Dw-rzii0.js";
1
+ import { D as resolveCodexGatewayTimeoutWithGraceMs } from "./shared-client-DKz23hHY.js";
2
2
  import { isApprovalNotFoundError, toErrorObject } from "openclaw/plugin-sdk/error-runtime";
3
3
  import { truncateUtf16Safe } from "openclaw/plugin-sdk/text-utility-runtime";
4
4
  //#region extensions/codex/src/app-server/plugin-approval-roundtrip.ts