@openclaw/codex 2026.9.1-beta.1 → 2026.9.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (73) hide show
  1. package/dist/api.js +5 -6
  2. package/dist/{attempt-client-cleanup-bfsmcQ6m.js → attempt-client-cleanup-DYHcRQAa.js} +31 -45
  3. package/dist/attempt-context-DmQUNWwT.js +634 -0
  4. package/dist/{auth-binding-B4FfbcCg.js → auth-binding-Ds_QVm-X.js} +18 -3
  5. package/dist/{binding-connection-BMvPX73o.js → binding-connection-E6uDsPlx.js} +2 -2
  6. package/dist/{bounded-turn-B7iBUcuP.js → bounded-turn-wzJrwKKe.js} +15 -20
  7. package/dist/{capabilities-BRMh0aIq.js → capabilities-dIjNVCYH.js} +1 -1
  8. package/dist/cli-metadata.js +1 -1
  9. package/dist/{command-formatters-DEsIufkt.js → command-formatters-CLHhEB1Q.js} +5 -4
  10. package/dist/{command-handlers-D_-1_qRp.js → command-handlers-CTGb2csu.js} +124 -101
  11. package/dist/{compact-BglNFZrQ.js → compact-_t0HQrUS.js} +38 -29
  12. package/dist/{config-giW8X0QA.js → config-BhmfC1s6.js} +294 -282
  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 +143 -12
  16. package/dist/{dynamic-tools-Dnlfa--w.js → dynamic-tools-BU9tmlYm.js} +599 -655
  17. package/dist/{effective-mcp-catalog-CTeGrnfO.js → effective-mcp-catalog-DzYBW4h1.js} +2 -2
  18. package/dist/{event-projector-assistant-message-C5-Ds8mA.js → event-projector-assistant-message-DHRFXKbS.js} +4 -4
  19. package/dist/{event-projector-usage-Bk1I90Bg.js → event-projector-usage-C5mcrGjp.js} +15 -148
  20. package/dist/{harness-Csz0F-DK.js → harness-DXVZ5II5.js} +42 -52
  21. package/dist/harness.js +1 -1
  22. package/dist/index.js +458 -404
  23. package/dist/{isolated-completion-Cv6FqygM.js → isolated-completion-kg9kv4iH.js} +4 -4
  24. package/dist/launch-args-RXQwn8zV.js +90 -0
  25. package/dist/{managed-binary-DFYK4DWq.js → managed-binary-4-Vjz5GH.js} +14 -9
  26. package/dist/media-understanding-provider.js +1 -1
  27. package/dist/model-catalog-CUM68Hkl.js +101 -0
  28. package/dist/{models-TS3HBU-q.js → models-sYnEc0gd.js} +25 -28
  29. package/dist/{native-subagent-monitor-4Mfq2HDs.js → native-subagent-monitor-CnH147jH.js} +55 -115
  30. package/dist/{node-exec-server.runtime-BpWqJO1V.js → node-exec-server.runtime-CstNHCmC.js} +9 -6
  31. package/dist/{plugin-approval-roundtrip-bUm777tR.js → plugin-approval-roundtrip-CNe-Xrjx.js} +30 -3
  32. package/dist/{plugin-marketplace-discovery-B9DvaAG-.js → plugin-marketplace-discovery-CfFlKqDl.js} +15 -14
  33. package/dist/{plugin-metadata-cache-CTCT3w5L.js → plugin-metadata-cache-BFrPhb2c.js} +6 -6
  34. package/dist/provider-capabilities-DW5p4k9w.js +101 -0
  35. package/dist/{rate-limits-C5_D8Gmb.js → rate-limits-CawQJfUS.js} +3 -2
  36. package/dist/{sandbox-guard-kuWTn9C5.js → request-DYAI5FQE.js} +195 -2
  37. package/dist/{run-attempt-DYc0QCBF.js → run-attempt-D1hJO4fX.js} +828 -2100
  38. package/dist/{runtime-artifact-BvyT1uyd.js → runtime-artifact-C3jVimFn.js} +21 -14
  39. package/dist/{session-binding-Bcynfd-_.js → session-binding-BHuTCRZQ.js} +198 -127
  40. package/dist/{session-catalog-DaLKVtpH.js → session-catalog-yyvTWFOw.js} +564 -408
  41. package/dist/{session-cli-DMc4oS2w.js → session-cli-CmFEXMAM.js} +1 -1
  42. package/dist/session-history-C5J1AKzG.js +87 -0
  43. package/dist/session-initialization-BeWzjGiR.js +74 -0
  44. package/dist/{session-permission-policy-BrNH1bjy.js → session-permission-policy-DeWVTCMj.js} +2 -2
  45. package/dist/session-retirement-BujDjXVF.js +97 -0
  46. package/dist/{session-upstream-marker-BIkusb95.js → session-upstream-marker-C351-5Qw.js} +19 -4
  47. package/dist/settled-turn-context-D3SNWtUn.js +268 -0
  48. package/dist/settled-turn-finalizer-BVJx4yoc.js +104 -0
  49. package/dist/{shared-client-DKz23hHY.js → shared-client-DxcfF9KX.js} +3480 -679
  50. package/dist/{side-question-DjA_jsNe.js → side-question-BTZAII4l.js} +108 -70
  51. package/dist/{thread-lifecycle-L7oEkTlq.js → thread-lifecycle-DAcEJ_Om.js} +2188 -1915
  52. package/dist/{thread-ownership-DZeuKH1j.js → thread-ownership-zGokd8i1.js} +25 -14
  53. package/dist/thread-policy-g4KbJPzp.js +54 -0
  54. package/dist/{plugin-app-cache-key-C1CAdfcP.js → thread-resume-C7pyVKeW.js} +59 -7
  55. package/dist/{transcript-mirror-DsCMWBca.js → transcript-mirror-DTUxFWa_.js} +79 -17
  56. package/dist/transport-stdio-CyPldczm.js +726 -0
  57. package/dist/{upstream-prompt-provenance-CFmsKwr9.js → upstream-prompt-provenance-LphB8slG.js} +8 -4
  58. package/dist/upstream-session-fork-CYlBIGVt.js +966 -0
  59. package/dist/{usage-ROIaW3wo.js → usage-Bj-rrzkR.js} +3 -3
  60. package/dist/{web-search-provider.runtime-ClaNPV7N.js → web-search-provider.runtime-D2FWSK4w.js} +3 -3
  61. package/openclaw.plugin.json +1 -30
  62. package/package.json +6 -6
  63. package/dist/command-rpc-CCeCkf_v.js +0 -90
  64. package/dist/incognito-session-ET_ufDH-.js +0 -2
  65. package/dist/model-catalog-i9rNBthX.js +0 -48
  66. package/dist/protocol-validators-VeJxxJ0U.js +0 -2421
  67. package/dist/request-DXXGHko0.js +0 -157
  68. package/dist/session-catalog-home-id-BNwAJ9D7.js +0 -18
  69. package/dist/session-retirement-CcNC3YSY.js +0 -36
  70. package/dist/settled-turn-finalizer-Dc3ApjU4.js +0 -328
  71. package/dist/thread-resume-BE9qNEW0.js +0 -30
  72. package/dist/transport-stdio-DhoGy33Z.js +0 -99
  73. package/dist/upstream-session-fork-DlaHxSLC.js +0 -326
@@ -1,15 +1,21 @@
1
- import { $ as releaseCodexAppServerLiveThread, Z as isCodexAppServerLiveThreadClaimed, et as retainCodexAppServerLiveThread, h as retainSharedCodexAppServerClientByInstanceId } from "./shared-client-DKz23hHY.js";
2
- import { a as closeCodexStartupClientBestEffort, d as unsubscribeCodexThreadBestEffort, r as CodexAppServerUnsafeSubscriptionError } from "./attempt-client-cleanup-bfsmcQ6m.js";
1
+ import { At as retainCodexAppServerLiveThread, Et as isCodexAppServerLiveThreadClaimed, _ as retainSharedCodexAppServerClientByInstanceId, kt as releaseCodexAppServerLiveThread } from "./shared-client-DxcfF9KX.js";
2
+ import { a as closeCodexStartupClientBestEffort, d as unsubscribeCodexThreadBestEffort, r as CodexAppServerUnsafeSubscriptionError } from "./attempt-client-cleanup-DYHcRQAa.js";
3
+ import { isIncognitoSessionKey } from "openclaw/plugin-sdk/routing";
4
+ import { resolveGlobalSingleton } from "openclaw/plugin-sdk/global-singleton";
3
5
  import { KeyedAsyncQueue } from "openclaw/plugin-sdk/keyed-async-queue";
4
6
  //#region extensions/codex/src/app-server/thread-ownership.ts
5
- const nativeThreadOwners = new KeyedAsyncQueue();
7
+ const nativeThreadOwners = resolveGlobalSingleton(Symbol.for("openclaw.codexNativeThreadOwners"), () => new KeyedAsyncQueue());
8
+ /** Serialize OpenClaw-owned lifecycle changes, not native-internal thread controllers. */
9
+ async function withCodexAppServerThreadMutation(threadId, run) {
10
+ return await nativeThreadOwners.enqueue(`thread:${threadId}`, run);
11
+ }
6
12
  /** Codex subscriptions belong to a physical connection, not the native thread ID alone. */
7
13
  function isSameCodexAppServerThreadOwner(current, expected) {
8
14
  return current !== void 0 && expected !== void 0 && current.threadId === expected.threadId && current.clientId === expected.clientId;
9
15
  }
10
16
  /** Fences native subscription and commit together; Codex subscriptions are not reference-counted. */
11
17
  async function withExclusiveCodexAppServerThread(params) {
12
- return await nativeThreadOwners.enqueue(`thread:${params.threadId}`, async () => {
18
+ return await withCodexAppServerThreadMutation(params.threadId, async () => {
13
19
  if (await params.bindingStore.hasOtherThreadOwner(params.threadId, params.identity)) throw new Error(`Codex thread ${params.threadId} is owned by another OpenClaw session or conversation.`);
14
20
  return await params.run();
15
21
  });
@@ -18,17 +24,19 @@ async function withExclusiveCodexAppServerThread(params) {
18
24
  async function withCodexConversationThreadActivity(bindingId, run) {
19
25
  return await nativeThreadOwners.enqueue(`conversation:${bindingId}`, run);
20
26
  }
21
- /** Publishes one owned persistent subscription into the shared bounded idle registry. */
27
+ /** Publishes one owned subscription with its persistent or ephemeral retention lifetime. */
22
28
  async function retainCodexAppServerBindingSubscription(client, threadId, ownership) {
23
- return await retainCodexAppServerLiveThread(client, threadId, ownership?.release ?? (async (releasedThreadId) => {
29
+ return await retainCodexAppServerLiveThread(client, threadId, ownership?.release ?? (async (releasedThreadId, assertCurrent) => {
24
30
  if (!await unsubscribeCodexThreadBestEffort(client, {
25
31
  threadId: releasedThreadId,
26
- timeoutMs: 5e3
32
+ timeoutMs: 5e3,
33
+ assertCurrent
27
34
  })) {
35
+ assertCurrent?.();
28
36
  await closeCodexStartupClientBestEffort(client);
29
37
  throw new CodexAppServerUnsafeSubscriptionError(`Codex thread subscription could not be released: ${releasedThreadId}`);
30
38
  }
31
- }), ownership?.configFingerprint, ownership?.serviceTier);
39
+ }), ownership?.configFingerprint, ownership?.serviceTier, ownership?.ephemeralPolicy);
32
40
  }
33
41
  /** Rolls back the exact subscription Codex created before its binding was committed. */
34
42
  async function rollbackCodexAppServerBindingSubscription(client, threadId, retained) {
@@ -41,15 +49,18 @@ async function rollbackCodexAppServerBindingSubscription(client, threadId, retai
41
49
  }
42
50
  /** Releases only the physical client and native thread recorded by the displaced binding owner. */
43
51
  async function releaseCodexAppServerBindingSubscription(binding, options = {}) {
52
+ options.assertCurrent?.();
44
53
  const clientLease = retainSharedCodexAppServerClientByInstanceId(binding.clientId);
45
54
  if (!clientLease) return;
46
55
  try {
47
- if (await releaseCodexAppServerLiveThread(clientLease.client, binding.threadId)) return;
56
+ if (await releaseCodexAppServerLiveThread(clientLease.client, binding.threadId, options.assertCurrent)) return;
57
+ options.assertCurrent?.();
48
58
  if (isCodexAppServerLiveThreadClaimed(clientLease.client, binding.threadId)) throw new Error(`Codex thread ${binding.threadId} has an active run; stop it before changing its owner.`);
49
59
  if (!options.allowUntracked) return;
50
60
  if (!await unsubscribeCodexThreadBestEffort(clientLease.client, {
51
61
  threadId: binding.threadId,
52
- timeoutMs: 5e3
62
+ timeoutMs: 5e3,
63
+ assertCurrent: options.assertCurrent
53
64
  })) {
54
65
  await closeCodexStartupClientBestEffort(clientLease.client);
55
66
  throw new CodexAppServerUnsafeSubscriptionError(`Codex retired thread subscription could not be released: ${binding.threadId}`);
@@ -62,9 +73,9 @@ async function releaseCodexAppServerBindingSubscription(binding, options = {}) {
62
73
  async function retireCodexConversationThreadBinding(params) {
63
74
  const expected = await params.bindingStore.read(params.identity);
64
75
  if (!expected || params.expectedThreadId && expected.threadId !== params.expectedThreadId) return false;
65
- return await params.bindingStore.withLease(params.identity, async () => {
76
+ return await withCodexAppServerThreadMutation(expected.threadId, () => params.bindingStore.withLease(params.identity, async () => {
66
77
  const current = await params.bindingStore.read(params.identity);
67
- if (current?.threadId !== expected.threadId || params.expectedStartId && current.conversationStartId !== params.expectedStartId) return false;
78
+ if (!current || !isSameCodexAppServerThreadOwner(current, expected) || params.expectedStartId && current?.conversationStartId !== params.expectedStartId) return false;
68
79
  await releaseCodexAppServerBindingSubscription(current, { allowUntracked: params.allowUntracked });
69
80
  const cleared = await params.bindingStore.mutate(params.identity, {
70
81
  kind: "clear",
@@ -86,7 +97,7 @@ async function retireCodexConversationThreadBinding(params) {
86
97
  }
87
98
  throw error;
88
99
  }
89
- });
100
+ }));
90
101
  }
91
102
  //#endregion
92
- export { rollbackCodexAppServerBindingSubscription as a, retireCodexConversationThreadBinding as i, releaseCodexAppServerBindingSubscription as n, withCodexConversationThreadActivity as o, retainCodexAppServerBindingSubscription as r, withExclusiveCodexAppServerThread as s, isSameCodexAppServerThreadOwner as t };
103
+ export { rollbackCodexAppServerBindingSubscription as a, withExclusiveCodexAppServerThread as c, retireCodexConversationThreadBinding as i, isIncognitoSessionKey as l, releaseCodexAppServerBindingSubscription as n, withCodexAppServerThreadMutation as o, retainCodexAppServerBindingSubscription as r, withCodexConversationThreadActivity as s, isSameCodexAppServerThreadOwner as t };
@@ -0,0 +1,54 @@
1
+ import { H as isCodexAppServerOverloadError, U as isCodexAppServerPrewriteRequestCancellationError } from "./shared-client-DxcfF9KX.js";
2
+ import { r as requestCodexAppServerClientJson, t as CodexAppServerScopedRequestRejectedError } from "./request-DYAI5FQE.js";
3
+ import { AgentHarnessPreflightError } from "openclaw/plugin-sdk/agent-harness-runtime";
4
+ //#region extensions/codex/src/app-server/thread-policy.ts
5
+ /** A refusal, not a failed native write: the ephemeral conversation must stay alive. */
6
+ var CodexIncognitoPolicyChangeError = class extends AgentHarnessPreflightError {
7
+ constructor() {
8
+ super("Codex cannot change generic instructions in a live incognito conversation. No turn was sent and the conversation is preserved. Restore the previous instructions to continue it, or start a new incognito conversation for the changed policy.");
9
+ this.name = "CodexIncognitoPolicyChangeError";
10
+ }
11
+ };
12
+ /** Never replay a handoff: native persistence can precede an unsuccessful RPC response. */
13
+ var CodexThreadPolicyHandoffError = class extends AgentHarnessPreflightError {
14
+ constructor(outcome, cause) {
15
+ super(`Codex session policy handoff failed: ${cause instanceof Error ? cause.message : String(cause)}. The conversation is preserved; reconnect before retrying.`, { cause });
16
+ this.outcome = outcome;
17
+ this.name = "CodexThreadPolicyHandoffError";
18
+ }
19
+ };
20
+ /** The complete body remains generic configuration for compaction and native child inheritance. */
21
+ async function refreshCodexThreadPolicy(params) {
22
+ const text = "The following is the complete current OpenClaw-supplied generic instruction policy. It replaces earlier OpenClaw-supplied generic policy, including OpenClaw-carried workspace text and sections now absent. Independently supplied native managed, guardian, security, collaboration, and project instructions retain their authority. User requests retain their own authority.\n\n" + (params.developerInstructions === "" ? "The current OpenClaw generic policy is empty; earlier OpenClaw generic policy is withdrawn." : params.developerInstructions);
23
+ let outcome = "unknown";
24
+ try {
25
+ await requestCodexAppServerClientJson({
26
+ ...params,
27
+ method: "thread/inject_items",
28
+ requestParams: {
29
+ threadId: params.threadId,
30
+ items: [{
31
+ type: "message",
32
+ role: "developer",
33
+ content: [{
34
+ type: "input_text",
35
+ text
36
+ }]
37
+ }]
38
+ }
39
+ });
40
+ outcome = "acknowledged";
41
+ params.assertCurrent();
42
+ params.signal?.throwIfAborted();
43
+ } catch (cause) {
44
+ if (outcome !== "acknowledged" && (cause instanceof CodexAppServerScopedRequestRejectedError || isCodexAppServerPrewriteRequestCancellationError(cause) || isCodexAppServerOverloadError(cause))) outcome = "not-written";
45
+ throw new CodexThreadPolicyHandoffError(outcome, cause);
46
+ }
47
+ }
48
+ /** Native lineage classifies the exact bound thread; it never grants session authority. */
49
+ function assertCodexSupervisionThreadLineage(binding, thread) {
50
+ if (binding.connectionScope !== "supervision" || binding.pendingSupervisionBranch) return;
51
+ if (thread.id !== binding.threadId || !binding.supervisionSourceThreadId || thread.forkedFromId !== null && (typeof thread.forkedFromId !== "string" || !thread.forkedFromId.trim() || thread.forkedFromId === thread.id)) throw new Error("Codex supervision lineage could not be verified; reconnect before continuing.");
52
+ }
53
+ //#endregion
54
+ export { refreshCodexThreadPolicy as i, CodexThreadPolicyHandoffError as n, assertCodexSupervisionThreadLineage as r, CodexIncognitoPolicyChangeError as t };
@@ -1,5 +1,7 @@
1
- import { S as resolveCodexAppServerUserHomeDir } from "./config-giW8X0QA.js";
2
- import { St as resolveCodexAppServerLocalHomeDir, xt as resolveCodexAppServerHomeDir } from "./shared-client-DKz23hHY.js";
1
+ import { $ as assertCodexThreadResumeResponse, H as isCodexAppServerOverloadError, M as isCodexAppServerStartupError, U as isCodexAppServerPrewriteRequestCancellationError, q as CodexAppServerRpcError, u as isCodexAppServerStartSelectionChangedError } from "./shared-client-DxcfF9KX.js";
2
+ import { F as resolveCodexAppServerHomeDir, I as resolveCodexAppServerLocalHomeDir, L as resolveCodexAppServerUserHomeDir } from "./config-BhmfC1s6.js";
3
+ import { d as unsubscribeCodexThreadBestEffort, i as assertCodexThreadResumeSubscription, r as CodexAppServerUnsafeSubscriptionError } from "./attempt-client-cleanup-DYHcRQAa.js";
4
+ import { t as CodexAppServerScopedRequestRejectedError } from "./request-DYAI5FQE.js";
3
5
  import { createRequire } from "node:module";
4
6
  import { isRecord } from "openclaw/plugin-sdk/string-coerce-runtime";
5
7
  import { readPluginPackageVersion } from "openclaw/plugin-sdk/extension-shared";
@@ -13,7 +15,7 @@ import { truncateUtf16Safe } from "openclaw/plugin-sdk/text-utility-runtime";
13
15
  * identity and safe to refresh in the background.
14
16
  */
15
17
  /** Default app inventory cache freshness window. */
16
- const CODEX_APP_INVENTORY_CACHE_TTL_MS = 3600 * 1e3;
18
+ const CODEX_APP_INVENTORY_CACHE_TTL_MS = 36e5;
17
19
  const CODEX_APP_READ_BATCH_LIMIT = 100;
18
20
  const MAX_SERIALIZED_ERROR_MESSAGE_LENGTH = 500;
19
21
  /** In-memory app inventory cache with coalesced refreshes per key. */
@@ -264,7 +266,10 @@ async function readInstalledApps(request, options) {
264
266
  apps: [],
265
267
  installedApps: []
266
268
  };
267
- const metadataResponses = await Promise.all(Array.from({ length: Math.ceil(apps.length / CODEX_APP_READ_BATCH_LIMIT) }, (_, index) => request("app/read", { appIds: apps.slice(index * CODEX_APP_READ_BATCH_LIMIT, (index + 1) * CODEX_APP_READ_BATCH_LIMIT).map((app) => app.id) })));
269
+ const metadataResponses = await Promise.all(Array.from({ length: Math.ceil(apps.length / CODEX_APP_READ_BATCH_LIMIT) }, (_, index) => request("app/read", {
270
+ appIds: apps.slice(index * CODEX_APP_READ_BATCH_LIMIT, (index + 1) * CODEX_APP_READ_BATCH_LIMIT).map((app) => app.id),
271
+ includeTools: true
272
+ })));
268
273
  const metadataById = new Map(metadataResponses.flatMap((response) => response.apps).map((metadata) => [metadata.id, metadata]));
269
274
  return {
270
275
  apps: apps.flatMap((installedApp) => {
@@ -283,7 +288,8 @@ async function readInstalledApps(request, options) {
283
288
  installUrl: metadata.installUrl ?? null,
284
289
  isAccessible: true,
285
290
  isEnabled: installedApp.enabled,
286
- pluginDisplayNames: metadata.pluginDisplayNames
291
+ pluginDisplayNames: metadata.pluginDisplayNames,
292
+ ...metadata.toolSummaries ? { toolSummaries: metadata.toolSummaries } : {}
287
293
  }];
288
294
  }),
289
295
  installedApps: apps
@@ -330,7 +336,8 @@ function isSensitiveErrorDataKey(key) {
330
336
  * Builds stable Codex plugin/app inventory cache keys from app-server startup,
331
337
  * auth, account, and version inputs without storing secret material.
332
338
  */
333
- const CODEX_PLUGIN_VERSION = readPluginPackageVersion({ require: createRequire(import.meta.url) });
339
+ const require = createRequire(import.meta.url);
340
+ const CODEX_PLUGIN_VERSION = readPluginPackageVersion({ require });
334
341
  let catalogConnectionHomes = /* @__PURE__ */ new Map();
335
342
  function catalogConnectionHomeKey(fingerprint, agentDir) {
336
343
  return `${agentDir ?? ""}\0${fingerprint}`;
@@ -420,4 +427,49 @@ function fingerprintCodexPluginAppCacheCredentials(startOptions) {
420
427
  return `sha256:${hash.digest("hex")}`;
421
428
  }
422
429
  //#endregion
423
- export { resolveCodexCatalogConnectionHome as a, replaceCodexCatalogConnectionHomes as i, buildCodexAppServerRuntimeFingerprint as n, defaultCodexAppInventoryCache as o, buildCodexPluginAppCacheKey as r, serializeCodexAppInventoryError as s, buildCodexAppServerConnectionFingerprint as t };
430
+ //#region extensions/codex/src/app-server/thread-resume.ts
431
+ /** Owns Codex thread/resume subscription safety. */
432
+ /** Resumes one thread, releasing or isolating every possible native subscription. */
433
+ async function resumeCodexAppServerThread(params) {
434
+ const threadId = params.request.threadId;
435
+ let response;
436
+ let ownershipRejected = false;
437
+ const assertCurrent = params.assertCurrent && (() => {
438
+ try {
439
+ params.assertCurrent?.();
440
+ } catch (error) {
441
+ ownershipRejected = true;
442
+ throw error;
443
+ }
444
+ });
445
+ try {
446
+ response = assertCodexThreadResumeResponse(await (params.requestResume ? params.requestResume(params.request) : params.client.request("thread/resume", params.request, {
447
+ ...params.timeoutMs !== void 0 ? { timeoutMs: params.timeoutMs } : {},
448
+ ...params.signal ? { signal: params.signal } : {},
449
+ assertCurrent
450
+ })));
451
+ assertCodexThreadResumeSubscription(threadId, response.thread.id);
452
+ } catch (error) {
453
+ if (ownershipRejected || isCodexAppServerStartSelectionChangedError(error) || isCodexAppServerStartupError(error) || error instanceof CodexAppServerScopedRequestRejectedError || isCodexAppServerPrewriteRequestCancellationError(error) || isCodexAppServerOverloadError(error)) throw error;
454
+ if (error instanceof CodexAppServerRpcError) {
455
+ if (await unsubscribeCodexThreadBestEffort(params.client, {
456
+ threadId,
457
+ timeoutMs: 5e3,
458
+ assertCurrent: params.assertCurrent
459
+ }).catch(() => false)) {
460
+ params.onSubscriptionReleased?.();
461
+ throw error;
462
+ }
463
+ }
464
+ try {
465
+ await params.abandonClient();
466
+ } catch (abandonError) {
467
+ throw new CodexAppServerUnsafeSubscriptionError(`Codex thread/resume client could not be retired for ${threadId}`, { cause: abandonError });
468
+ }
469
+ if (error instanceof CodexAppServerUnsafeSubscriptionError) throw error;
470
+ throw new CodexAppServerUnsafeSubscriptionError(error instanceof Error ? error.message : `Codex thread/resume outcome is indeterminate for ${threadId}`, { cause: error });
471
+ }
472
+ return response;
473
+ }
474
+ //#endregion
475
+ export { replaceCodexCatalogConnectionHomes as a, serializeCodexAppInventoryError as c, buildCodexPluginAppCacheKey as i, buildCodexAppServerConnectionFingerprint as n, resolveCodexCatalogConnectionHome as o, buildCodexAppServerRuntimeFingerprint as r, defaultCodexAppInventoryCache as s, resumeCodexAppServerThread as t };
@@ -1,15 +1,31 @@
1
- import { i as readUpstreamUserText, n as attachUpstreamUserText, r as readMirrorIdentity, t as attachCodexMirrorIdentity } from "./upstream-prompt-provenance-CFmsKwr9.js";
1
+ import { i as readUpstreamUserText, n as attachUpstreamUserText, r as readMirrorIdentity, t as attachCodexMirrorIdentity } from "./upstream-prompt-provenance-LphB8slG.js";
2
2
  import { asOptionalRecord, normalizeOptionalString } from "openclaw/plugin-sdk/string-coerce-runtime";
3
+ import path from "node:path";
3
4
  import { deliverAgentHarnessUserInputPrompt, embeddedAgentLog, formatErrorMessage, projectAgentHarnessTranscriptMessageForDisplay, runAgentHarnessBeforeMessageWriteHook } from "openclaw/plugin-sdk/agent-harness-runtime";
4
5
  import { createHash } from "node:crypto";
6
+ import fsSync from "node:fs";
5
7
  import { truncateUtf8Prefix } from "openclaw/plugin-sdk/text-utility-runtime";
6
8
  import { withCodexSessionTranscriptMirrorWriteLock } from "openclaw/plugin-sdk/codex-session-transcript-runtime";
7
9
  import { publishSessionTranscriptUpdateByIdentity } from "openclaw/plugin-sdk/session-transcript-runtime";
8
10
  import { Buffer } from "node:buffer";
11
+ //#region extensions/codex/src/session-catalog-home-id.ts
12
+ function canonicalCodexCatalogHome(value) {
13
+ const resolved = path.resolve(value);
14
+ try {
15
+ return fsSync.realpathSync.native(resolved);
16
+ } catch {
17
+ return resolved;
18
+ }
19
+ }
20
+ /** One canonical identity for catalog discovery and durable ownership rows. */
21
+ function codexCatalogHomeId(codexHome) {
22
+ return createHash("sha256").update("openclaw:codex-session-catalog-home:v1\0").update(canonicalCodexCatalogHome(codexHome)).digest("hex");
23
+ }
24
+ //#endregion
9
25
  //#region extensions/codex/src/app-server/transcript-history-projection.ts
10
26
  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;
27
+ const CODEX_HISTORY_IMPORT_MAX_BYTES = 524288;
28
+ const CODEX_HISTORY_IMPORT_MAX_MESSAGE_BYTES = 65536;
13
29
  const CODEX_HISTORY_TRUNCATION_SUFFIX = "\n\n[Message truncated during Codex history import.]";
14
30
  const CODEX_HISTORY_ASSISTANT_API = "openai-chatgpt-responses";
15
31
  const CODEX_HISTORY_ASSISTANT_PROVIDER = "openai";
@@ -34,7 +50,8 @@ function normalizeImportedHistoryText(value) {
34
50
  if (!text) return;
35
51
  if (Buffer.byteLength(text, "utf8") <= CODEX_HISTORY_IMPORT_MAX_MESSAGE_BYTES) return text;
36
52
  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}`;
53
+ const contentLimitBytes = Math.max(0, CODEX_HISTORY_IMPORT_MAX_MESSAGE_BYTES - suffixBytes);
54
+ return `${truncateUtf8Prefix(text, contentLimitBytes)}${CODEX_HISTORY_TRUNCATION_SUFFIX}`;
38
55
  }
39
56
  function projectCodexUserItemText(item) {
40
57
  if (!Array.isArray(item.content)) return;
@@ -178,6 +195,22 @@ const MIRROR_ORIGIN_META_KEY = "mirrorOrigin";
178
195
  const MIRROR_SOURCE_FINGERPRINT_META_KEY = "mirrorSourceFingerprint";
179
196
  const CODEX_APP_SERVER_MIRROR_ORIGIN = "codex-app-server";
180
197
  const CODEX_META_KEY = "__openclaw";
198
+ function applyCodexTranscriptTaint(message, state) {
199
+ if (message.role === "user") {
200
+ state.tainted = false;
201
+ return message;
202
+ }
203
+ const existing = CODEX_META_KEY in message ? message[CODEX_META_KEY] : void 0;
204
+ const metadata = asOptionalRecord(existing);
205
+ state.tainted ||= metadata?.turnTainted === true || metadata?.resultContentSource === "network";
206
+ return message.role === "assistant" && state.tainted ? {
207
+ ...message,
208
+ __openclaw: {
209
+ ...metadata,
210
+ turnTainted: true
211
+ }
212
+ } : message;
213
+ }
181
214
  function attachCodexMirrorAttestation(message, sourceFingerprint) {
182
215
  const existing = CODEX_META_KEY in message ? message[CODEX_META_KEY] : void 0;
183
216
  const baseMeta = existing && typeof existing === "object" && !Array.isArray(existing) ? existing : {};
@@ -191,7 +224,8 @@ function attachCodexMirrorAttestation(message, sourceFingerprint) {
191
224
  };
192
225
  }
193
226
  function attachCodexMirrorRunId(message, runId, terminal = false) {
194
- const { runTerminal: _staleTerminal, ...current } = asOptionalRecord(CODEX_META_KEY in message ? message[CODEX_META_KEY] : void 0) ?? {};
227
+ const existing = CODEX_META_KEY in message ? message[CODEX_META_KEY] : void 0;
228
+ const { runTerminal: _staleTerminal, ...current } = asOptionalRecord(existing) ?? {};
195
229
  return {
196
230
  ...message,
197
231
  [CODEX_META_KEY]: {
@@ -201,6 +235,10 @@ function attachCodexMirrorRunId(message, runId, terminal = false) {
201
235
  }
202
236
  };
203
237
  }
238
+ function hasCodexMirrorOrigin(message) {
239
+ const meta = CODEX_META_KEY in message ? message[CODEX_META_KEY] : void 0;
240
+ return asOptionalRecord(meta)?.[MIRROR_ORIGIN_META_KEY] === CODEX_APP_SERVER_MIRROR_ORIGIN;
241
+ }
204
242
  function readCodexMirrorSourceFingerprint(message) {
205
243
  const meta = CODEX_META_KEY in message ? message[CODEX_META_KEY] : void 0;
206
244
  if (!meta || typeof meta !== "object" || Array.isArray(meta)) return;
@@ -279,25 +317,26 @@ function readMirroredAssistantText(message) {
279
317
  }
280
318
  /** Imports a bounded, user-visible Codex history tail into a new OpenClaw transcript. */
281
319
  async function importCodexThreadHistoryToTranscript(params) {
282
- const projection = projectBoundedCodexThreadHistory({
320
+ const { transcriptMessages, importedMessages, omittedMessages } = projectBoundedCodexThreadHistory({
283
321
  thread: params.thread,
284
322
  throughTurnId: params.throughTurnId,
285
323
  importedAt: Date.now(),
286
324
  ...params.modelProvider ? { modelProvider: params.modelProvider } : {}
287
325
  });
288
- if (projection.transcriptMessages.length > 0) await mirror({
326
+ if (transcriptMessages.length > 0) await mirror({
327
+ assertCurrent: params.assertCurrent,
289
328
  storePath: params.storePath,
290
329
  sessionId: params.sessionId,
291
330
  sessionKey: params.sessionKey,
292
331
  ...params.agentId ? { agentId: params.agentId } : {},
293
332
  ...params.cwd ? { cwd: params.cwd } : {},
294
333
  ...params.config ? { config: params.config } : {},
295
- messages: projection.transcriptMessages,
334
+ messages: transcriptMessages,
296
335
  idempotencyScope: `codex-app-server:${params.thread.id}:history`
297
336
  });
298
337
  return {
299
- importedMessages: projection.importedMessages,
300
- omittedMessages: projection.omittedMessages
338
+ importedMessages,
339
+ omittedMessages
301
340
  };
302
341
  }
303
342
  async function mirrorBestEffort(params) {
@@ -325,6 +364,7 @@ async function mirrorBestEffort(params) {
325
364
  mirrorIdentity: `${params.turnId}:assistant`,
326
365
  runId: params.params.runId
327
366
  },
367
+ prepareAssistantTranscriptMessage: params.params.prepareAssistantTranscriptMessage,
328
368
  config: params.params.config
329
369
  });
330
370
  for (const receipt of mirrorResult.userMessageReceipts) try {
@@ -399,7 +439,18 @@ async function mirrorPromptAtTurnStartBestEffort(params) {
399
439
  hidden: params.params.trigger === "memory",
400
440
  message: attachUpstreamUserText(attachCodexMirrorIdentity(await buildResolvedCodexUserPromptMessage(params.params), `${params.turnId}:prompt`), params.upstreamUserText)
401
441
  });
442
+ if (params.params.userTurnTranscriptRecorder?.getAdmissionReceipt()) {
443
+ const annotate = params.params.hostCapabilities.annotateCurrentUserTurn;
444
+ if (!annotate || userPromptMessage.role !== "user") throw new Error("current host admission is unavailable for native prompt annotation");
445
+ await annotate({
446
+ mirrorIdentity: `${params.turnId}:prompt`,
447
+ upstreamUserText: params.upstreamUserText,
448
+ mirrorOrigin: "codex-app-server",
449
+ mirrorSourceFingerprint: fingerprintCodexMirrorSourceMessage(userPromptMessage)
450
+ });
451
+ }
402
452
  const mirrorResult = await mirror({
453
+ assertCurrent: params.params.hostCapabilities.assertActive,
403
454
  agentId: params.agentId,
404
455
  sessionKey: params.sessionKey,
405
456
  sessionId: params.params.sessionId,
@@ -431,9 +482,7 @@ function fingerprintMirrorMessageContent(message) {
431
482
  return createHash("sha256").update(payload).digest("hex").slice(0, 16);
432
483
  }
433
484
  function buildMirrorDedupeIdentity(message) {
434
- const explicit = readMirrorIdentity(message);
435
- if (explicit) return explicit;
436
- return `${message.role}:${fingerprintMirrorMessageContent(message)}`;
485
+ return readMirrorIdentity(message) || `${message.role}:${fingerprintMirrorMessageContent(message)}`;
437
486
  }
438
487
  async function mirror(params) {
439
488
  const messages = params.messages.filter(isMirroredAgentMessage);
@@ -457,10 +506,12 @@ async function mirror(params) {
457
506
  });
458
507
  const candidateIdempotencyKeys = candidates.flatMap(({ idempotencyKey }) => idempotencyKey ? [idempotencyKey] : []);
459
508
  const transcriptTarget = resolveCodexMirrorTranscriptTarget(params);
460
- const { appendedUpdates, assistantMirrorIdentitiesAppended, assistantMirrorIdentitiesOwned, anchorsByMirrorIdentity, messagesPresent, userMessageReceipts, userMessagesPresent } = await withCodexSessionTranscriptMirrorWriteLock({
509
+ params.assertCurrent?.();
510
+ const mirrorBatch = await withCodexSessionTranscriptMirrorWriteLock({
461
511
  ...transcriptTarget,
462
512
  config: params.config
463
513
  }, async (transcript) => {
514
+ params.assertCurrent?.();
464
515
  const nextAppendedUpdates = [];
465
516
  const nextAssistantMirrorIdentitiesAppended = /* @__PURE__ */ new Set();
466
517
  const nextAssistantMirrorIdentitiesOwned = /* @__PURE__ */ new Set();
@@ -469,6 +520,7 @@ async function mirror(params) {
469
520
  const nextUserMessageReceipts = [];
470
521
  const nextUserMessagesPresent = [];
471
522
  const mirrorFacts = await transcript.readMessageFacts({ idempotencyKeys: candidateIdempotencyKeys });
523
+ params.assertCurrent?.();
472
524
  for (const { dedupeIdentity, idempotencyKey, message, sourceFingerprint } of candidates) {
473
525
  const mirrorIdentity = readMirrorIdentity(message);
474
526
  const ownsRun = Boolean(params.runId && (!params.runMirrorIdentityPrefix || mirrorIdentity?.startsWith(params.runMirrorIdentityPrefix)));
@@ -495,10 +547,12 @@ async function mirror(params) {
495
547
  if (message.role === "assistant") nextAssistantMirrorIdentitiesOwned.add(dedupeIdentity);
496
548
  continue;
497
549
  }
498
- const nextMessage = params.skipBeforeMessageWriteHooks ? transcriptMessage : runAgentHarnessBeforeMessageWriteHook({
550
+ const nextMessage = runAgentHarnessBeforeMessageWriteHook({
499
551
  message: transcriptMessage,
500
552
  agentId: params.agentId,
501
- sessionKey: params.sessionKey
553
+ sessionKey: params.sessionKey,
554
+ skipBeforeMessageWriteHooks: params.skipBeforeMessageWriteHooks,
555
+ prepareAssistantTranscriptMessage: ownsTerminal ? params.prepareAssistantTranscriptMessage : void 0
502
556
  });
503
557
  if (!nextMessage) {
504
558
  if (message.role === "assistant") nextAssistantMirrorIdentitiesOwned.add(dedupeIdentity);
@@ -515,11 +569,17 @@ async function mirror(params) {
515
569
  hidden: message.display === false,
516
570
  message: messageToAppend
517
571
  });
572
+ params.assertCurrent?.();
518
573
  const { messageSeq, result: appended } = await transcript.appendMessageWithMessageSequence({
519
574
  message: messageToAppend,
575
+ ...params.assertCurrent ? { prepareMessageAfterIdempotencyCheck: (preparedMessage) => {
576
+ params.assertCurrent?.();
577
+ return preparedMessage;
578
+ } } : {},
520
579
  idempotencyLookup: "scan",
521
580
  cwd: params.cwd
522
581
  });
582
+ params.assertCurrent?.();
523
583
  if (!appended) continue;
524
584
  const { messageId, message: appendedMessage } = appended;
525
585
  if (isMirroredAgentMessage(appendedMessage)) {
@@ -558,6 +618,8 @@ async function mirror(params) {
558
618
  userMessagesPresent: nextUserMessagesPresent
559
619
  };
560
620
  });
621
+ params.assertCurrent?.();
622
+ const { appendedUpdates, assistantMirrorIdentitiesAppended, assistantMirrorIdentitiesOwned, anchorsByMirrorIdentity, messagesPresent, userMessageReceipts, userMessagesPresent } = mirrorBatch;
561
623
  for (const update of appendedUpdates) try {
562
624
  const terminalOwner = params.terminalAssistantOwner;
563
625
  const terminalRunId = update.message.role === "assistant" && terminalOwner && readMirrorIdentity(update.message) === terminalOwner.mirrorIdentity ? terminalOwner.runId : void 0;
@@ -666,4 +728,4 @@ function resolveCodexMirrorTranscriptTarget(params) {
666
728
  };
667
729
  }
668
730
  //#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 };
731
+ export { buildCodexUserPromptMessage as a, fingerprintCodexMirrorSourceMessage as c, serializeCodexMirrorSourceEvidence as d, projectBoundedCodexThreadHistory as f, codexCatalogHomeId as g, canonicalCodexCatalogHome as h, mirrorPromptAtTurnStartBestEffort as i, hasCodexMirrorOrigin as l, projectCodexUserItemText as m, createCodexAppServerUserMessagePersistenceNotifier as n, promptSnapshot as o, projectBoundedCodexVisibleSessionHistory as p, importCodexThreadHistoryToTranscript as r, applyCodexTranscriptTaint as s, codexTranscriptMirrorRuntime as t, readCodexMirrorSourceFingerprint as u };