mirror of
https://github.com/moltbot/moltbot.git
synced 2026-05-13 23:56:07 +00:00
test: remove followup store path registry
This commit is contained in:
@@ -20,9 +20,6 @@ let resolveQueuedReplyExecutionConfigActual:
|
||||
| undefined;
|
||||
let createFollowupRunner: typeof import("./followup-runner.js").createFollowupRunner;
|
||||
let clearRuntimeConfigSnapshot: typeof import("../../config/config.js").clearRuntimeConfigSnapshot;
|
||||
let loadSessionStore: typeof import("../../config/sessions/store.js").loadSessionStore;
|
||||
let saveSessionStore: typeof import("../../config/sessions/store.js").saveSessionStore;
|
||||
let clearSessionStoreCacheForTest: typeof import("../../config/sessions/store.js").clearSessionStoreCacheForTest;
|
||||
let clearFollowupQueue: typeof import("./queue.js").clearFollowupQueue;
|
||||
let enqueueFollowupRun: typeof import("./queue.js").enqueueFollowupRun;
|
||||
let sessionRunAccounting: typeof import("./session-run-accounting.js");
|
||||
@@ -37,7 +34,7 @@ const FOLLOWUP_TEST_QUEUES = new Map<
|
||||
lastRun?: FollowupRun["run"];
|
||||
}
|
||||
>();
|
||||
const FOLLOWUP_TEST_SESSION_STORES = new Map<string, Record<string, SessionEntry>>();
|
||||
const FOLLOWUP_TEST_SESSION_STORES = new Set<Record<string, SessionEntry>>();
|
||||
|
||||
function debugFollowupTest(message: string): void {
|
||||
if (!FOLLOWUP_DEBUG) {
|
||||
@@ -105,10 +102,9 @@ function expectNoBlockReplyTextIncludes(
|
||||
}
|
||||
|
||||
function registerFollowupTestSessionStore(
|
||||
storePath: string,
|
||||
sessionStore: Record<string, SessionEntry>,
|
||||
): void {
|
||||
FOLLOWUP_TEST_SESSION_STORES.set(storePath, sessionStore);
|
||||
FOLLOWUP_TEST_SESSION_STORES.add(sessionStore);
|
||||
}
|
||||
|
||||
async function incrementRunCompactionCountForFollowupTest(
|
||||
@@ -261,12 +257,16 @@ function refreshQueuedFollowupSessionForFollowupTest(params: {
|
||||
async function persistRunSessionUsageForFollowupTest(
|
||||
params: Parameters<typeof import("./session-run-accounting.js").persistRunSessionUsage>[0],
|
||||
): Promise<void> {
|
||||
const { storePath, sessionKey } = params;
|
||||
if (!storePath || !sessionKey) {
|
||||
const { sessionKey } = params;
|
||||
if (!sessionKey) {
|
||||
return;
|
||||
}
|
||||
const store = Array.from(FOLLOWUP_TEST_SESSION_STORES).find((candidate) =>
|
||||
Object.hasOwn(candidate, sessionKey),
|
||||
);
|
||||
if (!store) {
|
||||
return;
|
||||
}
|
||||
const registeredStore = FOLLOWUP_TEST_SESSION_STORES.get(storePath);
|
||||
const store = registeredStore ?? loadSessionStore(storePath);
|
||||
const entry = store[sessionKey];
|
||||
if (!entry) {
|
||||
return;
|
||||
@@ -294,10 +294,6 @@ async function persistRunSessionUsageForFollowupTest(
|
||||
nextEntry.totalTokens = promptTokens > 0 ? promptTokens : undefined;
|
||||
nextEntry.totalTokensFresh = promptTokens > 0;
|
||||
store[sessionKey] = nextEntry;
|
||||
if (registeredStore) {
|
||||
return;
|
||||
}
|
||||
await saveSessionStore(storePath, store);
|
||||
}
|
||||
|
||||
async function loadFreshFollowupRunnerModuleForTest() {
|
||||
@@ -307,12 +303,6 @@ async function loadFreshFollowupRunnerModuleForTest() {
|
||||
"../../agents/model-fallback.js",
|
||||
async () => await import("../../test-utils/model-fallback.mock.js"),
|
||||
);
|
||||
vi.doMock("../../agents/session-write-lock.js", () => ({
|
||||
acquireSessionWriteLock: vi.fn(async () => ({
|
||||
release: async () => {},
|
||||
})),
|
||||
resolveSessionLockMaxHoldFromTimeout: vi.fn(() => 1),
|
||||
}));
|
||||
vi.doMock("../../agents/pi-embedded.js", () => ({
|
||||
abortEmbeddedPiRun: vi.fn(async () => false),
|
||||
compactEmbeddedPiSession: (params: unknown) => compactEmbeddedPiSessionMock(params),
|
||||
@@ -400,8 +390,6 @@ async function loadFreshFollowupRunnerModuleForTest() {
|
||||
({ createFollowupRunner } = await import("./followup-runner.js"));
|
||||
({ clearRuntimeConfigSnapshot, setRuntimeConfigSnapshot } =
|
||||
await import("../../config/config.js"));
|
||||
({ clearSessionStoreCacheForTest, loadSessionStore, saveSessionStore } =
|
||||
await import("../../config/sessions/store.js"));
|
||||
({ clearFollowupQueue, enqueueFollowupRun } = await import("./queue.js"));
|
||||
sessionRunAccounting = await import("./session-run-accounting.js");
|
||||
({ createMockFollowupRun, createMockTypingController } = await import("./test-helpers.js"));
|
||||
@@ -465,7 +453,7 @@ afterEach(() => {
|
||||
FOLLOWUP_TEST_SESSION_STORES.clear();
|
||||
vi.clearAllTimers();
|
||||
vi.useRealTimers();
|
||||
clearSessionStoreCacheForTest();
|
||||
vi.unstubAllEnvs();
|
||||
if (!FOLLOWUP_DEBUG) {
|
||||
return;
|
||||
}
|
||||
@@ -704,10 +692,6 @@ describe("createFollowupRunner runtime config", () => {
|
||||
|
||||
describe("createFollowupRunner compaction", () => {
|
||||
it("adds verbose auto-compaction notice and tracks count", async () => {
|
||||
const storePath = path.join(
|
||||
await fs.mkdtemp(path.join(tmpdir(), "openclaw-compaction-")),
|
||||
"sessions.json",
|
||||
);
|
||||
const sessionEntry: SessionEntry = {
|
||||
sessionId: "session",
|
||||
updatedAt: Date.now(),
|
||||
@@ -716,7 +700,7 @@ describe("createFollowupRunner compaction", () => {
|
||||
main: sessionEntry,
|
||||
};
|
||||
const onBlockReply = vi.fn(async () => {});
|
||||
registerFollowupTestSessionStore(storePath, sessionStore);
|
||||
registerFollowupTestSessionStore(sessionStore);
|
||||
|
||||
mockCompactionRun({
|
||||
willRetry: true,
|
||||
@@ -730,7 +714,6 @@ describe("createFollowupRunner compaction", () => {
|
||||
sessionEntry,
|
||||
sessionStore,
|
||||
sessionKey: "main",
|
||||
storePath,
|
||||
defaultModel: "anthropic/claude-opus-4-6",
|
||||
});
|
||||
|
||||
@@ -749,20 +732,17 @@ describe("createFollowupRunner compaction", () => {
|
||||
});
|
||||
|
||||
it("tracks auto-compaction from embedded result metadata even when no compaction event is emitted", async () => {
|
||||
const storePath = path.join(
|
||||
await fs.mkdtemp(path.join(tmpdir(), "openclaw-compaction-meta-")),
|
||||
"sessions.json",
|
||||
);
|
||||
const sessionsDir = await fs.mkdtemp(path.join(tmpdir(), "openclaw-compaction-meta-"));
|
||||
const sessionEntry: SessionEntry = {
|
||||
sessionId: "session",
|
||||
sessionFile: path.join(path.dirname(storePath), "session.jsonl"),
|
||||
sessionFile: path.join(sessionsDir, "session.jsonl"),
|
||||
updatedAt: Date.now(),
|
||||
};
|
||||
const sessionStore: Record<string, SessionEntry> = {
|
||||
main: sessionEntry,
|
||||
};
|
||||
const onBlockReply = vi.fn(async () => {});
|
||||
registerFollowupTestSessionStore(storePath, sessionStore);
|
||||
registerFollowupTestSessionStore(sessionStore);
|
||||
|
||||
runEmbeddedPiAgentMock.mockResolvedValueOnce({
|
||||
payloads: [{ text: "final" }],
|
||||
@@ -782,7 +762,6 @@ describe("createFollowupRunner compaction", () => {
|
||||
sessionEntry,
|
||||
sessionStore,
|
||||
sessionKey: "main",
|
||||
storePath,
|
||||
defaultModel: "anthropic/claude-opus-4-6",
|
||||
});
|
||||
|
||||
@@ -800,24 +779,21 @@ describe("createFollowupRunner compaction", () => {
|
||||
expect(sessionStore.main.compactionCount).toBe(2);
|
||||
expect(sessionStore.main.sessionId).toBe("session-rotated");
|
||||
expect(await normalizeComparablePath(sessionStore.main.sessionFile ?? "")).toBe(
|
||||
await normalizeComparablePath(path.join(path.dirname(storePath), "session-rotated.jsonl")),
|
||||
await normalizeComparablePath(path.join(sessionsDir, "session-rotated.jsonl")),
|
||||
);
|
||||
});
|
||||
|
||||
it("refreshes queued followup runs to the rotated transcript", async () => {
|
||||
const storePath = path.join(
|
||||
await fs.mkdtemp(path.join(tmpdir(), "openclaw-compaction-queue-")),
|
||||
"sessions.json",
|
||||
);
|
||||
const sessionsDir = await fs.mkdtemp(path.join(tmpdir(), "openclaw-compaction-queue-"));
|
||||
const sessionEntry: SessionEntry = {
|
||||
sessionId: "session",
|
||||
sessionFile: path.join(path.dirname(storePath), "session.jsonl"),
|
||||
sessionFile: path.join(sessionsDir, "session.jsonl"),
|
||||
updatedAt: Date.now(),
|
||||
};
|
||||
const sessionStore: Record<string, SessionEntry> = {
|
||||
main: sessionEntry,
|
||||
};
|
||||
registerFollowupTestSessionStore(storePath, sessionStore);
|
||||
registerFollowupTestSessionStore(sessionStore);
|
||||
|
||||
runEmbeddedPiAgentMock.mockResolvedValueOnce({
|
||||
payloads: [{ text: "final" }],
|
||||
@@ -837,7 +813,6 @@ describe("createFollowupRunner compaction", () => {
|
||||
sessionEntry,
|
||||
sessionStore,
|
||||
sessionKey: "main",
|
||||
storePath,
|
||||
defaultModel: "anthropic/claude-opus-4-6",
|
||||
});
|
||||
|
||||
@@ -845,7 +820,7 @@ describe("createFollowupRunner compaction", () => {
|
||||
prompt: "next",
|
||||
run: {
|
||||
sessionId: "session",
|
||||
sessionFile: path.join(path.dirname(storePath), "session.jsonl"),
|
||||
sessionFile: path.join(sessionsDir, "session.jsonl"),
|
||||
},
|
||||
});
|
||||
const queueSettings: QueueSettings = { mode: "queue" };
|
||||
@@ -855,7 +830,7 @@ describe("createFollowupRunner compaction", () => {
|
||||
run: {
|
||||
verboseLevel: "on",
|
||||
sessionId: "session",
|
||||
sessionFile: path.join(path.dirname(storePath), "session.jsonl"),
|
||||
sessionFile: path.join(sessionsDir, "session.jsonl"),
|
||||
},
|
||||
});
|
||||
|
||||
@@ -863,15 +838,11 @@ describe("createFollowupRunner compaction", () => {
|
||||
|
||||
expect(queuedNext.run.sessionId).toBe("session-rotated");
|
||||
expect(await normalizeComparablePath(queuedNext.run.sessionFile)).toBe(
|
||||
await normalizeComparablePath(path.join(path.dirname(storePath), "session-rotated.jsonl")),
|
||||
await normalizeComparablePath(path.join(sessionsDir, "session-rotated.jsonl")),
|
||||
);
|
||||
});
|
||||
|
||||
it("does not count failed compaction end events in followup runs", async () => {
|
||||
const storePath = path.join(
|
||||
await fs.mkdtemp(path.join(tmpdir(), "openclaw-compaction-failed-")),
|
||||
"sessions.json",
|
||||
);
|
||||
const sessionEntry: SessionEntry = {
|
||||
sessionId: "session",
|
||||
updatedAt: Date.now(),
|
||||
@@ -880,7 +851,7 @@ describe("createFollowupRunner compaction", () => {
|
||||
main: sessionEntry,
|
||||
};
|
||||
const onBlockReply = vi.fn(async () => {});
|
||||
registerFollowupTestSessionStore(storePath, sessionStore);
|
||||
registerFollowupTestSessionStore(sessionStore);
|
||||
|
||||
const runner = createFollowupRunner({
|
||||
opts: { onBlockReply },
|
||||
@@ -889,7 +860,6 @@ describe("createFollowupRunner compaction", () => {
|
||||
sessionEntry,
|
||||
sessionStore,
|
||||
sessionKey: "main",
|
||||
storePath,
|
||||
defaultModel: "anthropic/claude-opus-4-6",
|
||||
});
|
||||
|
||||
@@ -925,7 +895,6 @@ describe("createFollowupRunner compaction", () => {
|
||||
|
||||
it("injects the post-compaction refresh prompt before followup runs after preflight compaction", async () => {
|
||||
const workspaceDir = await fs.mkdtemp(path.join(tmpdir(), "openclaw-preflight-followup-"));
|
||||
const storePath = path.join(workspaceDir, "sessions.json");
|
||||
const transcriptPath = path.join(workspaceDir, "session.jsonl");
|
||||
await fs.writeFile(
|
||||
transcriptPath,
|
||||
@@ -961,7 +930,7 @@ describe("createFollowupRunner compaction", () => {
|
||||
const sessionStore: Record<string, SessionEntry> = {
|
||||
main: sessionEntry,
|
||||
};
|
||||
registerFollowupTestSessionStore(storePath, sessionStore);
|
||||
registerFollowupTestSessionStore(sessionStore);
|
||||
|
||||
compactEmbeddedPiSessionMock.mockResolvedValueOnce({
|
||||
ok: true,
|
||||
@@ -979,7 +948,6 @@ describe("createFollowupRunner compaction", () => {
|
||||
sessionEntry?: SessionEntry;
|
||||
sessionStore?: Record<string, SessionEntry>;
|
||||
sessionKey?: string;
|
||||
storePath?: string;
|
||||
}) => {
|
||||
await compactEmbeddedPiSessionMock({
|
||||
sessionFile: transcriptPath,
|
||||
@@ -1001,16 +969,6 @@ describe("createFollowupRunner compaction", () => {
|
||||
if (params.sessionKey && params.sessionStore) {
|
||||
params.sessionStore[params.sessionKey] = updatedEntry;
|
||||
}
|
||||
if (params.storePath && params.sessionKey) {
|
||||
const registeredStore = FOLLOWUP_TEST_SESSION_STORES.get(params.storePath);
|
||||
if (registeredStore) {
|
||||
registeredStore[params.sessionKey] = updatedEntry;
|
||||
} else {
|
||||
const store = loadSessionStore(params.storePath);
|
||||
store[params.sessionKey] = updatedEntry;
|
||||
await saveSessionStore(params.storePath, store);
|
||||
}
|
||||
}
|
||||
}
|
||||
return updatedEntry;
|
||||
},
|
||||
@@ -1034,7 +992,6 @@ describe("createFollowupRunner compaction", () => {
|
||||
sessionEntry,
|
||||
sessionStore,
|
||||
sessionKey: "main",
|
||||
storePath,
|
||||
defaultModel: "anthropic/claude-opus-4-6",
|
||||
agentCfgContextTokens: 100_000,
|
||||
});
|
||||
@@ -1128,11 +1085,10 @@ describe("createFollowupRunner messaging delivery and dedupe", () => {
|
||||
sessionEntry: SessionEntry;
|
||||
sessionStore: Record<string, SessionEntry>;
|
||||
sessionKey: string;
|
||||
storePath: string;
|
||||
}> = {},
|
||||
) {
|
||||
if (overrides.storePath && overrides.sessionStore) {
|
||||
registerFollowupTestSessionStore(overrides.storePath, overrides.sessionStore);
|
||||
if (overrides.sessionStore) {
|
||||
registerFollowupTestSessionStore(overrides.sessionStore);
|
||||
}
|
||||
return createFollowupRunner({
|
||||
opts: { onBlockReply },
|
||||
@@ -1142,7 +1098,6 @@ describe("createFollowupRunner messaging delivery and dedupe", () => {
|
||||
sessionEntry: overrides.sessionEntry,
|
||||
sessionStore: overrides.sessionStore,
|
||||
sessionKey: overrides.sessionKey,
|
||||
storePath: overrides.storePath,
|
||||
});
|
||||
}
|
||||
|
||||
@@ -1153,7 +1108,6 @@ describe("createFollowupRunner messaging delivery and dedupe", () => {
|
||||
sessionEntry: SessionEntry;
|
||||
sessionStore: Record<string, SessionEntry>;
|
||||
sessionKey: string;
|
||||
storePath: string;
|
||||
}>;
|
||||
}) {
|
||||
const onBlockReply = createAsyncReplySpy();
|
||||
@@ -1175,7 +1129,6 @@ describe("createFollowupRunner messaging delivery and dedupe", () => {
|
||||
}
|
||||
|
||||
it("persists usage even when replies are suppressed", async () => {
|
||||
const storePath = "/tmp/openclaw-followup-usage.json";
|
||||
const sessionKey = "main";
|
||||
const sessionEntry: SessionEntry = { sessionId: "session", updatedAt: Date.now() };
|
||||
const sessionStore: Record<string, SessionEntry> = { [sessionKey]: sessionEntry };
|
||||
@@ -1212,14 +1165,12 @@ describe("createFollowupRunner messaging delivery and dedupe", () => {
|
||||
sessionEntry,
|
||||
sessionStore,
|
||||
sessionKey,
|
||||
storePath,
|
||||
},
|
||||
queued: baseQueuedRun("slack"),
|
||||
});
|
||||
|
||||
expect(onBlockReply).not.toHaveBeenCalled();
|
||||
const persistCall = requireMockCallArg(persistSpy, 0);
|
||||
expect(persistCall.storePath).toBe(storePath);
|
||||
expect(persistCall.sessionKey).toBe(sessionKey);
|
||||
expect(persistCall.modelUsed).toBe("claude-opus-4-6");
|
||||
expect(persistCall.providerUsed).toBe("anthropic");
|
||||
@@ -1232,7 +1183,6 @@ describe("createFollowupRunner messaging delivery and dedupe", () => {
|
||||
});
|
||||
|
||||
it("passes queued config into usage persistence during drained followups", async () => {
|
||||
const storePath = "/tmp/openclaw-followup-usage-cfg.json";
|
||||
const sessionKey = "main";
|
||||
const sessionEntry: SessionEntry = { sessionId: "session", updatedAt: Date.now() };
|
||||
const sessionStore: Record<string, SessionEntry> = { [sessionKey]: sessionEntry };
|
||||
@@ -1262,7 +1212,6 @@ describe("createFollowupRunner messaging delivery and dedupe", () => {
|
||||
sessionEntry,
|
||||
sessionStore,
|
||||
sessionKey,
|
||||
storePath,
|
||||
});
|
||||
|
||||
await expect(
|
||||
@@ -1276,14 +1225,12 @@ describe("createFollowupRunner messaging delivery and dedupe", () => {
|
||||
).resolves.toBeUndefined();
|
||||
|
||||
const persistCall = requireMockCallArg(persistSpy, 0);
|
||||
expect(persistCall.storePath).toBe(storePath);
|
||||
expect(persistCall.sessionKey).toBe(sessionKey);
|
||||
expect(persistCall.cfg).toBe(cfg);
|
||||
persistSpy.mockRestore();
|
||||
});
|
||||
|
||||
it("uses providerUsed for snapshot freshness when agent metadata overrides the run provider", async () => {
|
||||
const storePath = "/tmp/openclaw-followup-usage-provider.json";
|
||||
const sessionKey = "main";
|
||||
const sessionEntry: SessionEntry = { sessionId: "session", updatedAt: Date.now() };
|
||||
const sessionStore: Record<string, SessionEntry> = { [sessionKey]: sessionEntry };
|
||||
@@ -1308,7 +1255,6 @@ describe("createFollowupRunner messaging delivery and dedupe", () => {
|
||||
sessionEntry,
|
||||
sessionStore,
|
||||
sessionKey,
|
||||
storePath,
|
||||
});
|
||||
|
||||
await expect(
|
||||
|
||||
Reference in New Issue
Block a user