Skip to content

Commit 6b17c71

Browse files
committed
refactor: keep transcript reader dependency storage-neutral
1 parent 55d3a4e commit 6b17c71

7 files changed

Lines changed: 38 additions & 17 deletions

scripts/check-session-transcript-reader-boundary.mjs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,8 @@ const transcriptReaderNames = new Set([
4949
"visitSessionMessagesAsync",
5050
]);
5151

52+
const storageSpecificTranscriptReaderAliasNames = new Set(["readSessionMessagesFromFileAsync"]);
53+
5254
export const migratedSessionTranscriptReaderFiles = new Set([
5355
"src/agents/main-session-restart-recovery.ts",
5456
"src/agents/subagent-announce-output.test.ts",
@@ -126,6 +128,13 @@ export function findSessionTranscriptReaderBoundaryViolations(content, fileName
126128
const legacyNamespaces = new Set();
127129

128130
const visit = (node) => {
131+
if (ts.isIdentifier(node) && storageSpecificTranscriptReaderAliasNames.has(node.text)) {
132+
violations.push({
133+
line: toLine(sourceFile, node),
134+
reason: `uses storage-specific transcript reader alias "${node.text}"`,
135+
});
136+
}
137+
129138
if (ts.isImportDeclaration(node)) {
130139
const moduleName = importedModuleName(node);
131140
const namedBindings = node.importClause?.namedBindings;

src/agents/subagent-announce-output.test.ts

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,8 @@ import {
1212
type CallGateway = typeof import("../gateway/call.js").callGateway;
1313
type GetRuntimeConfig = typeof import("./subagent-announce.runtime.js").getRuntimeConfig;
1414
type ReadSessionEntry = typeof import("./subagent-announce.runtime.js").readSessionEntry;
15-
type ReadSessionMessagesFromFileAsync =
16-
typeof import("./subagent-announce.runtime.js").readSessionMessagesFromFileAsync;
15+
type ReadSessionMessagesAsync =
16+
typeof import("./subagent-announce.runtime.js").readSessionMessagesAsync;
1717
type ResolveAgentIdFromSessionKey =
1818
typeof import("./subagent-announce.runtime.js").resolveAgentIdFromSessionKey;
1919
type ResolveStorePath = typeof import("./subagent-announce.runtime.js").resolveStorePath;
@@ -23,13 +23,12 @@ function installOutputDeps(params: {
2323
transcriptMessages?: Array<unknown>;
2424
}) {
2525
const callGateway = vi.fn(async () => ({ messages: params.messages }));
26-
const readSessionMessagesFromFileAsync = vi.fn(async () => params.transcriptMessages ?? []);
26+
const readSessionMessagesAsync = vi.fn(async () => params.transcriptMessages ?? []);
2727
testing.setDepsForTest({
2828
callGateway: callGateway as unknown as CallGateway,
29-
readSessionMessagesFromFileAsync:
30-
readSessionMessagesFromFileAsync as unknown as ReadSessionMessagesFromFileAsync,
29+
readSessionMessagesAsync: readSessionMessagesAsync as unknown as ReadSessionMessagesAsync,
3130
});
32-
return { callGateway, readSessionMessagesFromFileAsync };
31+
return { callGateway, readSessionMessagesAsync };
3332
}
3433

3534
function sessionsYieldTurn(message = "Waiting for subagent completion.") {
@@ -216,7 +215,7 @@ describe("readSubagentOutput", () => {
216215
sessionFile: "/tmp/openclaw-internal-run.jsonl",
217216
}),
218217
).resolves.toBe("fresh recovered output");
219-
expect(deps.readSessionMessagesFromFileAsync).toHaveBeenCalledWith(
218+
expect(deps.readSessionMessagesAsync).toHaveBeenCalledWith(
220219
{
221220
sessionFile: "/tmp/openclaw-internal-run.jsonl",
222221
sessionId: "agent:main:subagent:child",

src/agents/subagent-announce-output.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ import {
1515
callGateway,
1616
getRuntimeConfig,
1717
readSessionEntry,
18-
readSessionMessagesFromFileAsync,
18+
readSessionMessagesAsync,
1919
resolveAgentIdFromSessionKey,
2020
resolveStorePath,
2121
} from "./subagent-announce.runtime.js";
@@ -29,7 +29,7 @@ type SubagentAnnounceOutputDeps = {
2929
callGateway: typeof callGateway;
3030
getRuntimeConfig: typeof getRuntimeConfig;
3131
readSessionEntry: typeof readSessionEntry;
32-
readSessionMessagesFromFileAsync: typeof readSessionMessagesFromFileAsync;
32+
readSessionMessagesAsync: typeof readSessionMessagesAsync;
3333
resolveAgentIdFromSessionKey: typeof resolveAgentIdFromSessionKey;
3434
resolveStorePath: typeof resolveStorePath;
3535
};
@@ -38,7 +38,7 @@ const defaultSubagentAnnounceOutputDeps: SubagentAnnounceOutputDeps = {
3838
callGateway,
3939
getRuntimeConfig,
4040
readSessionEntry,
41-
readSessionMessagesFromFileAsync,
41+
readSessionMessagesAsync,
4242
resolveAgentIdFromSessionKey,
4343
resolveStorePath,
4444
};
@@ -206,7 +206,7 @@ export async function readSubagentOutput(
206206
): Promise<string | undefined> {
207207
let messages: unknown[] | undefined;
208208
if (options?.sessionFile) {
209-
const transcriptMessages = await subagentAnnounceOutputDeps.readSessionMessagesFromFileAsync(
209+
const transcriptMessages = await subagentAnnounceOutputDeps.readSessionMessagesAsync(
210210
{
211211
sessionFile: options.sessionFile,
212212
sessionId: sessionKey,

src/agents/subagent-announce.runtime.ts

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,7 @@ export {
1212
resolveStorePath,
1313
} from "../config/sessions.js";
1414
export { callGateway } from "../gateway/call.js";
15-
export {
16-
readSessionMessagesAsync,
17-
readSessionMessagesAsync as readSessionMessagesFromFileAsync,
18-
} from "../gateway/session-transcript-readers.js";
15+
export { readSessionMessagesAsync } from "../gateway/session-transcript-readers.js";
1916
export { dispatchGatewayMethodInProcess } from "../gateway/server-plugins.js";
2017
export {
2118
isEmbeddedAgentRunActive,

src/agents/subagent-announce.test.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,6 @@ vi.mock("./subagent-announce.runtime.js", () => ({
6565
getRuntimeConfig: () => mockConfig,
6666
loadSessionStore: (storePath: string) => loadSessionStoreMock(storePath),
6767
readSessionMessagesAsync: vi.fn(async () => []),
68-
readSessionMessagesFromFileAsync: vi.fn(async () => []),
6968
readSessionEntry: (storePath: string, sessionKey: string) =>
7069
(loadSessionStoreMock(storePath) as Record<string, unknown>)[sessionKey],
7170
resolveAgentIdFromSessionKey: (sessionKey: string) =>

src/agents/subagent-announce.timeout.test.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -188,7 +188,6 @@ vi.mock("./subagent-announce.runtime.js", () => ({
188188
getRuntimeConfig: () => configOverride,
189189
loadSessionStore: vi.fn(() => sessionStore),
190190
readSessionMessagesAsync: vi.fn(async () => []),
191-
readSessionMessagesFromFileAsync: vi.fn(async () => []),
192191
readSessionEntry: (_storePath: string, sessionKey: string) => sessionStore[sessionKey],
193192
resolveAgentIdFromSessionKey: () => "main",
194193
resolveStorePath: () => "/tmp/sessions-main.json",

test/scripts/check-session-transcript-reader-boundary.test.ts

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,4 +128,22 @@ describe("session transcript reader boundary guard", () => {
128128
`),
129129
).toEqual([]);
130130
});
131+
132+
it("flags storage-specific reader aliases in migrated files", () => {
133+
expect(
134+
findSessionTranscriptReaderBoundaryViolations(`
135+
import { readSessionMessagesAsync as readSessionMessagesFromFileAsync } from "./session-transcript-readers.js";
136+
await readSessionMessagesFromFileAsync(scope, opts);
137+
`),
138+
).toEqual([
139+
{
140+
line: 2,
141+
reason: 'uses storage-specific transcript reader alias "readSessionMessagesFromFileAsync"',
142+
},
143+
{
144+
line: 3,
145+
reason: 'uses storage-specific transcript reader alias "readSessionMessagesFromFileAsync"',
146+
},
147+
]);
148+
});
131149
});

0 commit comments

Comments
 (0)