metadata object —
events, messages, tool calls, tools, interrupts, resume entries. It is the
open channel for what the protocol does not model: provider names, latencies,
finish reasons, token counts, trace keys, whatever an application wants to
ride along with its data.
The value
metadata is open by key. Any JSON value is allowed under a key, including
null — a null there is meaningful data. The object itself is either absent
or an object and MUST NOT be null.
Unknown metadata keys are protocol-legal, not unrecognised material: the
processing model never strips them, on any
key.
Keys
Theag-ui key is reserved for the protocol’s own use. Every other key is
application space; producers SHOULD prefix keys they invent with a vendor or
application name, so two parties extending the same stream do not collide.
Merging
A streamed item is assembled from several events, and the interesting values — token usage, a finish reason — are only known at the end. So metadata accumulates rather than being fixed when the item opens: a consumer MUST merge the metadata of every event making up an item, key by key, with the last write winning for each key. The merge MUST NOT recurse. A key’s value is replaced outright, so an object or array under a key is replaced wholesale rather than blended with what was there before.Where each event’s metadata lands
Merging needs a target, and the target is the thing the event builds — not always the message:Tool-call metadata landing on the call rather than its parent message is
deliberate. One assistant message can own several tool calls, so folding
their metadata into the parent would make the result depend on the order
the calls happened to interleave. Each call keeping its own is what keeps it
unambiguous.
RUN_FINISHED metadata in its own bookkeeping, say — but no rule requires it.
Stored metadata
Messages, tool calls, tools, interrupts and resume entries carrymetadata as
a plain stored field of their own. Nothing merges into those except the events
listed above; a tool’s metadata in run input,
or an interrupt’s, is simply data travelling with its carrier.
Data Types
Metadata is defined by the
schema reference, and every carrier’s entry there lists
its metadata field.