@openclaw/codex 2026.9.1-beta.1 → 2026.9.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 (81) hide show
  1. package/dist/api.js +8 -9
  2. package/dist/{attempt-client-cleanup-bfsmcQ6m.js → attempt-client-cleanup-Bp1ZOnk2.js} +105 -75
  3. package/dist/attempt-context-CSazkWns.js +634 -0
  4. package/dist/{auth-binding-B4FfbcCg.js → auth-binding-Ds_QVm-X.js} +18 -3
  5. package/dist/{bounded-turn-B7iBUcuP.js → bounded-turn-DxGJRYbY.js} +53 -57
  6. package/dist/{capabilities-BRMh0aIq.js → capabilities-B1mgvpP8.js} +2 -1
  7. package/dist/cli-metadata.js +1 -1
  8. package/dist/{command-formatters-DEsIufkt.js → command-formatters-DSbGMXA0.js} +5 -4
  9. package/dist/{command-handlers-D_-1_qRp.js → command-handlers-DOJvGv6-.js} +243 -148
  10. package/dist/{compact-BglNFZrQ.js → compact-Y_xBqrHN.js} +109 -65
  11. package/dist/{config-giW8X0QA.js → config-CyapYSji.js} +328 -374
  12. package/dist/config-utils-C57JiJrU.js +69 -0
  13. package/dist/{context-compaction-activity-BOeJf7yo.js → context-compaction-activity-CMla5FPJ.js} +4 -1
  14. package/dist/{conversation-binding-data-CW2GuupV.js → conversation-binding-data-BiodpIzq.js} +2 -1
  15. package/dist/doctor-contract-api.js +144 -14
  16. package/dist/{dynamic-tools-Dnlfa--w.js → dynamic-tools-BwpvTxaX.js} +1119 -1135
  17. package/dist/{effective-mcp-catalog-CTeGrnfO.js → effective-mcp-catalog-CY9Jn4bA.js} +4 -3
  18. package/dist/{event-projector-assistant-message-C5-Ds8mA.js → event-projector-assistant-message-B9kp6iGC.js} +15 -6
  19. package/dist/event-projector-usage-ZqEVbAEY.js +212 -0
  20. package/dist/{harness-Csz0F-DK.js → harness-Czh2Sdoc.js} +65 -52
  21. package/dist/harness.js +1 -1
  22. package/dist/{image-payload-sanitizer-CnfoUPCE.js → image-payload-sanitizer-tupAr-2o.js} +29 -15
  23. package/dist/index.js +495 -457
  24. package/dist/{isolated-completion-Cv6FqygM.js → isolated-completion-CRh-51AK.js} +9 -21
  25. package/dist/{managed-binary-DFYK4DWq.js → managed-binary-DcpnJF9x.js} +117 -80
  26. package/dist/media-understanding-provider.js +1 -1
  27. package/dist/model-catalog-DT5vo6qo.js +101 -0
  28. package/dist/{models-TS3HBU-q.js → models-CcrgSMQR.js} +26 -29
  29. package/dist/{native-subagent-monitor-4Mfq2HDs.js → native-subagent-monitor-B3bvQGcg.js} +63 -122
  30. package/dist/{node-exec-server.runtime-BpWqJO1V.js → node-exec-server.runtime-nfbUOtUB.js} +10 -7
  31. package/dist/{plugin-approval-roundtrip-bUm777tR.js → plugin-approval-roundtrip-aQVdyL5g.js} +30 -3
  32. package/dist/{plugin-marketplace-discovery-B9DvaAG-.js → plugin-marketplace-discovery-B7gHXJ3d.js} +44 -30
  33. package/dist/{plugin-metadata-cache-CTCT3w5L.js → plugin-metadata-cache-BwCLTY_U.js} +6 -6
  34. package/dist/provider-capabilities-BpG9Ltc5.js +101 -0
  35. package/dist/{rate-limits-C5_D8Gmb.js → rate-limits-Fx_l4eNa.js} +3 -2
  36. package/dist/{sandbox-guard-kuWTn9C5.js → request-C8H22rPi.js} +195 -2
  37. package/dist/{run-attempt-DYc0QCBF.js → run-attempt-BzthFQSM.js} +1616 -2634
  38. package/dist/{runtime-artifact-BvyT1uyd.js → runtime-artifact-Bh_gf6-t.js} +22 -15
  39. package/dist/{session-binding-Bcynfd-_.js → session-binding-4Ki04sW-.js} +282 -399
  40. package/dist/session-binding-record-CyaXZvTe.js +270 -0
  41. package/dist/{session-catalog-DaLKVtpH.js → session-catalog-B47uwekb.js} +812 -504
  42. package/dist/{session-cli-DMc4oS2w.js → session-cli-BjLhpmS1.js} +1 -1
  43. package/dist/session-history-DWmMqiqW.js +93 -0
  44. package/dist/session-history-read-LHldwvyh.js +36 -0
  45. package/dist/session-history-worker-runtime.js +48 -0
  46. package/dist/session-history.worker-zZVcx0ME.js +267 -0
  47. package/dist/session-history.worker.js +2 -0
  48. package/dist/session-initialization-BCFVnLL4.js +75 -0
  49. package/dist/{session-permission-policy-BrNH1bjy.js → session-permission-policy-BaueHmSj.js} +2 -2
  50. package/dist/session-retirement-DNdmYdFc.js +97 -0
  51. package/dist/{session-upstream-marker-BIkusb95.js → session-upstream-marker-DReTpGz6.js} +20 -4
  52. package/dist/settled-turn-context-BOM3Y1pl.js +45 -0
  53. package/dist/settled-turn-finalizer-BI-b1sry.js +115 -0
  54. package/dist/{shared-client-DKz23hHY.js → shared-client-CKhX2kFt.js} +3659 -847
  55. package/dist/{side-question-DjA_jsNe.js → side-question-B6DWAw1A.js} +168 -81
  56. package/dist/{thread-lifecycle-L7oEkTlq.js → thread-lifecycle-DPK30jad.js} +2412 -2145
  57. package/dist/{thread-ownership-DZeuKH1j.js → thread-ownership-CbucAmmp.js} +27 -16
  58. package/dist/thread-policy-CTalhWFy.js +105 -0
  59. package/dist/{plugin-app-cache-key-C1CAdfcP.js → thread-resume-BLgqkUc1.js} +61 -9
  60. package/dist/{transcript-mirror-DsCMWBca.js → transcript-mirror-_njEB84z.js} +114 -110
  61. package/dist/transcript-mirror-attestation-Byl34PC-.js +76 -0
  62. package/dist/transport-stdio-CzTngV0j.js +728 -0
  63. package/dist/{upstream-prompt-provenance-CFmsKwr9.js → upstream-prompt-provenance-LphB8slG.js} +8 -4
  64. package/dist/upstream-session-fork-1fwbNKzQ.js +886 -0
  65. package/dist/{usage-ROIaW3wo.js → usage-i9fv5-4m.js} +3 -3
  66. package/dist/{web-search-provider.runtime-ClaNPV7N.js → web-search-provider.runtime-DKQn67A7.js} +3 -3
  67. package/openclaw.plugin.json +1 -30
  68. package/package.json +6 -6
  69. package/dist/binding-connection-BMvPX73o.js +0 -45
  70. package/dist/command-rpc-CCeCkf_v.js +0 -90
  71. package/dist/event-projector-usage-Bk1I90Bg.js +0 -328
  72. package/dist/incognito-session-ET_ufDH-.js +0 -2
  73. package/dist/model-catalog-i9rNBthX.js +0 -48
  74. package/dist/protocol-validators-VeJxxJ0U.js +0 -2421
  75. package/dist/request-DXXGHko0.js +0 -157
  76. package/dist/session-catalog-home-id-BNwAJ9D7.js +0 -18
  77. package/dist/session-retirement-CcNC3YSY.js +0 -36
  78. package/dist/settled-turn-finalizer-Dc3ApjU4.js +0 -328
  79. package/dist/thread-resume-BE9qNEW0.js +0 -30
  80. package/dist/transport-stdio-DhoGy33Z.js +0 -99
  81. package/dist/upstream-session-fork-DlaHxSLC.js +0 -326
@@ -1,21 +1,17 @@
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
- import { t as attachCodexMirrorIdentity } from "./upstream-prompt-provenance-CFmsKwr9.js";
4
- import { n as sanitizeCodexHistoryImagePayloads } from "./image-payload-sanitizer-CnfoUPCE.js";
1
+ import { B as isJsonObject } from "./config-CyapYSji.js";
2
+ import { Ct as claimCodexAppServerLiveThread, Mt as retainCodexAppServerLiveThread, jt as releaseCodexAppServerLiveThread } from "./shared-client-CKhX2kFt.js";
3
+ import { A as shouldRecordNativeToolTranscript, B as readNonEmptyStringArray, C as isSideEffectingNativeToolItem, D as itemTitle, E as itemStatus, H as readNullableString$1, I as readHookOutputEntries, L as readItem, N as normalizeOptionalString$1, S as isNonSuccessItemStatus, T as itemName, j as shouldSynthesizeToolProgressForItem, w as itemKind, x as isMutatingNativeToolItem, y as auditNativeToolTerminalStatus, z as readNonEmptyString } from "./attempt-client-cleanup-Bp1ZOnk2.js";
4
+ import { t as attachCodexMirrorIdentity } from "./upstream-prompt-provenance-LphB8slG.js";
5
+ import { t as readCodexMirroredSessionHistoryMessages } from "./session-history-DWmMqiqW.js";
5
6
  import { t as resolveCodexLocalRuntimeAttribution } from "./local-runtime-attribution-B_2mnqhb.js";
6
- import { n as codexApprovalTimeoutText } from "./plugin-approval-roundtrip-bUm777tR.js";
7
+ import { n as codexApprovalTimeoutText } from "./plugin-approval-roundtrip-aQVdyL5g.js";
7
8
  import { asFiniteNumber, asNonArrayRecord, normalizeOptionalString, readStringField } from "openclaw/plugin-sdk/string-coerce-runtime";
8
- import fs from "node:fs/promises";
9
- import path from "node:path";
10
9
  import { asDateTimestampMs } from "openclaw/plugin-sdk/number-runtime";
10
+ import path from "node:path";
11
11
  import { TOOL_PROGRESS_OUTPUT_MAX_CHARS, embeddedAgentLog, emitAgentEvent, formatErrorMessage, formatToolAggregate, formatToolProgressOutput, inferToolMetaFromArgs, runAgentHarnessAfterToolCallHook } from "openclaw/plugin-sdk/agent-harness-runtime";
12
- import { getSessionEntry, parseSqliteSessionFileMarker, resolveTranscriptSessionKeyBySessionId } from "openclaw/plugin-sdk/session-store-runtime";
13
12
  import { truncateUtf16Safe } from "openclaw/plugin-sdk/text-utility-runtime";
14
13
  import { redactSensitiveFieldValue, redactToolPayloadText } from "openclaw/plugin-sdk/logging-core";
15
- import { readCodexSessionTranscriptEventsBeforeAdmission } from "openclaw/plugin-sdk/codex-session-transcript-runtime";
16
- import { readSessionTranscriptEvents } from "openclaw/plugin-sdk/session-transcript-runtime";
17
14
  import { KeyedAsyncQueue } from "openclaw/plugin-sdk/keyed-async-queue";
18
- import { buildSessionContext, migrateSessionEntries, parseSessionEntries } from "openclaw/plugin-sdk/agent-sessions";
19
15
  import { createAgentHarnessTaskRuntime, deliverAgentHarnessTaskCompletion, isDurableAgentHarnessCompletionDelivery } from "openclaw/plugin-sdk/agent-harness-task-runtime";
20
16
  //#region extensions/codex/src/app-server/event-projector-tool-output.ts
21
17
  const TOOL_TRANSCRIPT_OUTPUT_MAX_CHARS = 1e4;
@@ -114,7 +110,8 @@ function appendBoundedToolTranscriptText(currentPrefix, delta, originalLength) {
114
110
  };
115
111
  const textBudget = TOOL_TRANSCRIPT_OUTPUT_MAX_CHARS - notice.length;
116
112
  const remaining = Math.max(0, textBudget - currentPrefix.length);
117
- const rawPrefix = truncateUtf16Safe(remaining > 0 ? `${currentPrefix}${truncateUtf16Safe(delta, remaining)}` : currentPrefix, textBudget);
113
+ const prefix = remaining > 0 ? `${currentPrefix}${truncateUtf16Safe(delta, remaining)}` : currentPrefix;
114
+ const rawPrefix = truncateUtf16Safe(prefix, textBudget);
118
115
  return {
119
116
  text: `${rawPrefix}${notice}`,
120
117
  rawPrefix
@@ -127,7 +124,8 @@ function truncateToolTranscriptText(text, originalLength = text.length) {
127
124
  if (originalLength <= 1e4 && text.length <= 1e4) return text;
128
125
  const notice = toolTranscriptTruncationNotice(originalLength);
129
126
  if (notice.length >= 1e4) return notice.slice(1, 10001);
130
- return `${truncateUtf16Safe(text, TOOL_TRANSCRIPT_OUTPUT_MAX_CHARS - notice.length)}${notice}`;
127
+ const textBudget = TOOL_TRANSCRIPT_OUTPUT_MAX_CHARS - notice.length;
128
+ return `${truncateUtf16Safe(text, textBudget)}${notice}`;
131
129
  }
132
130
  function formatToolSummary(toolName, meta) {
133
131
  const trimmedMeta = meta?.trim();
@@ -570,7 +568,7 @@ var CodexToolProgressProjection = class {
570
568
  const args = itemToolArgs(item);
571
569
  if (!toolName || !shouldEmitTranscriptToolProgress(toolName, args)) return;
572
570
  this.resultSummaryItemIds.add(item.id);
573
- const meta = this.shouldEmitToolOutput() || !isCommandBearingToolItem(item, args) ? itemMeta(item, this.toolProgressDetailMode()) : void 0;
571
+ const meta = this.shouldIncludeFormattedMeta(isCommandBearingToolItem(item, args)) ? itemMeta(item, this.toolProgressDetailMode()) : void 0;
574
572
  this.emitToolResultMessage({
575
573
  itemId: item.id,
576
574
  text: formatToolSummary(toolName, meta)
@@ -582,9 +580,10 @@ var CodexToolProgressProjection = class {
582
580
  const toolName = itemName(item);
583
581
  const output = itemOutputText(item, this.output.textByItem);
584
582
  if (!toolName || !output || !shouldEmitTranscriptToolProgress(toolName, itemToolArgs(item))) return;
583
+ const meta = this.shouldIncludeFormattedMeta(isCommandBearingToolItem(item, itemToolArgs(item))) ? itemMeta(item, this.toolProgressDetailMode()) : void 0;
585
584
  this.emitToolResultMessage({
586
585
  itemId: item.id,
587
- text: formatToolOutput(toolName, itemMeta(item, this.toolProgressDetailMode()), output),
586
+ text: formatToolOutput(toolName, meta, output),
588
587
  finalOutput: true,
589
588
  isError: isNonSuccessItemStatus(itemStatus(item))
590
589
  });
@@ -643,6 +642,7 @@ var CodexToolProgressProjection = class {
643
642
  try {
644
643
  Promise.resolve(this.params.onToolResult?.({
645
644
  text,
645
+ ...(this.params.messageChannel || this.params.messageProvider) && { channelData: { openclawToolProgressId: params.itemId } },
646
646
  ...params.isError === true ? { isError: true } : {}
647
647
  })).catch(() => {});
648
648
  } catch {}
@@ -653,11 +653,15 @@ var CodexToolProgressProjection = class {
653
653
  shouldEmitToolOutput() {
654
654
  return typeof this.params.shouldEmitToolOutput === "function" ? this.params.shouldEmitToolOutput() : this.params.verboseLevel === "full";
655
655
  }
656
+ shouldIncludeFormattedMeta(commandBearing) {
657
+ const channel = this.params.messageChannel ?? this.params.messageProvider;
658
+ return !commandBearing || !channel && this.shouldEmitToolOutput();
659
+ }
656
660
  emitTranscriptToolCallProgress(params) {
657
661
  if (!shouldEmitTranscriptToolProgress(params.name, params.arguments)) return;
658
662
  this.transcriptProgressCallIds.add(params.id);
659
663
  const args = normalizeToolTranscriptArguments(params.arguments);
660
- const meta = this.shouldEmitToolOutput() || !isCodexCommandBearingToolCall(params.name, args) ? inferToolMetaFromArgs(params.name, args, { detailMode: this.toolProgressDetailMode() }) : void 0;
664
+ const meta = this.shouldIncludeFormattedMeta(isCodexCommandBearingToolCall(params.name, args)) ? inferToolMetaFromArgs(params.name, args, { detailMode: this.toolProgressDetailMode() }) : void 0;
661
665
  if (!this.params.onToolResult || !this.shouldEmitToolResult() || this.resultSummaryItemIds.has(params.id) || this.resultOutputStreamedItemIds.has(params.id)) return;
662
666
  this.resultSummaryItemIds.add(params.id);
663
667
  this.emitToolResultMessage({
@@ -717,85 +721,6 @@ var CodexToolProgressProjection = class {
717
721
  }
718
722
  };
719
723
  //#endregion
720
- //#region extensions/codex/src/app-server/session-history.ts
721
- /**
722
- * Reads OpenClaw session history for Codex transcript mirroring and sanitizes
723
- * image payloads before replaying messages into the app-server projector.
724
- */
725
- function isMissingFileError(error) {
726
- return Boolean(error && typeof error === "object" && "code" in error && error.code === "ENOENT");
727
- }
728
- /** Returns sanitized session-context messages for a Codex mirrored session file. */
729
- async function readCodexMirroredSessionHistoryMessages(target, admission) {
730
- try {
731
- const entries = await readCodexMirroredSessionEntries(target, admission);
732
- if (entries.length === 0) return [];
733
- const firstEntry = entries[0];
734
- if (firstEntry?.type !== "session") return [];
735
- if (typeof firstEntry.id !== "string") return;
736
- if (firstEntry.id !== target.sessionId) return [];
737
- migrateSessionEntries(entries);
738
- return sanitizeCodexHistoryImagePayloads(buildSessionContext(entries.filter((entry) => {
739
- return entry !== null && typeof entry === "object" && !Array.isArray(entry) && entry.type !== "session";
740
- })).messages, "codex mirrored history");
741
- } catch (error) {
742
- if (isMissingFileError(error)) return [];
743
- return;
744
- }
745
- }
746
- async function readCodexMirroredSessionEntries(target, admission) {
747
- if (target.sessionTarget) {
748
- const { agentId, sessionId, sessionKey, storePath } = target.sessionTarget;
749
- if (!agentId || !sessionId || !sessionKey || !storePath || sessionId !== target.sessionId || target.agentId !== void 0 && agentId !== target.agentId || target.sessionKey !== void 0 && sessionKey !== target.sessionKey) return [];
750
- const transcriptTarget = {
751
- agentId,
752
- sessionId,
753
- sessionKey,
754
- storePath
755
- };
756
- return await (admission ? readCodexSessionTranscriptEventsBeforeAdmission(transcriptTarget, admission) : readSessionTranscriptEvents(transcriptTarget));
757
- }
758
- const sqliteMarker = parseSqliteSessionFileMarker(target.sessionFile);
759
- if (sqliteMarker) {
760
- if (sqliteMarker.sessionId !== target.sessionId || target.agentId !== void 0 && sqliteMarker.agentId !== target.agentId) return [];
761
- const sessionKey = resolveSqliteMarkerSessionKey(target, sqliteMarker);
762
- if (!sessionKey) return [];
763
- const transcriptTarget = {
764
- agentId: sqliteMarker.agentId,
765
- sessionId: sqliteMarker.sessionId,
766
- sessionKey,
767
- storePath: sqliteMarker.storePath
768
- };
769
- return await (admission ? readCodexSessionTranscriptEventsBeforeAdmission(transcriptTarget, admission) : readSessionTranscriptEvents(transcriptTarget));
770
- }
771
- if (admission) {
772
- if (admission.sessionId !== target.sessionId || target.agentId !== void 0 && admission.agentId !== target.agentId || target.sessionKey !== void 0 && admission.sessionKey !== target.sessionKey) return [];
773
- return await readCodexSessionTranscriptEventsBeforeAdmission({
774
- agentId: admission.agentId,
775
- sessionId: admission.sessionId,
776
- sessionKey: admission.sessionKey,
777
- storePath: admission.storePath
778
- }, admission);
779
- }
780
- return parseSessionEntries(await fs.readFile(target.sessionFile, "utf-8"));
781
- }
782
- function resolveSqliteMarkerSessionKey(target, marker) {
783
- const explicitSessionKey = target.sessionKey?.trim();
784
- if (explicitSessionKey) {
785
- const explicitEntry = getSessionEntry({
786
- agentId: marker.agentId,
787
- sessionKey: explicitSessionKey,
788
- storePath: marker.storePath
789
- });
790
- if (explicitEntry) return explicitEntry.sessionId === marker.sessionId ? explicitSessionKey : void 0;
791
- }
792
- return resolveTranscriptSessionKeyBySessionId({
793
- agentId: marker.agentId,
794
- sessionId: marker.sessionId,
795
- storePath: marker.storePath
796
- });
797
- }
798
- //#endregion
799
724
  //#region extensions/codex/src/app-server/event-projector-tool-transcript.ts
800
725
  const ZERO_USAGE = {
801
726
  input: 0,
@@ -866,6 +791,7 @@ var CodexToolTranscriptProjection = class {
866
791
  this.nativeMcpAppResultDetailsAttempted = /* @__PURE__ */ new Set();
867
792
  this.approvalReviewsByCallId = /* @__PURE__ */ new Map();
868
793
  this.rawNativeToolOutputByCallId = /* @__PURE__ */ new Map();
794
+ this.pendingRawPatchOutputIds = /* @__PURE__ */ new Set();
869
795
  this.codeModeNativePatchInputsByCallId = /* @__PURE__ */ new Map();
870
796
  }
871
797
  get transcriptMessages() {
@@ -969,14 +895,18 @@ var CodexToolTranscriptProjection = class {
969
895
  } catch {
970
896
  return;
971
897
  }
972
- if (args) this.recordToolCall({
973
- id: callId,
974
- name: "apply_patch",
975
- arguments: args
976
- });
898
+ if (args) {
899
+ this.pendingRawPatchOutputIds.add(callId);
900
+ this.recordToolCall({
901
+ id: callId,
902
+ name: "apply_patch",
903
+ arguments: args
904
+ });
905
+ }
977
906
  return;
978
907
  }
979
908
  if (type !== "custom_tool_call_output" && type !== "function_call_output" || this.namesById.get(callId) !== "apply_patch" && !this.codeModeNativePatchInputsByCallId.has(callId)) return;
909
+ this.pendingRawPatchOutputIds.delete(callId);
980
910
  const text = typeof item.output === "string" ? item.output : Array.isArray(item.output) ? collectDynamicToolContentText(item.output) : "";
981
911
  if (!text.trim()) return;
982
912
  const codeModePatchInput = this.codeModeNativePatchInputsByCallId.get(callId);
@@ -1018,21 +948,20 @@ var CodexToolTranscriptProjection = class {
1018
948
  isError: result.isError
1019
949
  }).content;
1020
950
  }
1021
- async recordNativeToolResultWithDetails(item) {
951
+ async prepareNativeToolResultDetails(item) {
1022
952
  const preparedDetails = await this.prepareNativeMcpAppResultDetails(item);
1023
953
  const approvalReviewState = item ? this.approvalReviewsByCallId.get(item.id) : void 0;
1024
954
  const reviewDetails = approvalReviewState ? {
1025
955
  approvalReviews: approvalReviewState.reviews,
1026
956
  approvalReviewOutcome: toolApprovalReviewOutcome(approvalReviewState)
1027
957
  } : void 0;
1028
- const details = reviewDetails ? isJsonObject(preparedDetails) ? {
958
+ return reviewDetails ? isJsonObject(preparedDetails) ? {
1029
959
  ...preparedDetails,
1030
960
  ...reviewDetails
1031
961
  } : {
1032
962
  ...preparedDetails !== void 0 ? { toolDetails: preparedDetails } : {},
1033
963
  ...reviewDetails
1034
964
  } : preparedDetails;
1035
- this.recordNativeToolResult(item, details);
1036
965
  }
1037
966
  async prepareNativeMcpAppResultDetails(item) {
1038
967
  if (!item || item.type !== "mcpToolCall" || itemStatus(item) === "running") return;
@@ -1155,26 +1084,34 @@ var CodexToolTranscriptProjection = class {
1155
1084
  const missingCount = (/* @__PURE__ */ new Set([...missingTranscriptIds, ...missingTrajectoryIds])).size;
1156
1085
  return missingCount === 1 ? MISSING_TOOL_RESULT_ERROR : `${MISSING_TOOL_RESULT_ERROR} missingToolResultCount=${missingCount}`;
1157
1086
  }
1158
- async readMirroredSessionMessages() {
1087
+ async readMirroredSessionMessages(signal) {
1159
1088
  return await readCodexMirroredSessionHistoryMessages({
1160
1089
  agentId: this.params.agentId,
1161
1090
  sessionFile: this.params.sessionFile,
1162
1091
  sessionId: this.params.sessionId,
1163
- sessionKey: this.params.sessionKey
1164
- }) ?? [];
1092
+ sessionKey: this.params.sessionKey,
1093
+ sessionTarget: this.params.sessionTarget
1094
+ }, void 0, "native-evidence", signal) ?? [];
1165
1095
  }
1166
1096
  recordToolCall(params) {
1167
1097
  if (!params.id || !params.name || this.callIds.has(params.id)) return;
1168
1098
  this.callIds.add(params.id);
1169
1099
  this.namesById.set(params.id, params.name);
1170
1100
  this.progress.recordTranscriptCall(params);
1171
- this.messages.push(attachCodexMirrorIdentity(this.createToolCallMessage(params), `${this.turnId}:tool:${params.id}:call`));
1101
+ const message = attachCodexMirrorIdentity(this.createToolCallMessage(params), `${this.turnId}:tool:${params.id}:call`);
1102
+ this.messages.push(message);
1103
+ this.options.checkpointMessage?.({ read: () => message });
1172
1104
  }
1173
1105
  recordToolResult(params) {
1174
1106
  if (!params.id || !params.name || this.resultIds.has(params.id)) return;
1175
1107
  this.resultIds.add(params.id);
1176
1108
  this.progress.recordTranscriptResult(params);
1177
- this.messages.push(attachCodexMirrorIdentity(this.createToolResultMessage(params), `${this.turnId}:tool:${params.id}:result`));
1109
+ const message = attachCodexMirrorIdentity(this.createToolResultMessage(params), `${this.turnId}:tool:${params.id}:result`);
1110
+ this.messages.push(message);
1111
+ this.options.checkpointMessage?.({
1112
+ read: () => message,
1113
+ ready: () => !this.pendingRawPatchOutputIds.has(params.id)
1114
+ });
1178
1115
  }
1179
1116
  recordMissingToolError(missingTranscriptIds, missingTrajectoryIds) {
1180
1117
  const firstMissingId = missingTranscriptIds.find((id) => Boolean(this.namesById.get(id))) ?? missingTrajectoryIds.find((id) => Boolean(this.trajectoryNamesById.get(id) ?? this.namesById.get(id)));
@@ -1288,6 +1225,7 @@ function normalizeApprovalReviewStatus(status) {
1288
1225
  return status === "inProgress" ? "in_progress" : status === "timedOut" ? "timed_out" : status;
1289
1226
  }
1290
1227
  const GUARDIAN_TIMEOUT_WARNING = "Automatic approval review timed out while evaluating the requested approval.";
1228
+ const LOG_ONLY_CODEX_WARNING_PATTERNS = [/^Configured service tier `[^`\r\n]+` is not advertised as supported for model `[^`\r\n]+` and will be omitted from requests\.$/, /^Code Mode is enabled in configuration, but model `[^`\r\n]+` does not advertise Code Mode support\. This may degrade model performance\. Disable `features\.code_mode` and `features\.code_mode_only`, or select a model whose metadata enables Code Mode\.$/];
1291
1229
  function projectNormalizedToolItem(params) {
1292
1230
  const { item } = params;
1293
1231
  if (!item || !shouldSynthesizeToolProgressForItem(item)) return;
@@ -1429,7 +1367,8 @@ var CodexEventProjection = class {
1429
1367
  }
1430
1368
  handleWarning(params) {
1431
1369
  const message = [readStringField(params, "summary") ?? readStringField(params, "message"), readStringField(params, "details")].filter(Boolean).join("\n");
1432
- if (message) this.emitAgentEvent({
1370
+ if (LOG_ONLY_CODEX_WARNING_PATTERNS.some((pattern) => pattern.test(message))) embeddedAgentLog.warn(message);
1371
+ else if (message) this.emitAgentEvent({
1433
1372
  stream: "notice",
1434
1373
  data: {
1435
1374
  phase: "warning",
@@ -2347,19 +2286,21 @@ var Monitor = class {
2347
2286
  if (childState && !childState.terminal) this.emitChildTaskActivity(notification, childState);
2348
2287
  this.captureChildAssistantMessage(notification);
2349
2288
  await this.handleChildTurnCompletion(notification);
2350
- if (notification.method === "thread/status/changed" && threadId && threadStatus) if (threadStatus !== "systemerror") {
2351
- if (childState) this.clearSystemErrorFallback(childState);
2352
- } else {
2353
- if (childState) {
2354
- this.resumeChild(childState, { scheduleRecovery: false });
2355
- this.setRecoveryFallback(childState, systemErrorFallbackCompletion(childState.childThreadId), this.now());
2289
+ if (notification.method === "thread/status/changed" && threadId && threadStatus) {
2290
+ if (threadStatus !== "systemerror") {
2291
+ if (childState) this.clearSystemErrorFallback(childState);
2292
+ } else {
2293
+ if (childState) {
2294
+ this.resumeChild(childState, { scheduleRecovery: false });
2295
+ this.setRecoveryFallback(childState, systemErrorFallbackCompletion(childState.childThreadId), this.now());
2296
+ }
2297
+ this.reconcileChildThread(threadId).catch((error) => {
2298
+ this.logRecoveryFailure(threadId, error);
2299
+ return false;
2300
+ }).then((reconciled) => {
2301
+ if (!reconciled && childState && this.childStates.get(threadId) === childState) this.scheduleRecoveryPoll(childState);
2302
+ });
2356
2303
  }
2357
- this.reconcileChildThread(threadId).catch((error) => {
2358
- this.logRecoveryFailure(threadId, error);
2359
- return false;
2360
- }).then((reconciled) => {
2361
- if (!reconciled && childState && this.childStates.get(threadId) === childState) this.scheduleRecoveryPoll(childState);
2362
- });
2363
2304
  }
2364
2305
  await this.handleCompletionNotification(notification);
2365
2306
  }
@@ -3379,4 +3320,4 @@ function unrefTimer(timer) {
3379
3320
  if (typeof timer === "object" && timer && "unref" in timer) timer.unref();
3380
3321
  }
3381
3322
  //#endregion
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 };
3323
+ export { CodexToolProgressProjection as a, isCodexCommandBearingToolCall as c, sanitizeCodexToolResponse as d, CodexToolTranscriptProjection as i, resolveCodexToolProgressDetailMode as l, CodexEventProjection as n, shouldEmitTranscriptToolProgress as o, emitCodexAgentEvent as r, inferCodexDynamicToolMeta as s, codexNativeSubagentMonitorRuntime as t, sanitizeCodexToolArguments as u };
@@ -1,15 +1,14 @@
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";
3
- import { t as createStdioTransport } from "./transport-stdio-DhoGy33Z.js";
1
+ import { n as resolveManagedCodexAppServerStartOptions, r as resolveManagedCodexNativeCommand, t as isManagedCodexDesktopCommand } from "./managed-binary-DcpnJF9x.js";
2
+ import { i as closeCodexAppServerTransportAndWait, t as createStdioTransport } from "./transport-stdio-CzTngV0j.js";
4
3
  import { isRecord } from "openclaw/plugin-sdk/string-coerce-runtime";
4
+ import { killProcessTree } from "openclaw/plugin-sdk/process-runtime";
5
5
  import { mkdir } from "node:fs/promises";
6
6
  import path from "node:path";
7
7
  import { resolvePreferredOpenClawTmpDir, withTempWorkspace } from "openclaw/plugin-sdk/temp-path";
8
- import { killProcessTree } from "openclaw/plugin-sdk/process-runtime";
9
8
  import { once } from "node:events";
10
9
  import { sanitizeEnvVars } from "openclaw/plugin-sdk/sandbox";
11
10
  //#region extensions/codex/src/node-exec-server.runtime.ts
12
- const MAX_CODEX_EXEC_SERVER_MESSAGE_BYTES = 64 * 1024 * 1024;
11
+ const MAX_CODEX_EXEC_SERVER_MESSAGE_BYTES = 67108864;
13
12
  const CODEX_EXEC_SERVER_TERMINATION_GRACE_MS = 1e3;
14
13
  const CODEX_EXEC_SERVER_REAP_TIMEOUT_MS = 5e3;
15
14
  const NODE_EXEC_SERVER_PLATFORM_ENVIRONMENT = /^(?:SYSTEMROOT|WINDIR|COMSPEC|PATHEXT|TEMP|TMP|TMPDIR)$/iu;
@@ -125,7 +124,8 @@ async function runCodexNodeExecServer(params) {
125
124
  customAllowedPatterns: [NODE_EXEC_SERVER_PLATFORM_ENVIRONMENT]
126
125
  }).allowed;
127
126
  if (io.signal.aborted) throw nodeExecServerAbortError(io.signal);
128
- const child = createStdioTransport({
127
+ params.assertExecAuthorized();
128
+ const child = await createStdioTransport({
129
129
  transport: "stdio",
130
130
  command: native,
131
131
  commandSource: "resolved-managed",
@@ -138,7 +138,10 @@ async function runCodexNodeExecServer(params) {
138
138
  ...process.platform === "win32" ? { USERPROFILE: dir } : {}
139
139
  },
140
140
  clearEnv: ["NODE_OPTIONS"]
141
- }, baseEnv);
141
+ }, baseEnv, () => {
142
+ if (io.signal.aborted) throw nodeExecServerAbortError(io.signal);
143
+ params.assertExecAuthorized();
144
+ });
142
145
  child.stdin.on("error", (error) => {
143
146
  rejectDisconnected(error);
144
147
  });
@@ -1,10 +1,10 @@
1
- import { D as resolveCodexGatewayTimeoutWithGraceMs } from "./shared-client-DKz23hHY.js";
1
+ import { N as resolveCodexGatewayTimeoutWithGraceMs } from "./shared-client-CKhX2kFt.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
5
5
  const DEFAULT_CODEX_APPROVAL_TIMEOUT_MS = 12e4;
6
6
  const MAX_PLUGIN_APPROVAL_TITLE_LENGTH = 80;
7
- const MAX_PLUGIN_APPROVAL_DESCRIPTION_LENGTH = 256;
7
+ const MAX_PLUGIN_APPROVAL_DESCRIPTION_LENGTH = 512;
8
8
  const ANSI_OSC_SEQUENCE_RE = new RegExp(String.raw`(?:\u001b]|\u009d)[^\u001b\u009c\u0007]*(?:\u0007|\u001b\\|\u009c)`, "g");
9
9
  const ANSI_CONTROL_SEQUENCE_RE = new RegExp(String.raw`(?:\u001b\[[0-?]*[ -/]*[@-~]|\u009b[0-?]*[ -/]*[@-~]|\u001b[@-Z\\-_])`, "g");
10
10
  const CONTROL_CHARACTER_RE = new RegExp(String.raw`[\u0000-\u001f\u007f-\u009f]+`, "g");
@@ -23,11 +23,16 @@ function codexApprovalTimeoutText(kind) {
23
23
  async function requestPluginApproval(params) {
24
24
  const timeoutMs = DEFAULT_CODEX_APPROVAL_TIMEOUT_MS;
25
25
  return params.hostCapabilities.requestApproval({
26
+ signal: params.signal,
26
27
  title: truncateCodexApprovalDisplayText(params.title, MAX_PLUGIN_APPROVAL_TITLE_LENGTH),
27
28
  description: truncateCodexApprovalDisplayText(params.description, MAX_PLUGIN_APPROVAL_DESCRIPTION_LENGTH),
28
29
  severity: params.severity,
29
30
  toolName: params.toolName,
30
31
  toolCallId: params.toolCallId,
32
+ ...params.mcpTool ? {
33
+ mcpTool: params.mcpTool,
34
+ isMcpToolApprovalActive: params.isMcpToolApprovalActive
35
+ } : {},
31
36
  timeoutMs,
32
37
  transportTimeoutMs: resolveCodexGatewayTimeoutWithGraceMs(timeoutMs),
33
38
  ...params.allowedDecisions ? { allowedDecisions: params.allowedDecisions } : {}
@@ -81,6 +86,28 @@ function mapExecDecisionToOutcome(decision) {
81
86
  default: return "unavailable";
82
87
  }
83
88
  }
89
+ /** Runs one complete host approval request and maps transport failures to a closed outcome. */
90
+ async function requestPluginApprovalOutcome(params) {
91
+ try {
92
+ const requestResult = await requestPluginApproval({
93
+ ...params,
94
+ severity: "warning"
95
+ });
96
+ const approvalId = requestResult?.id;
97
+ if (!approvalId) return "unavailable";
98
+ const approvalResult = approvalRequestExplicitlyUnavailable(requestResult) ? void 0 : await waitForPluginApprovalDecision({
99
+ hostCapabilities: params.hostCapabilities,
100
+ approvalId,
101
+ signal: params.signal
102
+ });
103
+ if (params.signal?.aborted) return "cancelled";
104
+ if (approvalResult?.terminalReason === "timeout") return "timed-out";
105
+ const decision = approvalResult?.decision;
106
+ return mapExecDecisionToOutcome(decision === "allow-always" && params.allowedDecisions?.includes("allow-always") === false ? "allow-once" : decision);
107
+ } catch {
108
+ return params.signal?.aborted ? "cancelled" : "denied";
109
+ }
110
+ }
84
111
  function truncateCodexApprovalDisplayText(value, maxLength) {
85
112
  return value.length <= maxLength ? value : `${truncateUtf16Safe(value, maxLength - 3)}...`;
86
113
  }
@@ -92,4 +119,4 @@ function sanitizeCodexApprovalVisibleText(value, options = {}) {
92
119
  return (options.stripDanglingTerminalSequence ? stripDanglingCodexApprovalTerminalSequence(terminalSafe) : terminalSafe).replace(INVISIBLE_FORMATTING_CONTROL_RE, " ").replace(CONTROL_CHARACTER_RE, " ").replace(/\s+/g, " ").trim();
93
120
  }
94
121
  //#endregion
95
- export { sanitizeCodexApprovalVisibleText as a, waitForPluginApprovalDecision as c, requestPluginApproval as i, codexApprovalTimeoutText as n, stripDanglingCodexApprovalTerminalSequence as o, mapExecDecisionToOutcome as r, truncateCodexApprovalDisplayText as s, approvalRequestExplicitlyUnavailable as t };
122
+ export { requestPluginApprovalOutcome as a, truncateCodexApprovalDisplayText as c, requestPluginApproval as i, waitForPluginApprovalDecision as l, codexApprovalTimeoutText as n, sanitizeCodexApprovalVisibleText as o, mapExecDecisionToOutcome as r, stripDanglingCodexApprovalTerminalSequence as s, approvalRequestExplicitlyUnavailable as t };
@@ -1,12 +1,14 @@
1
- import { N as isCodexFastServiceTier } from "./config-giW8X0QA.js";
2
- import { o as getLeasedSharedCodexAppServerClient, p as releaseLeasedSharedCodexAppServerClient } from "./shared-client-DKz23hHY.js";
3
- import { o as isCodexAppServerNativeAuthProfile, r as bindingStoreKey, s as normalizeCodexAppServerBindingModelProvider } from "./session-binding-Bcynfd-_.js";
4
- import { B as resolveCodexAppServerRequestModelSelection, H as resolveCodexBindingModelProviderFallback } from "./thread-lifecycle-L7oEkTlq.js";
5
- import { r as formatCodexDisplayText } from "./command-formatters-DEsIufkt.js";
6
- import { n as resolveCodexBindingAppServerConnection } from "./binding-connection-BMvPX73o.js";
1
+ import { n as isCodexFastServiceTier } from "./config-utils-C57JiJrU.js";
2
+ import { t as bindingStoreKey } from "./session-binding-record-CyaXZvTe.js";
3
+ import "./config-CyapYSji.js";
4
+ import { c as getLeasedSharedCodexAppServerClient, h as releaseLeasedSharedCodexAppServerClient } from "./shared-client-CKhX2kFt.js";
5
+ import { a as isCodexAppServerNativeAuthProfile, o as normalizeCodexAppServerBindingModelProvider } from "./session-binding-4Ki04sW-.js";
6
+ import { E as resolveCodexAppServerRequestModelSelection, O as resolveCodexBindingModelProviderFallback } from "./thread-lifecycle-DPK30jad.js";
7
+ import { s as resolveCodexBindingAppServerConnection } from "./thread-policy-CTalhWFy.js";
8
+ import { a as formatCodexDisplayText } from "./command-formatters-DSbGMXA0.js";
7
9
  import { asOptionalRecord } from "openclaw/plugin-sdk/string-coerce-runtime";
8
- import { resolveAgentDir } from "openclaw/plugin-sdk/agent-runtime";
9
10
  import { getSessionEntry, patchSessionEntry, resolveStorePath } from "openclaw/plugin-sdk/session-store-runtime";
11
+ import { resolveAgentDir } from "openclaw/plugin-sdk/agent-runtime";
10
12
  import { ModelSelectionLockedError, applyModelOverrideWithAuthProfileCompatibility } from "openclaw/plugin-sdk/model-session-runtime";
11
13
  //#region extensions/codex/src/command-authorization.ts
12
14
  const CODEX_NATIVE_EXECUTION_AUTH_ERROR = "Only an owner or operator.admin can control Codex native execution.";
@@ -44,7 +46,7 @@ async function stopCodexConversationTurn(params) {
44
46
  message: "No active Codex run to stop."
45
47
  };
46
48
  const lookup = buildBindingLookup(params);
47
- const binding = await params.bindingStore.read(params.identity);
49
+ const binding = params.binding;
48
50
  if (binding?.threadId !== active.threadId) return {
49
51
  stopped: false,
50
52
  message: "The active Codex run no longer matches this session binding."
@@ -65,7 +67,10 @@ async function stopCodexConversationTurn(params) {
65
67
  await client.request("turn/interrupt", {
66
68
  threadId: active.threadId,
67
69
  turnId: active.turnId
68
- }, { timeoutMs: runtime.requestTimeoutMs });
70
+ }, {
71
+ timeoutMs: runtime.requestTimeoutMs,
72
+ assertCurrent: params.assertCurrent
73
+ });
69
74
  } finally {
70
75
  if (!active.client) releaseLeasedSharedCodexAppServerClient(client);
71
76
  }
@@ -86,7 +91,7 @@ async function steerCodexConversationTurn(params) {
86
91
  message: "No active Codex run to steer."
87
92
  };
88
93
  const lookup = buildBindingLookup(params);
89
- const binding = await params.bindingStore.read(params.identity);
94
+ const binding = params.binding;
90
95
  if (binding?.threadId !== active.threadId) return {
91
96
  steered: false,
92
97
  message: "The active Codex run no longer matches this session binding."
@@ -112,7 +117,10 @@ async function steerCodexConversationTurn(params) {
112
117
  text,
113
118
  text_elements: []
114
119
  }]
115
- }, { timeoutMs: runtime.requestTimeoutMs });
120
+ }, {
121
+ timeoutMs: runtime.requestTimeoutMs,
122
+ assertCurrent: params.assertCurrent
123
+ });
116
124
  } finally {
117
125
  if (!active.client) releaseLeasedSharedCodexAppServerClient(client);
118
126
  }
@@ -125,17 +133,19 @@ async function setCodexConversationModel(params) {
125
133
  const model = params.model.trim();
126
134
  if (!model) return "Usage: /codex model <model>";
127
135
  const lookup = buildBindingLookup(params);
128
- const binding = await requireThreadBinding(params.bindingStore, params.identity);
136
+ params.assertCurrent();
137
+ const binding = requirePreparedThreadBinding(params.binding);
129
138
  if (binding.connectionScope === "supervision") throw new ModelSelectionLockedError();
139
+ const modelProvider = resolveConversationControlModelProvider({
140
+ authProfileId: binding.authProfileId,
141
+ bindingModel: binding.model,
142
+ bindingModelProvider: binding.modelProvider,
143
+ currentModel: model,
144
+ ...lookup
145
+ });
130
146
  const modelSelection = resolveCodexAppServerRequestModelSelection({
131
147
  model,
132
- modelProvider: resolveConversationControlModelProvider({
133
- authProfileId: binding.authProfileId,
134
- bindingModel: binding.model,
135
- bindingModelProvider: binding.modelProvider,
136
- currentModel: model,
137
- ...lookup
138
- }),
148
+ modelProvider,
139
149
  authProfileId: binding.authProfileId,
140
150
  ...lookup
141
151
  });
@@ -154,10 +164,11 @@ async function setCodexConversationModel(params) {
154
164
  if (identity.kind === "session" && identity.sessionKey) {
155
165
  if (!await patchSessionEntry({
156
166
  agentId: identity.agentId,
157
- storePath: resolveStorePath(params.config?.session?.store, { agentId: identity.agentId }),
167
+ storePath: params.storePath ?? resolveStorePath(params.config?.session?.store, { agentId: identity.agentId }),
158
168
  sessionKey: identity.sessionKey,
159
169
  requireWriteSuccess: true,
160
170
  replaceEntry: true,
171
+ assertCommitAllowed: params.assertCurrent,
161
172
  update: (entry) => {
162
173
  if (entry.sessionId !== identity.sessionId) throw new Error("Codex session changed while applying the model selection.");
163
174
  applyModelOverrideWithAuthProfileCompatibility({
@@ -174,23 +185,25 @@ async function setCodexConversationModel(params) {
174
185
  return entry;
175
186
  }
176
187
  })) throw new Error("Codex session changed while applying the model selection.");
177
- if (modelChanged && binding.contextEngine?.projection) await patchThreadBinding(params.bindingStore, identity, binding.threadId, projectionPatch);
188
+ if (modelChanged && binding.contextEngine?.projection) await patchThreadBinding(params.bindingStore, identity, binding.threadId, projectionPatch, params.assertCurrent);
178
189
  } else await patchThreadBinding(params.bindingStore, params.identity, binding.threadId, {
179
190
  model: nextModel,
180
191
  modelProvider: nextModelProvider,
181
192
  ...projectionPatch
182
- });
193
+ }, params.assertCurrent);
183
194
  return `Codex model set to ${formatCodexDisplayText(nextModel)}.`;
184
195
  }
185
196
  async function setCodexConversationFastMode(params) {
186
- const binding = await requireThreadBinding(params.bindingStore, params.identity);
197
+ params.assertCurrent();
198
+ const binding = requirePreparedThreadBinding(params.binding);
187
199
  if (params.enabled == null) return `Codex fast mode: ${isCodexFastServiceTier(binding.serviceTier) ? "on" : "off"}.`;
188
200
  const serviceTier = params.enabled ? "priority" : "flex";
189
- await patchThreadBinding(params.bindingStore, params.identity, binding.threadId, { serviceTier });
201
+ await patchThreadBinding(params.bindingStore, params.identity, binding.threadId, { serviceTier }, params.assertCurrent);
190
202
  return `Codex fast mode ${params.enabled ? "enabled" : "disabled"}.`;
191
203
  }
192
204
  async function setCodexConversationPermissions(params) {
193
- const storePath = resolveStorePath(params.config?.session?.store, { agentId: params.session.agentId });
205
+ params.assertCurrent();
206
+ const storePath = params.storePath ?? resolveStorePath(params.config?.session?.store, { agentId: params.session.agentId });
194
207
  if (!params.mode) {
195
208
  const entry = getSessionEntry({
196
209
  agentId: params.session.agentId,
@@ -199,6 +212,7 @@ async function setCodexConversationPermissions(params) {
199
212
  sessionKey: params.session.sessionKey,
200
213
  storePath
201
214
  });
215
+ params.assertCurrent();
202
216
  if (entry?.sessionId !== params.session.sessionId) throw new Error("Codex session changed while reading the permission mode.");
203
217
  return `Codex permissions: ${formatPermissionsMode(entry.permissionMode)}.`;
204
218
  }
@@ -208,13 +222,14 @@ async function setCodexConversationPermissions(params) {
208
222
  sessionKey: params.session.sessionKey,
209
223
  requireWriteSuccess: true,
210
224
  replaceEntry: true,
225
+ assertCommitAllowed: params.assertCurrent,
211
226
  update: (entry) => {
212
227
  if (entry.sessionId !== params.session.sessionId) throw new Error("Codex session changed while applying the permission mode.");
213
228
  entry.permissionMode = params.mode === "yolo" ? "full" : "guarded";
214
229
  return entry;
215
230
  }
216
231
  })) throw new Error("Codex session changed while applying the permission mode.");
217
- return `Codex permissions set to ${params.mode === "yolo" ? "full access" : "default"}.`;
232
+ return `Codex permissions set to ${params.mode === "yolo" ? "full access" : "guarded"}.`;
218
233
  }
219
234
  function parseCodexFastModeArg(arg) {
220
235
  const normalized = arg?.trim().toLowerCase();
@@ -236,17 +251,16 @@ function parseCodexPermissionsModeArg(arg) {
236
251
  function formatPermissionsMode(mode) {
237
252
  return mode === "full" ? "full access" : mode ?? "default";
238
253
  }
239
- async function requireThreadBinding(bindingStore, identity) {
240
- const binding = await bindingStore.read(identity);
254
+ function requirePreparedThreadBinding(binding) {
241
255
  if (!binding?.threadId) throw new Error("No Codex thread is attached to this OpenClaw session yet.");
242
256
  return binding;
243
257
  }
244
- async function patchThreadBinding(bindingStore, identity, threadId, patch) {
258
+ async function patchThreadBinding(bindingStore, identity, threadId, patch, assertCurrent) {
245
259
  if (!await bindingStore.mutate(identity, {
246
260
  kind: "patch",
247
261
  threadId,
248
262
  patch
249
- })) throw new Error("Codex thread binding changed while applying the control update.");
263
+ }, assertCurrent)) throw new Error("Codex thread binding changed while applying the control update.");
250
264
  }
251
265
  function buildBindingLookup(params) {
252
266
  const agentDir = params.agentDir?.trim();
@@ -1,8 +1,8 @@
1
- import { i as resolveCodexAppServerRuntimeOptions, o as resolveCodexComputerUseConfig } from "./config-giW8X0QA.js";
2
- import { L as isCodexAppServerConnectionClosedError, R as isCodexAppServerIndeterminateRequestCancellationError, S as acquireCodexNativeConfigFence, b as waitForCodexAppServerClientDesktopGenerationDrain, bt as assertNotSymlink, c as isCodexAppServerStartSelectionChangedError, d as readCodexAppServerClientProcessIdentity, l as readCodexAppServerClientDesktopGeneration, m as resolveCodexNativeConfigFenceKey, o as getLeasedSharedCodexAppServerClient, p as releaseLeasedSharedCodexAppServerClient, st as reconcileCodexComputerUseStartArtifacts, t as assertCodexAppServerClientStartSelectionCurrent, xt as resolveCodexAppServerHomeDir, yt as resolveCodexManagedBundledMarketplacePath, z as isCodexAppServerIndeterminateTransportError } from "./shared-client-DKz23hHY.js";
3
- import { l as resolveMacOSDesktopCodexBundledMarketplaceCandidates, s as resolveFirstExistingMacOSDesktopCodexBundledMarketplacePath, t as isManagedCodexDesktopCommand } from "./managed-binary-DFYK4DWq.js";
4
- import { n as describeControlFailure } from "./capabilities-BRMh0aIq.js";
5
- import { r as requestCodexAppServerJson } from "./request-DXXGHko0.js";
1
+ import { M as resolveCodexAppServerHomeDir, i as resolveCodexAppServerRuntimeOptions, o as resolveCodexComputerUseConfig } from "./config-CyapYSji.js";
2
+ import { B as isCodexAppServerIndeterminateRequestCancellationError, D as acquireCodexNativeConfigFence, Jt as assertNotSymlink, S as waitForCodexAppServerClientDesktopGenerationDrain, V as isCodexAppServerIndeterminateTransportError, c as getLeasedSharedCodexAppServerClient, d as readCodexAppServerClientDesktopGeneration, g as resolveCodexNativeConfigFenceKey, h as releaseLeasedSharedCodexAppServerClient, p as readCodexAppServerClientProcessIdentity, qt as resolveCodexManagedBundledMarketplacePath, t as assertCodexAppServerClientStartSelectionCurrent, u as isCodexAppServerStartSelectionChangedError, z as isCodexAppServerConnectionClosedError, zt as reconcileCodexComputerUseStartArtifacts } from "./shared-client-CKhX2kFt.js";
3
+ import { c as resolveFirstExistingMacOSDesktopCodexBundledMarketplacePath, t as isManagedCodexDesktopCommand, u as resolveMacOSDesktopCodexBundledMarketplaceCandidates } from "./managed-binary-DcpnJF9x.js";
4
+ import { i as requestCodexAppServerJson } from "./request-C8H22rPi.js";
5
+ import { n as describeControlFailure } from "./capabilities-B1mgvpP8.js";
6
6
  import fs from "node:fs/promises";
7
7
  import path from "node:path";
8
8
  import { existsSync } from "node:fs";
@@ -721,7 +721,7 @@ function resolveComputerUseConfig(params) {
721
721
  }
722
722
  //#endregion
723
723
  //#region extensions/codex/src/app-server/plugin-metadata-cache.ts
724
- const CODEX_PLUGIN_METADATA_CACHE_TTL_MS = 3600 * 1e3;
724
+ const CODEX_PLUGIN_METADATA_CACHE_TTL_MS = 36e5;
725
725
  /** Process-local plugin metadata cache with coalesced loads per query. */
726
726
  var CodexPluginMetadataCache = class {
727
727
  constructor(nowMs = Date.now) {