@tanstack/ai 0.15.0 → 0.16.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/esm/activities/chat/adapter.d.ts +6 -3
- package/dist/esm/activities/chat/adapter.js.map +1 -1
- package/dist/esm/activities/chat/messages.js +4 -2
- package/dist/esm/activities/chat/messages.js.map +1 -1
- package/dist/esm/activities/chat/stream/message-updaters.d.ts +1 -0
- package/dist/esm/activities/chat/stream/message-updaters.js +3 -1
- package/dist/esm/activities/chat/stream/message-updaters.js.map +1 -1
- package/dist/esm/activities/chat/stream/processor.js +12 -4
- package/dist/esm/activities/chat/stream/processor.js.map +1 -1
- package/dist/esm/activities/chat/stream/types.d.ts +5 -0
- package/dist/esm/activities/chat/tools/tool-calls.js +1 -3
- package/dist/esm/activities/chat/tools/tool-calls.js.map +1 -1
- package/dist/esm/types.d.ts +15 -7
- package/package.json +2 -2
- package/src/activities/chat/adapter.ts +8 -2
- package/src/activities/chat/messages.ts +6 -0
- package/src/activities/chat/stream/message-updaters.ts +8 -0
- package/src/activities/chat/stream/processor.ts +12 -0
- package/src/activities/chat/stream/types.ts +5 -0
- package/src/activities/chat/tools/tool-calls.ts +1 -3
- package/src/types.ts +15 -7
package/dist/esm/types.d.ts
CHANGED
|
@@ -70,15 +70,17 @@ export type SchemaInput = StandardJSONSchemaV1<any, any> | JSONSchema;
|
|
|
70
70
|
* For plain JSONSchema, returns `any` since we can't infer types from JSON Schema at compile time.
|
|
71
71
|
*/
|
|
72
72
|
export type InferSchemaType<T> = T extends StandardJSONSchemaV1<infer TInput, unknown> ? TInput : unknown;
|
|
73
|
-
export interface ToolCall {
|
|
73
|
+
export interface ToolCall<TMetadata = unknown> {
|
|
74
74
|
id: string;
|
|
75
75
|
type: 'function';
|
|
76
76
|
function: {
|
|
77
77
|
name: string;
|
|
78
78
|
arguments: string;
|
|
79
79
|
};
|
|
80
|
-
/** Provider-specific metadata to carry through the tool call lifecycle
|
|
81
|
-
|
|
80
|
+
/** Provider-specific metadata to carry through the tool call lifecycle.
|
|
81
|
+
* Typed per-adapter via `TToolCallMetadata`. For example,
|
|
82
|
+
* `@tanstack/ai-gemini` sets this to `{ thoughtSignature?: string }`. */
|
|
83
|
+
metadata?: TMetadata;
|
|
82
84
|
}
|
|
83
85
|
/**
|
|
84
86
|
* Supported input modality types for multimodal content.
|
|
@@ -221,7 +223,7 @@ export interface TextPart<TMetadata = unknown> {
|
|
|
221
223
|
content: string;
|
|
222
224
|
metadata?: TMetadata;
|
|
223
225
|
}
|
|
224
|
-
export interface ToolCallPart {
|
|
226
|
+
export interface ToolCallPart<TMetadata = unknown> {
|
|
225
227
|
type: 'tool-call';
|
|
226
228
|
id: string;
|
|
227
229
|
name: string;
|
|
@@ -235,6 +237,9 @@ export interface ToolCallPart {
|
|
|
235
237
|
};
|
|
236
238
|
/** Tool execution output (for client tools or after approval) */
|
|
237
239
|
output?: any;
|
|
240
|
+
/** Provider-specific metadata that round-trips with the tool call.
|
|
241
|
+
* Typed per-adapter via `TToolCallMetadata`. */
|
|
242
|
+
metadata?: TMetadata;
|
|
238
243
|
}
|
|
239
244
|
export interface ToolResultPart {
|
|
240
245
|
type: 'tool-result';
|
|
@@ -740,7 +745,7 @@ export interface TextMessageEndEvent extends AGUITextMessageEndEvent {
|
|
|
740
745
|
* Emitted when a tool call starts.
|
|
741
746
|
*
|
|
742
747
|
* @ag-ui/core provides: `toolCallId`, `toolCallName`, `parentMessageId?`
|
|
743
|
-
* TanStack AI adds: `model?`, `toolName` (deprecated alias), `index?`, `
|
|
748
|
+
* TanStack AI adds: `model?`, `toolName` (deprecated alias), `index?`, `metadata?`
|
|
744
749
|
*/
|
|
745
750
|
export interface ToolCallStartEvent extends AGUIToolCallStartEvent {
|
|
746
751
|
/** Model identifier for multi-model support */
|
|
@@ -752,8 +757,11 @@ export interface ToolCallStartEvent extends AGUIToolCallStartEvent {
|
|
|
752
757
|
toolName: string;
|
|
753
758
|
/** Index for parallel tool calls */
|
|
754
759
|
index?: number;
|
|
755
|
-
/** Provider-specific metadata to carry into the ToolCall
|
|
756
|
-
|
|
760
|
+
/** Provider-specific metadata to carry into the ToolCall.
|
|
761
|
+
* Untyped at the event layer because events flow through a discriminated
|
|
762
|
+
* union that does not survive generics; adapters cast it to their typed
|
|
763
|
+
* `TToolCallMetadata` shape when emitting. */
|
|
764
|
+
metadata?: Record<string, unknown>;
|
|
757
765
|
}
|
|
758
766
|
/**
|
|
759
767
|
* Emitted when tool call arguments are streaming.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tanstack/ai",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.16.0",
|
|
4
4
|
"description": "Core TanStack AI library - Open source AI SDK",
|
|
5
5
|
"author": "Tanner Linsley",
|
|
6
6
|
"license": "MIT",
|
|
@@ -55,7 +55,7 @@
|
|
|
55
55
|
"dependencies": {
|
|
56
56
|
"@ag-ui/core": "0.0.49",
|
|
57
57
|
"partial-json": "^0.1.7",
|
|
58
|
-
"@tanstack/ai-event-client": "0.
|
|
58
|
+
"@tanstack/ai-event-client": "0.3.0"
|
|
59
59
|
},
|
|
60
60
|
"peerDependencies": {
|
|
61
61
|
"@opentelemetry/api": ">=1.9.0"
|
|
@@ -54,6 +54,7 @@ export interface StructuredOutputResult<T = unknown> {
|
|
|
54
54
|
* - TInputModalities: Supported input modalities for this model (already resolved)
|
|
55
55
|
* - TMessageMetadata: Metadata types for content parts (already resolved)
|
|
56
56
|
* - TToolCapabilities: Tuple of tool-kind strings supported by this model, resolved from `supports.tools`
|
|
57
|
+
* - TToolCallMetadata: Metadata type that round-trips with tool calls (e.g. Gemini's `thoughtSignature`)
|
|
57
58
|
*/
|
|
58
59
|
export interface TextAdapter<
|
|
59
60
|
TModel extends string,
|
|
@@ -61,6 +62,7 @@ export interface TextAdapter<
|
|
|
61
62
|
TInputModalities extends ReadonlyArray<Modality>,
|
|
62
63
|
TMessageMetadataByModality extends DefaultMessageMetadataByModality,
|
|
63
64
|
TToolCapabilities extends ReadonlyArray<string> = ReadonlyArray<string>,
|
|
65
|
+
TToolCallMetadata = unknown,
|
|
64
66
|
> {
|
|
65
67
|
/** Discriminator for adapter kind */
|
|
66
68
|
readonly kind: 'text'
|
|
@@ -77,6 +79,7 @@ export interface TextAdapter<
|
|
|
77
79
|
inputModalities: TInputModalities
|
|
78
80
|
messageMetadataByModality: TMessageMetadataByModality
|
|
79
81
|
toolCapabilities: TToolCapabilities
|
|
82
|
+
toolCallMetadata: TToolCallMetadata
|
|
80
83
|
}
|
|
81
84
|
|
|
82
85
|
/**
|
|
@@ -103,7 +106,7 @@ export interface TextAdapter<
|
|
|
103
106
|
* A TextAdapter with any/unknown type parameters.
|
|
104
107
|
* Useful as a constraint in generic functions and interfaces.
|
|
105
108
|
*/
|
|
106
|
-
export type AnyTextAdapter = TextAdapter<any, any, any, any, any>
|
|
109
|
+
export type AnyTextAdapter = TextAdapter<any, any, any, any, any, any>
|
|
107
110
|
|
|
108
111
|
/**
|
|
109
112
|
* Abstract base class for text adapters.
|
|
@@ -117,12 +120,14 @@ export abstract class BaseTextAdapter<
|
|
|
117
120
|
TInputModalities extends ReadonlyArray<Modality>,
|
|
118
121
|
TMessageMetadataByModality extends DefaultMessageMetadataByModality,
|
|
119
122
|
TToolCapabilities extends ReadonlyArray<string> = ReadonlyArray<string>,
|
|
123
|
+
TToolCallMetadata = unknown,
|
|
120
124
|
> implements TextAdapter<
|
|
121
125
|
TModel,
|
|
122
126
|
TProviderOptions,
|
|
123
127
|
TInputModalities,
|
|
124
128
|
TMessageMetadataByModality,
|
|
125
|
-
TToolCapabilities
|
|
129
|
+
TToolCapabilities,
|
|
130
|
+
TToolCallMetadata
|
|
126
131
|
> {
|
|
127
132
|
readonly kind = 'text' as const
|
|
128
133
|
abstract readonly name: string
|
|
@@ -134,6 +139,7 @@ export abstract class BaseTextAdapter<
|
|
|
134
139
|
inputModalities: TInputModalities
|
|
135
140
|
messageMetadataByModality: TMessageMetadataByModality
|
|
136
141
|
toolCapabilities: TToolCapabilities
|
|
142
|
+
toolCallMetadata: TToolCallMetadata
|
|
137
143
|
}
|
|
138
144
|
|
|
139
145
|
protected config: TextAdapterConfig
|
|
@@ -138,6 +138,10 @@ interface AssistantSegment {
|
|
|
138
138
|
id: string
|
|
139
139
|
type: 'function'
|
|
140
140
|
function: { name: string; arguments: string }
|
|
141
|
+
/** Provider-specific metadata that round-trips with the tool call.
|
|
142
|
+
* Untyped at this framework layer; adapters narrow it via their
|
|
143
|
+
* `TToolCallMetadata` generic. */
|
|
144
|
+
metadata?: unknown
|
|
141
145
|
}>
|
|
142
146
|
}
|
|
143
147
|
|
|
@@ -208,6 +212,7 @@ function buildAssistantMessages(uiMessage: UIMessage): Array<ModelMessage> {
|
|
|
208
212
|
name: part.name,
|
|
209
213
|
arguments: part.arguments,
|
|
210
214
|
},
|
|
215
|
+
...(part.metadata !== undefined && { metadata: part.metadata }),
|
|
211
216
|
})
|
|
212
217
|
}
|
|
213
218
|
break
|
|
@@ -362,6 +367,7 @@ export function modelMessageToUIMessage(
|
|
|
362
367
|
name: toolCall.function.name,
|
|
363
368
|
arguments: toolCall.function.arguments,
|
|
364
369
|
state: 'input-complete', // Model messages have complete arguments
|
|
370
|
+
...(toolCall.metadata !== undefined && { metadata: toolCall.metadata }),
|
|
365
371
|
})
|
|
366
372
|
}
|
|
367
373
|
}
|
|
@@ -55,6 +55,7 @@ export function updateToolCallPart(
|
|
|
55
55
|
name: string
|
|
56
56
|
arguments: string
|
|
57
57
|
state: ToolCallState
|
|
58
|
+
metadata?: Record<string, unknown>
|
|
58
59
|
},
|
|
59
60
|
): Array<UIMessage> {
|
|
60
61
|
return messages.map((msg) => {
|
|
@@ -67,6 +68,12 @@ export function updateToolCallPart(
|
|
|
67
68
|
(p): p is ToolCallPart => p.type === 'tool-call' && p.id === toolCall.id,
|
|
68
69
|
)
|
|
69
70
|
|
|
71
|
+
// Carry forward metadata from either the new toolCall or the existing
|
|
72
|
+
// part. Once the adapter has emitted metadata for a tool call (e.g.
|
|
73
|
+
// Gemini's thoughtSignature on TOOL_CALL_START) we must not lose it on
|
|
74
|
+
// subsequent updates that don't re-supply it.
|
|
75
|
+
const metadata = toolCall.metadata ?? existing?.metadata
|
|
76
|
+
|
|
70
77
|
const toolCallPart: ToolCallPart = {
|
|
71
78
|
type: 'tool-call',
|
|
72
79
|
id: toolCall.id,
|
|
@@ -76,6 +83,7 @@ export function updateToolCallPart(
|
|
|
76
83
|
// Carry forward approval and output from the existing part
|
|
77
84
|
...(existing?.approval && { approval: { ...existing.approval } }),
|
|
78
85
|
...(existing?.output !== undefined && { output: existing.output }),
|
|
86
|
+
...(metadata !== undefined && { metadata }),
|
|
79
87
|
}
|
|
80
88
|
|
|
81
89
|
if (existing) {
|
|
@@ -936,6 +936,11 @@ export class StreamProcessor {
|
|
|
936
936
|
const toolName =
|
|
937
937
|
(chunk as { toolCallName?: string }).toolCallName ?? chunk.toolName
|
|
938
938
|
|
|
939
|
+
// Capture provider metadata that arrived on TOOL_CALL_START so it
|
|
940
|
+
// round-trips back through the assistant message on the next turn
|
|
941
|
+
// (e.g. Gemini's thoughtSignature).
|
|
942
|
+
const chunkMetadata = chunk.metadata
|
|
943
|
+
|
|
939
944
|
const newToolCall: InternalToolCallState = {
|
|
940
945
|
id: chunk.toolCallId,
|
|
941
946
|
name: toolName,
|
|
@@ -943,6 +948,7 @@ export class StreamProcessor {
|
|
|
943
948
|
state: initialState,
|
|
944
949
|
parsedArguments: undefined,
|
|
945
950
|
index: chunk.index ?? state.toolCalls.size,
|
|
951
|
+
...(chunkMetadata !== undefined && { metadata: chunkMetadata }),
|
|
946
952
|
}
|
|
947
953
|
|
|
948
954
|
state.toolCalls.set(toolCallId, newToolCall)
|
|
@@ -957,6 +963,7 @@ export class StreamProcessor {
|
|
|
957
963
|
name: toolName,
|
|
958
964
|
arguments: '',
|
|
959
965
|
state: initialState,
|
|
966
|
+
...(chunkMetadata !== undefined && { metadata: chunkMetadata }),
|
|
960
967
|
})
|
|
961
968
|
this.emitMessagesChange()
|
|
962
969
|
|
|
@@ -1504,6 +1511,7 @@ export class StreamProcessor {
|
|
|
1504
1511
|
name: toolCall.name,
|
|
1505
1512
|
arguments: toolCall.arguments,
|
|
1506
1513
|
state: 'input-complete',
|
|
1514
|
+
...(toolCall.metadata !== undefined && { metadata: toolCall.metadata }),
|
|
1507
1515
|
})
|
|
1508
1516
|
this.emitMessagesChange()
|
|
1509
1517
|
|
|
@@ -1619,6 +1627,10 @@ export class StreamProcessor {
|
|
|
1619
1627
|
name: tc.name,
|
|
1620
1628
|
arguments: tc.arguments,
|
|
1621
1629
|
},
|
|
1630
|
+
// Preserve provider metadata (e.g. Gemini thoughtSignature) on
|
|
1631
|
+
// ProcessorResult.toolCalls so callers using process()/getResult()
|
|
1632
|
+
// get the same round-trip support as the streaming UI path.
|
|
1633
|
+
...(tc.metadata !== undefined && { metadata: tc.metadata }),
|
|
1622
1634
|
})
|
|
1623
1635
|
}
|
|
1624
1636
|
}
|
|
@@ -25,6 +25,11 @@ export interface InternalToolCallState {
|
|
|
25
25
|
state: ToolCallState
|
|
26
26
|
parsedArguments?: any
|
|
27
27
|
index: number
|
|
28
|
+
/** Provider-specific metadata that round-trips with the tool call
|
|
29
|
+
* (e.g. Gemini's `thoughtSignature`). Untyped at this layer because
|
|
30
|
+
* the stream processor is provider-agnostic; adapters narrow it
|
|
31
|
+
* via their `TToolCallMetadata` generic. */
|
|
32
|
+
metadata?: Record<string, unknown>
|
|
28
33
|
}
|
|
29
34
|
|
|
30
35
|
/**
|
package/src/types.ts
CHANGED
|
@@ -111,15 +111,17 @@ export type SchemaInput = StandardJSONSchemaV1<any, any> | JSONSchema
|
|
|
111
111
|
export type InferSchemaType<T> =
|
|
112
112
|
T extends StandardJSONSchemaV1<infer TInput, unknown> ? TInput : unknown
|
|
113
113
|
|
|
114
|
-
export interface ToolCall {
|
|
114
|
+
export interface ToolCall<TMetadata = unknown> {
|
|
115
115
|
id: string
|
|
116
116
|
type: 'function'
|
|
117
117
|
function: {
|
|
118
118
|
name: string
|
|
119
119
|
arguments: string // JSON string
|
|
120
120
|
}
|
|
121
|
-
/** Provider-specific metadata to carry through the tool call lifecycle
|
|
122
|
-
|
|
121
|
+
/** Provider-specific metadata to carry through the tool call lifecycle.
|
|
122
|
+
* Typed per-adapter via `TToolCallMetadata`. For example,
|
|
123
|
+
* `@tanstack/ai-gemini` sets this to `{ thoughtSignature?: string }`. */
|
|
124
|
+
metadata?: TMetadata
|
|
123
125
|
}
|
|
124
126
|
|
|
125
127
|
// ============================================================================
|
|
@@ -309,7 +311,7 @@ export interface TextPart<TMetadata = unknown> {
|
|
|
309
311
|
metadata?: TMetadata
|
|
310
312
|
}
|
|
311
313
|
|
|
312
|
-
export interface ToolCallPart {
|
|
314
|
+
export interface ToolCallPart<TMetadata = unknown> {
|
|
313
315
|
type: 'tool-call'
|
|
314
316
|
id: string
|
|
315
317
|
name: string
|
|
@@ -323,6 +325,9 @@ export interface ToolCallPart {
|
|
|
323
325
|
}
|
|
324
326
|
/** Tool execution output (for client tools or after approval) */
|
|
325
327
|
output?: any
|
|
328
|
+
/** Provider-specific metadata that round-trips with the tool call.
|
|
329
|
+
* Typed per-adapter via `TToolCallMetadata`. */
|
|
330
|
+
metadata?: TMetadata
|
|
326
331
|
}
|
|
327
332
|
|
|
328
333
|
export interface ToolResultPart {
|
|
@@ -892,7 +897,7 @@ export interface TextMessageEndEvent extends AGUITextMessageEndEvent {
|
|
|
892
897
|
* Emitted when a tool call starts.
|
|
893
898
|
*
|
|
894
899
|
* @ag-ui/core provides: `toolCallId`, `toolCallName`, `parentMessageId?`
|
|
895
|
-
* TanStack AI adds: `model?`, `toolName` (deprecated alias), `index?`, `
|
|
900
|
+
* TanStack AI adds: `model?`, `toolName` (deprecated alias), `index?`, `metadata?`
|
|
896
901
|
*/
|
|
897
902
|
export interface ToolCallStartEvent extends AGUIToolCallStartEvent {
|
|
898
903
|
/** Model identifier for multi-model support */
|
|
@@ -904,8 +909,11 @@ export interface ToolCallStartEvent extends AGUIToolCallStartEvent {
|
|
|
904
909
|
toolName: string
|
|
905
910
|
/** Index for parallel tool calls */
|
|
906
911
|
index?: number
|
|
907
|
-
/** Provider-specific metadata to carry into the ToolCall
|
|
908
|
-
|
|
912
|
+
/** Provider-specific metadata to carry into the ToolCall.
|
|
913
|
+
* Untyped at the event layer because events flow through a discriminated
|
|
914
|
+
* union that does not survive generics; adapters cast it to their typed
|
|
915
|
+
* `TToolCallMetadata` shape when emitting. */
|
|
916
|
+
metadata?: Record<string, unknown>
|
|
909
917
|
}
|
|
910
918
|
|
|
911
919
|
/**
|