@openclaw/codex 2026.9.4 → 2026.9.5

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 (148) hide show
  1. package/assets/activity.svg +30 -0
  2. package/assets/icon.png +0 -0
  3. package/dist/.setup/account-usage-runtime-C2MOIvfq.mjs +75 -0
  4. package/dist/{apply-CvT8tW5i.js → .setup/apply-CJ0ZfmBG.mjs} +11 -11
  5. package/dist/.setup/async-questions-DdhOCwGi.mjs +27 -0
  6. package/dist/{attempt-client-cleanup-DKHzbwt5.js → .setup/attempt-client-cleanup-BpYKdTA0.mjs} +29 -14
  7. package/dist/{attempt-context-D44yeDII.js → .setup/attempt-context-VXVwTCfS.mjs} +5 -5
  8. package/dist/.setup/attempt-terminal-gZrxQ35N.mjs +5 -0
  9. package/dist/{auth-binding-CWlKVccJ.js → .setup/auth-binding-DhLWa_7K.mjs} +1 -1
  10. package/dist/{auth-cache-key-7orQae_j.js → .setup/auth-cache-key-QirmgiCo.mjs} +3 -3
  11. package/dist/{auth-profile-CwzO4_RG.js → .setup/auth-profile-WqZtZfXN.mjs} +1 -1
  12. package/dist/.setup/binding-connection-Bm38niE8.mjs +50 -0
  13. package/dist/.setup/binding-connection.runtime-CnRMC0ta.mjs +48 -0
  14. package/dist/{bounded-turn-C_Hneydj.js → .setup/bounded-turn-BtlZcivC.mjs} +16 -11
  15. package/dist/{build-state-BCmg9-5p.js → .setup/build-state-Xx9ybZqa.mjs} +1 -1
  16. package/dist/{capabilities-8vx68WLH.js → .setup/capabilities-_vXcZGSx.mjs} +1 -1
  17. package/dist/{client-B57KWPQx.js → .setup/client-vXs2929Q.mjs} +332 -163
  18. package/dist/{command-dispatch-BpduNGVf.js → .setup/command-dispatch-naHIZwwF.mjs} +3 -3
  19. package/dist/{command-formatters-lxlkNZgU.js → .setup/command-formatters-CGEkdawF.mjs} +2 -2
  20. package/dist/{command-handlers-tiL9iWj7.js → .setup/command-handlers-BtAJEW1X.mjs} +59 -42
  21. package/dist/{command-rpc-CR5EOEZX.js → .setup/command-rpc-DHFpn4le.mjs} +22 -13
  22. package/dist/{compact-B_H3AOd7.js → .setup/compact-C3i3qlzj.mjs} +28 -43
  23. package/dist/{config-oIORaQ5T.js → .setup/config-CedDWjM-.mjs} +5 -4
  24. package/dist/{config-options-CXMq1T-C.js → .setup/config-options-BsanJ8QG.mjs} +6 -418
  25. package/dist/{protocol-5bh1G-H7.js → .setup/config-parsing-CcB9iPoq.mjs} +9 -51
  26. package/dist/{config-runtime-D0zGNIHu.js → .setup/config-runtime-CeAhl_h4.mjs} +2 -2
  27. package/dist/.setup/config-security-BRQ2mgW9.mjs +465 -0
  28. package/dist/{conversation-binding-DsB4-O7U.js → .setup/conversation-binding-DhzrpTM6.mjs} +23 -21
  29. package/dist/{conversation-binding-data-BiodpIzq.js → .setup/conversation-binding-data-CrcyZk6O.mjs} +1 -1
  30. package/dist/{conversation-control-CtUu1b3m.js → .setup/conversation-control-DN53ns41.mjs} +17 -13
  31. package/dist/.setup/cyber-failover-DYwbmf1o.mjs +123 -0
  32. package/dist/.setup/cyber-failover-notice-e9G3J9-e.mjs +17 -0
  33. package/dist/{dynamic-tools-CmN5RAip.js → .setup/dynamic-tools-D16lOp67.mjs} +101 -55
  34. package/dist/{effective-mcp-catalog-Bd73bqA8.js → .setup/effective-mcp-catalog-K6kLCN8X.mjs} +3 -3
  35. package/dist/{ephemeral-turn-D78_VmzO.js → .setup/ephemeral-turn-R1gA8Sn6.mjs} +4 -5
  36. package/dist/{event-projector-assistant-message-BmBM4qBV.js → .setup/event-projector-assistant-message-DNUR1s0A.mjs} +6 -3
  37. package/dist/{event-projector-items-5VhsECCO.js → .setup/event-projector-items-DyTQ_XqL.mjs} +1 -1
  38. package/dist/{attempt-notifications-C9XufG6l.js → .setup/event-projector-usage-C7Ntzs-f.mjs} +102 -9
  39. package/dist/{harness-C7rRa7bm.js → .setup/harness-rxaaoN-o.mjs} +74 -20
  40. package/dist/{inference-context-Dr_mzvk4.js → .setup/inference-context-fulhZuz8.mjs} +1 -1
  41. package/dist/{inference-proxy-HGXKUIre.js → .setup/inference-proxy-CC15HuSi.mjs} +4 -4
  42. package/dist/{isolated-completion-DWVb5U2J.js → .setup/isolated-completion-B6srt48J.mjs} +7 -7
  43. package/dist/{launch-args-RXQwn8zV.js → .setup/launch-args-DnMak49W.mjs} +22 -1
  44. package/dist/{managed-binary-D22rNEcR.js → .setup/managed-binary-DP6Rib3P.mjs} +2 -2
  45. package/dist/{managed-thread-store-D1t5jh3G.js → .setup/managed-thread-store-BMqgThVL.mjs} +48 -14
  46. package/dist/{model-catalog-Dq2n8f_p.js → .setup/model-catalog-DkvUuBey.mjs} +35 -10
  47. package/dist/{models-PCKOim-h.js → .setup/models-BDFgm_G-.mjs} +3 -3
  48. package/dist/.setup/native-auth-BLZGqFjw.mjs +57 -0
  49. package/dist/{native-subagent-history-DjtPloaU.js → .setup/native-subagent-history-YXaL6dMd.mjs} +24 -29
  50. package/dist/.setup/native-subagent-monitor-B1hxzIOy.mjs +5031 -0
  51. package/dist/{native-subagent-task-ids-BzTdT0Uw.js → .setup/native-subagent-task-ids-DsuOonKv.mjs} +32 -8
  52. package/dist/{node-cli-sessions-DKaOmVUh.js → .setup/node-cli-sessions-Cl8b2ZF3.mjs} +1 -1
  53. package/dist/{node-exec-server.runtime-Cl2vapEi.js → .setup/node-exec-server.runtime-BaViBKNz.mjs} +3 -3
  54. package/dist/{plan-7uG-Fp36.js → .setup/plan-xD7WKYTM.mjs} +64 -48
  55. package/dist/{plugin-activation-BYQculil.js → .setup/plugin-activation-r8nq5Jzp.mjs} +3 -3
  56. package/dist/{plugin-app-cache-key-d0eKxy7b.js → .setup/plugin-app-cache-key-BOxKP7db.mjs} +29 -25
  57. package/dist/{plugin-approval-roundtrip-Bz3FT8W5.js → .setup/plugin-approval-roundtrip-CjfzafAZ.mjs} +1 -1
  58. package/dist/{plugin-inventory-oL4Na1ZG.js → .setup/plugin-inventory-DUle8DLz.mjs} +7 -6
  59. package/dist/{plugin-metadata-cache-ClPJpRio.js → .setup/plugin-metadata-cache-DsS5buNa.mjs} +29 -14
  60. package/dist/{provider-capabilities-BvCUL69A.js → .setup/provider-capabilities-B8J4Dy-O.mjs} +2 -2
  61. package/dist/{provider-MQ8PVkuE.js → .setup/provider-fFh_-VR3.mjs} +4 -4
  62. package/dist/{rate-limits-CBMmWBr9.js → .setup/rate-limits-DOEGYRNs.mjs} +90 -46
  63. package/dist/{request-B7hEkBGq.js → .setup/request-BioXJLYa.mjs} +113 -33
  64. package/dist/.setup/run-attempt-lifecycle-B7JbY4-F.mjs +71 -0
  65. package/dist/{run-attempt-CvsAAGa0.js → .setup/run-attempt-rlA07pUv.mjs} +580 -498
  66. package/dist/{runtime-artifact-BJ0rXBZ_.js → .setup/runtime-artifact-Dy38Z5iU.mjs} +2 -2
  67. package/dist/{sandbox-guard-BxgyoM8M.js → .setup/sandbox-guard-BBP-RbTf.mjs} +3 -3
  68. package/dist/{session-binding-CI8UuilT.js → .setup/session-binding-_0W_fHRr.mjs} +46 -64
  69. package/dist/{session-binding-record-Bcvslnhf.js → .setup/session-binding-record-TH3xA0zj.mjs} +181 -3
  70. package/dist/.setup/session-binding-sidecars-CKYEcfNn.mjs +543 -0
  71. package/dist/{session-catalog-adoption-tcZi1IfX.js → .setup/session-catalog-adoption-CR_whkEW.mjs} +6 -6
  72. package/dist/{session-catalog-archive-CwKg8Xz2.js → .setup/session-catalog-archive-CwZaPacf.mjs} +6 -6
  73. package/dist/.setup/session-catalog-events-jMcYfQyd.mjs +250 -0
  74. package/dist/.setup/session-catalog-fUdWDx-U.mjs +2464 -0
  75. package/dist/.setup/session-catalog-index-B141u15s.mjs +1070 -0
  76. package/dist/.setup/session-catalog-index-order-Cc5BzlQr.mjs +48 -0
  77. package/dist/.setup/session-catalog-index-state-BAuDztHN.mjs +180 -0
  78. package/dist/{thread-history-page-D0JIp48V.js → .setup/session-catalog-native-projection-ChV3cCtm.mjs} +206 -95
  79. package/dist/{session-catalog-node-adoption-B1tgDW-m.js → .setup/session-catalog-node-adoption-BVRsYOSh.mjs} +3 -3
  80. package/dist/{session-catalog-node-continue-Ci-DXyJP.js → .setup/session-catalog-node-continue-Dowv8osw.mjs} +7 -7
  81. package/dist/.setup/session-catalog-projection-C1Bj9Jl-.mjs +414 -0
  82. package/dist/{session-cli-DNN_jhGc.js → .setup/session-cli-DIj-IE-E.mjs} +4 -4
  83. package/dist/{session-history-Cz-tOOYj.js → .setup/session-history-C--SrLI8.mjs} +10 -5
  84. package/dist/{session-history-import-DwyijFI6.js → .setup/session-history-import-JHXT5Xfi.mjs} +4 -4
  85. package/dist/{session-history-read-cxPUxyVV.js → .setup/session-history-read-B3ZfSUbF.mjs} +2 -2
  86. package/dist/{session-history.worker-BeK1YOyT.js → .setup/session-history.worker-CpNj7H_P.mjs} +5 -6
  87. package/dist/{session-initialization-Ct0_Hzmg.js → .setup/session-initialization-DH1z6fXn.mjs} +2 -2
  88. package/dist/{session-permission-policy-BBmXA8Eg.js → .setup/session-permission-policy-DhurXY0l.mjs} +2 -2
  89. package/dist/{session-retirement-B2YfbAAT.js → .setup/session-retirement-CU87AOg9.mjs} +6 -6
  90. package/dist/{settled-turn-context-Du6gdUDd.js → .setup/settled-turn-context-fmwouT5I.mjs} +2 -2
  91. package/dist/{settled-turn-finalizer-Dn91stmc.js → .setup/settled-turn-finalizer-CiY2bLFK.mjs} +9 -9
  92. package/dist/{shared-client-CscigXXL.js → .setup/shared-client-BpTtuLQ5.mjs} +286 -145
  93. package/dist/{side-question-BGMJQf4U.js → .setup/side-question-DSCZyoBD.mjs} +64 -47
  94. package/dist/{source-CElXU0Oy.js → .setup/source-Bjp4UQij.mjs} +7 -6
  95. package/dist/{thread-archive-guard-DfpBr-Sz.js → .setup/thread-archive-guard-jmecf6OJ.mjs} +1 -1
  96. package/dist/.setup/thread-history-page-BTx-4xsg.mjs +83 -0
  97. package/dist/{thread-lifecycle-DXl1-I6b.js → .setup/thread-lifecycle-Cik28qWn.mjs} +256 -128
  98. package/dist/{thread-ownership-BsDRTsyp.js → .setup/thread-ownership-skomxnIt.mjs} +4 -4
  99. package/dist/{thread-policy-BuEQfE0g.js → .setup/thread-policy-Cjs4B8xf.mjs} +2 -2
  100. package/dist/{thread-resume-DsDOZpFg.js → .setup/thread-resume-BkNpj9Pz.mjs} +8 -5
  101. package/dist/.setup/timeout-DZF05XrR.mjs +63 -0
  102. package/dist/{transcript-history-projection-v17wXgdK.js → .setup/transcript-history-projection-DHNBDhCU.mjs} +8 -3
  103. package/dist/{transcript-mirror-C5CKgNy6.js → .setup/transcript-mirror-D4qp_leP.mjs} +15 -6
  104. package/dist/{transcript-mirror-attestation-DibE0krH.js → .setup/transcript-mirror-attestation-CzM-94NC.mjs} +4 -1
  105. package/dist/{transport-stdio-BGjHoYLr.js → .setup/transport-stdio-Cmx94Oiy.mjs} +149 -44
  106. package/dist/{upstream-session-fork-BZerMte_.js → .setup/upstream-session-fork-D3UKxgVD.mjs} +27 -26
  107. package/dist/{usage-tCk-mg_x.js → .setup/usage-BOgBEKso.mjs} +4 -4
  108. package/dist/.setup/usage-limit-error-C0ow7DOc.mjs +166 -0
  109. package/dist/{version-omm6IPI3.js → .setup/version-CoqzXPgK.mjs} +1 -1
  110. package/dist/{web-search-provider.runtime-B7bGbGWq.js → .setup/web-search-provider.runtime-CTGuJt6i.mjs} +3 -3
  111. package/dist/api.js +6 -6
  112. package/dist/cli-metadata.js +1 -1
  113. package/dist/doctor-contract-api.js +8 -528
  114. package/dist/harness.js +1 -1
  115. package/dist/index.js +123 -83
  116. package/dist/media-understanding-provider.js +3 -3
  117. package/dist/migration-provider-api.js +1 -1
  118. package/dist/native-tool-policy.js +12 -0
  119. package/dist/provider-discovery.js +18 -0
  120. package/dist/session-history-worker-runtime.js +23 -5
  121. package/dist/session-history.worker.js +2 -2
  122. package/dist/web-search-contract-api.js +1 -1
  123. package/openclaw.plugin.json +354 -69
  124. package/package.json +11 -8
  125. package/dist/binding-connection-D3udKbIE.js +0 -60
  126. package/dist/event-projector-usage-BfXmpOec.js +0 -102
  127. package/dist/native-subagent-history-owner-Pcp7JuVF.js +0 -34
  128. package/dist/native-subagent-monitor-fQ7eIXEf.js +0 -2978
  129. package/dist/rpc-error-ttN_QjEm.js +0 -30
  130. package/dist/session-catalog-ct-AH01I.js +0 -1477
  131. package/dist/session-catalog-home-id-CwhLdC03.js +0 -18
  132. package/dist/session-catalog-provenance-D-dIfRAH.js +0 -96
  133. package/dist/timeout-BVw8aaM1.js +0 -33
  134. package/dist/{auth-profile-selection-DFu9e167.js → .setup/auth-profile-selection-DFu9e167.mjs} +0 -0
  135. package/dist/{config-utils-DujwEnhg.js → .setup/config-utils-DujwEnhg.mjs} +0 -0
  136. package/dist/{context-compaction-activity-CMla5FPJ.js → .setup/context-compaction-activity-CMla5FPJ.mjs} +0 -0
  137. package/dist/{elicitation-input-DPoK8F7w.js → .setup/elicitation-input-DPoK8F7w.mjs} +0 -0
  138. package/dist/{history-rejection-B4nOXNXF.js → .setup/history-rejection-B4nOXNXF.mjs} +0 -0
  139. package/dist/{image-payload-sanitizer-tupAr-2o.js → .setup/image-payload-sanitizer-tupAr-2o.mjs} +0 -0
  140. package/dist/{incognito-session-uhrBF6wJ.js → .setup/incognito-session-uhrBF6wJ.mjs} +0 -0
  141. package/dist/{local-runtime-attribution-B_2mnqhb.js → .setup/local-runtime-attribution-B_2mnqhb.mjs} +0 -0
  142. package/dist/{native-execution-policy-umd0tgh4.js → .setup/native-execution-policy-YBMHSzC4.mjs} +1 -1
  143. /package/dist/{plugin-marketplace-discovery-P-Vndfqq.js → .setup/plugin-marketplace-discovery-P-Vndfqq.mjs} +0 -0
  144. /package/dist/{rolldown-runtime-8H4AJuhK.js → .setup/rolldown-runtime-8H4AJuhK.mjs} +0 -0
  145. /package/dist/{session-binding-meta-B7aEMU7g.js → .setup/session-binding-meta-B7aEMU7g.mjs} +0 -0
  146. /package/dist/{session-upstream-marker-D15C9NHp.js → .setup/session-upstream-marker-D15C9NHp.mjs} +0 -0
  147. /package/dist/{upstream-prompt-provenance-LphB8slG.js → .setup/upstream-prompt-provenance-LphB8slG.mjs} +0 -0
  148. /package/dist/{web-search-provider.shared-BrZmlqyR.js → .setup/web-search-provider.shared-BrZmlqyR.mjs} +0 -0
@@ -0,0 +1,123 @@
1
+ import { d as readCodexPluginConfig } from "./config-parsing-CcB9iPoq.mjs";
2
+ import { t as attemptTerminal } from "./attempt-terminal-gZrxQ35N.mjs";
3
+ //#region extensions/codex/src/app-server/cyber-failover.ts
4
+ /**
5
+ * Automatic Daybreak escalation for OpenAI cyber-policy refusals.
6
+ *
7
+ * OpenAI refuses some defensive-cyber work on its general models and directs
8
+ * approved workspaces to a Daybreak model instead. When a turn is refused, the
9
+ * harness retries it once on the configured Daybreak model so the refused work
10
+ * reaches the tier allowed to answer it. Only a refused turn is ever routed
11
+ * there, and the retry never changes the session's stored model selection.
12
+ *
13
+ * Authorization stays server-owned. `model/list` advertises Daybreak to every
14
+ * client, but an unentitled workspace still gets 401/403 on use, and each such
15
+ * attempt costs the transport's full five-try reconnect ladder. Entitlement is
16
+ * therefore only ever observed from an actual attempt, and a failure is
17
+ * remembered per workspace so siblings do not each pay for it.
18
+ */
19
+ const DEFAULT_CYBER_FAILOVER = {
20
+ mode: "auto",
21
+ model: "gpt-daybreak-blue-latest",
22
+ cooloffMs: 6e5
23
+ };
24
+ function resolveCodexCyberFailoverConfig(pluginConfig) {
25
+ const configured = readCodexPluginConfig(pluginConfig).appServer?.cyberFailover;
26
+ if (!configured) return DEFAULT_CYBER_FAILOVER;
27
+ return {
28
+ mode: configured.mode ?? DEFAULT_CYBER_FAILOVER.mode,
29
+ model: configured.model ?? DEFAULT_CYBER_FAILOVER.model,
30
+ cooloffMs: configured.cooloffMs ?? DEFAULT_CYBER_FAILOVER.cooloffMs
31
+ };
32
+ }
33
+ const unavailableTargets = /* @__PURE__ */ new Map();
34
+ const MAX_UNAVAILABLE_TARGETS = 256;
35
+ const inFlightProbes = /* @__PURE__ */ new Set();
36
+ function targetKey(model, workspace) {
37
+ const normalized = model.trim().toLowerCase();
38
+ const slashIndex = normalized.lastIndexOf("/");
39
+ return [
40
+ workspace?.agentId?.trim().toLowerCase() ?? "",
41
+ workspace?.authProfileId?.trim().toLowerCase() ?? "",
42
+ slashIndex >= 0 ? normalized.slice(slashIndex + 1) : normalized
43
+ ].join("\0");
44
+ }
45
+ /** Marks a workspace/target probe in flight; the returned handle releases it. */
46
+ function reserveCodexCyberProbe(params) {
47
+ const key = targetKey(params.model, params.workspace);
48
+ inFlightProbes.add(key);
49
+ return () => {
50
+ inFlightProbes.delete(key);
51
+ };
52
+ }
53
+ /** Remembers that this workspace cannot use the target for `cooloffMs`. */
54
+ function recordCodexCyberTargetUnavailable(params) {
55
+ if (params.cooloffMs <= 0) return;
56
+ const now = params.now ?? Date.now();
57
+ for (const [key, expiresAt] of unavailableTargets) if (expiresAt <= now) unavailableTargets.delete(key);
58
+ while (unavailableTargets.size >= MAX_UNAVAILABLE_TARGETS) {
59
+ const oldest = unavailableTargets.keys().next();
60
+ if (oldest.done) break;
61
+ unavailableTargets.delete(oldest.value);
62
+ }
63
+ unavailableTargets.set(targetKey(params.model, params.workspace), now + params.cooloffMs);
64
+ }
65
+ /** Decides whether a refused turn may be retried on Daybreak. */
66
+ function planCodexCyberEscalation(params) {
67
+ const { config } = params;
68
+ if (config.mode !== "auto") return {
69
+ kind: "skip",
70
+ reason: "disabled"
71
+ };
72
+ if (!params.replaySafe) return {
73
+ kind: "skip",
74
+ reason: "not_replay_safe"
75
+ };
76
+ if (!config.model.trim()) return {
77
+ kind: "skip",
78
+ reason: "no_target"
79
+ };
80
+ const key = targetKey(config.model, params.workspace);
81
+ if (params.currentModel && targetKey(params.currentModel, params.workspace) === key) return {
82
+ kind: "skip",
83
+ reason: "already_daybreak"
84
+ };
85
+ const now = params.now ?? Date.now();
86
+ const expiresAt = unavailableTargets.get(key);
87
+ if (expiresAt !== void 0 && expiresAt <= now) unavailableTargets.delete(key);
88
+ else if (expiresAt !== void 0) return {
89
+ kind: "skip",
90
+ reason: "target_unavailable"
91
+ };
92
+ if (inFlightProbes.has(key)) return {
93
+ kind: "skip",
94
+ reason: "probe_in_flight"
95
+ };
96
+ return {
97
+ kind: "escalate",
98
+ model: config.model
99
+ };
100
+ }
101
+ const AUTHORIZATION_FAILURE_RE = /\b(401|403)\b|unauthorized|not authorized|forbidden/i;
102
+ /** Everything the escalation decision needs from one attempt outcome. */
103
+ function readCodexCyberAttemptVerdict(result) {
104
+ const message = result?.currentAttemptAssistant;
105
+ const refusals = message?.role === "assistant" ? message.diagnostics ?? [] : [];
106
+ const cyberRefused = result?.terminal.kind === "ok" && refusals.some((d) => d.type === "provider_refusal" && d.details?.category === "cyber" && d.details?.provider === "openai");
107
+ const promptError = result ? attemptTerminal.project(result.terminal).promptError : void 0;
108
+ const answered = !(promptError !== void 0 && promptError !== null) && message?.role === "assistant" && !refusals.some((d) => d.type === "provider_refusal") && message.stopReason !== "error" && message.stopReason !== "aborted";
109
+ const errorTexts = [
110
+ typeof promptError === "string" ? promptError : void 0,
111
+ promptError instanceof Error ? promptError.message : void 0,
112
+ result?.lastAssistant?.errorMessage,
113
+ message?.errorMessage
114
+ ];
115
+ return {
116
+ cyberRefused,
117
+ replaySafe: result?.replayMetadata?.replaySafe === true && result.runtimeContinuationStarted !== true,
118
+ answered,
119
+ unavailable: errorTexts.some((t) => t !== void 0 && AUTHORIZATION_FAILURE_RE.test(t))
120
+ };
121
+ }
122
+ //#endregion
123
+ export { planCodexCyberEscalation, readCodexCyberAttemptVerdict, recordCodexCyberTargetUnavailable, reserveCodexCyberProbe, resolveCodexCyberFailoverConfig };
@@ -0,0 +1,17 @@
1
+ import { t as emitCodexAppServerEvent } from "./run-attempt-lifecycle-B7JbY4-F.mjs";
2
+ //#region extensions/codex/src/app-server/cyber-failover-notice.ts
3
+ async function emitCodexCyberNotice(params, notice) {
4
+ await emitCodexAppServerEvent(params, {
5
+ stream: "notice",
6
+ data: {
7
+ phase: "provider_policy",
8
+ category: "cyber",
9
+ state: notice.state,
10
+ provider: "openai",
11
+ ...notice.model ? { model: notice.model } : {},
12
+ fallbackModel: notice.fallbackModel
13
+ }
14
+ });
15
+ }
16
+ //#endregion
17
+ export { emitCodexCyberNotice };
@@ -1,14 +1,17 @@
1
- import { a as flattenCodexDynamicToolFunctions, o as isJsonObject, r as CODEX_OPENCLAW_DIRECT_DYNAMIC_TOOL_NAMESPACE, x as readCodexPluginConfig, y as isCodexRemoteExecPlacementSandbox } from "./protocol-5bh1G-H7.js";
2
- import { B as withDynamicToolTranscriptDetails, E as createCodexElicitationResponse, L as resolveCodexToolAbortTerminalReason, R as createFailedDynamicToolResponse, w as readCodexTurn, z as withDynamicToolExecutionState } from "./client-B57KWPQx.js";
3
- import { o as formatCodexDisplayText } from "./command-formatters-lxlkNZgU.js";
4
- import { c as itemName, f as shouldClearTerminalPresentationForNativeItem, l as itemStatus, n as auditNativeToolTerminalStatus, r as auditNativeToolUnfinishedStatus, t as auditNativeToolName, x as readItem } from "./event-projector-items-5VhsECCO.js";
5
- import "./config-oIORaQ5T.js";
6
- import { r as sanitizeInlineImageDataUrl, t as invalidInlineImageText } from "./image-payload-sanitizer-tupAr-2o.js";
7
- import { h as isCodexNotificationForTurn } from "./attempt-client-cleanup-DKHzbwt5.js";
8
- import { C as resolveCodexWebSearchPlan, V as emitCodexNativePreToolUseFailureDiagnostic, at as isForcedPrivateQaCodexRuntime, ct as normalizeCodexDynamicToolName, it as filterCodexDynamicToolsForDisabledNativeSurface, rt as filterCodexDynamicTools, st as isSystemAgentOnlyCodexDynamicToolAllowlist } from "./thread-lifecycle-DXl1-I6b.js";
9
- import { n as resolveCodexNativeExecutionPolicy, r as resolveCodexNodeExecToolOverrides } from "./native-execution-policy-umd0tgh4.js";
10
- import { a as CODEX_NODE_EXEC_DYNAMIC_TOOL_NAME, c as createNodeExecAliasDynamicTool, i as CODEX_GATEWAY_PROCESS_DYNAMIC_TOOL_NAME, l as isCodexDynamicToolExcluded, o as createGatewayExecProjection, r as CODEX_GATEWAY_EXEC_DYNAMIC_TOOL_NAME, s as createGatewayProcessProjection } from "./provider-capabilities-BvCUL69A.js";
11
- import { a as requestPluginApprovalOutcome, c as truncateCodexApprovalDisplayText, i as requestPluginApproval, l as waitForPluginApprovalDecision, n as codexApprovalTimeoutText, o as sanitizeCodexApprovalVisibleText, r as mapExecDecisionToOutcome, s as stripDanglingCodexApprovalTerminalSequence, t as approvalRequestExplicitlyUnavailable } from "./plugin-approval-roundtrip-Bz3FT8W5.js";
1
+ import { CODEX_NATIVE_TOOL_REQUIREMENTS } from "../native-tool-policy.js";
2
+ import { d as CODEX_OPENCLAW_DIRECT_DYNAMIC_TOOL_NAMESPACE, m as isJsonObject, p as flattenCodexDynamicToolFunctions } from "./config-security-BRQ2mgW9.mjs";
3
+ import { d as readCodexPluginConfig, l as isCodexRemoteExecPlacementSandbox } from "./config-parsing-CcB9iPoq.mjs";
4
+ import { B as withDynamicToolTranscriptDetails, E as createCodexElicitationResponse, L as resolveCodexToolAbortTerminalReason, R as createFailedDynamicToolResponse, w as readCodexTurn, z as withDynamicToolExecutionState } from "./client-vXs2929Q.mjs";
5
+ import { o as formatCodexDisplayText } from "./command-formatters-CGEkdawF.mjs";
6
+ import { c as itemName, f as shouldClearTerminalPresentationForNativeItem, l as itemStatus, n as auditNativeToolTerminalStatus, r as auditNativeToolUnfinishedStatus, t as auditNativeToolName, x as readItem } from "./event-projector-items-DyTQ_XqL.mjs";
7
+ import { s as codexAppIdentityKey } from "./plugin-app-cache-key-BOxKP7db.mjs";
8
+ import "./config-CedDWjM-.mjs";
9
+ import { r as sanitizeInlineImageDataUrl, t as invalidInlineImageText } from "./image-payload-sanitizer-tupAr-2o.mjs";
10
+ import { v as isCodexNotificationForTurn } from "./attempt-client-cleanup-BpYKdTA0.mjs";
11
+ import { H as emitCodexNativePreToolUseFailureDiagnostic, at as filterCodexDynamicToolsForDisabledNativeSurface, ct as isSystemAgentOnlyCodexDynamicToolAllowlist, it as filterCodexDynamicTools, lt as normalizeCodexDynamicToolName, ot as isForcedPrivateQaCodexRuntime, w as resolveCodexWebSearchPlan } from "./thread-lifecycle-Cik28qWn.mjs";
12
+ import { n as resolveCodexNativeExecutionPolicy, r as resolveCodexNodeExecToolOverrides } from "./native-execution-policy-YBMHSzC4.mjs";
13
+ import { a as CODEX_NODE_EXEC_DYNAMIC_TOOL_NAME, c as createNodeExecAliasDynamicTool, i as CODEX_GATEWAY_PROCESS_DYNAMIC_TOOL_NAME, l as isCodexDynamicToolExcluded, o as createGatewayExecProjection, r as CODEX_GATEWAY_EXEC_DYNAMIC_TOOL_NAME, s as createGatewayProcessProjection } from "./provider-capabilities-B8J4Dy-O.mjs";
14
+ import { a as requestPluginApprovalOutcome, c as truncateCodexApprovalDisplayText, i as requestPluginApproval, l as waitForPluginApprovalDecision, n as codexApprovalTimeoutText, o as sanitizeCodexApprovalVisibleText, r as mapExecDecisionToOutcome, s as stripDanglingCodexApprovalTerminalSequence, t as approvalRequestExplicitlyUnavailable } from "./plugin-approval-roundtrip-CjfzafAZ.mjs";
12
15
  import { createRequire } from "node:module";
13
16
  import { asNonArrayRecord, asOptionalRecord, isRecord, normalizeOptionalString, normalizeTrimmedStringList, readStringField } from "openclaw/plugin-sdk/string-coerce-runtime";
14
17
  import { createHash, randomUUID } from "node:crypto";
@@ -21,14 +24,15 @@ import { once } from "node:events";
21
24
  import { spawn } from "node:child_process";
22
25
  import { coerceErrorMessage } from "openclaw/plugin-sdk/error-runtime";
23
26
  import { DEFAULT_MAX_LIVE_TOOL_RESULT_CHARS, estimateToolResultTextChars, resolveLiveToolResultMaxChars, sliceToolResultTextToBudget, sliceUtf16Safe, truncateUtf16Safe } from "openclaw/plugin-sdk/text-utility-runtime";
27
+ import { emitTrustedDiagnosticEvent } from "openclaw/plugin-sdk/diagnostic-runtime";
24
28
  import { createDeferred } from "openclaw/plugin-sdk/extension-shared";
25
29
  import { createStageTimingTracker, formatStageTimings } from "openclaw/plugin-sdk/time-runtime";
26
30
  import { isPathStrictlyInside, root } from "openclaw/plugin-sdk/file-access-runtime";
27
31
  import { fileURLToPath, pathToFileURL } from "node:url";
28
32
  import { resolveAgentDir } from "openclaw/plugin-sdk/agent-runtime";
29
- import { HEARTBEAT_RESPONSE_TOOL_NAME, buildAgentHookContextChannelFields, buildEmbeddedAttemptToolRunContext, consumeAdjustedParamsForToolCall, consumePreExecutionBlockedToolCall, createAgentToolResultMiddlewareRunner, createCodexAppServerToolResultExtensionRunner, embeddedAgentLog, extractMessagingToolSend, extractMessagingToolSendResult, extractToolResultMediaArtifact, filterProviderNormalizableTools, filterToolResultMediaUrls, finalizeAgentToolAvailability, finalizeToolTerminalPresentation, formatApprovalDisplayPath, formatToolExecutionErrorMessage, getBeforeToolCallFailureDisposition, getChannelAgentToolMeta, getPluginToolMeta, getPluginToolSideEffectOwnerKey, hasNativeHookRelayInvocation, invokeNativeHookRelay, isDeliveredMessageToolOnlySourceReplyResult, isDeliveredMessagingToolResult, isHostScopedAgentToolActive, isMessagingTool, isMessagingToolSendAction, isReplaySafeToolCall, isSubagentSessionKey, isToolResultError, isToolWrappedWithBeforeToolCallHook, normalizeAgentRuntimeTools, normalizeHeartbeatToolResponse, projectRuntimeToolInputSchema, resolveAttemptSpawnWorkspaceDir, resolveModelAuthMode, resolveNativeHookRelayDeferredToolApproval, resolveToolExecutionErrorKind, resolveToolResultFailureKind, runAgentHarnessAfterToolCallHook, sanitizeToolResult, setBeforeToolCallDiagnosticsEnabled, supportsModelTools, wrapToolWithBeforeToolCallHook } from "openclaw/plugin-sdk/agent-harness-runtime";
33
+ import { HEARTBEAT_RESPONSE_TOOL_NAME, applyEmbeddedAttemptToolsAllow, buildAgentHookContextChannelFields, buildEmbeddedAttemptToolRunContext, consumeAdjustedParamsForToolCall, consumePreExecutionBlockedToolCall, createAgentToolResultMiddlewareRunner, createCodexAppServerToolResultExtensionRunner, embeddedAgentLog, extractMessagingToolSend, extractMessagingToolSendResult, extractToolResultMediaArtifact, filterProviderNormalizableTools, filterToolResultMediaUrls, finalizeAgentToolAvailability, finalizeToolTerminalPresentation, formatApprovalDisplayPath, formatToolExecutionErrorMessage, getBeforeToolCallFailureDisposition, getChannelAgentToolMeta, getPluginToolMeta, getPluginToolSideEffectOwnerKey, hasNativeHookRelayInvocation, invokeNativeHookRelay, isDeliveredMessageToolOnlySourceReplyResult, isDeliveredMessagingToolResult, isHostScopedAgentToolActive, isMessagingTool, isMessagingToolSendAction, isReplaySafeToolCall, isSubagentSessionKey, isToolResultError, isToolWrappedWithBeforeToolCallHook, normalizeAgentRuntimeTools, normalizeHeartbeatToolResponse, projectRuntimeToolInputSchema, resolveAttemptSpawnWorkspaceDir, resolveModelAuthMode, resolveNativeHookRelayDeferredToolApproval, resolveToolExecutionErrorKind, resolveToolResultFailureKind, runAgentHarnessAfterToolCallHook, sanitizeToolResult, setBeforeToolCallDiagnosticsEnabled, supportsModelTools, wrapToolWithBeforeToolCallHook } from "openclaw/plugin-sdk/agent-harness-runtime";
30
34
  import { formatErrorMessage as formatErrorMessage$2, redactSensitiveText } from "openclaw/plugin-sdk/security-runtime";
31
- import { emitTrustedDiagnosticEvent } from "openclaw/plugin-sdk/diagnostic-runtime";
35
+ import { consumeTrustedToolNoStartError, copyInternalToolResultState, getCoreTtsToolResultMediaUrls } from "openclaw/plugin-sdk/agent-harness-tool-runtime";
32
36
  import { isIP } from "node:net";
33
37
  import { redactToolPayloadText } from "openclaw/plugin-sdk/logging-core";
34
38
  import { formatMcpCodexApprovalRemedy, requiresMcpCodexToolApproval, resolveCodexScheduledToolProjectionFactory, resolveProjectedMcpCodexToolApprovalMode, runWithCronCreatorAuthorityCapabilityResolver } from "openclaw/plugin-sdk/codex-mcp-projection";
@@ -36,7 +40,6 @@ import { buildRemoteCommand, isToolAllowed, sanitizeEnvVars } from "openclaw/plu
36
40
  import { SsrFBlockedError, isBlockedHostnameOrIp } from "openclaw/plugin-sdk/ssrf-runtime";
37
41
  import { saveMediaBuffer } from "openclaw/plugin-sdk/media-store";
38
42
  import { getMediaDir } from "openclaw/plugin-sdk/media-runtime";
39
- import { consumeTrustedToolNoStartError, copyInternalToolResultState, getCoreTtsToolResultMediaUrls } from "openclaw/plugin-sdk/agent-harness-tool-runtime";
40
43
  import { normalizeOpenAIStrictCompatSchema } from "openclaw/plugin-sdk/provider-tools";
41
44
  //#region extensions/codex/src/app-server/dynamic-tool-build-state.ts
42
45
  /** Mutable dependency seam shared by dynamic-tool construction and its behavioral tests. */
@@ -106,14 +109,6 @@ function filterCodexVisionTools(tools, params) {
106
109
  * OpenClaw-owned tools, Codex native-tool fallback rules, sandbox shell shims,
107
110
  * and provider allowlist normalization.
108
111
  */
109
- const CODEX_NATIVE_SANDBOX_TOOL_REQUIREMENTS = [
110
- "exec",
111
- "process",
112
- "read",
113
- "write",
114
- "edit",
115
- "apply_patch"
116
- ];
117
112
  const CODEX_MEMORY_FLUSH_DYNAMIC_TOOL_ALLOW = /* @__PURE__ */ new Set(["read", "write"]);
118
113
  const CODEX_DISABLED_NATIVE_SHELL_DYNAMIC_TOOLS = /* @__PURE__ */ new Set([
119
114
  "exec",
@@ -210,6 +205,7 @@ async function buildDynamicTools(input) {
210
205
  nativeToolSurfaceEnabled: input.nativeToolSurfaceEnabled,
211
206
  nativeProviderWebSearchSupport: input.nativeProviderWebSearchSupport
212
207
  });
208
+ const messageToolProvider = resolveCodexMessageToolProvider(params);
213
209
  const webFetchHostnameAllowlistRef = {};
214
210
  const toolConstructionPlan = resolveCodexNodePlacementToolConstructionPlan(input.sandbox, input.nativeToolSurfaceEnabled);
215
211
  const options = {
@@ -229,11 +225,11 @@ async function buildDynamicTools(input) {
229
225
  } : void 0,
230
226
  sandbox: input.sandbox,
231
227
  ...toolConstructionPlan ? { toolConstructionPlan } : {},
232
- messageProvider: resolveCodexMessageToolProvider(params),
228
+ messageProvider: messageToolProvider,
233
229
  toolPolicyMessageProvider: params.messageProvider ?? params.messageChannel,
234
230
  ...params.onToolResult ? { questionPrompt: {
235
231
  send: params.onToolResult,
236
- ...params.messageChannel ? { messageChannel: params.messageChannel } : {}
232
+ messageChannel: messageToolProvider
237
233
  } } : {},
238
234
  inputProvenance: params.inputProvenance,
239
235
  trustedInternalHandoff: params.trustedInternalHandoff,
@@ -336,7 +332,7 @@ async function buildDynamicTools(input) {
336
332
  agentId: input.policyAgentId,
337
333
  sessionKey: input.sandboxSessionKey,
338
334
  sandboxToolPolicy: input.sandbox?.tools,
339
- messageProvider: resolveCodexMessageToolProvider(params),
335
+ messageProvider: messageToolProvider,
340
336
  agentAccountId: params.agentAccountId,
341
337
  groupId: params.groupId,
342
338
  groupChannel: params.groupChannel,
@@ -457,7 +453,7 @@ function canCodexAppServerNativeToolSurfaceHonorSandbox(sandbox, options = {}) {
457
453
  return false;
458
454
  }
459
455
  function canSandboxToolPolicyExposeCodexNativeToolSurface(sandbox) {
460
- return CODEX_NATIVE_SANDBOX_TOOL_REQUIREMENTS.every((toolName) => isToolAllowed(sandbox.tools, toolName));
456
+ return CODEX_NATIVE_TOOL_REQUIREMENTS.every((toolName) => isToolAllowed(sandbox.tools, toolName));
461
457
  }
462
458
  function isCodexMemoryFlushRun(params) {
463
459
  return params?.trigger === "memory" && Boolean(params.memoryFlushWritePath?.trim());
@@ -566,13 +562,12 @@ function placeDisabledNativeShellToolsInDirectNamespace(tools, nativeToolSurface
566
562
  }
567
563
  /** Applies a normalized tool allowlist while preserving shell aliases for exec/process. */
568
564
  function filterCodexDynamicToolsForAllowlist(tools, toolsAllow) {
569
- if (!toolsAllow) return tools;
570
- if (toolsAllow.length === 0) return [];
571
- if (hasWildcardCodexToolsAllow(toolsAllow)) return tools;
572
- const allowSet = new Set(toolsAllow.map((name) => normalizeCodexDynamicToolName(name)).filter(Boolean));
573
- return tools.filter((tool) => {
574
- const normalized = normalizeCodexDynamicToolName(tool.name);
575
- return allowSet.has(normalized) || normalized === "sandbox_exec" && allowSet.has("exec") || normalized === "sandbox_process" && (allowSet.has("exec") || allowSet.has("process")) || normalized === "gateway_exec" && allowSet.has("exec") || normalized === "gateway_process" && (allowSet.has("exec") || allowSet.has("process")) || normalized === "node_exec" && allowSet.has("exec");
565
+ return applyEmbeddedAttemptToolsAllow(tools, toolsAllow, {
566
+ toolMeta: getPluginToolMeta,
567
+ toolAliases: (tool) => {
568
+ const normalized = normalizeCodexDynamicToolName(tool.name);
569
+ return normalized === "sandbox_exec" || normalized === "gateway_exec" || normalized === "node_exec" ? ["exec"] : normalized === "sandbox_process" || normalized === "gateway_process" ? ["exec", "process"] : [];
570
+ }
576
571
  });
577
572
  }
578
573
  /** Detects the wildcard allowlist marker after Codex tool-name normalization. */
@@ -1855,32 +1850,50 @@ async function readFile(execServer, params) {
1855
1850
  async function writeFile(execServer, params) {
1856
1851
  const record = requireObject(params, "fs/writeFile params");
1857
1852
  const filePath = resolveExecServerPath(requireString(record.path, "path"), "write path");
1853
+ const fsBridge = execServer.fsBridge;
1854
+ const canonicalDestination = await fsBridge.resolvePinnedMutationTarget?.({
1855
+ filePath,
1856
+ action: "write"
1857
+ });
1858
1858
  assertFsSandboxAccess(execServer, record, [{
1859
1859
  path: filePath,
1860
1860
  access: "write"
1861
- }]);
1862
- const fsBridge = execServer.fsBridge;
1861
+ }, ...canonicalDestination ? [{
1862
+ path: canonicalDestination.policyPath,
1863
+ access: "write"
1864
+ }] : []]);
1863
1865
  if ((await fsBridge.stat({ filePath: posix.dirname(filePath) }))?.type !== "directory") throw new JsonRpcProtocolError(JSON_RPC_NOT_FOUND, "parent directory not found");
1864
1866
  await fsBridge.writeFile({
1865
1867
  filePath,
1866
1868
  data: Buffer.from(requireBase64String(record.dataBase64, "dataBase64"), "base64"),
1867
- mkdir: false
1869
+ mkdir: false,
1870
+ pinnedPath: canonicalDestination?.pinnedPath
1868
1871
  });
1869
1872
  }
1870
1873
  /** Creates a sandbox directory, respecting recursive and parent-directory semantics. */
1871
1874
  async function createDirectory(execServer, params) {
1872
1875
  const record = requireObject(params, "fs/createDirectory params");
1873
1876
  const filePath = resolveExecServerPath(requireString(record.path, "path"), "create-directory path");
1877
+ const fsBridge = execServer.fsBridge;
1878
+ const canonicalDestination = await fsBridge.resolvePinnedMutationTarget?.({
1879
+ filePath,
1880
+ action: "mkdir"
1881
+ });
1874
1882
  assertFsSandboxAccess(execServer, record, [{
1875
1883
  path: filePath,
1876
1884
  access: "write"
1877
- }]);
1878
- const fsBridge = execServer.fsBridge;
1885
+ }, ...canonicalDestination ? [{
1886
+ path: canonicalDestination.policyPath,
1887
+ access: "write"
1888
+ }] : []]);
1879
1889
  if (record.recursive === false) {
1880
1890
  const parentPath = posix.dirname(filePath);
1881
1891
  if ((await fsBridge.stat({ filePath: parentPath }))?.type !== "directory") throw new JsonRpcProtocolError(JSON_RPC_NOT_FOUND, "parent directory not found");
1882
1892
  }
1883
- await fsBridge.mkdirp({ filePath });
1893
+ await fsBridge.mkdirp({
1894
+ filePath,
1895
+ pinnedPath: canonicalDestination?.pinnedPath
1896
+ });
1884
1897
  }
1885
1898
  /** Returns normalized metadata for a sandbox path. */
1886
1899
  async function getMetadata(execServer, params) {
@@ -1929,15 +1942,26 @@ async function removePath(execServer, params) {
1929
1942
  const record = requireObject(params, "fs/remove params");
1930
1943
  const filePath = resolveExecServerPath(requireString(record.path, "path"), "remove path");
1931
1944
  const fsSandboxPolicy = resolveFsSandboxPolicy(execServer, record);
1945
+ const canonicalDestination = await execServer.fsBridge.resolvePinnedMutationTarget?.({
1946
+ filePath,
1947
+ action: "remove"
1948
+ });
1932
1949
  assertResolvedFsSandboxAccess(fsSandboxPolicy, [{
1933
1950
  path: filePath,
1934
1951
  access: "write"
1935
- }]);
1936
- if (record.recursive !== false) assertNoReadOnlyDescendant(fsSandboxPolicy, filePath, "remove");
1952
+ }, ...canonicalDestination ? [{
1953
+ path: canonicalDestination.policyPath,
1954
+ access: "write"
1955
+ }] : []]);
1956
+ if (record.recursive !== false) {
1957
+ assertNoReadOnlyDescendant(fsSandboxPolicy, filePath, "remove");
1958
+ if (canonicalDestination) assertNoReadOnlyDescendant(fsSandboxPolicy, canonicalDestination.policyPath, "remove");
1959
+ }
1937
1960
  await execServer.fsBridge.remove({
1938
1961
  filePath,
1939
1962
  recursive: record.recursive !== false,
1940
- force: record.force !== false
1963
+ force: record.force !== false,
1964
+ pinnedPath: canonicalDestination?.pinnedPath
1941
1965
  });
1942
1966
  }
1943
1967
  /** Copies sandbox files or recursive directories while enforcing source and destination policy. */
@@ -1971,10 +1995,25 @@ async function copySandboxPath(execServer, params) {
1971
1995
  }]);
1972
1996
  const sourceStat = await fsBridge.stat({ filePath: params.sourcePath });
1973
1997
  if (!sourceStat) throw new JsonRpcProtocolError(JSON_RPC_NOT_FOUND, "file not found");
1974
- if (sourceStat?.type === "directory") {
1998
+ const canonicalDestination = await fsBridge.resolvePinnedMutationTarget?.({
1999
+ filePath: params.destinationPath,
2000
+ action: sourceStat.type === "directory" ? "mkdir" : "copy-destination"
2001
+ });
2002
+ const canonicalPolicyEntries = canonicalDestination ? [{
2003
+ path: canonicalDestination.policyPath,
2004
+ access: "write"
2005
+ }] : [];
2006
+ assertResolvedFsSandboxAccess(params.fsSandboxPolicy, canonicalPolicyEntries);
2007
+ if (sourceStat.type === "directory") {
1975
2008
  if (!params.recursive) throw new Error(`Cannot copy directory without recursive=true: ${params.sourcePath}`);
1976
- if (pathContains(normalizeSandboxAbsolutePath(params.sourcePath, "copy source path"), normalizeSandboxAbsolutePath(params.destinationPath, "copy destination path"))) throw new Error("Cannot recursively copy a directory into itself.");
1977
- await fsBridge.mkdirp({ filePath: params.destinationPath });
2009
+ if (pathContains(normalizeSandboxAbsolutePath((await fsBridge.resolvePinnedMutationTarget?.({
2010
+ filePath: params.sourcePath,
2011
+ action: "mkdir"
2012
+ }))?.policyPath ?? params.sourcePath, "copy source path"), normalizeSandboxAbsolutePath(canonicalDestination?.policyPath ?? params.destinationPath, "copy destination path"))) throw new Error("Cannot recursively copy a directory into itself.");
2013
+ await fsBridge.mkdirp({
2014
+ filePath: params.destinationPath,
2015
+ pinnedPath: canonicalDestination?.pinnedPath
2016
+ });
1978
2017
  for (const entry of await listDirectoryEntries(execServer, params.sourcePath, params.fsSandboxPolicy)) {
1979
2018
  if (!entry.isDirectory && !entry.isFile) throw new Error(`Cannot copy unsupported filesystem entry: ${entry.fileName}`);
1980
2019
  await copySandboxPath(execServer, {
@@ -1990,7 +2029,8 @@ async function copySandboxPath(execServer, params) {
1990
2029
  await fsBridge.copyFile({
1991
2030
  sourcePath: params.sourcePath,
1992
2031
  destinationPath: params.destinationPath,
1993
- mkdir: true
2032
+ mkdir: true,
2033
+ pinnedPath: canonicalDestination?.pinnedPath
1994
2034
  });
1995
2035
  return;
1996
2036
  }
@@ -2002,7 +2042,8 @@ async function copySandboxPath(execServer, params) {
2002
2042
  await fsBridge.writeFile({
2003
2043
  filePath: params.destinationPath,
2004
2044
  data,
2005
- mkdir: true
2045
+ mkdir: true,
2046
+ pinnedPath: canonicalDestination?.pinnedPath
2006
2047
  });
2007
2048
  }
2008
2049
  function assertSandboxFileReadWithinLimit(stat) {
@@ -4221,7 +4262,7 @@ function resolvePluginElicitation(params) {
4221
4262
  const appId = readFirstString$1(meta, PLUGIN_APP_ID_META_KEYS) ?? readFirstString$1(requestParams, PLUGIN_APP_ID_META_KEYS);
4222
4263
  const connectorId = readFirstString$1(meta, PLUGIN_CONNECTOR_ID_META_KEYS);
4223
4264
  const isCodexConnectorApproval = isCodexConnectorApprovalElicitation(requestParams, meta);
4224
- if (isCodexConnectorApproval && appId && connectorId && appId !== connectorId) return {
4265
+ if (isCodexConnectorApproval && appId && connectorId && codexAppIdentityKey(appId) !== codexAppIdentityKey(connectorId)) return {
4225
4266
  kind: "decline",
4226
4267
  reason: "app_id_connector_id_mismatch"
4227
4268
  };
@@ -4230,20 +4271,19 @@ function resolvePluginElicitation(params) {
4230
4271
  kind: "decline",
4231
4272
  reason: "missing_policy_context"
4232
4273
  };
4233
- const entry = context.apps[appId];
4234
- if (entry?.source === "account" && !isCodexConnectorApproval) return {
4274
+ const matches = Object.entries(context.apps).filter(([id]) => codexAppIdentityKey(id) === codexAppIdentityKey(appId)).map(([, entry]) => entry);
4275
+ if (matches.some((entry) => entry.source === "account") && !isCodexConnectorApproval) return {
4235
4276
  kind: "decline",
4236
4277
  reason: "account_app_source_mismatch"
4237
4278
  };
4238
- return uniquePluginMatch(entry ? [entry] : [], "app_id");
4279
+ return uniquePluginMatch(matches, "app_id");
4239
4280
  }
4240
4281
  if (isCodexConnectorApproval && connectorId) {
4241
4282
  if (!context) return {
4242
4283
  kind: "decline",
4243
4284
  reason: "missing_policy_context"
4244
4285
  };
4245
- const entry = context.apps[connectorId];
4246
- return uniquePluginMatch(entry ? [entry] : [], "connector_id");
4286
+ return uniquePluginMatch(Object.entries(context.apps).filter(([id]) => codexAppIdentityKey(id) === codexAppIdentityKey(connectorId)).map(([, entry]) => entry), "connector_id");
4247
4287
  }
4248
4288
  const serverName = readNonBlankStringField(requestParams, "serverName");
4249
4289
  if (serverName && context) {
@@ -5142,6 +5182,11 @@ function createCodexDynamicToolBridge(params) {
5142
5182
  const registrationNames = inheritedNames ?? new Set(registeredProjection.tools.map((entry) => entry.name));
5143
5183
  const finalized = finalizeCodexToolAvailability(availableProjection.tools.filter((entry) => registrationNames.has(entry.name)));
5144
5184
  const availableTools = finalized.tools;
5185
+ const pluginLocalMediaTrustByToolName = /* @__PURE__ */ new Map();
5186
+ for (const { name, tool } of availableTools) {
5187
+ const pluginMeta = getPluginToolMeta(tool);
5188
+ if (pluginMeta) pluginLocalMediaTrustByToolName.set(name, new Set(pluginMeta.trustedLocalMedia === true ? [name] : []));
5189
+ }
5145
5190
  availableProjection.quarantinedTools.push(...finalized.quarantinedTools);
5146
5191
  const toolMap = new Map(availableTools.map((entry) => [entry.name, entry]));
5147
5192
  const quarantinedAvailableToolNames = new Set(availableProjection.quarantinedTools.map((tool) => tool.tool));
@@ -5399,7 +5444,8 @@ function createCodexDynamicToolBridge(params) {
5399
5444
  autoDeliveryTtsMediaUrls,
5400
5445
  coreTtsToolResult: autoDeliveryTtsMediaUrls?.length ? rawResult : void 0,
5401
5446
  messagingTarget: confirmedMessagingTarget,
5402
- sourceReplyFinal
5447
+ sourceReplyFinal,
5448
+ trustedLocalMediaToolNames: pluginLocalMediaTrustByToolName.get(toolName)
5403
5449
  });
5404
5450
  if (deliveredSourceReply || receiptConfirmedSourceReply || toolConfirmedSourceReply) telemetry.didDeliverSourceReplyViaMessageTool = true;
5405
5451
  const continuesSourceReplyProgress = confirmedSourceReply && sourceReplyFinal === false;
@@ -5573,7 +5619,7 @@ function collectToolTelemetry(params) {
5573
5619
  if (params.result && !params.signal.aborted) {
5574
5620
  const media = extractToolResultMediaArtifact(params.result);
5575
5621
  if (media) {
5576
- const mediaUrls = filterToolResultMediaUrls(params.toolName, media.mediaUrls, params.mediaTrustResult ?? params.result);
5622
+ const mediaUrls = filterToolResultMediaUrls(params.toolName, media.mediaUrls, params.coreTtsToolResult ?? params.mediaTrustResult ?? params.result, params.trustedLocalMediaToolNames);
5577
5623
  const seen = new Set(params.telemetry.toolMediaUrls);
5578
5624
  const autoDeliveryMediaUrls = new Set(params.telemetry.toolAutoDeliveryMediaUrls);
5579
5625
  const rawAutoDeliveryMediaUrls = new Set(params.autoDeliveryTtsMediaUrls);
@@ -1,6 +1,6 @@
1
- import { l as sessionBindingIdentity } from "./session-binding-record-Bcvslnhf.js";
2
- import { _ as retainSharedCodexAppServerClientByInstanceId } from "./shared-client-CscigXXL.js";
3
- import "./session-binding-CI8UuilT.js";
1
+ import { p as sessionBindingIdentity } from "./session-binding-record-TH3xA0zj.mjs";
2
+ import { _ as retainSharedCodexAppServerClientByInstanceId } from "./shared-client-BpTtuLQ5.mjs";
3
+ import "./session-binding-_0W_fHRr.mjs";
4
4
  import { asOptionalRecord, normalizeOptionalString } from "openclaw/plugin-sdk/string-coerce-runtime";
5
5
  import { assignMcpCatalogSafeServerNames } from "openclaw/plugin-sdk/agent-harness-runtime";
6
6
  //#region extensions/codex/src/app-server/effective-mcp-catalog.ts
@@ -1,8 +1,7 @@
1
- import { o as isJsonObject } from "./protocol-5bh1G-H7.js";
2
- import { T as readCodexTurnCompletedNotification } from "./client-B57KWPQx.js";
3
- import { p as getCodexAppServerTurnRouter } from "./attempt-client-cleanup-DKHzbwt5.js";
4
- import { o as isTerminalTurnStatus, s as readCodexNotificationItem } from "./attempt-notifications-C9XufG6l.js";
5
- import { t as CodexUsageProjection } from "./event-projector-usage-BfXmpOec.js";
1
+ import { m as isJsonObject } from "./config-security-BRQ2mgW9.mjs";
2
+ import { T as readCodexTurnCompletedNotification } from "./client-vXs2929Q.mjs";
3
+ import { m as getCodexAppServerTurnRouter } from "./attempt-client-cleanup-BpYKdTA0.mjs";
4
+ import { c as readCodexNotificationItem, s as isTerminalTurnStatus, t as CodexUsageProjection } from "./event-projector-usage-C7Ntzs-f.mjs";
6
5
  import { readStringField } from "openclaw/plugin-sdk/string-coerce-runtime";
7
6
  import { toStringifiedError } from "openclaw/plugin-sdk/error-runtime";
8
7
  import { createDeferred } from "openclaw/plugin-sdk/extension-shared";
@@ -1,4 +1,4 @@
1
- import { t as resolveCodexLocalRuntimeAttribution } from "./local-runtime-attribution-B_2mnqhb.js";
1
+ import { t as resolveCodexLocalRuntimeAttribution } from "./local-runtime-attribution-B_2mnqhb.mjs";
2
2
  import { formatErrorMessage } from "openclaw/plugin-sdk/agent-harness-runtime";
3
3
  //#region extensions/codex/src/app-server/event-projector-assistant-message.ts
4
4
  const ZERO_USAGE = {
@@ -70,13 +70,16 @@ function createAssistantCommentaryMessage(params, text, itemId, timestamp) {
70
70
  }
71
71
  };
72
72
  }
73
- function createAssistantAsyncMessage(params, text, itemId, timestamp) {
73
+ function createAssistantAsyncMessage(params, text, itemId, timestamp, questions) {
74
74
  return {
75
75
  ...createNonterminalAssistantMessage(params, [{
76
76
  type: "text",
77
77
  text
78
78
  }], timestamp),
79
- openclawAsyncDelivery: { itemId }
79
+ openclawAsyncDelivery: {
80
+ itemId,
81
+ ...questions ? { questions } : {}
82
+ }
80
83
  };
81
84
  }
82
85
  function createAssistantReasoningMessage(params, text) {
@@ -1,4 +1,4 @@
1
- import { o as isJsonObject } from "./protocol-5bh1G-H7.js";
1
+ import { m as isJsonObject } from "./config-security-BRQ2mgW9.mjs";
2
2
  import { asFiniteNumber, normalizeOptionalString as normalizeOptionalString$1, readStringField } from "openclaw/plugin-sdk/string-coerce-runtime";
3
3
  //#region extensions/codex/src/app-server/event-projector-values.ts
4
4
  const BIO_POLICY_SAFETY_ACCESS_BLOCK_PREFIX = "This content was flagged for possible biological risk.";