reduce

Folds one ChatEvent into the assistant Message. Pure, so it is trivially unit-testable and every backend shares the exact same message semantics.

Parts are keyed by id: a delta for an unknown id appends a new part at the end, which preserves the interleaving order of multi-step agent runs.