1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
|
/**
* Bench the PURE pipeline a tab runs when opening a conversation mid-turn:
* history fetch → applyHistory → fold every replayed event (one render-pass
* worth of derivations per event, like the UI does) .
* bun scripts/bench-pure.ts <conversationId> [scale]
* `scale` synthesizes a longer turn by repeating the replay's step events.
*/
import {
applyHistory,
foldEvent,
groupRenderedChunks,
initialState,
initialWindowSize,
selectChunks,
windowTranscript,
} from "../src/core/chunks/index.ts";
import { interleaveTurnMetrics } from "../src/core/metrics/index.ts";
import { renderMarkdown } from "../src/features/markdown/logic/markdown.ts";
const conv = process.argv[2] ?? "";
const HTTP = process.env.PROBE_HTTP ?? "http://localhost:24991";
const replay = JSON.parse(await Bun.file(`/tmp/replay-${conv}.json`).text()) as { type: string }[];
const hist = (await (await fetch(`${HTTP}/conversations/${conv}?sinceSeq=0`)).json()) as {
chunks: { seq: number; turnId?: string; chunk: { type: string } }[];
};
const turnId = (replay.find((e) => e.type === "turn-start") as { turnId: string }).turnId;
const committedThisTurn = hist.chunks.filter((c) => c.turnId === turnId).length;
console.log(
`history chunks=${hist.chunks.length} (of which current turn=${committedThisTurn}), replay events=${replay.length}`,
);
let state = windowTranscript(
applyHistory(initialState(), hist.chunks as never),
initialWindowSize(256),
);
let derive = 0;
let md = 0;
const t0 = performance.now();
for (const ev of replay) {
state = foldEvent(state, ev as never);
// What each per-event render recomputes in ChatView:
const d0 = performance.now();
const chunks = selectChunks(state);
interleaveTurnMetrics(groupRenderedChunks(chunks), []);
derive += performance.now() - d0;
const last = chunks[chunks.length - 1];
if (last?.streaming && last.chunk.type === "text") {
const m0 = performance.now();
renderMarkdown(last.chunk.text, { streaming: true });
md += performance.now() - m0;
}
}
const total = performance.now() - t0;
const rendered = selectChunks(state);
const dupTool = new Map<string, number>();
for (const r of rendered) {
if (r.chunk.type === "tool-call" || r.chunk.type === "tool-result") {
const k = `${r.chunk.type}:${(r.chunk as { toolCallId: string }).toolCallId}`;
dupTool.set(k, (dupTool.get(k) ?? 0) + 1);
}
}
const dups = [...dupTool.values()].filter((n) => n > 1).length;
console.log({
renderedChunks: rendered.length,
committed: state.committed.length,
provisional: state.provisional.length,
duplicatedToolChunks: dups,
totalMs: Math.round(total),
deriveMs: Math.round(derive),
markdownFullRerenderMs: Math.round(md),
});
|