@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,15 +1,32 @@
1
- import { i as readUpstreamUserText, n as attachUpstreamUserText, r as readMirrorIdentity, t as attachCodexMirrorIdentity } from "./upstream-prompt-provenance-CFmsKwr9.js";
2
- import { asOptionalRecord, normalizeOptionalString } from "openclaw/plugin-sdk/string-coerce-runtime";
3
- import { deliverAgentHarnessUserInputPrompt, embeddedAgentLog, formatErrorMessage, projectAgentHarnessTranscriptMessageForDisplay, runAgentHarnessBeforeMessageWriteHook } from "openclaw/plugin-sdk/agent-harness-runtime";
1
+ import { i as readUpstreamUserText, n as attachUpstreamUserText, r as readMirrorIdentity, t as attachCodexMirrorIdentity } from "./upstream-prompt-provenance-LphB8slG.js";
2
+ import { i as fingerprintCodexMirrorSourceMessage, n as attachCodexMirrorAttestation, o as readCodexMirrorSourceFingerprint, r as attachCodexMirrorRunId } from "./transcript-mirror-attestation-Byl34PC-.js";
3
+ import { normalizeOptionalString } from "openclaw/plugin-sdk/string-coerce-runtime";
4
4
  import { createHash } from "node:crypto";
5
+ import path from "node:path";
6
+ import { deliverAgentHarnessUserInputPrompt, embeddedAgentLog, formatErrorMessage, projectAgentHarnessTranscriptMessageForDisplay, restorePreparedUserTurnOperationalMetaForRuntime, runAgentHarnessBeforeMessageWriteHook } from "openclaw/plugin-sdk/agent-harness-runtime";
7
+ import fsSync from "node:fs";
5
8
  import { truncateUtf8Prefix } from "openclaw/plugin-sdk/text-utility-runtime";
6
9
  import { withCodexSessionTranscriptMirrorWriteLock } from "openclaw/plugin-sdk/codex-session-transcript-runtime";
7
10
  import { publishSessionTranscriptUpdateByIdentity } from "openclaw/plugin-sdk/session-transcript-runtime";
8
11
  import { Buffer } from "node:buffer";
12
+ //#region extensions/codex/src/session-catalog-home-id.ts
13
+ function canonicalCodexCatalogHome(value) {
14
+ const resolved = path.resolve(value);
15
+ try {
16
+ return fsSync.realpathSync.native(resolved);
17
+ } catch {
18
+ return resolved;
19
+ }
20
+ }
21
+ /** One canonical identity for catalog discovery and durable ownership rows. */
22
+ function codexCatalogHomeId(codexHome) {
23
+ return createHash("sha256").update("openclaw:codex-session-catalog-home:v1\0").update(canonicalCodexCatalogHome(codexHome)).digest("hex");
24
+ }
25
+ //#endregion
9
26
  //#region extensions/codex/src/app-server/transcript-history-projection.ts
10
27
  const CODEX_HISTORY_IMPORT_MAX_MESSAGES = 200;
11
- const CODEX_HISTORY_IMPORT_MAX_BYTES = 512 * 1024;
12
- const CODEX_HISTORY_IMPORT_MAX_MESSAGE_BYTES = 64 * 1024;
28
+ const CODEX_HISTORY_IMPORT_MAX_BYTES = 524288;
29
+ const CODEX_HISTORY_IMPORT_MAX_MESSAGE_BYTES = 65536;
13
30
  const CODEX_HISTORY_TRUNCATION_SUFFIX = "\n\n[Message truncated during Codex history import.]";
14
31
  const CODEX_HISTORY_ASSISTANT_API = "openai-chatgpt-responses";
15
32
  const CODEX_HISTORY_ASSISTANT_PROVIDER = "openai";
@@ -34,7 +51,8 @@ function normalizeImportedHistoryText(value) {
34
51
  if (!text) return;
35
52
  if (Buffer.byteLength(text, "utf8") <= CODEX_HISTORY_IMPORT_MAX_MESSAGE_BYTES) return text;
36
53
  const suffixBytes = Buffer.byteLength(CODEX_HISTORY_TRUNCATION_SUFFIX, "utf8");
37
- return `${truncateUtf8Prefix(text, Math.max(0, CODEX_HISTORY_IMPORT_MAX_MESSAGE_BYTES - suffixBytes))}${CODEX_HISTORY_TRUNCATION_SUFFIX}`;
54
+ const contentLimitBytes = Math.max(0, CODEX_HISTORY_IMPORT_MAX_MESSAGE_BYTES - suffixBytes);
55
+ return `${truncateUtf8Prefix(text, contentLimitBytes)}${CODEX_HISTORY_TRUNCATION_SUFFIX}`;
38
56
  }
39
57
  function projectCodexUserItemText(item) {
40
58
  if (!Array.isArray(item.content)) return;
@@ -173,57 +191,6 @@ function projectBoundedCodexVisibleSessionHistory(entries) {
173
191
  return selectBoundedCodexHistoryTail(projected).map(({ responseItem }) => responseItem);
174
192
  }
175
193
  //#endregion
176
- //#region extensions/codex/src/app-server/transcript-mirror-attestation.ts
177
- const MIRROR_ORIGIN_META_KEY = "mirrorOrigin";
178
- const MIRROR_SOURCE_FINGERPRINT_META_KEY = "mirrorSourceFingerprint";
179
- const CODEX_APP_SERVER_MIRROR_ORIGIN = "codex-app-server";
180
- const CODEX_META_KEY = "__openclaw";
181
- function attachCodexMirrorAttestation(message, sourceFingerprint) {
182
- const existing = CODEX_META_KEY in message ? message[CODEX_META_KEY] : void 0;
183
- const baseMeta = existing && typeof existing === "object" && !Array.isArray(existing) ? existing : {};
184
- return {
185
- ...message,
186
- [CODEX_META_KEY]: {
187
- ...baseMeta,
188
- [MIRROR_ORIGIN_META_KEY]: CODEX_APP_SERVER_MIRROR_ORIGIN,
189
- ...sourceFingerprint ? { [MIRROR_SOURCE_FINGERPRINT_META_KEY]: sourceFingerprint } : {}
190
- }
191
- };
192
- }
193
- function attachCodexMirrorRunId(message, runId, terminal = false) {
194
- const { runTerminal: _staleTerminal, ...current } = asOptionalRecord(CODEX_META_KEY in message ? message[CODEX_META_KEY] : void 0) ?? {};
195
- return {
196
- ...message,
197
- [CODEX_META_KEY]: {
198
- ...current,
199
- runId,
200
- ...terminal ? { runTerminal: true } : {}
201
- }
202
- };
203
- }
204
- function readCodexMirrorSourceFingerprint(message) {
205
- const meta = CODEX_META_KEY in message ? message[CODEX_META_KEY] : void 0;
206
- if (!meta || typeof meta !== "object" || Array.isArray(meta)) return;
207
- const value = meta[MIRROR_SOURCE_FINGERPRINT_META_KEY];
208
- return typeof value === "string" && value ? value : void 0;
209
- }
210
- function serializeCodexMirrorSourceEvidence(message) {
211
- const content = "content" in message ? message.content : void 0;
212
- return JSON.stringify({
213
- role: message.role,
214
- content,
215
- ...message.role === "user" ? { upstreamUserText: readUpstreamUserText(message) } : {},
216
- ...message.role === "toolResult" ? {
217
- toolCallId: message.toolCallId,
218
- toolName: message.toolName,
219
- isError: message.isError
220
- } : {}
221
- });
222
- }
223
- function fingerprintCodexMirrorSourceMessage(message) {
224
- return createHash("sha256").update(serializeCodexMirrorSourceEvidence(message)).digest("hex").slice(0, 32);
225
- }
226
- //#endregion
227
194
  //#region extensions/codex/src/app-server/user-prompt-message.ts
228
195
  function buildSenderLabel(params) {
229
196
  const label = params.senderName ?? params.senderUsername ?? params.senderE164 ?? params.senderId;
@@ -268,6 +235,18 @@ function promptSnapshot(params, turnId, upstreamUserText) {
268
235
  async function buildResolvedCodexUserPromptMessage(params) {
269
236
  return buildFromPrepared(params, await params.userTurnTranscriptRecorder?.resolveMessage() ?? params.userTurnTranscriptRecorder?.message);
270
237
  }
238
+ async function resolveFinalCodexMirrorMessages(params) {
239
+ if (params.params.suppressNextUserMessagePersistence || !params.params.userTurnTranscriptRecorder) return params.messagesSnapshot;
240
+ const previousPrompt = params.messagesSnapshot.find((message) => message.role === "user");
241
+ const resolvedBase = attachCodexMirrorIdentity(await buildResolvedCodexUserPromptMessage(params.params), `${params.turnId}:prompt`);
242
+ const upstreamUserText = readUpstreamUserText(previousPrompt);
243
+ const resolvedPrompt = upstreamUserText ? attachUpstreamUserText(resolvedBase, upstreamUserText) : resolvedBase;
244
+ const firstUserIndex = params.messagesSnapshot.findIndex((message) => message.role === "user");
245
+ if (firstUserIndex === -1) return [resolvedPrompt, ...params.messagesSnapshot];
246
+ const messages = params.messagesSnapshot.slice();
247
+ messages[firstUserIndex] = resolvedPrompt;
248
+ return messages;
249
+ }
271
250
  //#endregion
272
251
  //#region extensions/codex/src/app-server/transcript-mirror.ts
273
252
  function isMirroredAgentMessage(message) {
@@ -279,25 +258,26 @@ function readMirroredAssistantText(message) {
279
258
  }
280
259
  /** Imports a bounded, user-visible Codex history tail into a new OpenClaw transcript. */
281
260
  async function importCodexThreadHistoryToTranscript(params) {
282
- const projection = projectBoundedCodexThreadHistory({
261
+ const { transcriptMessages, importedMessages, omittedMessages } = projectBoundedCodexThreadHistory({
283
262
  thread: params.thread,
284
263
  throughTurnId: params.throughTurnId,
285
264
  importedAt: Date.now(),
286
265
  ...params.modelProvider ? { modelProvider: params.modelProvider } : {}
287
266
  });
288
- if (projection.transcriptMessages.length > 0) await mirror({
267
+ if (transcriptMessages.length > 0) await mirror({
268
+ assertCurrent: params.assertCurrent,
289
269
  storePath: params.storePath,
290
270
  sessionId: params.sessionId,
291
271
  sessionKey: params.sessionKey,
292
272
  ...params.agentId ? { agentId: params.agentId } : {},
293
273
  ...params.cwd ? { cwd: params.cwd } : {},
294
274
  ...params.config ? { config: params.config } : {},
295
- messages: projection.transcriptMessages,
275
+ messages: transcriptMessages,
296
276
  idempotencyScope: `codex-app-server:${params.thread.id}:history`
297
277
  });
298
278
  return {
299
- importedMessages: projection.importedMessages,
300
- omittedMessages: projection.omittedMessages
279
+ importedMessages,
280
+ omittedMessages
301
281
  };
302
282
  }
303
283
  async function mirrorBestEffort(params) {
@@ -311,7 +291,9 @@ async function mirrorBestEffort(params) {
311
291
  messagesSnapshot: params.result.messagesSnapshot,
312
292
  turnId: params.turnId
313
293
  });
294
+ params.assertWriteCurrent?.();
314
295
  const mirrorResult = await mirror({
296
+ assertWriteCurrent: params.assertWriteCurrent,
315
297
  agentId: params.agentId,
316
298
  sessionKey: params.sessionKey,
317
299
  sessionId: params.params.sessionId,
@@ -325,10 +307,11 @@ async function mirrorBestEffort(params) {
325
307
  mirrorIdentity: `${params.turnId}:assistant`,
326
308
  runId: params.params.runId
327
309
  },
310
+ prepareAssistantTranscriptMessage: params.params.prepareAssistantTranscriptMessage,
328
311
  config: params.params.config
329
312
  });
330
313
  for (const receipt of mirrorResult.userMessageReceipts) try {
331
- params.notifyUserMessagePersisted(receipt.message, receipt.anchor);
314
+ params.notifyUserMessagePersisted(receipt);
332
315
  } catch (error) {
333
316
  embeddedAgentLog.warn("failed to notify codex app-server user-message persistence", { error: formatErrorMessage(error) });
334
317
  }
@@ -366,26 +349,14 @@ async function mirrorBestEffort(params) {
366
349
  };
367
350
  }
368
351
  }
369
- async function resolveFinalCodexMirrorMessages(params) {
370
- if (params.params.suppressNextUserMessagePersistence || !params.params.userTurnTranscriptRecorder) return params.messagesSnapshot;
371
- const promptSnapshot = params.messagesSnapshot.find((message) => message.role === "user");
372
- const resolvedBase = attachCodexMirrorIdentity(await buildResolvedCodexUserPromptMessage(params.params), `${params.turnId}:prompt`);
373
- const upstreamUserText = readUpstreamUserText(promptSnapshot);
374
- const resolvedPrompt = upstreamUserText ? attachUpstreamUserText(resolvedBase, upstreamUserText) : resolvedBase;
375
- const firstUserIndex = params.messagesSnapshot.findIndex((message) => message.role === "user");
376
- if (firstUserIndex === -1) return [resolvedPrompt, ...params.messagesSnapshot];
377
- const messages = params.messagesSnapshot.slice();
378
- messages[firstUserIndex] = resolvedPrompt;
379
- return messages;
380
- }
381
352
  function createCodexAppServerUserMessagePersistenceNotifier(runParams) {
382
353
  let notified = false;
383
- return (message, anchor) => {
354
+ return (receipt) => {
384
355
  if (notified) return;
385
356
  notified = true;
386
- runParams.userTurnTranscriptRecorder?.markRuntimePersisted(message, anchor);
357
+ runParams.userTurnTranscriptRecorder?.markRuntimePersisted(receipt.message, receipt.anchor, receipt);
387
358
  try {
388
- runParams.onUserMessagePersisted?.(message);
359
+ runParams.onUserMessagePersisted?.(receipt.message);
389
360
  } catch (error) {
390
361
  embeddedAgentLog.warn("codex app-server user persistence notification failed", { error: formatErrorMessage(error) });
391
362
  }
@@ -399,7 +370,19 @@ async function mirrorPromptAtTurnStartBestEffort(params) {
399
370
  hidden: params.params.trigger === "memory",
400
371
  message: attachUpstreamUserText(attachCodexMirrorIdentity(await buildResolvedCodexUserPromptMessage(params.params), `${params.turnId}:prompt`), params.upstreamUserText)
401
372
  });
373
+ const recorder = params.params.userTurnTranscriptRecorder;
374
+ if (recorder?.getAdmissionReceipt() && recorder.getPersistedMessage?.()?.display !== false) {
375
+ const annotate = params.params.hostCapabilities.annotateCurrentUserTurn;
376
+ if (!annotate || userPromptMessage.role !== "user") throw new Error("current host admission is unavailable for native prompt annotation");
377
+ await annotate({
378
+ mirrorIdentity: `${params.turnId}:prompt`,
379
+ upstreamUserText: params.upstreamUserText,
380
+ mirrorOrigin: "codex-app-server",
381
+ mirrorSourceFingerprint: fingerprintCodexMirrorSourceMessage(userPromptMessage)
382
+ });
383
+ }
402
384
  const mirrorResult = await mirror({
385
+ assertCurrent: params.params.hostCapabilities.assertActive,
403
386
  agentId: params.agentId,
404
387
  sessionKey: params.sessionKey,
405
388
  sessionId: params.params.sessionId,
@@ -411,7 +394,7 @@ async function mirrorPromptAtTurnStartBestEffort(params) {
411
394
  runMirrorIdentityPrefix: `${params.turnId}:`,
412
395
  config: params.params.config
413
396
  });
414
- for (const receipt of mirrorResult.userMessageReceipts) params.notifyUserMessagePersisted(receipt.message, receipt.anchor);
397
+ for (const receipt of mirrorResult.userMessageReceipts) params.notifyUserMessagePersisted(receipt);
415
398
  })();
416
399
  params.params.userTurnTranscriptRecorder?.markRuntimePersistencePending(mirrorPromise);
417
400
  await mirrorPromise;
@@ -431,9 +414,7 @@ function fingerprintMirrorMessageContent(message) {
431
414
  return createHash("sha256").update(payload).digest("hex").slice(0, 16);
432
415
  }
433
416
  function buildMirrorDedupeIdentity(message) {
434
- const explicit = readMirrorIdentity(message);
435
- if (explicit) return explicit;
436
- return `${message.role}:${fingerprintMirrorMessageContent(message)}`;
417
+ return readMirrorIdentity(message) || `${message.role}:${fingerprintMirrorMessageContent(message)}`;
437
418
  }
438
419
  async function mirror(params) {
439
420
  const messages = params.messages.filter(isMirroredAgentMessage);
@@ -442,8 +423,7 @@ async function mirror(params) {
442
423
  assistantMirrorIdentitiesOwned: [],
443
424
  anchorsByMirrorIdentity: /* @__PURE__ */ new Map(),
444
425
  messagesPresent: [],
445
- userMessageReceipts: [],
446
- userMessagesPresent: []
426
+ userMessageReceipts: []
447
427
  };
448
428
  const candidates = messages.map((message) => {
449
429
  const dedupeIdentity = buildMirrorDedupeIdentity(message);
@@ -457,25 +437,32 @@ async function mirror(params) {
457
437
  });
458
438
  const candidateIdempotencyKeys = candidates.flatMap(({ idempotencyKey }) => idempotencyKey ? [idempotencyKey] : []);
459
439
  const transcriptTarget = resolveCodexMirrorTranscriptTarget(params);
460
- const { appendedUpdates, assistantMirrorIdentitiesAppended, assistantMirrorIdentitiesOwned, anchorsByMirrorIdentity, messagesPresent, userMessageReceipts, userMessagesPresent } = await withCodexSessionTranscriptMirrorWriteLock({
440
+ const assertWritable = () => {
441
+ params.assertCurrent?.();
442
+ params.assertWriteCurrent?.();
443
+ };
444
+ assertWritable();
445
+ const mirrorBatch = await withCodexSessionTranscriptMirrorWriteLock({
461
446
  ...transcriptTarget,
462
447
  config: params.config
463
448
  }, async (transcript) => {
449
+ assertWritable();
464
450
  const nextAppendedUpdates = [];
465
451
  const nextAssistantMirrorIdentitiesAppended = /* @__PURE__ */ new Set();
466
452
  const nextAssistantMirrorIdentitiesOwned = /* @__PURE__ */ new Set();
467
453
  const nextAnchorsByMirrorIdentity = /* @__PURE__ */ new Map();
468
454
  const nextMessagesPresent = [];
469
455
  const nextUserMessageReceipts = [];
470
- const nextUserMessagesPresent = [];
471
456
  const mirrorFacts = await transcript.readMessageFacts({ idempotencyKeys: candidateIdempotencyKeys });
457
+ assertWritable();
472
458
  for (const { dedupeIdentity, idempotencyKey, message, sourceFingerprint } of candidates) {
473
459
  const mirrorIdentity = readMirrorIdentity(message);
474
460
  const ownsRun = Boolean(params.runId && (!params.runMirrorIdentityPrefix || mirrorIdentity?.startsWith(params.runMirrorIdentityPrefix)));
475
461
  const terminalOwner = params.terminalAssistantOwner;
476
462
  const ownsTerminal = Boolean(ownsRun && terminalOwner && mirrorIdentity === terminalOwner.mirrorIdentity);
463
+ const ownedMessage = ownsRun && params.runId ? attachCodexMirrorRunId(message, params.runId, ownsTerminal) : message;
477
464
  const transcriptMessage = {
478
- ...attachCodexMirrorAttestation(ownsRun && params.runId ? attachCodexMirrorRunId(message, params.runId, ownsTerminal) : message, sourceFingerprint),
465
+ ...attachCodexMirrorAttestation(ownedMessage, sourceFingerprint),
479
466
  ...idempotencyKey ? { idempotencyKey } : {}
480
467
  };
481
468
  if (idempotencyKey && mirrorFacts.existingIdempotencyKeys.has(idempotencyKey)) {
@@ -483,31 +470,44 @@ async function mirror(params) {
483
470
  const persistedAnchor = mirrorFacts.anchorsByIdempotencyKey.get(idempotencyKey);
484
471
  if (persistedMessage && isMirroredAgentMessage(persistedMessage)) {
485
472
  nextMessagesPresent.push(persistedMessage);
486
- if (persistedMessage.role === "user") {
487
- nextUserMessagesPresent.push(persistedMessage);
488
- if (persistedAnchor) nextUserMessageReceipts.push({
489
- anchor: persistedAnchor,
490
- message: persistedMessage
491
- });
492
- }
473
+ if (persistedMessage.role === "user" && persistedAnchor) nextUserMessageReceipts.push({
474
+ anchor: persistedAnchor,
475
+ appended: false,
476
+ message: persistedMessage
477
+ });
493
478
  }
494
479
  if (persistedAnchor) nextAnchorsByMirrorIdentity.set(dedupeIdentity, persistedAnchor);
495
480
  if (message.role === "assistant") nextAssistantMirrorIdentitiesOwned.add(dedupeIdentity);
496
481
  continue;
497
482
  }
498
- const nextMessage = params.skipBeforeMessageWriteHooks ? transcriptMessage : runAgentHarnessBeforeMessageWriteHook({
483
+ assertWritable();
484
+ const preparedUserMessage = transcriptMessage.role === "user" ? {
485
+ ...transcriptMessage,
486
+ __openclaw: { ...Reflect.get(transcriptMessage, "__openclaw") }
487
+ } : void 0;
488
+ if (preparedUserMessage?.["__openclaw"].humanMentions !== void 0) {
489
+ preparedUserMessage.content = structuredClone(preparedUserMessage.content);
490
+ preparedUserMessage["__openclaw"].humanMentions = structuredClone(preparedUserMessage["__openclaw"].humanMentions);
491
+ }
492
+ const nextMessage = runAgentHarnessBeforeMessageWriteHook({
499
493
  message: transcriptMessage,
500
494
  agentId: params.agentId,
501
- sessionKey: params.sessionKey
495
+ sessionKey: params.sessionKey,
496
+ skipBeforeMessageWriteHooks: params.skipBeforeMessageWriteHooks,
497
+ prepareAssistantTranscriptMessage: ownsTerminal ? params.prepareAssistantTranscriptMessage : void 0
502
498
  });
503
499
  if (!nextMessage) {
504
500
  if (message.role === "assistant") nextAssistantMirrorIdentitiesOwned.add(dedupeIdentity);
505
501
  continue;
506
502
  }
503
+ const restoredMessage = restorePreparedUserTurnOperationalMetaForRuntime({
504
+ runtimeMessage: nextMessage,
505
+ preparedMessage: preparedUserMessage
506
+ });
507
507
  let messageToAppend = idempotencyKey ? {
508
- ...attachCodexMirrorAttestation(nextMessage, sourceFingerprint),
508
+ ...attachCodexMirrorAttestation(restoredMessage, sourceFingerprint),
509
509
  idempotencyKey
510
- } : attachCodexMirrorAttestation(nextMessage, sourceFingerprint);
510
+ } : attachCodexMirrorAttestation(restoredMessage, sourceFingerprint);
511
511
  if (mirrorIdentity) messageToAppend = attachCodexMirrorIdentity(messageToAppend, mirrorIdentity);
512
512
  if (ownsRun && params.runId) messageToAppend = attachCodexMirrorRunId(messageToAppend, params.runId, ownsTerminal);
513
513
  if (message.role === "assistant" && message.openclawAsyncDelivery) messageToAppend = Object.assign(messageToAppend, { openclawAsyncDelivery: { itemId: message.openclawAsyncDelivery.itemId } });
@@ -515,11 +515,17 @@ async function mirror(params) {
515
515
  hidden: message.display === false,
516
516
  message: messageToAppend
517
517
  });
518
+ assertWritable();
518
519
  const { messageSeq, result: appended } = await transcript.appendMessageWithMessageSequence({
519
520
  message: messageToAppend,
521
+ ...params.assertCurrent || params.assertWriteCurrent ? { prepareMessageAfterIdempotencyCheck: (preparedMessage) => {
522
+ assertWritable();
523
+ return preparedMessage;
524
+ } } : {},
520
525
  idempotencyLookup: "scan",
521
526
  cwd: params.cwd
522
527
  });
528
+ params.assertCurrent?.();
523
529
  if (!appended) continue;
524
530
  const { messageId, message: appendedMessage } = appended;
525
531
  if (isMirroredAgentMessage(appendedMessage)) {
@@ -528,13 +534,11 @@ async function mirror(params) {
528
534
  }
529
535
  if (message.role === "assistant") nextAssistantMirrorIdentitiesOwned.add(dedupeIdentity);
530
536
  if (appended.anchor) nextAnchorsByMirrorIdentity.set(dedupeIdentity, appended.anchor);
531
- if (appendedMessage.role === "user" && appended.anchor) {
532
- nextUserMessagesPresent.push(appendedMessage);
533
- nextUserMessageReceipts.push({
534
- anchor: appended.anchor,
535
- message: appendedMessage
536
- });
537
- }
537
+ if (appendedMessage.role === "user" && appended.anchor) nextUserMessageReceipts.push({
538
+ anchor: appended.anchor,
539
+ appended: appended.appended,
540
+ message: appendedMessage
541
+ });
538
542
  if (appended.appended) {
539
543
  if (message.role === "assistant") nextAssistantMirrorIdentitiesAppended.add(dedupeIdentity);
540
544
  nextAppendedUpdates.push({
@@ -554,10 +558,11 @@ async function mirror(params) {
554
558
  assistantMirrorIdentitiesOwned: [...nextAssistantMirrorIdentitiesOwned],
555
559
  anchorsByMirrorIdentity: nextAnchorsByMirrorIdentity,
556
560
  messagesPresent: nextMessagesPresent,
557
- userMessageReceipts: nextUserMessageReceipts,
558
- userMessagesPresent: nextUserMessagesPresent
561
+ userMessageReceipts: nextUserMessageReceipts
559
562
  };
560
563
  });
564
+ params.assertCurrent?.();
565
+ const { appendedUpdates, assistantMirrorIdentitiesAppended, assistantMirrorIdentitiesOwned, anchorsByMirrorIdentity, messagesPresent, userMessageReceipts } = mirrorBatch;
561
566
  for (const update of appendedUpdates) try {
562
567
  const terminalOwner = params.terminalAssistantOwner;
563
568
  const terminalRunId = update.message.role === "assistant" && terminalOwner && readMirrorIdentity(update.message) === terminalOwner.mirrorIdentity ? terminalOwner.runId : void 0;
@@ -580,8 +585,7 @@ async function mirror(params) {
580
585
  assistantMirrorIdentitiesOwned,
581
586
  anchorsByMirrorIdentity,
582
587
  messagesPresent,
583
- userMessageReceipts,
584
- userMessagesPresent
588
+ userMessageReceipts
585
589
  };
586
590
  }
587
591
  async function deliverAsyncMessageBestEffort(params) {
@@ -666,4 +670,4 @@ function resolveCodexMirrorTranscriptTarget(params) {
666
670
  };
667
671
  }
668
672
  //#endregion
669
- export { buildCodexUserPromptMessage as a, readCodexMirrorSourceFingerprint as c, projectBoundedCodexVisibleSessionHistory as d, mirrorPromptAtTurnStartBestEffort as i, serializeCodexMirrorSourceEvidence as l, createCodexAppServerUserMessagePersistenceNotifier as n, promptSnapshot as o, importCodexThreadHistoryToTranscript as r, fingerprintCodexMirrorSourceMessage as s, codexTranscriptMirrorRuntime as t, projectBoundedCodexThreadHistory as u };
673
+ export { buildCodexUserPromptMessage as a, projectBoundedCodexVisibleSessionHistory as c, codexCatalogHomeId as d, mirrorPromptAtTurnStartBestEffort as i, projectCodexUserItemText as l, createCodexAppServerUserMessagePersistenceNotifier as n, promptSnapshot as o, importCodexThreadHistoryToTranscript as r, projectBoundedCodexThreadHistory as s, codexTranscriptMirrorRuntime as t, canonicalCodexCatalogHome as u };
@@ -0,0 +1,76 @@
1
+ import { i as readUpstreamUserText } from "./upstream-prompt-provenance-LphB8slG.js";
2
+ import { asOptionalRecord } from "openclaw/plugin-sdk/string-coerce-runtime";
3
+ import { createHash } from "node:crypto";
4
+ //#region extensions/codex/src/app-server/transcript-mirror-attestation.ts
5
+ const MIRROR_ORIGIN_META_KEY = "mirrorOrigin";
6
+ const MIRROR_SOURCE_FINGERPRINT_META_KEY = "mirrorSourceFingerprint";
7
+ const CODEX_APP_SERVER_MIRROR_ORIGIN = "codex-app-server";
8
+ const CODEX_META_KEY = "__openclaw";
9
+ function applyCodexTranscriptTaint(message, state) {
10
+ if (message.role === "user") {
11
+ state.tainted = false;
12
+ return message;
13
+ }
14
+ const existing = CODEX_META_KEY in message ? message[CODEX_META_KEY] : void 0;
15
+ const metadata = asOptionalRecord(existing);
16
+ state.tainted ||= metadata?.turnTainted === true || metadata?.resultContentSource === "network";
17
+ return message.role === "assistant" && state.tainted ? {
18
+ ...message,
19
+ __openclaw: {
20
+ ...metadata,
21
+ turnTainted: true
22
+ }
23
+ } : message;
24
+ }
25
+ function attachCodexMirrorAttestation(message, sourceFingerprint) {
26
+ const existing = CODEX_META_KEY in message ? message[CODEX_META_KEY] : void 0;
27
+ const baseMeta = existing && typeof existing === "object" && !Array.isArray(existing) ? existing : {};
28
+ return {
29
+ ...message,
30
+ [CODEX_META_KEY]: {
31
+ ...baseMeta,
32
+ [MIRROR_ORIGIN_META_KEY]: CODEX_APP_SERVER_MIRROR_ORIGIN,
33
+ ...sourceFingerprint ? { [MIRROR_SOURCE_FINGERPRINT_META_KEY]: sourceFingerprint } : {}
34
+ }
35
+ };
36
+ }
37
+ function attachCodexMirrorRunId(message, runId, terminal = false) {
38
+ const existing = CODEX_META_KEY in message ? message[CODEX_META_KEY] : void 0;
39
+ const { runTerminal: _staleTerminal, ...current } = asOptionalRecord(existing) ?? {};
40
+ return {
41
+ ...message,
42
+ [CODEX_META_KEY]: {
43
+ ...current,
44
+ runId,
45
+ ...terminal ? { runTerminal: true } : {}
46
+ }
47
+ };
48
+ }
49
+ function hasCodexMirrorOrigin(message) {
50
+ const meta = CODEX_META_KEY in message ? message[CODEX_META_KEY] : void 0;
51
+ return asOptionalRecord(meta)?.[MIRROR_ORIGIN_META_KEY] === CODEX_APP_SERVER_MIRROR_ORIGIN;
52
+ }
53
+ function readCodexMirrorSourceFingerprint(message) {
54
+ const meta = CODEX_META_KEY in message ? message[CODEX_META_KEY] : void 0;
55
+ if (!meta || typeof meta !== "object" || Array.isArray(meta)) return;
56
+ const value = meta[MIRROR_SOURCE_FINGERPRINT_META_KEY];
57
+ return typeof value === "string" && value ? value : void 0;
58
+ }
59
+ function serializeCodexMirrorSourceEvidence(message) {
60
+ const content = "content" in message ? message.content : void 0;
61
+ return JSON.stringify({
62
+ role: message.role,
63
+ content,
64
+ ...message.role === "user" ? { upstreamUserText: readUpstreamUserText(message) } : {},
65
+ ...message.role === "toolResult" ? {
66
+ toolCallId: message.toolCallId,
67
+ toolName: message.toolName,
68
+ isError: message.isError
69
+ } : {}
70
+ });
71
+ }
72
+ function fingerprintCodexMirrorSourceMessage(message) {
73
+ return createHash("sha256").update(serializeCodexMirrorSourceEvidence(message)).digest("hex").slice(0, 32);
74
+ }
75
+ //#endregion
76
+ export { hasCodexMirrorOrigin as a, fingerprintCodexMirrorSourceMessage as i, attachCodexMirrorAttestation as n, readCodexMirrorSourceFingerprint as o, attachCodexMirrorRunId as r, serializeCodexMirrorSourceEvidence as s, applyCodexTranscriptTaint as t };