@openclaw/codex 2026.7.2-beta.5 → 2026.8.1-beta.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -0
- package/dist/{app-server-policy-BmDgseo_.js → app-server-policy-zcBDc1JU.js} +1 -1
- package/dist/attempt-client-cleanup-DMLXUfa8.js +735 -0
- package/dist/binding-connection-I5Bo-AsX.js +33 -0
- package/dist/{bounded-turn-FEbUXoYT.js → bounded-turn-qgZmzy_4.js} +71 -63
- package/dist/{capabilities-BHRSI6Cn.js → capabilities-CybGI1oz.js} +8 -2
- package/dist/cli-metadata.js +1 -1
- package/dist/{command-formatters-ico4ZFnk.js → command-formatters-B1AEz8ZA.js} +18 -18
- package/dist/{command-handlers-CRmnwI2N.js → command-handlers-Db8pu_ds.js} +484 -95
- package/dist/{compact-dEN49UH6.js → compact-LspQaGfl.js} +213 -199
- package/dist/{conversation-binding-data-BHRpYbX3.js → conversation-binding-data-CW2GuupV.js} +6 -10
- package/dist/doctor-contract-api.js +40 -43
- package/dist/{dynamic-tools-LIt9ojep.js → dynamic-tools-BVdyWkUD.js} +2984 -1221
- package/dist/effective-mcp-catalog-DIIhAtOZ.js +119 -0
- package/dist/{event-projector-assistant-message-DTgnPPVF.js → event-projector-assistant-message-BwxV4d6N.js} +11 -23
- package/dist/{attempt-notifications-CMR2_fmR.js → event-projector-usage-e5huIQWu.js} +113 -29
- package/dist/harness.js +83 -13
- package/dist/image-payload-sanitizer-CnfoUPCE.js +65 -0
- package/dist/index.js +703 -329
- package/dist/isolated-completion-C58NbL40.js +75 -0
- package/dist/local-runtime-attribution-B_2mnqhb.js +19 -0
- package/dist/media-understanding-provider.js +5 -5
- package/dist/{models-BA01NEez.js → models-BFlpn1Ex.js} +12 -17
- package/dist/native-subagent-monitor-DyTGmTUx.js +3111 -0
- package/dist/{plugin-app-cache-key-DSXX-rXO.js → plugin-app-cache-key-C3H2CVp6.js} +135 -42
- package/dist/plugin-marketplace-discovery-CzrGJdCR.js +385 -0
- package/dist/{computer-use-BjGylO-E.js → plugin-metadata-cache-CNJPj4_b.js} +211 -113
- package/dist/protocol-validators-B4F7L8Rf.js +2346 -0
- package/dist/{rate-limits-S_PXs0ul.js → rate-limits-DZXmOL8-.js} +17 -35
- package/dist/{request-CXpPennK.js → request-BRl5_UfX.js} +4 -4
- package/dist/{run-attempt-C5GTPJOE.js → run-attempt-P8BdxC1I.js} +1996 -5728
- package/dist/{runtime-artifact-C2ITXdhM.js → runtime-artifact-BVSPdd6g.js} +91 -40
- package/dist/{sandbox-guard-D1Wky__S.js → sandbox-guard-Cmwc9eIk.js} +10 -13
- package/dist/{session-binding-DlVQ-Pxs.js → session-binding-DPxIvMgE.js} +305 -271
- package/dist/{session-catalog-CP2oCcEb.js → session-catalog-xwNi_SDM.js} +418 -144
- package/dist/{session-cli-CqZ0Fp2a.js → session-cli-7hgXZDV7.js} +1 -1
- package/dist/session-retirement-DoMMJFKm.js +36 -0
- package/dist/{session-upstream-marker-QE-m5QFG.js → session-upstream-marker-CrIFX06J.js} +1 -1
- package/dist/{settled-turn-finalizer-CA_2QXIE.js → settled-turn-finalizer-BRWBO4MO.js} +36 -15
- package/dist/{shared-client-BVKE40c-.js → shared-client-kIBbGjk4.js} +721 -240
- package/dist/{side-question-CO12sHxo.js → side-question-9HAL26l9.js} +102 -53
- package/dist/{thread-lifecycle-DRg_FdzC.js → thread-lifecycle-Bu1BTDXr.js} +1355 -660
- package/dist/thread-ownership-6kOQHlyC.js +92 -0
- package/dist/thread-resume-CPrJNQVM.js +30 -0
- package/dist/{transcript-mirror-uKA-A4tB.js → transcript-mirror-B9gGgnJS.js} +202 -182
- package/dist/{transport-stdio-DXgGZ7Ib.js → transport-stdio-DIImwDVS.js} +11 -0
- package/dist/upstream-prompt-provenance-ClRBije0.js +41 -0
- package/dist/{upstream-session-fork-_Vrz4WJr.js → upstream-session-fork-CE-_LdnP.js} +5 -5
- package/dist/{usage-UpVbdX5G.js → usage-CHlV0e-o.js} +3 -3
- package/dist/{web-search-provider.runtime-CaQMYDbp.js → web-search-provider.runtime-DRw2Vl42.js} +8 -9
- package/openclaw.plugin.json +18 -3
- package/package.json +6 -7
- package/dist/attempt-client-cleanup-Ia52yRWc.js +0 -127
- package/dist/conversation-control-DE7d9DOj.js +0 -287
- package/dist/event-projector-usage-tvgb1NCX.js +0 -69
- package/dist/notification-correlation-Bj_Ak_jI.js +0 -67
- package/dist/protocol-validators-Dm4eXZmt.js +0 -6337
- package/dist/realtime-voice-api-BPcA1uN9.js +0 -494
- package/dist/realtime-voice-api.js +0 -2
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import { K as releaseCodexAppServerLiveThread, W as isCodexAppServerLiveThreadClaimed, d as retainSharedCodexAppServerClientByInstanceId, q as retainCodexAppServerLiveThread } from "./shared-client-kIBbGjk4.js";
|
|
2
|
+
import { a as closeCodexStartupClientBestEffort, d as unsubscribeCodexThreadBestEffort, r as CodexAppServerUnsafeSubscriptionError } from "./attempt-client-cleanup-DMLXUfa8.js";
|
|
3
|
+
import { KeyedAsyncQueue } from "openclaw/plugin-sdk/keyed-async-queue";
|
|
4
|
+
//#region extensions/codex/src/app-server/thread-ownership.ts
|
|
5
|
+
const nativeThreadOwners = new KeyedAsyncQueue();
|
|
6
|
+
/** Codex subscriptions belong to a physical connection, not the native thread ID alone. */
|
|
7
|
+
function isSameCodexAppServerThreadOwner(current, expected) {
|
|
8
|
+
return current !== void 0 && expected !== void 0 && current.threadId === expected.threadId && current.clientId === expected.clientId;
|
|
9
|
+
}
|
|
10
|
+
/** Fences native subscription and commit together; Codex subscriptions are not reference-counted. */
|
|
11
|
+
async function withExclusiveCodexAppServerThread(params) {
|
|
12
|
+
return await nativeThreadOwners.enqueue(`thread:${params.threadId}`, async () => {
|
|
13
|
+
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
|
+
return await params.run();
|
|
15
|
+
});
|
|
16
|
+
}
|
|
17
|
+
/** Serializes bound turns and retirement so detach cannot unsubscribe an active turn. */
|
|
18
|
+
async function withCodexConversationThreadActivity(bindingId, run) {
|
|
19
|
+
return await nativeThreadOwners.enqueue(`conversation:${bindingId}`, run);
|
|
20
|
+
}
|
|
21
|
+
/** Publishes one owned persistent subscription into the shared bounded idle registry. */
|
|
22
|
+
async function retainCodexAppServerBindingSubscription(client, threadId, ownership) {
|
|
23
|
+
return await retainCodexAppServerLiveThread(client, threadId, ownership?.release ?? (async (releasedThreadId) => {
|
|
24
|
+
if (!await unsubscribeCodexThreadBestEffort(client, {
|
|
25
|
+
threadId: releasedThreadId,
|
|
26
|
+
timeoutMs: 5e3
|
|
27
|
+
})) {
|
|
28
|
+
await closeCodexStartupClientBestEffort(client);
|
|
29
|
+
throw new CodexAppServerUnsafeSubscriptionError(`Codex thread subscription could not be released: ${releasedThreadId}`);
|
|
30
|
+
}
|
|
31
|
+
}), ownership?.configFingerprint, ownership?.serviceTier);
|
|
32
|
+
}
|
|
33
|
+
/** Rolls back the exact subscription Codex created before its binding was committed. */
|
|
34
|
+
async function rollbackCodexAppServerBindingSubscription(client, threadId, retained) {
|
|
35
|
+
if (retained && await releaseCodexAppServerLiveThread(client, threadId)) return;
|
|
36
|
+
if (isCodexAppServerLiveThreadClaimed(client, threadId)) return;
|
|
37
|
+
if (!await unsubscribeCodexThreadBestEffort(client, {
|
|
38
|
+
threadId,
|
|
39
|
+
timeoutMs: 5e3
|
|
40
|
+
})) await closeCodexStartupClientBestEffort(client);
|
|
41
|
+
}
|
|
42
|
+
/** Releases only the physical client and native thread recorded by the displaced binding owner. */
|
|
43
|
+
async function releaseCodexAppServerBindingSubscription(binding, options = {}) {
|
|
44
|
+
const clientLease = retainSharedCodexAppServerClientByInstanceId(binding.clientId);
|
|
45
|
+
if (!clientLease) return;
|
|
46
|
+
try {
|
|
47
|
+
if (await releaseCodexAppServerLiveThread(clientLease.client, binding.threadId)) return;
|
|
48
|
+
if (isCodexAppServerLiveThreadClaimed(clientLease.client, binding.threadId)) throw new Error(`Codex thread ${binding.threadId} has an active run; stop it before changing its owner.`);
|
|
49
|
+
if (!options.allowUntracked) return;
|
|
50
|
+
if (!await unsubscribeCodexThreadBestEffort(clientLease.client, {
|
|
51
|
+
threadId: binding.threadId,
|
|
52
|
+
timeoutMs: 5e3
|
|
53
|
+
})) {
|
|
54
|
+
await closeCodexStartupClientBestEffort(clientLease.client);
|
|
55
|
+
throw new CodexAppServerUnsafeSubscriptionError(`Codex retired thread subscription could not be released: ${binding.threadId}`);
|
|
56
|
+
}
|
|
57
|
+
} finally {
|
|
58
|
+
clientLease.release();
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
/** Clears and releases one exact conversation generation without touching its replacement. */
|
|
62
|
+
async function retireCodexConversationThreadBinding(params) {
|
|
63
|
+
const expected = await params.bindingStore.read(params.identity);
|
|
64
|
+
if (!expected || params.expectedThreadId && expected.threadId !== params.expectedThreadId) return false;
|
|
65
|
+
return await params.bindingStore.withLease(params.identity, async () => {
|
|
66
|
+
const current = await params.bindingStore.read(params.identity);
|
|
67
|
+
if (current?.threadId !== expected.threadId || params.expectedStartId && current.conversationStartId !== params.expectedStartId) return false;
|
|
68
|
+
await releaseCodexAppServerBindingSubscription(current, { allowUntracked: params.allowUntracked });
|
|
69
|
+
const cleared = await params.bindingStore.mutate(params.identity, {
|
|
70
|
+
kind: "clear",
|
|
71
|
+
threadId: current.threadId
|
|
72
|
+
});
|
|
73
|
+
if (!cleared || !params.afterClear) return cleared;
|
|
74
|
+
try {
|
|
75
|
+
await params.afterClear();
|
|
76
|
+
return true;
|
|
77
|
+
} catch (error) {
|
|
78
|
+
try {
|
|
79
|
+
if (!await params.bindingStore.mutate(params.identity, {
|
|
80
|
+
kind: "set",
|
|
81
|
+
binding: current,
|
|
82
|
+
if: { kind: "absent" }
|
|
83
|
+
})) throw new Error("the previous Codex binding generation could not be restored", { cause: error });
|
|
84
|
+
} catch (restorationError) {
|
|
85
|
+
throw new AggregateError([error, restorationError], `Codex conversation detachment failed and native thread ${current.threadId} could not be restored; run /codex resume ${current.threadId} to recover it`, { cause: restorationError });
|
|
86
|
+
}
|
|
87
|
+
throw error;
|
|
88
|
+
}
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
//#endregion
|
|
92
|
+
export { rollbackCodexAppServerBindingSubscription as a, retireCodexConversationThreadBinding as i, releaseCodexAppServerBindingSubscription as n, withCodexConversationThreadActivity as o, retainCodexAppServerBindingSubscription as r, withExclusiveCodexAppServerThread as s, isSameCodexAppServerThreadOwner as t };
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { F as isCodexAppServerPrewriteRequestCancellationError, s as isCodexAppServerStartSelectionChangedError, z as CodexAppServerRpcError } from "./shared-client-kIBbGjk4.js";
|
|
2
|
+
import { i as assertCodexThreadResumeSubscription, r as CodexAppServerUnsafeSubscriptionError } from "./attempt-client-cleanup-DMLXUfa8.js";
|
|
3
|
+
import { i as assertCodexThreadResumeResponse } from "./protocol-validators-B4F7L8Rf.js";
|
|
4
|
+
//#region extensions/codex/src/app-server/thread-resume.ts
|
|
5
|
+
/** Owns Codex thread/resume subscription safety. */
|
|
6
|
+
/** Resumes one thread and retires the physical client when acceptance is indeterminate. */
|
|
7
|
+
async function resumeCodexAppServerThread(params) {
|
|
8
|
+
const threadId = params.request.threadId;
|
|
9
|
+
let response;
|
|
10
|
+
try {
|
|
11
|
+
response = assertCodexThreadResumeResponse(await params.client.request("thread/resume", params.request, {
|
|
12
|
+
...params.timeoutMs !== void 0 ? { timeoutMs: params.timeoutMs } : {},
|
|
13
|
+
...params.signal ? { signal: params.signal } : {}
|
|
14
|
+
}));
|
|
15
|
+
assertCodexThreadResumeSubscription(threadId, response.thread.id);
|
|
16
|
+
} catch (error) {
|
|
17
|
+
if (isCodexAppServerStartSelectionChangedError(error) || isCodexAppServerPrewriteRequestCancellationError(error)) throw error;
|
|
18
|
+
if (error instanceof CodexAppServerRpcError) throw error;
|
|
19
|
+
try {
|
|
20
|
+
await params.abandonClient();
|
|
21
|
+
} catch (abandonError) {
|
|
22
|
+
throw new CodexAppServerUnsafeSubscriptionError(`Codex thread/resume client could not be retired for ${threadId}`, { cause: abandonError });
|
|
23
|
+
}
|
|
24
|
+
if (error instanceof CodexAppServerUnsafeSubscriptionError) throw error;
|
|
25
|
+
throw new CodexAppServerUnsafeSubscriptionError(error instanceof Error ? error.message : `Codex thread/resume outcome is indeterminate for ${threadId}`, { cause: error });
|
|
26
|
+
}
|
|
27
|
+
return response;
|
|
28
|
+
}
|
|
29
|
+
//#endregion
|
|
30
|
+
export { resumeCodexAppServerThread as t };
|
|
@@ -1,137 +1,11 @@
|
|
|
1
|
+
import { i as readUpstreamUserText, n as attachUpstreamUserText, r as readMirrorIdentity, t as attachCodexMirrorIdentity } from "./upstream-prompt-provenance-ClRBije0.js";
|
|
2
|
+
import { normalizeOptionalString } from "openclaw/plugin-sdk/string-coerce-runtime";
|
|
1
3
|
import { embeddedAgentLog, formatErrorMessage, projectAgentHarnessTranscriptMessageForDisplay, runAgentHarnessBeforeMessageWriteHook } from "openclaw/plugin-sdk/agent-harness-runtime";
|
|
2
4
|
import { createHash } from "node:crypto";
|
|
3
|
-
import {
|
|
5
|
+
import { withCodexSessionTranscriptMirrorWriteLock } from "openclaw/plugin-sdk/codex-session-transcript-runtime";
|
|
6
|
+
import { publishSessionTranscriptUpdateByIdentity } from "openclaw/plugin-sdk/session-transcript-runtime";
|
|
4
7
|
import { Buffer } from "node:buffer";
|
|
5
|
-
|
|
6
|
-
//#region extensions/codex/src/app-server/upstream-prompt-provenance.ts
|
|
7
|
-
const UPSTREAM_USER_TEXT_META_KEY = "upstreamUserText";
|
|
8
|
-
const MIRROR_IDENTITY_META_KEY = "mirrorIdentity";
|
|
9
|
-
function attachCodexMirrorIdentity(message, identity) {
|
|
10
|
-
const record = message;
|
|
11
|
-
const existing = record["__openclaw"];
|
|
12
|
-
const baseMeta = existing && typeof existing === "object" && !Array.isArray(existing) ? existing : {};
|
|
13
|
-
return {
|
|
14
|
-
...record,
|
|
15
|
-
__openclaw: {
|
|
16
|
-
...baseMeta,
|
|
17
|
-
[MIRROR_IDENTITY_META_KEY]: identity
|
|
18
|
-
}
|
|
19
|
-
};
|
|
20
|
-
}
|
|
21
|
-
function readMirrorIdentity(message) {
|
|
22
|
-
const meta = message["__openclaw"];
|
|
23
|
-
if (!meta || typeof meta !== "object" || Array.isArray(meta)) return;
|
|
24
|
-
const id = meta[MIRROR_IDENTITY_META_KEY];
|
|
25
|
-
return typeof id === "string" && id ? id : void 0;
|
|
26
|
-
}
|
|
27
|
-
function attachUpstreamUserText(message, text) {
|
|
28
|
-
const record = message;
|
|
29
|
-
const existing = record["__openclaw"];
|
|
30
|
-
const baseMeta = existing && typeof existing === "object" && !Array.isArray(existing) ? existing : {};
|
|
31
|
-
return {
|
|
32
|
-
...record,
|
|
33
|
-
__openclaw: {
|
|
34
|
-
...baseMeta,
|
|
35
|
-
[UPSTREAM_USER_TEXT_META_KEY]: text
|
|
36
|
-
}
|
|
37
|
-
};
|
|
38
|
-
}
|
|
39
|
-
function readUpstreamUserText(message) {
|
|
40
|
-
const meta = message?.["__openclaw"];
|
|
41
|
-
if (!meta || typeof meta !== "object" || Array.isArray(meta)) return;
|
|
42
|
-
const text = meta[UPSTREAM_USER_TEXT_META_KEY];
|
|
43
|
-
return typeof text === "string" && text ? text : void 0;
|
|
44
|
-
}
|
|
45
|
-
//#endregion
|
|
46
|
-
//#region extensions/codex/src/app-server/transcript-mirror-attestation.ts
|
|
47
|
-
const MIRROR_ORIGIN_META_KEY = "mirrorOrigin";
|
|
48
|
-
const MIRROR_SOURCE_FINGERPRINT_META_KEY = "mirrorSourceFingerprint";
|
|
49
|
-
const CODEX_APP_SERVER_MIRROR_ORIGIN = "codex-app-server";
|
|
50
|
-
function attachCodexMirrorAttestation(message, sourceFingerprint) {
|
|
51
|
-
const record = message;
|
|
52
|
-
const existing = record["__openclaw"];
|
|
53
|
-
const baseMeta = existing && typeof existing === "object" && !Array.isArray(existing) ? existing : {};
|
|
54
|
-
return {
|
|
55
|
-
...record,
|
|
56
|
-
__openclaw: {
|
|
57
|
-
...baseMeta,
|
|
58
|
-
[MIRROR_ORIGIN_META_KEY]: CODEX_APP_SERVER_MIRROR_ORIGIN,
|
|
59
|
-
...sourceFingerprint ? { [MIRROR_SOURCE_FINGERPRINT_META_KEY]: sourceFingerprint } : {}
|
|
60
|
-
}
|
|
61
|
-
};
|
|
62
|
-
}
|
|
63
|
-
function readCodexMirrorSourceFingerprint(message) {
|
|
64
|
-
const meta = message["__openclaw"];
|
|
65
|
-
if (!meta || typeof meta !== "object" || Array.isArray(meta)) return;
|
|
66
|
-
const value = meta[MIRROR_SOURCE_FINGERPRINT_META_KEY];
|
|
67
|
-
return typeof value === "string" && value ? value : void 0;
|
|
68
|
-
}
|
|
69
|
-
function serializeCodexMirrorSourceEvidence(message) {
|
|
70
|
-
const record = message;
|
|
71
|
-
return JSON.stringify({
|
|
72
|
-
role: message.role,
|
|
73
|
-
content: record.content,
|
|
74
|
-
...message.role === "user" ? { upstreamUserText: readUpstreamUserText(message) } : {},
|
|
75
|
-
...message.role === "toolResult" ? {
|
|
76
|
-
toolCallId: record.toolCallId,
|
|
77
|
-
toolName: record.toolName,
|
|
78
|
-
isError: record.isError === true
|
|
79
|
-
} : {}
|
|
80
|
-
});
|
|
81
|
-
}
|
|
82
|
-
function fingerprintCodexMirrorSourceMessage(message) {
|
|
83
|
-
return createHash("sha256").update(serializeCodexMirrorSourceEvidence(message)).digest("hex").slice(0, 32);
|
|
84
|
-
}
|
|
85
|
-
//#endregion
|
|
86
|
-
//#region extensions/codex/src/app-server/user-prompt-message.ts
|
|
87
|
-
function buildSenderLabel(params) {
|
|
88
|
-
const label = params.senderName ?? params.senderUsername ?? params.senderE164 ?? params.senderId;
|
|
89
|
-
if (!label) return;
|
|
90
|
-
return !params.senderId || label.includes(params.senderId) ? label : `${label} (${params.senderId})`;
|
|
91
|
-
}
|
|
92
|
-
function buildFromPrepared(params, preparedUserMessage) {
|
|
93
|
-
const senderId = normalizeOptionalString(params.senderId);
|
|
94
|
-
const senderName = normalizeOptionalString(params.senderName);
|
|
95
|
-
const senderUsername = normalizeOptionalString(params.senderUsername);
|
|
96
|
-
const senderE164 = normalizeOptionalString(params.senderE164);
|
|
97
|
-
const senderLabel = buildSenderLabel({
|
|
98
|
-
senderId,
|
|
99
|
-
senderName,
|
|
100
|
-
senderUsername,
|
|
101
|
-
senderE164
|
|
102
|
-
});
|
|
103
|
-
const sourceChannel = normalizeOptionalString(params.inputProvenance?.sourceChannel ?? params.messageChannel ?? params.messageProvider);
|
|
104
|
-
return {
|
|
105
|
-
role: "user",
|
|
106
|
-
timestamp: Date.now(),
|
|
107
|
-
...params.inputProvenance ? { provenance: params.inputProvenance } : {},
|
|
108
|
-
...sourceChannel ? { sourceChannel } : {},
|
|
109
|
-
...senderId ? { senderId } : {},
|
|
110
|
-
...senderName ? { senderName } : {},
|
|
111
|
-
...senderUsername ? { senderUsername } : {},
|
|
112
|
-
...senderE164 ? { senderE164 } : {},
|
|
113
|
-
...senderLabel ? { senderLabel } : {},
|
|
114
|
-
...preparedUserMessage ? preparedUserMessage : { content: params.prompt }
|
|
115
|
-
};
|
|
116
|
-
}
|
|
117
|
-
function buildCodexUserPromptMessage(params) {
|
|
118
|
-
return buildFromPrepared(params, params.userTurnTranscriptRecorder?.message);
|
|
119
|
-
}
|
|
120
|
-
function buildCodexUpstreamPromptMessage(params, identity, upstreamUserText) {
|
|
121
|
-
const message = attachCodexMirrorIdentity(buildCodexUserPromptMessage(params), identity);
|
|
122
|
-
return upstreamUserText ? attachUpstreamUserText(message, upstreamUserText) : message;
|
|
123
|
-
}
|
|
124
|
-
function promptSnapshot(params, turnId, upstreamUserText) {
|
|
125
|
-
return params.suppressNextUserMessagePersistence ? [] : [buildCodexUpstreamPromptMessage(params, `${turnId}:prompt`, upstreamUserText)];
|
|
126
|
-
}
|
|
127
|
-
async function buildResolvedCodexUserPromptMessage(params) {
|
|
128
|
-
return buildFromPrepared(params, await params.userTurnTranscriptRecorder?.resolveMessage() ?? params.userTurnTranscriptRecorder?.message);
|
|
129
|
-
}
|
|
130
|
-
//#endregion
|
|
131
|
-
//#region extensions/codex/src/app-server/transcript-mirror.ts
|
|
132
|
-
function isMirroredAgentMessage(message) {
|
|
133
|
-
return message.role === "user" || message.role === "assistant" || message.role === "toolResult";
|
|
134
|
-
}
|
|
8
|
+
//#region extensions/codex/src/app-server/transcript-history-projection.ts
|
|
135
9
|
const CODEX_HISTORY_IMPORT_MAX_MESSAGES = 200;
|
|
136
10
|
const CODEX_HISTORY_IMPORT_MAX_BYTES = 512 * 1024;
|
|
137
11
|
const CODEX_HISTORY_IMPORT_MAX_MESSAGE_BYTES = 64 * 1024;
|
|
@@ -186,6 +60,7 @@ function projectCodexUserItemText(item) {
|
|
|
186
60
|
parts.push("[Image attachment]");
|
|
187
61
|
continue;
|
|
188
62
|
}
|
|
63
|
+
if (input.type === "audio" || input.type === "localAudio" || input.type === "local_audio") parts.push("[Audio attachment]");
|
|
189
64
|
if (input.type === "skill" || input.type === "mention") {
|
|
190
65
|
const name = normalizeOptionalString(input.name);
|
|
191
66
|
if (name) parts.push(`${input.type === "skill" ? "$" : "@"}${name}`);
|
|
@@ -226,7 +101,8 @@ function projectCodexThreadHistory(params) {
|
|
|
226
101
|
provider: normalizeOptionalString(params.modelProvider) ?? normalizeOptionalString(params.thread.modelProvider) ?? CODEX_HISTORY_ASSISTANT_PROVIDER,
|
|
227
102
|
model: CODEX_HISTORY_ASSISTANT_MODEL,
|
|
228
103
|
usage: CODEX_HISTORY_ZERO_USAGE,
|
|
229
|
-
stopReason: "stop",
|
|
104
|
+
stopReason: turn.status === "interrupted" ? "aborted" : turn.status === "failed" ? "error" : "stop",
|
|
105
|
+
...turn.status === "failed" && turn.error?.message ? { errorMessage: turn.error.message } : {},
|
|
230
106
|
timestamp
|
|
231
107
|
}, identity) : attachCodexMirrorIdentity({
|
|
232
108
|
role,
|
|
@@ -274,10 +150,124 @@ function projectBoundedCodexThreadHistory(params) {
|
|
|
274
150
|
return {
|
|
275
151
|
importedMessages: selected.length,
|
|
276
152
|
omittedMessages: projected.length - selected.length,
|
|
277
|
-
responseItems: selected.map(({ responseItem }) => responseItem),
|
|
153
|
+
responseItems: selected.filter(({ message }) => message.role !== "assistant" || message.stopReason !== "aborted" && message.stopReason !== "error").map(({ responseItem }) => responseItem),
|
|
278
154
|
transcriptMessages: selected.map(({ message }) => message)
|
|
279
155
|
};
|
|
280
156
|
}
|
|
157
|
+
/** Projects only visible local user/assistant messages through the same bounded history policy. */
|
|
158
|
+
function projectBoundedCodexVisibleSessionHistory(entries) {
|
|
159
|
+
const projected = [];
|
|
160
|
+
for (const entry of entries) {
|
|
161
|
+
if (entry.role !== "user" && entry.role !== "assistant" || !("content" in entry.message)) continue;
|
|
162
|
+
if (entry.role === "assistant" && "stopReason" in entry.message && (entry.message.stopReason === "aborted" || entry.message.stopReason === "error")) continue;
|
|
163
|
+
const content = entry.message.content;
|
|
164
|
+
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);
|
|
165
|
+
if (!text) continue;
|
|
166
|
+
projected.push({
|
|
167
|
+
message: entry.message,
|
|
168
|
+
responseItem: {
|
|
169
|
+
type: "message",
|
|
170
|
+
role: entry.role,
|
|
171
|
+
content: [{
|
|
172
|
+
type: entry.role === "assistant" ? "output_text" : "input_text",
|
|
173
|
+
text
|
|
174
|
+
}]
|
|
175
|
+
},
|
|
176
|
+
textBytes: Buffer.byteLength(text, "utf8")
|
|
177
|
+
});
|
|
178
|
+
}
|
|
179
|
+
return selectBoundedCodexHistoryTail(projected).map(({ responseItem }) => responseItem);
|
|
180
|
+
}
|
|
181
|
+
//#endregion
|
|
182
|
+
//#region extensions/codex/src/app-server/transcript-mirror-attestation.ts
|
|
183
|
+
const MIRROR_ORIGIN_META_KEY = "mirrorOrigin";
|
|
184
|
+
const MIRROR_SOURCE_FINGERPRINT_META_KEY = "mirrorSourceFingerprint";
|
|
185
|
+
const CODEX_APP_SERVER_MIRROR_ORIGIN = "codex-app-server";
|
|
186
|
+
function attachCodexMirrorAttestation(message, sourceFingerprint) {
|
|
187
|
+
const record = message;
|
|
188
|
+
const existing = record["__openclaw"];
|
|
189
|
+
const baseMeta = existing && typeof existing === "object" && !Array.isArray(existing) ? existing : {};
|
|
190
|
+
return {
|
|
191
|
+
...record,
|
|
192
|
+
__openclaw: {
|
|
193
|
+
...baseMeta,
|
|
194
|
+
[MIRROR_ORIGIN_META_KEY]: CODEX_APP_SERVER_MIRROR_ORIGIN,
|
|
195
|
+
...sourceFingerprint ? { [MIRROR_SOURCE_FINGERPRINT_META_KEY]: sourceFingerprint } : {}
|
|
196
|
+
}
|
|
197
|
+
};
|
|
198
|
+
}
|
|
199
|
+
function readCodexMirrorSourceFingerprint(message) {
|
|
200
|
+
const meta = message["__openclaw"];
|
|
201
|
+
if (!meta || typeof meta !== "object" || Array.isArray(meta)) return;
|
|
202
|
+
const value = meta[MIRROR_SOURCE_FINGERPRINT_META_KEY];
|
|
203
|
+
return typeof value === "string" && value ? value : void 0;
|
|
204
|
+
}
|
|
205
|
+
function serializeCodexMirrorSourceEvidence(message) {
|
|
206
|
+
const record = message;
|
|
207
|
+
return JSON.stringify({
|
|
208
|
+
role: message.role,
|
|
209
|
+
content: record.content,
|
|
210
|
+
...message.role === "user" ? { upstreamUserText: readUpstreamUserText(message) } : {},
|
|
211
|
+
...message.role === "toolResult" ? {
|
|
212
|
+
toolCallId: record.toolCallId,
|
|
213
|
+
toolName: record.toolName,
|
|
214
|
+
isError: record.isError === true
|
|
215
|
+
} : {}
|
|
216
|
+
});
|
|
217
|
+
}
|
|
218
|
+
function fingerprintCodexMirrorSourceMessage(message) {
|
|
219
|
+
return createHash("sha256").update(serializeCodexMirrorSourceEvidence(message)).digest("hex").slice(0, 32);
|
|
220
|
+
}
|
|
221
|
+
//#endregion
|
|
222
|
+
//#region extensions/codex/src/app-server/user-prompt-message.ts
|
|
223
|
+
function buildSenderLabel(params) {
|
|
224
|
+
const label = params.senderName ?? params.senderUsername ?? params.senderE164 ?? params.senderId;
|
|
225
|
+
if (!label) return;
|
|
226
|
+
return !params.senderId || label.includes(params.senderId) ? label : `${label} (${params.senderId})`;
|
|
227
|
+
}
|
|
228
|
+
function buildFromPrepared(params, preparedUserMessage) {
|
|
229
|
+
const senderId = normalizeOptionalString(params.senderId);
|
|
230
|
+
const senderName = normalizeOptionalString(params.senderName);
|
|
231
|
+
const senderUsername = normalizeOptionalString(params.senderUsername);
|
|
232
|
+
const senderE164 = normalizeOptionalString(params.senderE164);
|
|
233
|
+
const senderLabel = buildSenderLabel({
|
|
234
|
+
senderId,
|
|
235
|
+
senderName,
|
|
236
|
+
senderUsername,
|
|
237
|
+
senderE164
|
|
238
|
+
});
|
|
239
|
+
const sourceChannel = normalizeOptionalString(params.inputProvenance?.sourceChannel ?? params.messageChannel ?? params.messageProvider);
|
|
240
|
+
return {
|
|
241
|
+
role: "user",
|
|
242
|
+
timestamp: Date.now(),
|
|
243
|
+
...params.inputProvenance ? { provenance: params.inputProvenance } : {},
|
|
244
|
+
...sourceChannel ? { sourceChannel } : {},
|
|
245
|
+
...senderId ? { senderId } : {},
|
|
246
|
+
...senderName ? { senderName } : {},
|
|
247
|
+
...senderUsername ? { senderUsername } : {},
|
|
248
|
+
...senderE164 ? { senderE164 } : {},
|
|
249
|
+
...senderLabel ? { senderLabel } : {},
|
|
250
|
+
...preparedUserMessage ? preparedUserMessage : { content: params.prompt }
|
|
251
|
+
};
|
|
252
|
+
}
|
|
253
|
+
function buildCodexUserPromptMessage(params) {
|
|
254
|
+
return buildFromPrepared(params, params.userTurnTranscriptRecorder?.message);
|
|
255
|
+
}
|
|
256
|
+
function buildCodexUpstreamPromptMessage(params, identity, upstreamUserText) {
|
|
257
|
+
const message = attachCodexMirrorIdentity(buildCodexUserPromptMessage(params), identity);
|
|
258
|
+
return upstreamUserText ? attachUpstreamUserText(message, upstreamUserText) : message;
|
|
259
|
+
}
|
|
260
|
+
function promptSnapshot(params, turnId, upstreamUserText) {
|
|
261
|
+
return params.suppressNextUserMessagePersistence ? [] : [buildCodexUpstreamPromptMessage(params, `${turnId}:prompt`, upstreamUserText)];
|
|
262
|
+
}
|
|
263
|
+
async function buildResolvedCodexUserPromptMessage(params) {
|
|
264
|
+
return buildFromPrepared(params, await params.userTurnTranscriptRecorder?.resolveMessage() ?? params.userTurnTranscriptRecorder?.message);
|
|
265
|
+
}
|
|
266
|
+
//#endregion
|
|
267
|
+
//#region extensions/codex/src/app-server/transcript-mirror.ts
|
|
268
|
+
function isMirroredAgentMessage(message) {
|
|
269
|
+
return message.role === "user" || message.role === "assistant" || message.role === "toolResult";
|
|
270
|
+
}
|
|
281
271
|
/** Imports a bounded, user-visible Codex history tail into a new OpenClaw transcript. */
|
|
282
272
|
async function importCodexThreadHistoryToTranscript(params) {
|
|
283
273
|
const projection = projectBoundedCodexThreadHistory({
|
|
@@ -302,6 +292,10 @@ async function importCodexThreadHistoryToTranscript(params) {
|
|
|
302
292
|
};
|
|
303
293
|
}
|
|
304
294
|
async function mirrorBestEffort(params) {
|
|
295
|
+
if (!params.params.sessionTarget) return {
|
|
296
|
+
assistantTranscriptOwned: false,
|
|
297
|
+
mirroredMessages: []
|
|
298
|
+
};
|
|
305
299
|
try {
|
|
306
300
|
const messages = await resolveFinalCodexMirrorMessages({
|
|
307
301
|
params: params.params,
|
|
@@ -318,8 +312,8 @@ async function mirrorBestEffort(params) {
|
|
|
318
312
|
idempotencyScope: `codex-app-server:${params.threadId}`,
|
|
319
313
|
config: params.params.config
|
|
320
314
|
});
|
|
321
|
-
for (const
|
|
322
|
-
params.notifyUserMessagePersisted(message);
|
|
315
|
+
for (const receipt of mirrorResult.userMessageReceipts) try {
|
|
316
|
+
params.notifyUserMessagePersisted(receipt.message, receipt.anchor);
|
|
323
317
|
} catch (error) {
|
|
324
318
|
embeddedAgentLog.warn("failed to notify codex app-server user-message persistence", { error: formatErrorMessage(error) });
|
|
325
319
|
}
|
|
@@ -335,13 +329,21 @@ async function mirrorBestEffort(params) {
|
|
|
335
329
|
const assistantMirrorIdentity = `${params.turnId}:assistant`;
|
|
336
330
|
const assistantTranscriptOwned = mirrorResult.assistantMirrorIdentitiesOwned.includes(assistantMirrorIdentity);
|
|
337
331
|
const assistantTranscriptIdempotencyKey = normalizeOptionalString((assistantTranscriptOwned ? mirroredMessages.find((message) => readMirrorIdentity(message) === assistantMirrorIdentity) : void 0)?.idempotencyKey);
|
|
332
|
+
const terminalMessage = mirroredMessages.at(-1);
|
|
333
|
+
const terminalMirrorIdentity = terminalMessage ? readMirrorIdentity(terminalMessage) : void 0;
|
|
334
|
+
const terminalAnchor = (terminalMirrorIdentity ? mirrorResult.anchorsByMirrorIdentity.get(terminalMirrorIdentity) : void 0) ?? params.params.userTurnTranscriptRecorder?.getAdmissionReceipt();
|
|
338
335
|
return {
|
|
339
336
|
assistantTranscriptOwned,
|
|
340
337
|
...assistantTranscriptIdempotencyKey ? { assistantTranscriptIdempotencyKey } : {},
|
|
338
|
+
...terminalAnchor ? { terminalAnchor } : {},
|
|
341
339
|
mirroredMessages
|
|
342
340
|
};
|
|
343
341
|
} catch (error) {
|
|
344
|
-
embeddedAgentLog.warn("failed to mirror codex app-server transcript", {
|
|
342
|
+
embeddedAgentLog.warn("failed to mirror codex app-server transcript", {
|
|
343
|
+
error: formatErrorMessage(error),
|
|
344
|
+
runId: params.params.runId,
|
|
345
|
+
sessionId: params.params.sessionId
|
|
346
|
+
});
|
|
345
347
|
return {
|
|
346
348
|
assistantTranscriptOwned: false,
|
|
347
349
|
mirroredMessages: []
|
|
@@ -362,10 +364,10 @@ async function resolveFinalCodexMirrorMessages(params) {
|
|
|
362
364
|
}
|
|
363
365
|
function createCodexAppServerUserMessagePersistenceNotifier(runParams) {
|
|
364
366
|
let notified = false;
|
|
365
|
-
return (message) => {
|
|
367
|
+
return (message, anchor) => {
|
|
366
368
|
if (notified) return;
|
|
367
369
|
notified = true;
|
|
368
|
-
runParams.userTurnTranscriptRecorder?.markRuntimePersisted(message);
|
|
370
|
+
runParams.userTurnTranscriptRecorder?.markRuntimePersisted(message, anchor);
|
|
369
371
|
try {
|
|
370
372
|
runParams.onUserMessagePersisted?.(message);
|
|
371
373
|
} catch (error) {
|
|
@@ -374,7 +376,7 @@ function createCodexAppServerUserMessagePersistenceNotifier(runParams) {
|
|
|
374
376
|
};
|
|
375
377
|
}
|
|
376
378
|
async function mirrorPromptAtTurnStartBestEffort(params) {
|
|
377
|
-
if (params.params.suppressNextUserMessagePersistence) return;
|
|
379
|
+
if (params.params.suppressNextUserMessagePersistence || !params.params.sessionTarget) return;
|
|
378
380
|
try {
|
|
379
381
|
const mirrorPromise = (async () => {
|
|
380
382
|
const userPromptMessage = projectAgentHarnessTranscriptMessageForDisplay({
|
|
@@ -391,12 +393,16 @@ async function mirrorPromptAtTurnStartBestEffort(params) {
|
|
|
391
393
|
idempotencyScope: `codex-app-server:${params.threadId}`,
|
|
392
394
|
config: params.params.config
|
|
393
395
|
});
|
|
394
|
-
for (const
|
|
396
|
+
for (const receipt of mirrorResult.userMessageReceipts) params.notifyUserMessagePersisted(receipt.message, receipt.anchor);
|
|
395
397
|
})();
|
|
396
398
|
params.params.userTurnTranscriptRecorder?.markRuntimePersistencePending(mirrorPromise);
|
|
397
399
|
await mirrorPromise;
|
|
398
400
|
} catch (error) {
|
|
399
|
-
embeddedAgentLog.warn("failed to mirror codex app-server prompt at turn start", {
|
|
401
|
+
embeddedAgentLog.warn("failed to mirror codex app-server prompt at turn start", {
|
|
402
|
+
error: formatErrorMessage(error),
|
|
403
|
+
runId: params.params.runId,
|
|
404
|
+
sessionId: params.params.sessionId
|
|
405
|
+
});
|
|
400
406
|
}
|
|
401
407
|
}
|
|
402
408
|
function fingerprintMirrorMessageContent(message) {
|
|
@@ -415,33 +421,53 @@ async function mirror(params) {
|
|
|
415
421
|
const messages = params.messages.filter(isMirroredAgentMessage);
|
|
416
422
|
if (messages.length === 0) return {
|
|
417
423
|
assistantMirrorIdentitiesOwned: [],
|
|
424
|
+
anchorsByMirrorIdentity: /* @__PURE__ */ new Map(),
|
|
418
425
|
messagesPresent: [],
|
|
426
|
+
userMessageReceipts: [],
|
|
419
427
|
userMessagesPresent: []
|
|
420
428
|
};
|
|
429
|
+
const candidates = messages.map((message) => {
|
|
430
|
+
const dedupeIdentity = buildMirrorDedupeIdentity(message);
|
|
431
|
+
const sourceFingerprint = fingerprintCodexMirrorSourceMessage(message);
|
|
432
|
+
return {
|
|
433
|
+
dedupeIdentity,
|
|
434
|
+
idempotencyKey: (message.role === "user" ? normalizeOptionalString(message.idempotencyKey) : void 0) ?? (params.idempotencyScope ? `${params.idempotencyScope}:${dedupeIdentity}` : void 0),
|
|
435
|
+
message,
|
|
436
|
+
sourceFingerprint
|
|
437
|
+
};
|
|
438
|
+
});
|
|
439
|
+
const candidateIdempotencyKeys = candidates.flatMap(({ idempotencyKey }) => idempotencyKey ? [idempotencyKey] : []);
|
|
421
440
|
const transcriptTarget = resolveCodexMirrorTranscriptTarget(params);
|
|
422
|
-
const { appendedUpdates, assistantMirrorIdentitiesOwned, messagesPresent, userMessagesPresent } = await
|
|
441
|
+
const { appendedUpdates, assistantMirrorIdentitiesOwned, anchorsByMirrorIdentity, messagesPresent, userMessageReceipts, userMessagesPresent } = await withCodexSessionTranscriptMirrorWriteLock({
|
|
423
442
|
...transcriptTarget,
|
|
424
443
|
config: params.config
|
|
425
444
|
}, async (transcript) => {
|
|
426
445
|
const nextAppendedUpdates = [];
|
|
427
446
|
const nextAssistantMirrorIdentitiesOwned = /* @__PURE__ */ new Set();
|
|
447
|
+
const nextAnchorsByMirrorIdentity = /* @__PURE__ */ new Map();
|
|
428
448
|
const nextMessagesPresent = [];
|
|
449
|
+
const nextUserMessageReceipts = [];
|
|
429
450
|
const nextUserMessagesPresent = [];
|
|
430
|
-
const
|
|
431
|
-
|
|
432
|
-
for (const message of messages) {
|
|
433
|
-
const dedupeIdentity = buildMirrorDedupeIdentity(message);
|
|
434
|
-
const sourceFingerprint = fingerprintCodexMirrorSourceMessage(message);
|
|
435
|
-
const idempotencyKey = (message.role === "user" ? normalizeOptionalString(message.idempotencyKey) : void 0) ?? (params.idempotencyScope ? `${params.idempotencyScope}:${dedupeIdentity}` : void 0);
|
|
451
|
+
const mirrorFacts = await transcript.readMessageFacts({ idempotencyKeys: candidateIdempotencyKeys });
|
|
452
|
+
for (const { dedupeIdentity, idempotencyKey, message, sourceFingerprint } of candidates) {
|
|
436
453
|
const transcriptMessage = {
|
|
437
454
|
...attachCodexMirrorAttestation(message, sourceFingerprint),
|
|
438
455
|
...idempotencyKey ? { idempotencyKey } : {}
|
|
439
456
|
};
|
|
440
|
-
if (idempotencyKey &&
|
|
441
|
-
const persistedMessage =
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
457
|
+
if (idempotencyKey && mirrorFacts.existingIdempotencyKeys.has(idempotencyKey)) {
|
|
458
|
+
const persistedMessage = mirrorFacts.messagesByIdempotencyKey.get(idempotencyKey);
|
|
459
|
+
const persistedAnchor = mirrorFacts.anchorsByIdempotencyKey.get(idempotencyKey);
|
|
460
|
+
if (persistedMessage && isMirroredAgentMessage(persistedMessage)) {
|
|
461
|
+
nextMessagesPresent.push(persistedMessage);
|
|
462
|
+
if (persistedMessage.role === "user") {
|
|
463
|
+
nextUserMessagesPresent.push(persistedMessage);
|
|
464
|
+
if (persistedAnchor) nextUserMessageReceipts.push({
|
|
465
|
+
anchor: persistedAnchor,
|
|
466
|
+
message: persistedMessage
|
|
467
|
+
});
|
|
468
|
+
}
|
|
469
|
+
}
|
|
470
|
+
if (persistedAnchor) nextAnchorsByMirrorIdentity.set(dedupeIdentity, persistedAnchor);
|
|
445
471
|
if (message.role === "assistant") nextAssistantMirrorIdentitiesOwned.add(dedupeIdentity);
|
|
446
472
|
continue;
|
|
447
473
|
}
|
|
@@ -464,31 +490,42 @@ async function mirror(params) {
|
|
|
464
490
|
hidden: message.display === false,
|
|
465
491
|
message: messageToAppend
|
|
466
492
|
});
|
|
467
|
-
const appended = await transcript.
|
|
493
|
+
const { messageSeq, result: appended } = await transcript.appendMessageWithMessageSequence({
|
|
468
494
|
message: messageToAppend,
|
|
469
|
-
idempotencyLookup:
|
|
495
|
+
idempotencyLookup: "scan",
|
|
470
496
|
cwd: params.cwd
|
|
471
497
|
});
|
|
472
498
|
if (!appended) continue;
|
|
473
499
|
const { messageId, message: appendedMessage } = appended;
|
|
474
500
|
if (isMirroredAgentMessage(appendedMessage)) {
|
|
475
501
|
nextMessagesPresent.push(appendedMessage);
|
|
476
|
-
if (idempotencyKey)
|
|
502
|
+
if (idempotencyKey) mirrorFacts.messagesByIdempotencyKey.set(idempotencyKey, appendedMessage);
|
|
477
503
|
}
|
|
478
504
|
if (message.role === "assistant") nextAssistantMirrorIdentitiesOwned.add(dedupeIdentity);
|
|
479
|
-
if (
|
|
480
|
-
|
|
481
|
-
|
|
505
|
+
if (appended.anchor) nextAnchorsByMirrorIdentity.set(dedupeIdentity, appended.anchor);
|
|
506
|
+
if (appendedMessage.role === "user" && appended.anchor) {
|
|
507
|
+
nextUserMessagesPresent.push(appendedMessage);
|
|
508
|
+
nextUserMessageReceipts.push({
|
|
509
|
+
anchor: appended.anchor,
|
|
510
|
+
message: appendedMessage
|
|
511
|
+
});
|
|
512
|
+
}
|
|
513
|
+
if (appended.appended) nextAppendedUpdates.push({
|
|
482
514
|
messageId,
|
|
483
515
|
message: appendedMessage,
|
|
484
|
-
messageSeq:
|
|
516
|
+
...messageSeq !== void 0 ? { messageSeq } : {}
|
|
485
517
|
});
|
|
486
|
-
if (idempotencyKey)
|
|
518
|
+
if (idempotencyKey) {
|
|
519
|
+
mirrorFacts.existingIdempotencyKeys.add(idempotencyKey);
|
|
520
|
+
if (appended.anchor) mirrorFacts.anchorsByIdempotencyKey.set(idempotencyKey, appended.anchor);
|
|
521
|
+
}
|
|
487
522
|
}
|
|
488
523
|
return {
|
|
489
524
|
appendedUpdates: nextAppendedUpdates,
|
|
490
525
|
assistantMirrorIdentitiesOwned: [...nextAssistantMirrorIdentitiesOwned],
|
|
526
|
+
anchorsByMirrorIdentity: nextAnchorsByMirrorIdentity,
|
|
491
527
|
messagesPresent: nextMessagesPresent,
|
|
528
|
+
userMessageReceipts: nextUserMessageReceipts,
|
|
492
529
|
userMessagesPresent: nextUserMessagesPresent
|
|
493
530
|
};
|
|
494
531
|
});
|
|
@@ -499,7 +536,7 @@ async function mirror(params) {
|
|
|
499
536
|
...params.agentId ? { agentId: params.agentId } : {},
|
|
500
537
|
message: update.message,
|
|
501
538
|
messageId: update.messageId,
|
|
502
|
-
messageSeq: update.messageSeq,
|
|
539
|
+
...update.messageSeq !== void 0 ? { messageSeq: update.messageSeq } : {},
|
|
503
540
|
sessionKey: transcriptTarget.sessionKey
|
|
504
541
|
}
|
|
505
542
|
});
|
|
@@ -508,7 +545,9 @@ async function mirror(params) {
|
|
|
508
545
|
}
|
|
509
546
|
return {
|
|
510
547
|
assistantMirrorIdentitiesOwned,
|
|
548
|
+
anchorsByMirrorIdentity,
|
|
511
549
|
messagesPresent,
|
|
550
|
+
userMessageReceipts,
|
|
512
551
|
userMessagesPresent
|
|
513
552
|
};
|
|
514
553
|
}
|
|
@@ -527,24 +566,5 @@ function resolveCodexMirrorTranscriptTarget(params) {
|
|
|
527
566
|
storePath
|
|
528
567
|
};
|
|
529
568
|
}
|
|
530
|
-
function readTranscriptMirrorState(events) {
|
|
531
|
-
const idempotencyKeys = /* @__PURE__ */ new Set();
|
|
532
|
-
const messagesByIdempotencyKey = /* @__PURE__ */ new Map();
|
|
533
|
-
let messageCount = 0;
|
|
534
|
-
for (const event of events) {
|
|
535
|
-
if (!event || typeof event !== "object" || Array.isArray(event)) continue;
|
|
536
|
-
const parsed = event;
|
|
537
|
-
if (parsed.type === "message") messageCount += 1;
|
|
538
|
-
if (typeof parsed.message?.idempotencyKey === "string") {
|
|
539
|
-
idempotencyKeys.add(parsed.message.idempotencyKey);
|
|
540
|
-
if (isMirroredAgentMessage(parsed.message)) messagesByIdempotencyKey.set(parsed.message.idempotencyKey, parsed.message);
|
|
541
|
-
}
|
|
542
|
-
}
|
|
543
|
-
return {
|
|
544
|
-
idempotencyKeys,
|
|
545
|
-
messagesByIdempotencyKey,
|
|
546
|
-
messageCount
|
|
547
|
-
};
|
|
548
|
-
}
|
|
549
569
|
//#endregion
|
|
550
|
-
export {
|
|
570
|
+
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 };
|