@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.
Files changed (83) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +131 -0
  3. package/dist/esm/base-adapter.d.ts +35 -0
  4. package/dist/esm/base-adapter.js +12 -0
  5. package/dist/esm/base-adapter.js.map +1 -0
  6. package/dist/esm/core/chat-common-options.d.ts +52 -0
  7. package/dist/esm/core/chat.d.ts +30 -0
  8. package/dist/esm/core/chat.js +533 -0
  9. package/dist/esm/core/chat.js.map +1 -0
  10. package/dist/esm/core/embedding.d.ts +8 -0
  11. package/dist/esm/core/embedding.js +33 -0
  12. package/dist/esm/core/embedding.js.map +1 -0
  13. package/dist/esm/core/summarize.d.ts +9 -0
  14. package/dist/esm/core/summarize.js +36 -0
  15. package/dist/esm/core/summarize.js.map +1 -0
  16. package/dist/esm/event-client.d.ts +311 -0
  17. package/dist/esm/event-client.js +62 -0
  18. package/dist/esm/event-client.js.map +1 -0
  19. package/dist/esm/index.d.ts +16 -0
  20. package/dist/esm/index.js +50 -0
  21. package/dist/esm/index.js.map +1 -0
  22. package/dist/esm/message-converters.d.ts +52 -0
  23. package/dist/esm/message-converters.js +162 -0
  24. package/dist/esm/message-converters.js.map +1 -0
  25. package/dist/esm/stream/index.d.ts +11 -0
  26. package/dist/esm/stream/json-parser.d.ts +38 -0
  27. package/dist/esm/stream/json-parser.js +28 -0
  28. package/dist/esm/stream/json-parser.js.map +1 -0
  29. package/dist/esm/stream/message-updaters.d.ts +44 -0
  30. package/dist/esm/stream/message-updaters.js +141 -0
  31. package/dist/esm/stream/message-updaters.js.map +1 -0
  32. package/dist/esm/stream/processor.d.ts +242 -0
  33. package/dist/esm/stream/processor.js +693 -0
  34. package/dist/esm/stream/processor.js.map +1 -0
  35. package/dist/esm/stream/strategies.d.ts +43 -0
  36. package/dist/esm/stream/strategies.js +54 -0
  37. package/dist/esm/stream/strategies.js.map +1 -0
  38. package/dist/esm/stream/types.d.ts +71 -0
  39. package/dist/esm/tools/tool-calls.d.ts +112 -0
  40. package/dist/esm/tools/tool-calls.js +302 -0
  41. package/dist/esm/tools/tool-calls.js.map +1 -0
  42. package/dist/esm/tools/tool-definition.d.ts +125 -0
  43. package/dist/esm/tools/tool-definition.js +25 -0
  44. package/dist/esm/tools/tool-definition.js.map +1 -0
  45. package/dist/esm/tools/zod-converter.d.ts +30 -0
  46. package/dist/esm/tools/zod-converter.js +36 -0
  47. package/dist/esm/tools/zod-converter.js.map +1 -0
  48. package/dist/esm/types.d.ts +619 -0
  49. package/dist/esm/utilities/agent-loop-strategies.d.ts +59 -0
  50. package/dist/esm/utilities/agent-loop-strategies.js +23 -0
  51. package/dist/esm/utilities/agent-loop-strategies.js.map +1 -0
  52. package/dist/esm/utilities/chat-options.d.ts +6 -0
  53. package/dist/esm/utilities/chat-options.js +7 -0
  54. package/dist/esm/utilities/chat-options.js.map +1 -0
  55. package/dist/esm/utilities/messages.d.ts +30 -0
  56. package/dist/esm/utilities/messages.js +7 -0
  57. package/dist/esm/utilities/messages.js.map +1 -0
  58. package/dist/esm/utilities/stream-to-response.d.ts +48 -0
  59. package/dist/esm/utilities/stream-to-response.js +62 -0
  60. package/dist/esm/utilities/stream-to-response.js.map +1 -0
  61. package/package.json +65 -0
  62. package/src/base-adapter.ts +85 -0
  63. package/src/core/chat-common-options.ts +55 -0
  64. package/src/core/chat.ts +771 -0
  65. package/src/core/embedding.ts +54 -0
  66. package/src/core/summarize.ts +56 -0
  67. package/src/event-client.ts +389 -0
  68. package/src/index.ts +68 -0
  69. package/src/message-converters.ts +285 -0
  70. package/src/stream/index.ts +41 -0
  71. package/src/stream/json-parser.ts +58 -0
  72. package/src/stream/message-updaters.ts +275 -0
  73. package/src/stream/processor.ts +1092 -0
  74. package/src/stream/strategies.ts +78 -0
  75. package/src/stream/types.ts +94 -0
  76. package/src/tools/tool-calls.ts +471 -0
  77. package/src/tools/tool-definition.ts +206 -0
  78. package/src/tools/zod-converter.ts +85 -0
  79. package/src/types.ts +872 -0
  80. package/src/utilities/agent-loop-strategies.ts +85 -0
  81. package/src/utilities/chat-options.ts +35 -0
  82. package/src/utilities/messages.ts +63 -0
  83. 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
+ }