Files
hermes-agent/apps
Teknium 544169a41a perf(desktop): stop per-event full-timeline allocations on streamed tool events
Every tool.start / tool.progress / tool.complete ran three whole-timeline
passes that each allocated per part: `completeOpenStreamParts` (`map` with a
spread per row), the pending-row scan (`map` → `filter` → `map`, one wrapper
object per part), and `generatedImageEchoSources` (`flatMap` + a throwaway
array per non-image row) — then `dedupeGeneratedImageEchoesInParts` copied
the array again even when it stripped nothing, handing React a fresh
identity per event. Replace them with single in-place loops, and return the
input array from the dedupe when there are no echoes so a no-op stays a
no-op for the store.

Measured on the real `useMessageStream` hook (vitest/jsdom, 2,000 starts +
2,000 completions interleaved with text deltas): 618 ms → 138 ms; the
tool-only 2,000×2 case 252 ms → 67 ms. The remaining O(n) is one
`findIndex` per event over a ~4k array (~8 µs), well under the cost of the
copy React needs anyway, so no per-stream id index is introduced.

Behaviour is unchanged: same first-match `toolCallId` resolution, same
sparse/no-id contextual correlation, same ordering of parts.

Co-authored-by: Xipong <217837358+Xipong@users.noreply.github.com>
2026-09-09 12:13:14 -07:00
..