summaryrefslogtreecommitdiffhomepage
path: root/packages/api/tests
diff options
context:
space:
mode:
Diffstat (limited to 'packages/api/tests')
-rw-r--r--packages/api/tests/agent-manager.test.ts39
1 files changed, 39 insertions, 0 deletions
diff --git a/packages/api/tests/agent-manager.test.ts b/packages/api/tests/agent-manager.test.ts
index 95fb558..6d7d66f 100644
--- a/packages/api/tests/agent-manager.test.ts
+++ b/packages/api/tests/agent-manager.test.ts
@@ -104,6 +104,13 @@ function resetAppendChunksCalls(): void {
appendChunksCalls.length = 0;
}
+// Seedable return value for the mocked getUsageStatsForTab — what the backend
+// reads (post-write) to attach to the `turn-sealed` event.
+const fakeUsageStatsByTab = new Map<string, unknown>();
+function resetFakeUsageStats(): void {
+ fakeUsageStatsByTab.clear();
+}
+
// Allow tests to swap in a custom `run` generator (e.g. to simulate
// a fallback failure mid-stream). Returning to undefined restores
// the default.
@@ -371,6 +378,9 @@ vi.mock("@dispatch/core", () => ({
getMessagesForTab(tabId: string) {
return fakeMessagesByTab.get(tabId) ?? [];
},
+ getUsageStatsForTab(tabId: string) {
+ return fakeUsageStatsByTab.get(tabId) ?? null;
+ },
appendEventToChunks: appendEventToChunksSpy,
applySystemEvent(_messages: unknown[], _event: unknown) {
return { messageId: "mock-system-msg" };
@@ -421,6 +431,7 @@ describe("AgentManager", () => {
setRunImpl(null);
appendEventToChunksSpy.mockClear();
resetAppendChunksCalls();
+ resetFakeUsageStats();
});
it("initial status is idle", () => {
@@ -1402,6 +1413,34 @@ describe("AgentManager", () => {
});
});
+ it("attaches the DB usage aggregate to the turn-sealed event for live reconciliation", async () => {
+ const manager = new AgentManager();
+ const aggregate = {
+ inputTokens: 222,
+ outputTokens: 22,
+ cacheReadTokens: 100,
+ cacheWriteTokens: 5,
+ requests: 1,
+ last: { inputTokens: 222, outputTokens: 22, cacheReadTokens: 100, cacheWriteTokens: 5 },
+ };
+ fakeUsageStatsByTab.set("tab-sealed-usage", aggregate);
+
+ const events: AgentEvent[] = [];
+ manager.onEvent((event) => {
+ events.push(event);
+ });
+
+ await manager.processMessage("tab-sealed-usage", "go");
+
+ const sealed = events.find((e) => e.type === "turn-sealed") as
+ | Extract<AgentEvent, { type: "turn-sealed" }>
+ | undefined;
+ expect(sealed).toBeDefined();
+ // The aggregate read AFTER the write is carried on the event so the
+ // frontend can REPLACE its live cacheStats with the DB truth.
+ expect(sealed?.usageStats).toEqual(aggregate);
+ });
+
it("emits usage rows in the SAME appendChunks call as the turn's content (one atomic write)", async () => {
const manager = new AgentManager();
setRunImpl(async function* () {