@tanstack/ai 0.0.1
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/LICENSE +21 -0
- package/README.md +131 -0
- package/dist/esm/base-adapter.d.ts +35 -0
- package/dist/esm/base-adapter.js +12 -0
- package/dist/esm/base-adapter.js.map +1 -0
- package/dist/esm/core/chat-common-options.d.ts +52 -0
- package/dist/esm/core/chat.d.ts +30 -0
- package/dist/esm/core/chat.js +533 -0
- package/dist/esm/core/chat.js.map +1 -0
- package/dist/esm/core/embedding.d.ts +8 -0
- package/dist/esm/core/embedding.js +33 -0
- package/dist/esm/core/embedding.js.map +1 -0
- package/dist/esm/core/summarize.d.ts +9 -0
- package/dist/esm/core/summarize.js +36 -0
- package/dist/esm/core/summarize.js.map +1 -0
- package/dist/esm/event-client.d.ts +311 -0
- package/dist/esm/event-client.js +62 -0
- package/dist/esm/event-client.js.map +1 -0
- package/dist/esm/index.d.ts +16 -0
- package/dist/esm/index.js +50 -0
- package/dist/esm/index.js.map +1 -0
- package/dist/esm/message-converters.d.ts +52 -0
- package/dist/esm/message-converters.js +162 -0
- package/dist/esm/message-converters.js.map +1 -0
- package/dist/esm/stream/index.d.ts +11 -0
- package/dist/esm/stream/json-parser.d.ts +38 -0
- package/dist/esm/stream/json-parser.js +28 -0
- package/dist/esm/stream/json-parser.js.map +1 -0
- package/dist/esm/stream/message-updaters.d.ts +44 -0
- package/dist/esm/stream/message-updaters.js +141 -0
- package/dist/esm/stream/message-updaters.js.map +1 -0
- package/dist/esm/stream/processor.d.ts +242 -0
- package/dist/esm/stream/processor.js +693 -0
- package/dist/esm/stream/processor.js.map +1 -0
- package/dist/esm/stream/strategies.d.ts +43 -0
- package/dist/esm/stream/strategies.js +54 -0
- package/dist/esm/stream/strategies.js.map +1 -0
- package/dist/esm/stream/types.d.ts +71 -0
- package/dist/esm/tools/tool-calls.d.ts +112 -0
- package/dist/esm/tools/tool-calls.js +302 -0
- package/dist/esm/tools/tool-calls.js.map +1 -0
- package/dist/esm/tools/tool-definition.d.ts +125 -0
- package/dist/esm/tools/tool-definition.js +25 -0
- package/dist/esm/tools/tool-definition.js.map +1 -0
- package/dist/esm/tools/zod-converter.d.ts +30 -0
- package/dist/esm/tools/zod-converter.js +36 -0
- package/dist/esm/tools/zod-converter.js.map +1 -0
- package/dist/esm/types.d.ts +619 -0
- package/dist/esm/utilities/agent-loop-strategies.d.ts +59 -0
- package/dist/esm/utilities/agent-loop-strategies.js +23 -0
- package/dist/esm/utilities/agent-loop-strategies.js.map +1 -0
- package/dist/esm/utilities/chat-options.d.ts +6 -0
- package/dist/esm/utilities/chat-options.js +7 -0
- package/dist/esm/utilities/chat-options.js.map +1 -0
- package/dist/esm/utilities/messages.d.ts +30 -0
- package/dist/esm/utilities/messages.js +7 -0
- package/dist/esm/utilities/messages.js.map +1 -0
- package/dist/esm/utilities/stream-to-response.d.ts +48 -0
- package/dist/esm/utilities/stream-to-response.js +62 -0
- package/dist/esm/utilities/stream-to-response.js.map +1 -0
- package/package.json +65 -0
- package/src/base-adapter.ts +85 -0
- package/src/core/chat-common-options.ts +55 -0
- package/src/core/chat.ts +771 -0
- package/src/core/embedding.ts +54 -0
- package/src/core/summarize.ts +56 -0
- package/src/event-client.ts +389 -0
- package/src/index.ts +68 -0
- package/src/message-converters.ts +285 -0
- package/src/stream/index.ts +41 -0
- package/src/stream/json-parser.ts +58 -0
- package/src/stream/message-updaters.ts +275 -0
- package/src/stream/processor.ts +1092 -0
- package/src/stream/strategies.ts +78 -0
- package/src/stream/types.ts +94 -0
- package/src/tools/tool-calls.ts +471 -0
- package/src/tools/tool-definition.ts +206 -0
- package/src/tools/zod-converter.ts +85 -0
- package/src/types.ts +872 -0
- package/src/utilities/agent-loop-strategies.ts +85 -0
- package/src/utilities/chat-options.ts +35 -0
- package/src/utilities/messages.ts +63 -0
- package/src/utilities/stream-to-response.ts +116 -0
|
@@ -0,0 +1,206 @@
|
|
|
1
|
+
import type { z } from 'zod'
|
|
2
|
+
import type { Tool } from '../types'
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Marker type for server-side tools
|
|
6
|
+
*/
|
|
7
|
+
export interface ServerTool<
|
|
8
|
+
TInput extends z.ZodType = z.ZodType,
|
|
9
|
+
TOutput extends z.ZodType = z.ZodType,
|
|
10
|
+
TName extends string = string,
|
|
11
|
+
> extends Tool<TInput, TOutput, TName> {
|
|
12
|
+
__toolSide: 'server'
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Marker type for client-side tools
|
|
17
|
+
*/
|
|
18
|
+
export interface ClientTool<
|
|
19
|
+
TInput extends z.ZodType = z.ZodType,
|
|
20
|
+
TOutput extends z.ZodType = z.ZodType,
|
|
21
|
+
TName extends string = string,
|
|
22
|
+
> {
|
|
23
|
+
__toolSide: 'client'
|
|
24
|
+
name: TName
|
|
25
|
+
description: string
|
|
26
|
+
inputSchema?: TInput
|
|
27
|
+
outputSchema?: TOutput
|
|
28
|
+
needsApproval?: boolean
|
|
29
|
+
metadata?: Record<string, any>
|
|
30
|
+
execute?: (
|
|
31
|
+
args: z.infer<TInput>,
|
|
32
|
+
) => Promise<z.infer<TOutput>> | z.infer<TOutput>
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Tool definition that can be used directly or instantiated for server/client
|
|
37
|
+
*/
|
|
38
|
+
export interface ToolDefinitionInstance<
|
|
39
|
+
TInput extends z.ZodType = z.ZodType,
|
|
40
|
+
TOutput extends z.ZodType = z.ZodType,
|
|
41
|
+
TName extends string = string,
|
|
42
|
+
> extends Tool<TInput, TOutput, TName> {
|
|
43
|
+
__toolSide: 'definition'
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Union type for any kind of client-side tool (client tool or definition)
|
|
48
|
+
*/
|
|
49
|
+
export type AnyClientTool =
|
|
50
|
+
| ClientTool<any, any>
|
|
51
|
+
| ToolDefinitionInstance<any, any>
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Extract the tool name as a literal type
|
|
55
|
+
*/
|
|
56
|
+
export type InferToolName<T> = T extends { name: infer N } ? N : never
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Extract the input type from a tool (inferred from Zod schema)
|
|
60
|
+
*/
|
|
61
|
+
export type InferToolInput<T> = T extends { inputSchema?: infer TInput }
|
|
62
|
+
? TInput extends z.ZodType
|
|
63
|
+
? z.infer<TInput>
|
|
64
|
+
: any
|
|
65
|
+
: any
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* Extract the output type from a tool (inferred from Zod schema)
|
|
69
|
+
*/
|
|
70
|
+
export type InferToolOutput<T> = T extends { outputSchema?: infer TOutput }
|
|
71
|
+
? TOutput extends z.ZodType
|
|
72
|
+
? z.infer<TOutput>
|
|
73
|
+
: any
|
|
74
|
+
: any
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* Tool definition configuration
|
|
78
|
+
*/
|
|
79
|
+
export interface ToolDefinitionConfig<
|
|
80
|
+
TInput extends z.ZodType = z.ZodType,
|
|
81
|
+
TOutput extends z.ZodType = z.ZodType,
|
|
82
|
+
TName extends string = string,
|
|
83
|
+
> {
|
|
84
|
+
name: TName
|
|
85
|
+
description: string
|
|
86
|
+
inputSchema?: TInput
|
|
87
|
+
outputSchema?: TOutput
|
|
88
|
+
needsApproval?: boolean
|
|
89
|
+
metadata?: Record<string, any>
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* Tool definition builder that allows creating server or client tools from a shared definition
|
|
94
|
+
*/
|
|
95
|
+
export interface ToolDefinition<
|
|
96
|
+
TInput extends z.ZodType = z.ZodType,
|
|
97
|
+
TOutput extends z.ZodType = z.ZodType,
|
|
98
|
+
TName extends string = string,
|
|
99
|
+
> extends ToolDefinitionInstance<TInput, TOutput, TName> {
|
|
100
|
+
/**
|
|
101
|
+
* Create a server-side tool with execute function
|
|
102
|
+
*/
|
|
103
|
+
server: (
|
|
104
|
+
execute: (
|
|
105
|
+
args: z.infer<TInput>,
|
|
106
|
+
) => Promise<z.infer<TOutput>> | z.infer<TOutput>,
|
|
107
|
+
) => ServerTool<TInput, TOutput, TName>
|
|
108
|
+
|
|
109
|
+
/**
|
|
110
|
+
* Create a client-side tool with optional execute function
|
|
111
|
+
*/
|
|
112
|
+
client: (
|
|
113
|
+
execute?: (
|
|
114
|
+
args: z.infer<TInput>,
|
|
115
|
+
) => Promise<z.infer<TOutput>> | z.infer<TOutput>,
|
|
116
|
+
) => ClientTool<TInput, TOutput, TName>
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
/**
|
|
120
|
+
* Create an isomorphic tool definition that can be used directly or instantiated for server/client
|
|
121
|
+
*
|
|
122
|
+
* The definition contains all tool metadata (name, description, schemas) and can be:
|
|
123
|
+
* 1. Used directly in chat() on the server (as a tool definition without execute)
|
|
124
|
+
* 2. Instantiated as a server tool with .server()
|
|
125
|
+
* 3. Instantiated as a client tool with .client()
|
|
126
|
+
*
|
|
127
|
+
* @example
|
|
128
|
+
* ```typescript
|
|
129
|
+
* import { toolDefinition } from '@tanstack/ai';
|
|
130
|
+
* import { z } from 'zod';
|
|
131
|
+
*
|
|
132
|
+
* const addToCartTool = toolDefinition({
|
|
133
|
+
* name: 'addToCart',
|
|
134
|
+
* description: 'Add a guitar to the shopping cart (requires approval)',
|
|
135
|
+
* needsApproval: true,
|
|
136
|
+
* inputSchema: z.object({
|
|
137
|
+
* guitarId: z.string(),
|
|
138
|
+
* quantity: z.number(),
|
|
139
|
+
* }),
|
|
140
|
+
* outputSchema: z.object({
|
|
141
|
+
* success: z.boolean(),
|
|
142
|
+
* cartId: z.string(),
|
|
143
|
+
* totalItems: z.number(),
|
|
144
|
+
* }),
|
|
145
|
+
* });
|
|
146
|
+
*
|
|
147
|
+
* // Use directly in chat (server-side, no execute function)
|
|
148
|
+
* chat({
|
|
149
|
+
* tools: [addToCartTool],
|
|
150
|
+
* // ...
|
|
151
|
+
* });
|
|
152
|
+
*
|
|
153
|
+
* // Or create server-side implementation
|
|
154
|
+
* const addToCartServer = addToCartTool.server(async (args) => {
|
|
155
|
+
* // args is typed as { guitarId: string; quantity: number }
|
|
156
|
+
* return {
|
|
157
|
+
* success: true,
|
|
158
|
+
* cartId: 'CART_' + Date.now(),
|
|
159
|
+
* totalItems: args.quantity,
|
|
160
|
+
* };
|
|
161
|
+
* });
|
|
162
|
+
*
|
|
163
|
+
* // Or create client-side implementation
|
|
164
|
+
* const addToCartClient = addToCartTool.client(async (args) => {
|
|
165
|
+
* // Client-specific logic (e.g., localStorage)
|
|
166
|
+
* return { success: true, cartId: 'local', totalItems: 1 };
|
|
167
|
+
* });
|
|
168
|
+
* ```
|
|
169
|
+
*/
|
|
170
|
+
export function toolDefinition<
|
|
171
|
+
TInput extends z.ZodType = z.ZodAny,
|
|
172
|
+
TOutput extends z.ZodType = z.ZodAny,
|
|
173
|
+
TName extends string = string,
|
|
174
|
+
>(
|
|
175
|
+
config: ToolDefinitionConfig<TInput, TOutput, TName>,
|
|
176
|
+
): ToolDefinition<TInput, TOutput, TName> {
|
|
177
|
+
const definition: ToolDefinition<TInput, TOutput, TName> = {
|
|
178
|
+
__toolSide: 'definition',
|
|
179
|
+
...config,
|
|
180
|
+
server(
|
|
181
|
+
execute: (
|
|
182
|
+
args: z.infer<TInput>,
|
|
183
|
+
) => Promise<z.infer<TOutput>> | z.infer<TOutput>,
|
|
184
|
+
): ServerTool<TInput, TOutput, TName> {
|
|
185
|
+
return {
|
|
186
|
+
__toolSide: 'server',
|
|
187
|
+
...config,
|
|
188
|
+
execute,
|
|
189
|
+
}
|
|
190
|
+
},
|
|
191
|
+
|
|
192
|
+
client(
|
|
193
|
+
execute?: (
|
|
194
|
+
args: z.infer<TInput>,
|
|
195
|
+
) => Promise<z.infer<TOutput>> | z.infer<TOutput>,
|
|
196
|
+
): ClientTool<TInput, TOutput, TName> {
|
|
197
|
+
return {
|
|
198
|
+
__toolSide: 'client',
|
|
199
|
+
...config,
|
|
200
|
+
execute,
|
|
201
|
+
}
|
|
202
|
+
},
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
return definition
|
|
206
|
+
}
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import { toJSONSchema } from 'zod'
|
|
2
|
+
import type { z } from 'zod'
|
|
3
|
+
/**
|
|
4
|
+
* Converts a Zod schema to JSON Schema format compatible with LLM providers.
|
|
5
|
+
*
|
|
6
|
+
*
|
|
7
|
+
* @param schema - Zod schema to convert
|
|
8
|
+
* @returns JSON Schema object that can be sent to LLM providers
|
|
9
|
+
*
|
|
10
|
+
* @example
|
|
11
|
+
* ```typescript
|
|
12
|
+
* import { z } from 'zod';
|
|
13
|
+
*
|
|
14
|
+
* const schema = z.object({
|
|
15
|
+
* location: z.string().describe('City name'),
|
|
16
|
+
* unit: z.enum(['celsius', 'fahrenheit']).optional()
|
|
17
|
+
* });
|
|
18
|
+
*
|
|
19
|
+
* const jsonSchema = convertZodToJsonSchema(schema);
|
|
20
|
+
* // Returns:
|
|
21
|
+
* // {
|
|
22
|
+
* // type: 'object',
|
|
23
|
+
* // properties: {
|
|
24
|
+
* // location: { type: 'string', description: 'City name' },
|
|
25
|
+
* // unit: { type: 'string', enum: ['celsius', 'fahrenheit'] }
|
|
26
|
+
* // },
|
|
27
|
+
* // required: ['location']
|
|
28
|
+
* // }
|
|
29
|
+
* ```
|
|
30
|
+
*/
|
|
31
|
+
export function convertZodToJsonSchema(
|
|
32
|
+
schema: z.ZodType | undefined,
|
|
33
|
+
): Record<string, any> | undefined {
|
|
34
|
+
if (!schema) return undefined
|
|
35
|
+
|
|
36
|
+
// Use Alcyone Labs fork which is compatible with Zod v4
|
|
37
|
+
const jsonSchema = toJSONSchema(schema, {
|
|
38
|
+
target: 'openapi-3.0',
|
|
39
|
+
reused: 'ref',
|
|
40
|
+
})
|
|
41
|
+
|
|
42
|
+
// Remove $schema property as it's not needed for LLM providers
|
|
43
|
+
let result = jsonSchema
|
|
44
|
+
if (typeof result === 'object' && '$schema' in result) {
|
|
45
|
+
const { $schema, ...rest } = result
|
|
46
|
+
result = rest
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
// Ensure object schemas always have type: "object"
|
|
50
|
+
// This fixes cases where zod-to-json-schema doesn't set type for empty objects
|
|
51
|
+
if (typeof result === 'object') {
|
|
52
|
+
// Check if the input schema is a ZodObject by inspecting its internal structure
|
|
53
|
+
const isZodObject =
|
|
54
|
+
typeof schema === 'object' &&
|
|
55
|
+
'def' in schema &&
|
|
56
|
+
schema.def.type === 'object'
|
|
57
|
+
|
|
58
|
+
// If we know it's a ZodObject but result doesn't have type, set it
|
|
59
|
+
if (isZodObject && !result.type) {
|
|
60
|
+
result.type = 'object'
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
// If result is completely empty (no keys), it's likely an empty object schema
|
|
64
|
+
if (Object.keys(result).length === 0) {
|
|
65
|
+
result.type = 'object'
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
// If it has properties (even empty), it should be an object type
|
|
69
|
+
if ('properties' in result && !result.type) {
|
|
70
|
+
result.type = 'object'
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
// Ensure properties exists for object types (even if empty)
|
|
74
|
+
if (result.type === 'object' && !('properties' in result)) {
|
|
75
|
+
result.properties = {}
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
// Ensure required exists for object types (even if empty array)
|
|
79
|
+
if (result.type === 'object' && !('required' in result)) {
|
|
80
|
+
result.required = []
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
return result
|
|
85
|
+
}
|