diff --git a/packages/typescript/ai/src/activities/chat/messages.ts b/packages/typescript/ai/src/activities/chat/messages.ts index b7f97b880..67fa86d52 100644 --- a/packages/typescript/ai/src/activities/chat/messages.ts +++ b/packages/typescript/ai/src/activities/chat/messages.ts @@ -138,6 +138,7 @@ interface AssistantSegment { id: string type: 'function' function: { name: string; arguments: string } + providerMetadata?: Record }> } @@ -205,6 +206,9 @@ function buildAssistantMessages(uiMessage: UIMessage): Array { name: part.name, arguments: part.arguments, }, + ...(part.providerMetadata && { + providerMetadata: part.providerMetadata, + }), }) } break @@ -340,6 +344,9 @@ export function modelMessageToUIMessage( name: toolCall.function.name, arguments: toolCall.function.arguments, state: 'input-complete', // Model messages have complete arguments + ...(toolCall.providerMetadata && { + providerMetadata: toolCall.providerMetadata, + }), }) } } diff --git a/packages/typescript/ai/src/activities/chat/stream/message-updaters.ts b/packages/typescript/ai/src/activities/chat/stream/message-updaters.ts index 80b94d59a..6a18bdee2 100644 --- a/packages/typescript/ai/src/activities/chat/stream/message-updaters.ts +++ b/packages/typescript/ai/src/activities/chat/stream/message-updaters.ts @@ -55,6 +55,7 @@ export function updateToolCallPart( name: string arguments: string state: ToolCallState + providerMetadata?: Record }, ): Array { return messages.map((msg) => { @@ -67,6 +68,10 @@ export function updateToolCallPart( (p): p is ToolCallPart => p.type === 'tool-call' && p.id === toolCall.id, ) + // Carry forward providerMetadata from either the new toolCall or the existing part + const providerMetadata = + toolCall.providerMetadata ?? existing?.providerMetadata + const toolCallPart: ToolCallPart = { type: 'tool-call', id: toolCall.id, @@ -76,6 +81,7 @@ export function updateToolCallPart( // Carry forward approval and output from the existing part ...(existing?.approval && { approval: { ...existing.approval } }), ...(existing?.output !== undefined && { output: existing.output }), + ...(providerMetadata && { providerMetadata }), } if (existing) { diff --git a/packages/typescript/ai/src/activities/chat/stream/processor.ts b/packages/typescript/ai/src/activities/chat/stream/processor.ts index dc5330f17..f83b980d5 100644 --- a/packages/typescript/ai/src/activities/chat/stream/processor.ts +++ b/packages/typescript/ai/src/activities/chat/stream/processor.ts @@ -856,6 +856,9 @@ export class StreamProcessor { state: initialState, parsedArguments: undefined, index: chunk.index ?? state.toolCalls.size, + ...(chunk.providerMetadata && { + providerMetadata: chunk.providerMetadata, + }), } state.toolCalls.set(toolCallId, newToolCall) @@ -870,6 +873,9 @@ export class StreamProcessor { name: chunk.toolName, arguments: '', state: initialState, + ...(chunk.providerMetadata && { + providerMetadata: chunk.providerMetadata, + }), }) this.emitMessagesChange() @@ -1367,6 +1373,9 @@ export class StreamProcessor { name: tc.name, arguments: tc.arguments, }, + ...(tc.providerMetadata && { + providerMetadata: tc.providerMetadata, + }), }) } } diff --git a/packages/typescript/ai/src/activities/chat/stream/types.ts b/packages/typescript/ai/src/activities/chat/stream/types.ts index c1806238f..374572505 100644 --- a/packages/typescript/ai/src/activities/chat/stream/types.ts +++ b/packages/typescript/ai/src/activities/chat/stream/types.ts @@ -25,6 +25,8 @@ export interface InternalToolCallState { state: ToolCallState parsedArguments?: any index: number + /** Provider-specific metadata (e.g. Gemini thoughtSignature) */ + providerMetadata?: Record } /** diff --git a/packages/typescript/ai/src/types.ts b/packages/typescript/ai/src/types.ts index 984e15125..5a4ef502b 100644 --- a/packages/typescript/ai/src/types.ts +++ b/packages/typescript/ai/src/types.ts @@ -295,6 +295,8 @@ export interface ToolCallPart { } /** Tool execution output (for client tools or after approval) */ output?: any + /** Provider-specific metadata carried through the tool call lifecycle (e.g. Gemini thoughtSignature) */ + providerMetadata?: Record } export interface ToolResultPart {