refactor: drop file-era transcript fixture coverage

This commit is contained in:
Peter Steinberger
2026-05-09 07:13:54 +01:00
parent 16e3bc053c
commit 18bfb3e5f5
7 changed files with 10 additions and 68 deletions

View File

@@ -76,8 +76,8 @@ interfaces that still look like the old file world:
JSON as possible write targets.
- Agent-owned tables live in per-agent SQLite databases. The global DB keeps
registry/control-plane rows; transcript identity is a canonical
`sqlite-transcript://<agent>/<session>.jsonl` locator derived from the
per-agent transcript rows.
`sqlite-transcript://<agent>/<session>` locator derived from the per-agent
transcript rows.
- Doctor already imports several legacy files. The cleanup is to make that a
single explicit migration implementation that doctor calls, with a durable
migration report.
@@ -208,8 +208,8 @@ The remaining cleanup is mostly consolidation and deletion:
SQLite; JSONL is now a legacy doctor input or in-memory export
encoding, not a runtime state file.
- Runtime session path resolution now canonicalizes active sessions to
`sqlite-transcript://<agent>/<session>.jsonl` locators. Legacy absolute JSONL
paths are doctor migration inputs instead of active runtime identity.
`sqlite-transcript://<agent>/<session>` locators. Legacy absolute JSONL paths
are doctor migration inputs instead of active runtime identity.
- Gateway transcript-key lookup compares canonical transcript locators directly
and no longer realpaths or stats transcript filenames.
- Automatic compaction transcript rotation writes successor transcript rows
@@ -248,10 +248,9 @@ The remaining cleanup is mostly consolidation and deletion:
SQLite transcript rows directly. Runtime callers pass canonical SQLite
locators, not writable `.jsonl` paths.
- Fresh runtime session rows now use virtual
`sqlite-transcript://<agent>/<session>.jsonl` locators instead of fake
`sqlite-transcript://<agent>/<session>` locators instead of fake
`agents/<agentId>/sessions/*.jsonl` paths. The old path builders remain for
doctor imports, explicit debug/export artifacts, and path-compatibility
tests.
doctor imports and explicit debug/export artifacts.
- Starting a new persisted transcript session now always allocates a fresh
SQLite locator. The session manager no longer reuses a previous file-era
transcript path as the identity for the new session.
@@ -283,9 +282,9 @@ The remaining cleanup is mostly consolidation and deletion:
classification helpers; transcript filtering now derives from SQLite row
metadata during entry construction.
- Memory-host and QMD session-export tests default to virtual
`sqlite-transcript://<agent>/<session>.jsonl` locators. Old
`sqlite-transcript://<agent>/<session>` locators. Old
`agents/<agentId>/sessions/*.jsonl` paths stay covered only where a test is
intentionally proving legacy path compatibility.
intentionally proving doctor/import/export compatibility.
- QA-lab raw session inspection now uses `sessions.list` through the gateway
instead of reading `agents/qa/sessions/sessions.json`; MSteams feedback
appends directly to SQLite transcripts without fabricating a JSONL path.

View File

@@ -1204,7 +1204,6 @@ describe("CodexAppServerEventProjector", () => {
expect(beforeCompaction).toHaveBeenCalledWith(
expect.objectContaining({
messageCount: 1,
sessionFile: expect.stringMatching(/^sqlite-transcript:\/\/main\/session-1-.+\.jsonl$/u),
messages: [expect.objectContaining({ role: "assistant" })],
}),
expect.objectContaining({
@@ -1216,7 +1215,6 @@ describe("CodexAppServerEventProjector", () => {
expect.objectContaining({
messageCount: 1,
compactedCount: -1,
sessionFile: expect.stringMatching(/^sqlite-transcript:\/\/main\/session-1-.+\.jsonl$/u),
}),
expect.objectContaining({
runId: "run-1",

View File

@@ -273,7 +273,6 @@ describe("generateVoiceResponse", () => {
agentId: "main",
sandboxSessionKey: "agent:main:voice:15550001111",
workspaceDir: "/tmp/openclaw/workspace/main",
sessionFile: expect.stringMatching(/^sqlite-transcript:\/\/main\/.+\.jsonl$/),
}),
);
});
@@ -311,7 +310,6 @@ describe("generateVoiceResponse", () => {
agentId: "voice",
sandboxSessionKey: "agent:voice:voice:15550001111",
workspaceDir: "/tmp/openclaw/workspace/voice",
sessionFile: expect.stringMatching(/^sqlite-transcript:\/\/voice\/.+\.jsonl$/),
}),
);
});

View File

@@ -3,7 +3,6 @@ export {
HEARTBEAT_TOKEN,
SILENT_REPLY_TOKEN,
hasInterSessionUserProvenance,
isCompactionCheckpointTranscriptFileName,
isCronRunSessionKey,
isExecCompletionEvent,
isHeartbeatUserMessage,

View File

@@ -48,7 +48,6 @@ export {
} from "../../../../src/config/config.js";
export type { OpenClawConfig } from "../../../../src/config/config.js";
export { resolveStateDir } from "../../../../src/config/paths.js";
export { isCompactionCheckpointTranscriptFileName } from "../../../../src/config/sessions/artifacts.js";
export {
listSqliteSessionTranscripts,
loadSqliteSessionTranscriptEvents,

View File

@@ -194,33 +194,9 @@ describe("buildSessionTranscriptEntry", () => {
expect(entry.lineMap).toEqual([]);
});
it("skips checkpoint artifacts so snapshots do not double-index session content", async () => {
const checkpointPath = path.join(
tmpDir,
"agents",
"main",
"sessions",
"ordinary.checkpoint.11111111-1111-4111-8111-111111111111.jsonl",
);
seedTranscript({
sessionId: "ordinary.checkpoint.11111111-1111-4111-8111-111111111111",
transcriptPath: checkpointPath,
events: [
{
type: "message",
message: { role: "user", content: "Archived hello" },
},
],
});
await expect(buildSessionTranscriptEntry(checkpointPath)).resolves.toBeNull();
});
it("keeps cron-run deleted archives opaque when the live session store entry is gone", async () => {
const archivePath = path.join(tmpDir, "cron-run.jsonl.deleted.2026-02-16T22-27-33.000Z");
it("keeps cron-run transcripts opaque when the live session store entry is gone", async () => {
const transcriptRef = seedTranscript({
sessionId: "cron-run-deleted",
transcriptPath: archivePath,
events: [
{
type: "message",
@@ -243,11 +219,9 @@ describe("buildSessionTranscriptEntry", () => {
expect(entry.generatedByCronRun).toBe(true);
});
it("keeps cron-run reset archives opaque when session metadata preserves the cron key", async () => {
const archivePath = path.join(tmpDir, "cron-run.jsonl.reset.2026-02-16T22-26-33.000Z");
it("keeps cron-run transcripts opaque when session metadata preserves the cron key", async () => {
const transcriptRef = seedTranscript({
sessionId: "cron-run-reset",
transcriptPath: archivePath,
events: [
{
type: "session-meta",

View File

@@ -5,7 +5,6 @@ import {
HEARTBEAT_PROMPT,
HEARTBEAT_TOKEN,
hasInterSessionUserProvenance,
isCompactionCheckpointTranscriptFileName,
isCronRunSessionKey,
isExecCompletionEvent,
isHeartbeatUserMessage,
@@ -57,16 +56,6 @@ export type SessionTranscriptDeltaStats = {
updatedAt: number;
};
function shouldSkipTranscriptFileForDreaming(absPath: string): boolean {
const fileName = path.basename(absPath);
// Compaction checkpoints are always skipped: they are derived snapshots of an
// active session and would double-index the same content.
if (isCompactionCheckpointTranscriptFileName(fileName)) {
return true;
}
return false;
}
function isDreamingNarrativeBootstrapRecord(record: unknown): boolean {
if (!record || typeof record !== "object" || Array.isArray(record)) {
return false;
@@ -205,7 +194,6 @@ export function sessionPathForTranscript(absPath: string): string {
export function resolveSessionTranscriptScope(locator: string): {
agentId: string;
sessionId: string;
transcriptPath?: string;
} | null {
const sqliteRef = parseSqliteSessionTranscriptRef(locator);
if (sqliteRef) {
@@ -457,19 +445,6 @@ export async function buildSessionTranscriptEntry(
(total, entry) => total + JSON.stringify(entry.event).length + 1,
0,
);
if (shouldSkipTranscriptFileForDreaming(absPath)) {
return {
path: sessionPathForTranscript(absPath),
absPath,
mtimeMs,
size,
messageCount,
hash: hashText("\n\n"),
content: "",
lineMap: [],
messageTimestampsMs: [],
};
}
const collected: string[] = [];
const lineMap: number[] = [];
const messageTimestampsMs: number[] = [];