diff --git a/packages/engine/src/__tests__/agent-log-assertions.ts b/packages/engine/src/__tests__/agent-log-assertions.ts new file mode 100644 index 0000000000..4f6319354a --- /dev/null +++ b/packages/engine/src/__tests__/agent-log-assertions.ts @@ -0,0 +1,37 @@ +import { expect, type Mock } from "vitest"; + +/** + * FNXC:AgentLogging 2026-07-07-08:10: + * FN-7503 added optional timing telemetry (`durationMs`/`timeToFirstTokenMs`) as a + * 6th positional argument to `TaskStore.appendAgentLog` for entries that carry + * timing (text/tool_result/tool_error with measured metrics). Calls without timing + * still pass only five args, so the 6th is genuinely optional. + * + * Assertions on agent-log writes must pin the meaningful first five positional args + * (taskId/text/type/detail/agent) and stay tolerant of the optional timing object, + * otherwise every executor/heartbeat/merger test re-breaks whenever a new timing + * field is added. Use this helper instead of `toHaveBeenCalledWith(...)` for those + * five-arg assertions. See `packages/engine/src/agent-logger.ts` flushPendingEntries. + */ +export function expectAppendAgentLog( + mock: Mock, + taskId: string, + text: string, + type: string, + detail: unknown, + agent: string, +): void { + const calls = mock.mock.calls as unknown[][]; + const found = calls.some( + (call) => + call[0] === taskId && + call[1] === text && + call[2] === type && + call[3] === detail && + call[4] === agent, + ); + expect( + found, + `expected appendAgentLog to have been called with (${JSON.stringify(taskId)}, ${JSON.stringify(text)}, ${JSON.stringify(type)}, ${JSON.stringify(detail)}, ${JSON.stringify(agent)}) as its first five args (ignoring any optional timing object); actual calls were:\n${calls.map((c) => JSON.stringify(c)).join("\n")}`, + ).toBe(true); +} diff --git a/packages/engine/src/__tests__/merger-merge-details.test.ts b/packages/engine/src/__tests__/merger-merge-details.test.ts index d241e25d0f..48f8c6703f 100644 --- a/packages/engine/src/__tests__/merger-merge-details.test.ts +++ b/packages/engine/src/__tests__/merger-merge-details.test.ts @@ -153,6 +153,10 @@ import { createFnAgent } from "../pi.js"; import { execSync, exec } from "node:child_process"; import * as core from "@fusion/core"; import { type TaskStore, type Task, type MergeResult, DEFAULT_SETTINGS } from "@fusion/core"; +// FNXC:AgentLogging 2026-07-07-08:40: FN-7503 added optional 6th timing arg to +// appendAgentLog. Use the shared 5-arg-tolerant helper for text-delta assertions +// instead of toHaveBeenCalledWith so the timing object doesn't re-break them. +import { expectAppendAgentLog } from "./agent-log-assertions.js"; const mockedCreateFnAgent = vi.mocked(createFnAgent); const mockedExecSync = vi.mocked(execSync); @@ -496,7 +500,7 @@ describe("aiMergeTask — agent log persistence", () => { await aiMergeTask(store, "/tmp/root", "FN-050"); - expect(store.appendAgentLog).toHaveBeenCalledWith("FN-050", "Hello merge", "text", undefined, "merger"); + expectAppendAgentLog(store.appendAgentLog, "FN-050", "Hello merge", "text", undefined, "merger"); }); it("logs tool invocations to store.appendAgentLog", async () => { @@ -550,7 +554,7 @@ describe("aiMergeTask — agent log persistence", () => { await aiMergeTask(store, "/tmp/root", "FN-050", { onAgentText }); expect(onAgentText).toHaveBeenCalledWith("hi"); - expect(store.appendAgentLog).toHaveBeenCalledWith("FN-050", "hi", "text", undefined, "merger"); + expectAppendAgentLog(store.appendAgentLog, "FN-050", "hi", "text", undefined, "merger"); }); });