Files
openclaw/src/plugin-sdk/session-transcript-mirror-runtime.test.ts
T
Peter Steinberger 3d76246792 refactor: eliminate final export name collisions (#122083)
* refactor: resolve final export name collisions

* refactor: update remaining collision rename consumers

* style: format rebased auth helpers

* test: update remaining session entry mocks

* test: update remaining runtime mock exports

* test: update delivery info path mock

* refactor: reconcile combined collision sweeps

* chore: regenerate collision and sdk baselines
2026-08-11 11:18:24 -07:00

204 lines
7.2 KiB
TypeScript

import path from "node:path";
import { afterEach, beforeEach, describe, expect, it } from "vitest";
import { useAutoCleanupTempDirTracker } from "../../test/helpers/temp-dir.js";
import { upsertSessionEntryCore } from "../config/sessions/session-accessor.js";
import {
runExclusiveSqliteSessionWrite,
resolveSqliteTranscriptScope,
toDatabaseOptions,
} from "../config/sessions/session-accessor.sqlite-scope.js";
import { SessionTranscriptReadFenceError } from "../config/sessions/session-transcript-read-fence.js";
import { waitForSessionTranscriptProjection } from "../config/sessions/session-transcript-reconcile.js";
import { runOpenClawAgentWriteTransaction } from "../state/openclaw-agent-db.js";
import {
readCodexSessionTranscriptEventsBeforeAdmission,
withCodexSessionTranscriptMirrorWriteLock,
} from "./codex-session-transcript-runtime.js";
import {
appendSessionTranscriptMessageByIdentity,
readSessionTranscriptVisibleMessageDelta,
} from "./session-transcript-runtime.js";
const tempDirs = useAutoCleanupTempDirTracker(afterEach);
describe("private session transcript mirror runtime", () => {
let storePath: string;
beforeEach(() => {
const tempDir = tempDirs.make("openclaw-sdk-transcript-mirror-");
storePath = path.join(tempDir, "sessions.json");
});
it("rechecks idempotency and publishes only committed visible sequences", async () => {
const scope = {
agentId: "main",
sessionId: "indexed-mirror-session",
sessionKey: "agent:main:indexed-mirror",
storePath,
};
await upsertSessionEntryCore(scope, { sessionId: scope.sessionId, updatedAt: 1 });
await withCodexSessionTranscriptMirrorWriteLock(scope, async (locked) => {
expect(await locked.readMessageFacts({ idempotencyKeys: ["mirror-user"] })).toEqual({
anchorsByIdempotencyKey: new Map(),
existingIdempotencyKeys: new Set(),
messagesByIdempotencyKey: new Map(),
});
const first = await locked.appendMessageWithMessageSequence({
idempotencyLookup: "scan",
message: {
role: "user",
content: [{ type: "text", text: "persist once" }],
idempotencyKey: "mirror-user",
timestamp: 1,
},
});
expect(first).toMatchObject({
messageSeq: 1,
result: { appended: true, message: { role: "user" } },
});
expect(await locked.readMessageFacts({ idempotencyKeys: ["mirror-user"] })).toMatchObject({
existingIdempotencyKeys: new Set(["mirror-user"]),
messagesByIdempotencyKey: new Map([
["mirror-user", expect.objectContaining({ role: "user" })],
]),
});
const replay = await locked.appendMessageWithMessageSequence({
idempotencyLookup: "scan",
message: {
role: "user",
content: [{ type: "text", text: "persist once" }],
idempotencyKey: "mirror-user",
timestamp: 2,
},
});
expect(replay).toMatchObject({
result: {
appended: false,
message: { content: [{ text: "persist once", type: "text" }], role: "user" },
},
});
expect(replay.messageSeq).toBeUndefined();
if (!first.result) {
throw new Error("expected initial mirror append");
}
await locked.appendMessage({
message: {
role: "assistant",
content: [{ type: "text", text: "abandoned branch" }],
idempotencyKey: "mirror-abandoned",
timestamp: 3,
},
parentId: first.result.messageId,
});
const activeBranch = await locked.appendMessageWithMessageSequence({
message: {
role: "assistant",
content: [{ type: "text", text: "final active branch" }],
idempotencyKey: "mirror-active",
timestamp: 4,
},
parentId: first.result.messageId,
});
expect(activeBranch).toMatchObject({
result: { appended: true, message: { role: "assistant" } },
});
expect(activeBranch.messageSeq).toBeUndefined();
});
const resolvedScope = resolveSqliteTranscriptScope(scope);
await expect(
readSessionTranscriptVisibleMessageDelta({ ...scope, maxMessages: 10 }),
).resolves.toEqual({
kind: "unavailable",
reason: "projection_rebuilding",
});
await waitForSessionTranscriptProjection(scope);
await withCodexSessionTranscriptMirrorWriteLock(scope, async (locked) => {
const afterReconcile = await locked.appendMessageWithMessageSequence({
message: {
role: "assistant",
content: [{ type: "text", text: "after active branch" }],
idempotencyKey: "mirror-after-reconcile",
timestamp: 5,
},
});
expect(afterReconcile).toMatchObject({
messageSeq: 3,
result: { appended: true, message: { role: "assistant" } },
});
});
await waitForSessionTranscriptProjection(scope);
await runExclusiveSqliteSessionWrite(resolvedScope, async () => {
runOpenClawAgentWriteTransaction((database) => {
database.db
.prepare(
"UPDATE session_transcript_index_state SET needs_rebuild = 1 WHERE session_id = ?",
)
.run(scope.sessionId);
}, toDatabaseOptions(resolvedScope));
});
await withCodexSessionTranscriptMirrorWriteLock(scope, async (locked) => {
expect(await locked.readMessageFacts({ idempotencyKeys: ["mirror-user"] })).toMatchObject({
existingIdempotencyKeys: new Set(["mirror-user"]),
messagesByIdempotencyKey: new Map([
["mirror-user", expect.objectContaining({ role: "user" })],
]),
});
const dirtyProjection = await locked.appendMessageWithMessageSequence({
idempotencyLookup: "scan",
message: {
role: "assistant",
content: [{ type: "text", text: "projection fallback" }],
idempotencyKey: "mirror-dirty",
timestamp: 6,
},
});
expect(dirtyProjection).toMatchObject({
result: { appended: true, message: { role: "assistant" } },
});
expect(dirtyProjection.messageSeq).toBeUndefined();
});
});
it("rejects an admission receipt for a different transcript target", async () => {
const admittedScope = {
agentId: "main",
sessionId: "admitted-session",
sessionKey: "agent:main:admitted-session",
storePath,
};
const requestedScope = {
...admittedScope,
sessionId: "requested-session",
sessionKey: "agent:main:requested-session",
};
await upsertSessionEntryCore(admittedScope, {
sessionId: admittedScope.sessionId,
updatedAt: 1,
});
await upsertSessionEntryCore(requestedScope, {
sessionId: requestedScope.sessionId,
updatedAt: 1,
});
const admitted = await appendSessionTranscriptMessageByIdentity({
...admittedScope,
message: { role: "user", content: "admitted elsewhere" },
});
if (!admitted?.anchor) {
throw new Error("expected admitted transcript anchor");
}
await expect(
readCodexSessionTranscriptEventsBeforeAdmission(requestedScope, {
...admitted.anchor,
logicalTurnId: "admitted-turn",
role: "user",
}),
).rejects.toBeInstanceOf(SessionTranscriptReadFenceError);
});
});