@openclaw/codex 2026.8.1-beta.3 → 2026.8.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 +4 -5
- package/dist/{attempt-client-cleanup-URjUlCHg.js → attempt-client-cleanup-CVPvp9dL.js} +47 -5
- package/dist/{auth-binding-B4FfbcCg.js → auth-binding-Ds_QVm-X.js} +18 -3
- package/dist/{binding-connection-DAvZwp96.js → binding-connection-CCQFs8lf.js} +2 -2
- package/dist/{bounded-turn-4BjrZEwW.js → bounded-turn-rq5tiSXk.js} +13 -18
- package/dist/{capabilities-CH3K57v4.js → capabilities-CGm_94eL.js} +1 -1
- package/dist/cli-metadata.js +1 -1
- package/dist/{command-formatters-D0nZ3qtd.js → command-formatters-C54Yg3eA.js} +2 -2
- package/dist/{command-handlers-DC86lgT4.js → command-handlers-BvOAHTrA.js} +89 -62
- package/dist/{compact-COqgBRny.js → compact-Hd7SAc0N.js} +8 -9
- package/dist/{config-CpNeo5AE.js → config-Cxw3Cl3k.js} +346 -286
- package/dist/doctor-contract-api.js +115 -14
- package/dist/{dynamic-tools-fJZhl4CE.js → dynamic-tools-BFoUcRdx.js} +147 -903
- package/dist/{effective-mcp-catalog-4YKn51aG.js → effective-mcp-catalog-BTJHnDSx.js} +2 -2
- package/dist/{event-projector-assistant-message-BwxV4d6N.js → event-projector-assistant-message-C5-Ds8mA.js} +18 -1
- package/dist/{event-projector-usage-CLwNEJqW.js → event-projector-usage-D3PHFFXh.js} +3 -3
- package/dist/{harness-DoKQcF8n.js → harness-DVfUQBlQ.js} +42 -52
- package/dist/harness.js +1 -1
- package/dist/index.js +278 -295
- package/dist/{isolated-completion-DPMtlH9r.js → isolated-completion-Cbbx_5Ed.js} +4 -4
- package/dist/launch-args-sXOAg0SX.js +84 -0
- package/dist/{managed-binary-By4FZC6i.js → managed-binary-ZkGodW19.js} +43 -7
- package/dist/media-understanding-provider.js +1 -1
- package/dist/model-catalog-o6Cgjoss.js +101 -0
- package/dist/{models-CZw1wClT.js → models-DgFWSuxA.js} +25 -28
- package/dist/{native-subagent-monitor-GGq3RnOo.js → native-subagent-monitor-CwFyoylz.js} +207 -30
- package/dist/{node-exec-server.runtime-Bsu1LdFZ.js → node-exec-server.runtime-DXrqpw1c.js} +8 -5
- package/dist/{plugin-approval-roundtrip-C75Yiiwc.js → plugin-approval-roundtrip-D80UZiJ_.js} +1 -1
- package/dist/{plugin-marketplace-discovery-CSWDkMrP.js → plugin-marketplace-discovery-mdmScYOj.js} +30 -39
- package/dist/{plugin-metadata-cache-BXH5NF-4.js → plugin-metadata-cache-CulOABwu.js} +162 -135
- package/dist/{protocol-validators-VAVyEnDp.js → protocol-validators-Bg5rpNxk.js} +148 -5
- package/dist/{rate-limits-BI1dMHDG.js → rate-limits-hFtzt2Up.js} +1 -1
- package/dist/{sandbox-guard-C1qEeZ5C.js → request-CCm4LaED.js} +183 -2
- package/dist/{run-attempt-BV3HzuCf.js → run-attempt-BwNQDH2u.js} +599 -361
- package/dist/{runtime-artifact-BvyT1uyd.js → runtime-artifact-DeBvleJw.js} +1 -1
- package/dist/{session-binding-BTrLf9Qm.js → session-binding-q2WSTVmC.js} +195 -122
- package/dist/{session-catalog-ezP_UcRM.js → session-catalog-C2Tae4rI.js} +229 -122
- package/dist/session-catalog-home-id-DAKUrm3C.js +112 -0
- package/dist/{session-cli-B1hKvfkI.js → session-cli-BuDjm5Ou.js} +1 -1
- package/dist/session-permission-policy-gLm40Vtq.js +160 -0
- package/dist/session-retirement-CdkI0bvb.js +90 -0
- package/dist/{session-upstream-marker-D_2npHlA.js → session-upstream-marker-Bcy33kam.js} +2 -3
- package/dist/{settled-turn-finalizer-Dx1onIqg.js → settled-turn-finalizer-B8JJcxCi.js} +7 -6
- package/dist/{shared-client-Dw-rzii0.js → shared-client-kNkljY-R.js} +1720 -786
- package/dist/{side-question-DbXkJZzg.js → side-question-GwD73tX6.js} +69 -39
- package/dist/{thread-lifecycle-DKdrnTMX.js → thread-lifecycle-Ss-uwnC4.js} +852 -359
- package/dist/{thread-ownership-i2NBwDUL.js → thread-ownership-CeYBqg_4.js} +18 -8
- package/dist/{plugin-app-cache-key-DMNQ8Zi8.js → thread-resume-DF54hagX.js} +52 -6
- package/dist/{transcript-mirror-BU0_LKAL.js → transcript-mirror-CkEQIna-.js} +112 -13
- package/dist/transport-stdio-C7-s9TLG.js +708 -0
- package/dist/{upstream-session-fork-BDVJCLAD.js → upstream-session-fork-BACGlOFa.js} +78 -86
- package/dist/{usage-9dKJCgcy.js → usage-C2l8Mils.js} +3 -3
- package/dist/{web-search-provider.runtime-DCdx4DGu.js → web-search-provider.runtime-B2XgRdFv.js} +3 -3
- package/openclaw.plugin.json +19 -1
- package/package.json +8 -8
- package/dist/app-server-policy-bg5QPSVP.js +0 -25
- package/dist/command-rpc-xUIIonsO.js +0 -90
- package/dist/incognito-session-ET_ufDH-.js +0 -2
- package/dist/model-catalog-CmGoqVKB.js +0 -48
- package/dist/request-DSK0W6YI.js +0 -157
- package/dist/session-catalog-home-id-BNwAJ9D7.js +0 -18
- package/dist/session-retirement-CE4iMiLh.js +0 -36
- package/dist/thread-resume-CdJk2Ehf.js +0 -30
- package/dist/transport-stdio-DhoGy33Z.js +0 -99
|
@@ -1,15 +1,20 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { a as closeCodexStartupClientBestEffort,
|
|
1
|
+
import { Ct as retainCodexAppServerLiveThread, St as releaseCodexAppServerLiveThread, _ as retainSharedCodexAppServerClientByInstanceId, bt as isCodexAppServerLiveThreadClaimed } from "./shared-client-kNkljY-R.js";
|
|
2
|
+
import { a as closeCodexStartupClientBestEffort, f as unsubscribeCodexThreadBestEffort, r as CodexAppServerUnsafeSubscriptionError } from "./attempt-client-cleanup-CVPvp9dL.js";
|
|
3
|
+
import { isIncognitoSessionKey } from "openclaw/plugin-sdk/routing";
|
|
3
4
|
import { KeyedAsyncQueue } from "openclaw/plugin-sdk/keyed-async-queue";
|
|
4
5
|
//#region extensions/codex/src/app-server/thread-ownership.ts
|
|
5
6
|
const nativeThreadOwners = new KeyedAsyncQueue();
|
|
7
|
+
/** Serialize connection-scoped unsubscribe with attach/resume of the same native thread. */
|
|
8
|
+
async function withCodexAppServerThreadMutation(threadId, run) {
|
|
9
|
+
return await nativeThreadOwners.enqueue(`thread:${threadId}`, run);
|
|
10
|
+
}
|
|
6
11
|
/** Codex subscriptions belong to a physical connection, not the native thread ID alone. */
|
|
7
12
|
function isSameCodexAppServerThreadOwner(current, expected) {
|
|
8
13
|
return current !== void 0 && expected !== void 0 && current.threadId === expected.threadId && current.clientId === expected.clientId;
|
|
9
14
|
}
|
|
10
15
|
/** Fences native subscription and commit together; Codex subscriptions are not reference-counted. */
|
|
11
16
|
async function withExclusiveCodexAppServerThread(params) {
|
|
12
|
-
return await
|
|
17
|
+
return await withCodexAppServerThreadMutation(params.threadId, async () => {
|
|
13
18
|
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
19
|
return await params.run();
|
|
15
20
|
});
|
|
@@ -20,11 +25,13 @@ async function withCodexConversationThreadActivity(bindingId, run) {
|
|
|
20
25
|
}
|
|
21
26
|
/** Publishes one owned persistent subscription into the shared bounded idle registry. */
|
|
22
27
|
async function retainCodexAppServerBindingSubscription(client, threadId, ownership) {
|
|
23
|
-
return await retainCodexAppServerLiveThread(client, threadId, ownership?.release ?? (async (releasedThreadId) => {
|
|
28
|
+
return await retainCodexAppServerLiveThread(client, threadId, ownership?.release ?? (async (releasedThreadId, assertCurrent) => {
|
|
24
29
|
if (!await unsubscribeCodexThreadBestEffort(client, {
|
|
25
30
|
threadId: releasedThreadId,
|
|
26
|
-
timeoutMs: 5e3
|
|
31
|
+
timeoutMs: 5e3,
|
|
32
|
+
assertCurrent
|
|
27
33
|
})) {
|
|
34
|
+
assertCurrent?.();
|
|
28
35
|
await closeCodexStartupClientBestEffort(client);
|
|
29
36
|
throw new CodexAppServerUnsafeSubscriptionError(`Codex thread subscription could not be released: ${releasedThreadId}`);
|
|
30
37
|
}
|
|
@@ -41,15 +48,18 @@ async function rollbackCodexAppServerBindingSubscription(client, threadId, retai
|
|
|
41
48
|
}
|
|
42
49
|
/** Releases only the physical client and native thread recorded by the displaced binding owner. */
|
|
43
50
|
async function releaseCodexAppServerBindingSubscription(binding, options = {}) {
|
|
51
|
+
options.assertCurrent?.();
|
|
44
52
|
const clientLease = retainSharedCodexAppServerClientByInstanceId(binding.clientId);
|
|
45
53
|
if (!clientLease) return;
|
|
46
54
|
try {
|
|
47
|
-
if (await releaseCodexAppServerLiveThread(clientLease.client, binding.threadId)) return;
|
|
55
|
+
if (await releaseCodexAppServerLiveThread(clientLease.client, binding.threadId, options.assertCurrent)) return;
|
|
56
|
+
options.assertCurrent?.();
|
|
48
57
|
if (isCodexAppServerLiveThreadClaimed(clientLease.client, binding.threadId)) throw new Error(`Codex thread ${binding.threadId} has an active run; stop it before changing its owner.`);
|
|
49
58
|
if (!options.allowUntracked) return;
|
|
50
59
|
if (!await unsubscribeCodexThreadBestEffort(clientLease.client, {
|
|
51
60
|
threadId: binding.threadId,
|
|
52
|
-
timeoutMs: 5e3
|
|
61
|
+
timeoutMs: 5e3,
|
|
62
|
+
assertCurrent: options.assertCurrent
|
|
53
63
|
})) {
|
|
54
64
|
await closeCodexStartupClientBestEffort(clientLease.client);
|
|
55
65
|
throw new CodexAppServerUnsafeSubscriptionError(`Codex retired thread subscription could not be released: ${binding.threadId}`);
|
|
@@ -89,4 +99,4 @@ async function retireCodexConversationThreadBinding(params) {
|
|
|
89
99
|
});
|
|
90
100
|
}
|
|
91
101
|
//#endregion
|
|
92
|
-
export { rollbackCodexAppServerBindingSubscription as a, retireCodexConversationThreadBinding as i, releaseCodexAppServerBindingSubscription as n,
|
|
102
|
+
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 };
|
|
@@ -1,5 +1,8 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { F as resolveCodexAppServerLocalHomeDir, I as resolveCodexAppServerUserHomeDir, P as resolveCodexAppServerHomeDir } from "./config-Cxw3Cl3k.js";
|
|
2
|
+
import { $ as CodexAppServerRpcError, J as isCodexAppServerOverloadError, P as isCodexAppServerStartupError, Y as isCodexAppServerPrewriteRequestCancellationError, u as isCodexAppServerStartSelectionChangedError } from "./shared-client-kNkljY-R.js";
|
|
3
|
+
import { o as assertCodexThreadResumeResponse } from "./protocol-validators-Bg5rpNxk.js";
|
|
4
|
+
import { f as unsubscribeCodexThreadBestEffort, i as assertCodexThreadResumeSubscription, r as CodexAppServerUnsafeSubscriptionError } from "./attempt-client-cleanup-CVPvp9dL.js";
|
|
5
|
+
import { t as CodexAppServerScopedRequestRejectedError } from "./request-CCm4LaED.js";
|
|
3
6
|
import { createRequire } from "node:module";
|
|
4
7
|
import { isRecord } from "openclaw/plugin-sdk/string-coerce-runtime";
|
|
5
8
|
import { readPluginPackageVersion } from "openclaw/plugin-sdk/extension-shared";
|
|
@@ -264,7 +267,10 @@ async function readInstalledApps(request, options) {
|
|
|
264
267
|
apps: [],
|
|
265
268
|
installedApps: []
|
|
266
269
|
};
|
|
267
|
-
const metadataResponses = await Promise.all(Array.from({ length: Math.ceil(apps.length / CODEX_APP_READ_BATCH_LIMIT) }, (_, index) => request("app/read", {
|
|
270
|
+
const metadataResponses = await Promise.all(Array.from({ length: Math.ceil(apps.length / CODEX_APP_READ_BATCH_LIMIT) }, (_, index) => request("app/read", {
|
|
271
|
+
appIds: apps.slice(index * CODEX_APP_READ_BATCH_LIMIT, (index + 1) * CODEX_APP_READ_BATCH_LIMIT).map((app) => app.id),
|
|
272
|
+
includeTools: true
|
|
273
|
+
})));
|
|
268
274
|
const metadataById = new Map(metadataResponses.flatMap((response) => response.apps).map((metadata) => [metadata.id, metadata]));
|
|
269
275
|
return {
|
|
270
276
|
apps: apps.flatMap((installedApp) => {
|
|
@@ -283,7 +289,8 @@ async function readInstalledApps(request, options) {
|
|
|
283
289
|
installUrl: metadata.installUrl ?? null,
|
|
284
290
|
isAccessible: true,
|
|
285
291
|
isEnabled: installedApp.enabled,
|
|
286
|
-
pluginDisplayNames: metadata.pluginDisplayNames
|
|
292
|
+
pluginDisplayNames: metadata.pluginDisplayNames,
|
|
293
|
+
...metadata.toolSummaries ? { toolSummaries: metadata.toolSummaries } : {}
|
|
287
294
|
}];
|
|
288
295
|
}),
|
|
289
296
|
installedApps: apps
|
|
@@ -348,7 +355,10 @@ function buildCodexPluginAppCacheKey(params) {
|
|
|
348
355
|
accountId: params.accountId,
|
|
349
356
|
envApiKeyFingerprint: params.envApiKeyFingerprint,
|
|
350
357
|
appServerVersion: params.appServerVersion ?? params.runtimeIdentity?.serverVersion,
|
|
351
|
-
runtimeIdentity: params.
|
|
358
|
+
runtimeIdentity: params.desktopGenerationFingerprint ? {
|
|
359
|
+
...params.runtimeIdentity,
|
|
360
|
+
desktopGeneration: params.desktopGenerationFingerprint
|
|
361
|
+
} : params.runtimeIdentity
|
|
352
362
|
}, OPENCLAW_VERSION, CODEX_PLUGIN_VERSION);
|
|
353
363
|
}
|
|
354
364
|
/** Builds a durable thread-binding fingerprint for one initialized app-server runtime. */
|
|
@@ -417,4 +427,40 @@ function fingerprintCodexPluginAppCacheCredentials(startOptions) {
|
|
|
417
427
|
return `sha256:${hash.digest("hex")}`;
|
|
418
428
|
}
|
|
419
429
|
//#endregion
|
|
420
|
-
|
|
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
|
+
try {
|
|
437
|
+
response = assertCodexThreadResumeResponse(await (params.requestResume ? params.requestResume(params.request) : params.client.request("thread/resume", params.request, {
|
|
438
|
+
...params.timeoutMs !== void 0 ? { timeoutMs: params.timeoutMs } : {},
|
|
439
|
+
...params.signal ? { signal: params.signal } : {},
|
|
440
|
+
assertCurrent: params.assertCurrent
|
|
441
|
+
})));
|
|
442
|
+
assertCodexThreadResumeSubscription(threadId, response.thread.id);
|
|
443
|
+
} catch (error) {
|
|
444
|
+
if (params.isPrewriteOwnershipError?.(error) || isCodexAppServerStartSelectionChangedError(error) || isCodexAppServerStartupError(error) || error instanceof CodexAppServerScopedRequestRejectedError || isCodexAppServerPrewriteRequestCancellationError(error) || isCodexAppServerOverloadError(error)) throw error;
|
|
445
|
+
if (error instanceof CodexAppServerRpcError) {
|
|
446
|
+
if (await unsubscribeCodexThreadBestEffort(params.client, {
|
|
447
|
+
threadId,
|
|
448
|
+
timeoutMs: 5e3,
|
|
449
|
+
assertCurrent: params.assertCurrent
|
|
450
|
+
}).catch(() => false)) {
|
|
451
|
+
params.onSubscriptionReleased?.();
|
|
452
|
+
throw error;
|
|
453
|
+
}
|
|
454
|
+
}
|
|
455
|
+
try {
|
|
456
|
+
await params.abandonClient();
|
|
457
|
+
} catch (abandonError) {
|
|
458
|
+
throw new CodexAppServerUnsafeSubscriptionError(`Codex thread/resume client could not be retired for ${threadId}`, { cause: abandonError });
|
|
459
|
+
}
|
|
460
|
+
if (error instanceof CodexAppServerUnsafeSubscriptionError) throw error;
|
|
461
|
+
throw new CodexAppServerUnsafeSubscriptionError(error instanceof Error ? error.message : `Codex thread/resume outcome is indeterminate for ${threadId}`, { cause: error });
|
|
462
|
+
}
|
|
463
|
+
return response;
|
|
464
|
+
}
|
|
465
|
+
//#endregion
|
|
466
|
+
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,6 +1,6 @@
|
|
|
1
1
|
import { i as readUpstreamUserText, n as attachUpstreamUserText, r as readMirrorIdentity, t as attachCodexMirrorIdentity } from "./upstream-prompt-provenance-CFmsKwr9.js";
|
|
2
2
|
import { asOptionalRecord, normalizeOptionalString } from "openclaw/plugin-sdk/string-coerce-runtime";
|
|
3
|
-
import { embeddedAgentLog, formatErrorMessage, projectAgentHarnessTranscriptMessageForDisplay, runAgentHarnessBeforeMessageWriteHook } from "openclaw/plugin-sdk/agent-harness-runtime";
|
|
3
|
+
import { deliverAgentHarnessUserInputPrompt, embeddedAgentLog, formatErrorMessage, projectAgentHarnessTranscriptMessageForDisplay, runAgentHarnessBeforeMessageWriteHook } from "openclaw/plugin-sdk/agent-harness-runtime";
|
|
4
4
|
import { createHash } from "node:crypto";
|
|
5
5
|
import { truncateUtf8Prefix } from "openclaw/plugin-sdk/text-utility-runtime";
|
|
6
6
|
import { withCodexSessionTranscriptMirrorWriteLock } from "openclaw/plugin-sdk/codex-session-transcript-runtime";
|
|
@@ -82,6 +82,8 @@ function projectCodexThreadHistory(params) {
|
|
|
82
82
|
const role = item.type === "userMessage" ? "user" : item.type === "agentMessage" ? "assistant" : void 0;
|
|
83
83
|
itemOffset += 1;
|
|
84
84
|
if (!text || !role) continue;
|
|
85
|
+
const phase = item.phase === "commentary" || item.phase === "final_answer" ? item.phase : void 0;
|
|
86
|
+
const asyncDelivery = item.delivery === "async";
|
|
85
87
|
const message = role === "assistant" ? attachCodexMirrorIdentity({
|
|
86
88
|
role,
|
|
87
89
|
content: [{
|
|
@@ -94,13 +96,14 @@ function projectCodexThreadHistory(params) {
|
|
|
94
96
|
usage: CODEX_HISTORY_ZERO_USAGE,
|
|
95
97
|
stopReason: turn.status === "interrupted" ? "aborted" : turn.status === "failed" ? "error" : "stop",
|
|
96
98
|
...turn.status === "failed" && turn.error?.message ? { errorMessage: turn.error.message } : {},
|
|
99
|
+
...phase ? { phase } : {},
|
|
100
|
+
...asyncDelivery && itemId ? { openclawAsyncDelivery: { itemId } } : {},
|
|
97
101
|
timestamp
|
|
98
102
|
}, identity) : attachCodexMirrorIdentity({
|
|
99
103
|
role,
|
|
100
104
|
content: text,
|
|
101
105
|
timestamp
|
|
102
106
|
}, identity);
|
|
103
|
-
const phase = item.phase === "commentary" || item.phase === "final_answer" ? item.phase : void 0;
|
|
104
107
|
projected.push({
|
|
105
108
|
message,
|
|
106
109
|
responseItem: {
|
|
@@ -141,7 +144,7 @@ function projectBoundedCodexThreadHistory(params) {
|
|
|
141
144
|
return {
|
|
142
145
|
importedMessages: selected.length,
|
|
143
146
|
omittedMessages: projected.length - selected.length,
|
|
144
|
-
responseItems: selected.filter(({ message }) => message.role !== "assistant" || message.stopReason !== "aborted" && message.stopReason !== "error").map(({ responseItem }) => responseItem),
|
|
147
|
+
responseItems: selected.filter(({ message }) => message.role !== "assistant" || message.stopReason !== "aborted" && message.stopReason !== "error" && !("openclawAsyncDelivery" in message)).map(({ responseItem }) => responseItem),
|
|
145
148
|
transcriptMessages: selected.map(({ message }) => message)
|
|
146
149
|
};
|
|
147
150
|
}
|
|
@@ -150,7 +153,7 @@ function projectBoundedCodexVisibleSessionHistory(entries) {
|
|
|
150
153
|
const projected = [];
|
|
151
154
|
for (const entry of entries) {
|
|
152
155
|
if (entry.role !== "user" && entry.role !== "assistant" || !("content" in entry.message)) continue;
|
|
153
|
-
if (entry.role === "assistant" && "stopReason" in entry.message && (entry.message.stopReason === "aborted" || entry.message.stopReason === "error")) continue;
|
|
156
|
+
if (entry.role === "assistant" && ("stopReason" in entry.message && (entry.message.stopReason === "aborted" || entry.message.stopReason === "error") || "openclawAsyncDelivery" in entry.message)) continue;
|
|
154
157
|
const content = entry.message.content;
|
|
155
158
|
const text = normalizeImportedHistoryText(typeof content === "string" ? content : Array.isArray(content) ? content.flatMap((part) => part && typeof part === "object" && "text" in part && typeof part.text === "string" ? [part.text] : []).join("\n") : void 0);
|
|
156
159
|
if (!text) continue;
|
|
@@ -175,6 +178,21 @@ const MIRROR_ORIGIN_META_KEY = "mirrorOrigin";
|
|
|
175
178
|
const MIRROR_SOURCE_FINGERPRINT_META_KEY = "mirrorSourceFingerprint";
|
|
176
179
|
const CODEX_APP_SERVER_MIRROR_ORIGIN = "codex-app-server";
|
|
177
180
|
const CODEX_META_KEY = "__openclaw";
|
|
181
|
+
function applyCodexTranscriptTaint(message, state) {
|
|
182
|
+
if (message.role === "user") {
|
|
183
|
+
state.tainted = false;
|
|
184
|
+
return message;
|
|
185
|
+
}
|
|
186
|
+
const metadata = asOptionalRecord(CODEX_META_KEY in message ? message[CODEX_META_KEY] : void 0);
|
|
187
|
+
state.tainted ||= metadata?.turnTainted === true || metadata?.resultContentSource === "network";
|
|
188
|
+
return message.role === "assistant" && state.tainted ? {
|
|
189
|
+
...message,
|
|
190
|
+
__openclaw: {
|
|
191
|
+
...metadata,
|
|
192
|
+
turnTainted: true
|
|
193
|
+
}
|
|
194
|
+
} : message;
|
|
195
|
+
}
|
|
178
196
|
function attachCodexMirrorAttestation(message, sourceFingerprint) {
|
|
179
197
|
const existing = CODEX_META_KEY in message ? message[CODEX_META_KEY] : void 0;
|
|
180
198
|
const baseMeta = existing && typeof existing === "object" && !Array.isArray(existing) ? existing : {};
|
|
@@ -270,6 +288,10 @@ async function buildResolvedCodexUserPromptMessage(params) {
|
|
|
270
288
|
function isMirroredAgentMessage(message) {
|
|
271
289
|
return message.role === "user" || message.role === "assistant" || message.role === "toolResult";
|
|
272
290
|
}
|
|
291
|
+
function readMirroredAssistantText(message) {
|
|
292
|
+
if (message?.role !== "assistant") return;
|
|
293
|
+
return message.content.flatMap((part) => part.type === "text" ? [part.text] : []).join("\n") || void 0;
|
|
294
|
+
}
|
|
273
295
|
/** Imports a bounded, user-visible Codex history tail into a new OpenClaw transcript. */
|
|
274
296
|
async function importCodexThreadHistoryToTranscript(params) {
|
|
275
297
|
const projection = projectBoundedCodexThreadHistory({
|
|
@@ -318,6 +340,7 @@ async function mirrorBestEffort(params) {
|
|
|
318
340
|
mirrorIdentity: `${params.turnId}:assistant`,
|
|
319
341
|
runId: params.params.runId
|
|
320
342
|
},
|
|
343
|
+
prepareAssistantTranscriptMessage: params.params.prepareAssistantTranscriptMessage,
|
|
321
344
|
config: params.params.config
|
|
322
345
|
});
|
|
323
346
|
for (const receipt of mirrorResult.userMessageReceipts) try {
|
|
@@ -431,6 +454,7 @@ function buildMirrorDedupeIdentity(message) {
|
|
|
431
454
|
async function mirror(params) {
|
|
432
455
|
const messages = params.messages.filter(isMirroredAgentMessage);
|
|
433
456
|
if (messages.length === 0) return {
|
|
457
|
+
assistantMirrorIdentitiesAppended: [],
|
|
434
458
|
assistantMirrorIdentitiesOwned: [],
|
|
435
459
|
anchorsByMirrorIdentity: /* @__PURE__ */ new Map(),
|
|
436
460
|
messagesPresent: [],
|
|
@@ -449,11 +473,12 @@ async function mirror(params) {
|
|
|
449
473
|
});
|
|
450
474
|
const candidateIdempotencyKeys = candidates.flatMap(({ idempotencyKey }) => idempotencyKey ? [idempotencyKey] : []);
|
|
451
475
|
const transcriptTarget = resolveCodexMirrorTranscriptTarget(params);
|
|
452
|
-
const { appendedUpdates, assistantMirrorIdentitiesOwned, anchorsByMirrorIdentity, messagesPresent, userMessageReceipts, userMessagesPresent } = await withCodexSessionTranscriptMirrorWriteLock({
|
|
476
|
+
const { appendedUpdates, assistantMirrorIdentitiesAppended, assistantMirrorIdentitiesOwned, anchorsByMirrorIdentity, messagesPresent, userMessageReceipts, userMessagesPresent } = await withCodexSessionTranscriptMirrorWriteLock({
|
|
453
477
|
...transcriptTarget,
|
|
454
478
|
config: params.config
|
|
455
479
|
}, async (transcript) => {
|
|
456
480
|
const nextAppendedUpdates = [];
|
|
481
|
+
const nextAssistantMirrorIdentitiesAppended = /* @__PURE__ */ new Set();
|
|
457
482
|
const nextAssistantMirrorIdentitiesOwned = /* @__PURE__ */ new Set();
|
|
458
483
|
const nextAnchorsByMirrorIdentity = /* @__PURE__ */ new Map();
|
|
459
484
|
const nextMessagesPresent = [];
|
|
@@ -486,10 +511,12 @@ async function mirror(params) {
|
|
|
486
511
|
if (message.role === "assistant") nextAssistantMirrorIdentitiesOwned.add(dedupeIdentity);
|
|
487
512
|
continue;
|
|
488
513
|
}
|
|
489
|
-
const nextMessage =
|
|
514
|
+
const nextMessage = runAgentHarnessBeforeMessageWriteHook({
|
|
490
515
|
message: transcriptMessage,
|
|
491
516
|
agentId: params.agentId,
|
|
492
|
-
sessionKey: params.sessionKey
|
|
517
|
+
sessionKey: params.sessionKey,
|
|
518
|
+
skipBeforeMessageWriteHooks: params.skipBeforeMessageWriteHooks,
|
|
519
|
+
prepareAssistantTranscriptMessage: ownsTerminal ? params.prepareAssistantTranscriptMessage : void 0
|
|
493
520
|
});
|
|
494
521
|
if (!nextMessage) {
|
|
495
522
|
if (message.role === "assistant") nextAssistantMirrorIdentitiesOwned.add(dedupeIdentity);
|
|
@@ -501,6 +528,7 @@ async function mirror(params) {
|
|
|
501
528
|
} : attachCodexMirrorAttestation(nextMessage, sourceFingerprint);
|
|
502
529
|
if (mirrorIdentity) messageToAppend = attachCodexMirrorIdentity(messageToAppend, mirrorIdentity);
|
|
503
530
|
if (ownsRun && params.runId) messageToAppend = attachCodexMirrorRunId(messageToAppend, params.runId, ownsTerminal);
|
|
531
|
+
if (message.role === "assistant" && message.openclawAsyncDelivery) messageToAppend = Object.assign(messageToAppend, { openclawAsyncDelivery: { itemId: message.openclawAsyncDelivery.itemId } });
|
|
504
532
|
messageToAppend = projectAgentHarnessTranscriptMessageForDisplay({
|
|
505
533
|
hidden: message.display === false,
|
|
506
534
|
message: messageToAppend
|
|
@@ -525,11 +553,14 @@ async function mirror(params) {
|
|
|
525
553
|
message: appendedMessage
|
|
526
554
|
});
|
|
527
555
|
}
|
|
528
|
-
if (appended.appended)
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
556
|
+
if (appended.appended) {
|
|
557
|
+
if (message.role === "assistant") nextAssistantMirrorIdentitiesAppended.add(dedupeIdentity);
|
|
558
|
+
nextAppendedUpdates.push({
|
|
559
|
+
messageId,
|
|
560
|
+
message: appendedMessage,
|
|
561
|
+
...messageSeq !== void 0 ? { messageSeq } : {}
|
|
562
|
+
});
|
|
563
|
+
}
|
|
533
564
|
if (idempotencyKey) {
|
|
534
565
|
mirrorFacts.existingIdempotencyKeys.add(idempotencyKey);
|
|
535
566
|
if (appended.anchor) mirrorFacts.anchorsByIdempotencyKey.set(idempotencyKey, appended.anchor);
|
|
@@ -537,6 +568,7 @@ async function mirror(params) {
|
|
|
537
568
|
}
|
|
538
569
|
return {
|
|
539
570
|
appendedUpdates: nextAppendedUpdates,
|
|
571
|
+
assistantMirrorIdentitiesAppended: [...nextAssistantMirrorIdentitiesAppended],
|
|
540
572
|
assistantMirrorIdentitiesOwned: [...nextAssistantMirrorIdentitiesOwned],
|
|
541
573
|
anchorsByMirrorIdentity: nextAnchorsByMirrorIdentity,
|
|
542
574
|
messagesPresent: nextMessagesPresent,
|
|
@@ -562,6 +594,7 @@ async function mirror(params) {
|
|
|
562
594
|
embeddedAgentLog.warn("failed to publish codex app-server transcript update", { error: formatErrorMessage(error) });
|
|
563
595
|
}
|
|
564
596
|
return {
|
|
597
|
+
assistantMirrorIdentitiesAppended,
|
|
565
598
|
assistantMirrorIdentitiesOwned,
|
|
566
599
|
anchorsByMirrorIdentity,
|
|
567
600
|
messagesPresent,
|
|
@@ -569,10 +602,76 @@ async function mirror(params) {
|
|
|
569
602
|
userMessagesPresent
|
|
570
603
|
};
|
|
571
604
|
}
|
|
605
|
+
async function deliverAsyncMessageBestEffort(params) {
|
|
606
|
+
const mirrorIdentity = `${params.turnId}:async:${params.itemId}`;
|
|
607
|
+
const deliveryIntentId = `block-reply:v1:codex-app-server:${[
|
|
608
|
+
params.threadId,
|
|
609
|
+
params.turnId,
|
|
610
|
+
params.itemId
|
|
611
|
+
].map(encodeURIComponent).join(":")}`;
|
|
612
|
+
const target = params.params.sessionTarget;
|
|
613
|
+
if (!target) {
|
|
614
|
+
if (!params.params.onBlockReply) return "retry";
|
|
615
|
+
try {
|
|
616
|
+
await deliverAsyncBlockReply(params.params.onBlockReply, params.text, deliveryIntentId);
|
|
617
|
+
return "settled";
|
|
618
|
+
} catch (error) {
|
|
619
|
+
embeddedAgentLog.warn("failed to deliver codex async agent message", {
|
|
620
|
+
error: formatErrorMessage(error),
|
|
621
|
+
itemId: params.itemId,
|
|
622
|
+
runId: params.params.runId,
|
|
623
|
+
threadId: params.threadId,
|
|
624
|
+
turnId: params.turnId
|
|
625
|
+
});
|
|
626
|
+
return "retry";
|
|
627
|
+
}
|
|
628
|
+
}
|
|
629
|
+
let result;
|
|
630
|
+
try {
|
|
631
|
+
result = await mirror({
|
|
632
|
+
agentId: target.agentId ?? params.params.agentId,
|
|
633
|
+
sessionId: target.sessionId ?? params.params.sessionId,
|
|
634
|
+
sessionKey: target.sessionKey ?? params.params.sessionKey,
|
|
635
|
+
storePath: target.storePath,
|
|
636
|
+
cwd: params.cwd,
|
|
637
|
+
config: params.params.config,
|
|
638
|
+
messages: [attachCodexMirrorIdentity(params.message, mirrorIdentity)],
|
|
639
|
+
idempotencyScope: `codex-app-server:${params.threadId}`
|
|
640
|
+
});
|
|
641
|
+
} catch (error) {
|
|
642
|
+
embeddedAgentLog.warn("failed to persist codex async agent message", {
|
|
643
|
+
error: formatErrorMessage(error),
|
|
644
|
+
itemId: params.itemId,
|
|
645
|
+
runId: params.params.runId,
|
|
646
|
+
threadId: params.threadId,
|
|
647
|
+
turnId: params.turnId
|
|
648
|
+
});
|
|
649
|
+
return "retry";
|
|
650
|
+
}
|
|
651
|
+
if (!result.assistantMirrorIdentitiesOwned.includes(mirrorIdentity)) return "retry";
|
|
652
|
+
const persistedText = readMirroredAssistantText(result.messagesPresent.find((message) => readMirrorIdentity(message) === mirrorIdentity));
|
|
653
|
+
if (params.params.onBlockReply && persistedText !== void 0) try {
|
|
654
|
+
await deliverAsyncBlockReply(params.params.onBlockReply, persistedText, deliveryIntentId);
|
|
655
|
+
} catch (error) {
|
|
656
|
+
embeddedAgentLog.warn("failed to deliver persisted codex async agent message", {
|
|
657
|
+
error: formatErrorMessage(error),
|
|
658
|
+
itemId: params.itemId,
|
|
659
|
+
runId: params.params.runId,
|
|
660
|
+
threadId: params.threadId,
|
|
661
|
+
turnId: params.turnId
|
|
662
|
+
});
|
|
663
|
+
return "retry";
|
|
664
|
+
}
|
|
665
|
+
return "settled";
|
|
666
|
+
}
|
|
572
667
|
const codexTranscriptMirrorRuntime = {
|
|
668
|
+
deliverAsyncMessageBestEffort,
|
|
573
669
|
mirror,
|
|
574
670
|
mirrorBestEffort
|
|
575
671
|
};
|
|
672
|
+
async function deliverAsyncBlockReply(onBlockReply, text, deliveryIntentId) {
|
|
673
|
+
await deliverAgentHarnessUserInputPrompt({ onBlockReply: (payload) => onBlockReply(payload, { deliveryIntentId }) }, [], { intro: text });
|
|
674
|
+
}
|
|
576
675
|
function resolveCodexMirrorTranscriptTarget(params) {
|
|
577
676
|
const sessionKey = params.sessionKey?.trim();
|
|
578
677
|
const storePath = params.storePath?.trim();
|
|
@@ -585,4 +684,4 @@ function resolveCodexMirrorTranscriptTarget(params) {
|
|
|
585
684
|
};
|
|
586
685
|
}
|
|
587
686
|
//#endregion
|
|
588
|
-
export { buildCodexUserPromptMessage as a,
|
|
687
|
+
export { buildCodexUserPromptMessage as a, fingerprintCodexMirrorSourceMessage as c, projectBoundedCodexThreadHistory as d, projectBoundedCodexVisibleSessionHistory as f, mirrorPromptAtTurnStartBestEffort as i, readCodexMirrorSourceFingerprint as l, createCodexAppServerUserMessagePersistenceNotifier as n, promptSnapshot as o, projectCodexUserItemText as p, importCodexThreadHistoryToTranscript as r, applyCodexTranscriptTaint as s, codexTranscriptMirrorRuntime as t, serializeCodexMirrorSourceEvidence as u };
|