Expand description
Normalizing *_CHUNK events into explicit start/content/end triples.
A producer that cannot bracket its output — most provider adapters, because
the upstream API does not tell them a message has ended until the next one
begins — sends TEXT_MESSAGE_CHUNK, TOOL_CALL_CHUNK and
REASONING_MESSAGE_CHUNK instead. Those events fold start, content and end
into one, and they carry their id and name only on the first chunk:
TEXT_MESSAGE_CHUNK { messageId: "msg-1", delta: "Hel" }
TEXT_MESSAGE_CHUNK { delta: "lo" }
TEXT_MESSAGE_CHUNK { messageId: "msg-2", delta: "Bye" } <- msg-1 just endedSo the id has to be remembered, and the end of one stream is only knowable from the start of the next — or from the end of the run. That bookkeeping is this module.
use ag_ui::client::chunks::normalize_all;
use ag_ui::{Event, EventType, MessageId};
let events = normalize_all([
Event::text_message_chunk(Some(MessageId::new("msg-1")), Some("Hel".into())),
Event::text_message_chunk(None, Some("lo".into())),
])?;
let types: Vec<EventType> = events.iter().map(Event::event_type).collect();
assert_eq!(types, [
EventType::TextMessageStart,
EventType::TextMessageContent,
EventType::TextMessageContent,
EventType::TextMessageEnd,
]);§Subagents
“The previous chunk” is only meaningful per subagent once several stream
at once, so the shorthand resolves within the sending subagent’s own
stream: one stream may be open per owner, and a chunk that names no id
continues the stream of the subagent it is attributed to. A chunk that
carries neither an id nor a subagentRunId continues the parent’s open
stream when there is one, and otherwise the sole open stream; when several
subagents’ streams could all claim it there is nothing to resolve it
against, and it is rejected rather than guessed at. When streaming
concurrently, attribute every chunk — or repeat the id.
Structs§
- Chunk
Normalizer - Expands chunk events into the explicit events the rest of the protocol is written in.
Functions§
- normalize_
all - Normalizes a whole run in one call, closing anything left open at the end.