@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.
- package/dist/api.js +5 -6
- package/dist/{attempt-client-cleanup-bfsmcQ6m.js → attempt-client-cleanup-DYHcRQAa.js} +31 -45
- package/dist/attempt-context-DmQUNWwT.js +634 -0
- package/dist/{auth-binding-B4FfbcCg.js → auth-binding-Ds_QVm-X.js} +18 -3
- package/dist/{binding-connection-BMvPX73o.js → binding-connection-E6uDsPlx.js} +2 -2
- package/dist/{bounded-turn-B7iBUcuP.js → bounded-turn-wzJrwKKe.js} +15 -20
- package/dist/{capabilities-BRMh0aIq.js → capabilities-dIjNVCYH.js} +1 -1
- package/dist/cli-metadata.js +1 -1
- package/dist/{command-formatters-DEsIufkt.js → command-formatters-CLHhEB1Q.js} +5 -4
- package/dist/{command-handlers-D_-1_qRp.js → command-handlers-CTGb2csu.js} +124 -101
- package/dist/{compact-BglNFZrQ.js → compact-_t0HQrUS.js} +38 -29
- package/dist/{config-giW8X0QA.js → config-BhmfC1s6.js} +294 -282
- package/dist/{context-compaction-activity-BOeJf7yo.js → context-compaction-activity-CMla5FPJ.js} +4 -1
- package/dist/{conversation-binding-data-CW2GuupV.js → conversation-binding-data-BiodpIzq.js} +2 -1
- package/dist/doctor-contract-api.js +143 -12
- package/dist/{dynamic-tools-Dnlfa--w.js → dynamic-tools-BU9tmlYm.js} +599 -655
- package/dist/{effective-mcp-catalog-CTeGrnfO.js → effective-mcp-catalog-DzYBW4h1.js} +2 -2
- package/dist/{event-projector-assistant-message-C5-Ds8mA.js → event-projector-assistant-message-DHRFXKbS.js} +4 -4
- package/dist/{event-projector-usage-Bk1I90Bg.js → event-projector-usage-C5mcrGjp.js} +15 -148
- package/dist/{harness-Csz0F-DK.js → harness-DXVZ5II5.js} +42 -52
- package/dist/harness.js +1 -1
- package/dist/index.js +458 -404
- package/dist/{isolated-completion-Cv6FqygM.js → isolated-completion-kg9kv4iH.js} +4 -4
- package/dist/launch-args-RXQwn8zV.js +90 -0
- package/dist/{managed-binary-DFYK4DWq.js → managed-binary-4-Vjz5GH.js} +14 -9
- package/dist/media-understanding-provider.js +1 -1
- package/dist/model-catalog-CUM68Hkl.js +101 -0
- package/dist/{models-TS3HBU-q.js → models-sYnEc0gd.js} +25 -28
- package/dist/{native-subagent-monitor-4Mfq2HDs.js → native-subagent-monitor-CnH147jH.js} +55 -115
- package/dist/{node-exec-server.runtime-BpWqJO1V.js → node-exec-server.runtime-CstNHCmC.js} +9 -6
- package/dist/{plugin-approval-roundtrip-bUm777tR.js → plugin-approval-roundtrip-CNe-Xrjx.js} +30 -3
- package/dist/{plugin-marketplace-discovery-B9DvaAG-.js → plugin-marketplace-discovery-CfFlKqDl.js} +15 -14
- package/dist/{plugin-metadata-cache-CTCT3w5L.js → plugin-metadata-cache-BFrPhb2c.js} +6 -6
- package/dist/provider-capabilities-DW5p4k9w.js +101 -0
- package/dist/{rate-limits-C5_D8Gmb.js → rate-limits-CawQJfUS.js} +3 -2
- package/dist/{sandbox-guard-kuWTn9C5.js → request-DYAI5FQE.js} +195 -2
- package/dist/{run-attempt-DYc0QCBF.js → run-attempt-D1hJO4fX.js} +828 -2100
- package/dist/{runtime-artifact-BvyT1uyd.js → runtime-artifact-C3jVimFn.js} +21 -14
- package/dist/{session-binding-Bcynfd-_.js → session-binding-BHuTCRZQ.js} +198 -127
- package/dist/{session-catalog-DaLKVtpH.js → session-catalog-yyvTWFOw.js} +564 -408
- package/dist/{session-cli-DMc4oS2w.js → session-cli-CmFEXMAM.js} +1 -1
- package/dist/session-history-C5J1AKzG.js +87 -0
- package/dist/session-initialization-BeWzjGiR.js +74 -0
- package/dist/{session-permission-policy-BrNH1bjy.js → session-permission-policy-DeWVTCMj.js} +2 -2
- package/dist/session-retirement-BujDjXVF.js +97 -0
- package/dist/{session-upstream-marker-BIkusb95.js → session-upstream-marker-C351-5Qw.js} +19 -4
- package/dist/settled-turn-context-D3SNWtUn.js +268 -0
- package/dist/settled-turn-finalizer-BVJx4yoc.js +104 -0
- package/dist/{shared-client-DKz23hHY.js → shared-client-DxcfF9KX.js} +3480 -679
- package/dist/{side-question-DjA_jsNe.js → side-question-BTZAII4l.js} +108 -70
- package/dist/{thread-lifecycle-L7oEkTlq.js → thread-lifecycle-DAcEJ_Om.js} +2188 -1915
- package/dist/{thread-ownership-DZeuKH1j.js → thread-ownership-zGokd8i1.js} +25 -14
- package/dist/thread-policy-g4KbJPzp.js +54 -0
- package/dist/{plugin-app-cache-key-C1CAdfcP.js → thread-resume-C7pyVKeW.js} +59 -7
- package/dist/{transcript-mirror-DsCMWBca.js → transcript-mirror-DTUxFWa_.js} +79 -17
- package/dist/transport-stdio-CyPldczm.js +726 -0
- package/dist/{upstream-prompt-provenance-CFmsKwr9.js → upstream-prompt-provenance-LphB8slG.js} +8 -4
- package/dist/upstream-session-fork-CYlBIGVt.js +966 -0
- package/dist/{usage-ROIaW3wo.js → usage-Bj-rrzkR.js} +3 -3
- package/dist/{web-search-provider.runtime-ClaNPV7N.js → web-search-provider.runtime-D2FWSK4w.js} +3 -3
- package/openclaw.plugin.json +1 -30
- package/package.json +6 -6
- package/dist/command-rpc-CCeCkf_v.js +0 -90
- package/dist/incognito-session-ET_ufDH-.js +0 -2
- package/dist/model-catalog-i9rNBthX.js +0 -48
- package/dist/protocol-validators-VeJxxJ0U.js +0 -2421
- package/dist/request-DXXGHko0.js +0 -157
- package/dist/session-catalog-home-id-BNwAJ9D7.js +0 -18
- package/dist/session-retirement-CcNC3YSY.js +0 -36
- package/dist/settled-turn-finalizer-Dc3ApjU4.js +0 -328
- package/dist/thread-resume-BE9qNEW0.js +0 -30
- package/dist/transport-stdio-DhoGy33Z.js +0 -99
- package/dist/upstream-session-fork-DlaHxSLC.js +0 -326
|
@@ -1,15 +1,21 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { a as closeCodexStartupClientBestEffort, d as unsubscribeCodexThreadBestEffort, r as CodexAppServerUnsafeSubscriptionError } from "./attempt-client-cleanup-
|
|
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
|
|
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
|
|
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
|
|
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,
|
|
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 {
|
|
2
|
-
import {
|
|
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 =
|
|
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", {
|
|
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
|
|
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
|
-
|
|
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-
|
|
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 =
|
|
12
|
-
const CODEX_HISTORY_IMPORT_MAX_MESSAGE_BYTES =
|
|
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
|
-
|
|
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
|
|
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
|
|
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 (
|
|
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:
|
|
334
|
+
messages: transcriptMessages,
|
|
296
335
|
idempotencyScope: `codex-app-server:${params.thread.id}:history`
|
|
297
336
|
});
|
|
298
337
|
return {
|
|
299
|
-
importedMessages
|
|
300
|
-
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
|
-
|
|
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
|
-
|
|
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 =
|
|
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,
|
|
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 };
|