Files
Shoubhit Dash a4cec2c78a refactor(ai): type each protocol's provider metadata round-trip
Every protocol wrote its own provider metadata onto stream events through
an untyped `providerMetadata(key, Record<string, unknown>)` one-liner —
copied verbatim into anthropic-messages, bedrock-converse and gemini — and
read it back in request lowering with `isRecord(x) && typeof x.signature
=== "string"`. Writer and reader of the same namespace never met at
compile time, so a typo on either side only showed up as a signature that
failed to round-trip.

`ProviderShared.providerMetadata(schema)` now pairs a typed `write` with a
synchronous `read` (`decodeUnknownOption`). Each of anthropic-messages,
bedrock-converse, gemini, open-responses and openai-chat declares one
`Schema.Struct` of the fields it publishes under its `providerMetadataKey`
and uses the pair; the hand-written readers are deleted, and
responses-compaction's raw metadata literal goes through the typed writer.

Fields use `lenient` because the old readers were independent per field:
a malformed `signature` never dropped `redactedData`. A new test pins
that. Every reader was probed against v2 for undefined/null/array/string/
empty-object metadata and unknown keys; behaviour is unchanged. Bedrock
keeps its own two-field struct rather than importing Anthropic's, since no
protocol depends on another protocol's internals. Raw usage passthroughs
stay raw: they forward each provider's usage object and are never read
back.
2026-09-18 19:49:06 +05:30
..
2026-09-18 09:12:33 +00:00
2026-09-18 09:12:33 +00:00
2026-09-18 09:12:33 +00:00
2026-09-18 09:12:33 +00:00
2026-09-18 09:12:33 +00:00
2026-09-18 09:12:33 +00:00
2026-09-18 09:12:33 +00:00
2026-09-18 09:12:33 +00:00
2026-09-18 09:12:33 +00:00
2026-09-18 09:12:33 +00:00
2026-09-18 09:12:33 +00:00
2026-09-18 09:12:33 +00:00
2026-09-18 09:12:33 +00:00
2026-09-18 09:12:33 +00:00
2026-09-18 09:12:33 +00:00
2026-09-18 09:12:33 +00:00
2026-09-18 09:12:33 +00:00
2026-09-18 09:12:33 +00:00
2026-09-18 09:12:33 +00:00