You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
feat(ai): typed metadata on tool calls + thread through pipeline
Renames `providerMetadata` to `metadata` and types it per-adapter via a
new `TToolCallMetadata` generic on `BaseTextAdapter`, mirroring the
existing typed-metadata pattern on content parts (`ImagePart<TMetadata>`,
etc.).
Also threads metadata through the client-side UIMessage pipeline so it
round-trips with each tool call, fixing the silent drop surfaced in
#403/#404 (incorporates that PR's plumbing under the new name).
Gemini adapter now declares `TToolCallMetadata = GeminiToolCallMetadata`,
giving consumers typed `toolCall.metadata?.thoughtSignature` end-to-end.
Per maintainer feedback on #459 (AlemTuzlak): use `metadata` (typed
per-adapter generic) rather than the previous `providerMetadata` bag.
The `ToolCallStartEvent` event remains non-generic with
`metadata?: Record<string, unknown>` because making it generic breaks
the AGUIEvent discriminated-union narrowing.
Breaking: consumers reading `toolCall.providerMetadata` or
`toolCallStartEvent.providerMetadata` should rename to `metadata`.
Co-authored-by: houmark <noreply@github.com>
fix(ai-gemini): read/write thoughtSignature at Part level
7
+
fix(ai-gemini): read/write thoughtSignature at Part level + thread typed metadata through tool-call lifecycle
6
8
7
-
Gemini emits `thoughtSignature` as a Part-level sibling of `functionCall` (per the `@google/genai``Part` type definition), not nested inside `functionCall`. The `FunctionCall` type has never had a `thoughtSignature` property. The adapter was reading from `functionCall.thoughtSignature` (which doesn't exist in the SDK types) and writing it back nested inside `functionCall`, causing Gemini 3.x to reject subsequent tool-call turns with `400 INVALID_ARGUMENT: "Function call is missing a thought_signature"`.
9
+
Two fixes shipped together because the adapter fix is only effective once the framework also preserves provider metadata across the tool-call round-trip.
8
10
9
-
This fix:
11
+
**Adapter (Gemini):** Gemini emits `thoughtSignature` as a Part-level sibling of `functionCall` (per the `@google/genai``Part` type definition), not nested inside `functionCall`. The `FunctionCall` type has never had a `thoughtSignature` property. The adapter was reading from `functionCall.thoughtSignature` (does not exist in SDK types) and writing it back nested inside `functionCall`, causing Gemini 3.x to reject subsequent tool-call turns with `400 INVALID_ARGUMENT: "Function call is missing a thought_signature"`.
10
12
11
-
-**Read side:** reads `part.thoughtSignature` directly, using the SDK's typed `Part` interface
12
-
-**Write side:** emits `thoughtSignature` as a Part-level sibling of `functionCall`, using the SDK's typed `Part` interface
13
+
-**Read side:** reads `part.thoughtSignature` directly using the SDK's typed `Part` interface
14
+
-**Write side:** emits `thoughtSignature` as a Part-level sibling of `functionCall`
15
+
16
+
**Framework (typed tool-call metadata):**
17
+
18
+
-`ToolCall.providerMetadata: Record<string, unknown>` is now `ToolCall<TMetadata>.metadata?: TMetadata`, mirroring the existing typed-metadata pattern on content parts (`ImagePart<TMetadata>`, `AudioPart<TMetadata>`, etc.).
19
+
-`ToolCallPart` gains a typed `metadata?: TMetadata` field (also generic).
20
+
-`ToolCallStartEvent.providerMetadata` becomes `metadata` (kept as `Record<string, unknown>` because the AGUIEvent discriminated union does not survive a generic on the event type; adapters cast to their typed shape when emitting).
21
+
-`BaseTextAdapter` and `TextAdapter` gain a sixth generic `TToolCallMetadata` (default `unknown`), exposed via `~types.toolCallMetadata` for inference at call sites.
22
+
-`InternalToolCallState` gains a `metadata?: Record<string, unknown>` field captured at `TOOL_CALL_START` and threaded through `updateToolCallPart`, `buildAssistantMessages`, `modelMessageToUIMessage`, and `completeToolCall`, fixing a previously-silent drop of provider metadata across the client-side UIMessage pipeline (closes the gap surfaced in #403/#404).
23
+
24
+
**Gemini concrete impl:** new `GeminiToolCallMetadata { thoughtSignature?: string }` exported from `@tanstack/ai-gemini`. The adapter declares its `TToolCallMetadata` as this type, so consumers see `toolCall.metadata?.thoughtSignature` typed end-to-end.
25
+
26
+
**Breaking:** consumers reading `toolCall.providerMetadata` or `toolCallStartEvent.providerMetadata` should rename to `metadata`.
0 commit comments