@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,619 @@
1
+ import { CommonOptions } from './core/chat-common-options.js';
2
+ import { z } from 'zod';
3
+ import { ToolCallState, ToolResultState } from './stream/types.js';
4
+ export interface ToolCall {
5
+ id: string;
6
+ type: 'function';
7
+ function: {
8
+ name: string;
9
+ arguments: string;
10
+ };
11
+ }
12
+ /**
13
+ * Supported input modality types for multimodal content.
14
+ * - 'text': Plain text content
15
+ * - 'image': Image content (base64 or URL)
16
+ * - 'audio': Audio content (base64 or URL)
17
+ * - 'video': Video content (base64 or URL)
18
+ * - 'document': Document content like PDFs (base64 or URL)
19
+ */
20
+ export type Modality = 'text' | 'image' | 'audio' | 'video' | 'document';
21
+ /**
22
+ * Source specification for multimodal content.
23
+ * Supports both inline data (base64) and URL-based content.
24
+ */
25
+ export interface ContentPartSource {
26
+ /**
27
+ * The type of source:
28
+ * - 'data': Inline data (typically base64 encoded)
29
+ * - 'url': URL reference to the content
30
+ */
31
+ type: 'data' | 'url';
32
+ /**
33
+ * The actual content value:
34
+ * - For 'data': base64-encoded string
35
+ * - For 'url': HTTP(S) URL or data URI
36
+ */
37
+ value: string;
38
+ }
39
+ /**
40
+ * Image content part for multimodal messages.
41
+ * @template TMetadata - Provider-specific metadata type (e.g., OpenAI's detail level)
42
+ */
43
+ export interface ImagePart<TMetadata = unknown> {
44
+ type: 'image';
45
+ /** Source of the image content */
46
+ source: ContentPartSource;
47
+ /** Provider-specific metadata (e.g., OpenAI's detail: 'auto' | 'low' | 'high') */
48
+ metadata?: TMetadata;
49
+ }
50
+ /**
51
+ * Audio content part for multimodal messages.
52
+ * @template TMetadata - Provider-specific metadata type
53
+ */
54
+ export interface AudioPart<TMetadata = unknown> {
55
+ type: 'audio';
56
+ /** Source of the audio content */
57
+ source: ContentPartSource;
58
+ /** Provider-specific metadata (e.g., format, sample rate) */
59
+ metadata?: TMetadata;
60
+ }
61
+ /**
62
+ * Video content part for multimodal messages.
63
+ * @template TMetadata - Provider-specific metadata type
64
+ */
65
+ export interface VideoPart<TMetadata = unknown> {
66
+ type: 'video';
67
+ /** Source of the video content */
68
+ source: ContentPartSource;
69
+ /** Provider-specific metadata (e.g., duration, resolution) */
70
+ metadata?: TMetadata;
71
+ }
72
+ /**
73
+ * Document content part for multimodal messages (e.g., PDFs).
74
+ * @template TMetadata - Provider-specific metadata type (e.g., Anthropic's media_type)
75
+ */
76
+ export interface DocumentPart<TMetadata = unknown> {
77
+ type: 'document';
78
+ /** Source of the document content */
79
+ source: ContentPartSource;
80
+ /** Provider-specific metadata (e.g., media_type for PDFs) */
81
+ metadata?: TMetadata;
82
+ }
83
+ /**
84
+ * Union type for all multimodal content parts.
85
+ * @template TImageMeta - Provider-specific image metadata type
86
+ * @template TAudioMeta - Provider-specific audio metadata type
87
+ * @template TVideoMeta - Provider-specific video metadata type
88
+ * @template TDocumentMeta - Provider-specific document metadata type
89
+ */
90
+ export type ContentPart<TImageMeta = unknown, TAudioMeta = unknown, TVideoMeta = unknown, TDocumentMeta = unknown> = TextPart | ImagePart<TImageMeta> | AudioPart<TAudioMeta> | VideoPart<TVideoMeta> | DocumentPart<TDocumentMeta>;
91
+ /**
92
+ * Helper type to filter ContentPart union to only include specific modalities.
93
+ * Used to constrain message content based on model capabilities.
94
+ */
95
+ export type ContentPartForModalities<TModalities extends Modality, TImageMeta = unknown, TAudioMeta = unknown, TVideoMeta = unknown, TDocumentMeta = unknown> = Extract<ContentPart<TImageMeta, TAudioMeta, TVideoMeta, TDocumentMeta>, {
96
+ type: TModalities;
97
+ }>;
98
+ /**
99
+ * Helper type to convert a readonly array of modalities to a union type.
100
+ * e.g., readonly ['text', 'image'] -> 'text' | 'image'
101
+ */
102
+ export type ModalitiesArrayToUnion<T extends ReadonlyArray<Modality>> = T[number];
103
+ /**
104
+ * Type for message content constrained by supported modalities.
105
+ * When modalities is ['text', 'image'], only TextPart and ImagePart are allowed in the array.
106
+ */
107
+ export type ConstrainedContent<TModalities extends ReadonlyArray<Modality>, TImageMeta = unknown, TAudioMeta = unknown, TVideoMeta = unknown, TDocumentMeta = unknown> = string | null | Array<ContentPartForModalities<ModalitiesArrayToUnion<TModalities>, TImageMeta, TAudioMeta, TVideoMeta, TDocumentMeta>>;
108
+ export interface ModelMessage<TContent extends string | null | Array<ContentPart> = string | null | Array<ContentPart>> {
109
+ role: 'user' | 'assistant' | 'tool';
110
+ content: TContent;
111
+ name?: string;
112
+ toolCalls?: Array<ToolCall>;
113
+ toolCallId?: string;
114
+ }
115
+ /**
116
+ * Message parts - building blocks of UIMessage
117
+ */
118
+ export interface TextPart {
119
+ type: 'text';
120
+ content: string;
121
+ }
122
+ export interface ToolCallPart {
123
+ type: 'tool-call';
124
+ id: string;
125
+ name: string;
126
+ arguments: string;
127
+ state: ToolCallState;
128
+ /** Approval metadata if tool requires user approval */
129
+ approval?: {
130
+ id: string;
131
+ needsApproval: boolean;
132
+ approved?: boolean;
133
+ };
134
+ /** Tool execution output (for client tools or after approval) */
135
+ output?: any;
136
+ }
137
+ export interface ToolResultPart {
138
+ type: 'tool-result';
139
+ toolCallId: string;
140
+ content: string;
141
+ state: ToolResultState;
142
+ error?: string;
143
+ }
144
+ export interface ThinkingPart {
145
+ type: 'thinking';
146
+ content: string;
147
+ }
148
+ export type MessagePart = TextPart | ToolCallPart | ToolResultPart | ThinkingPart;
149
+ /**
150
+ * UIMessage - Domain-specific message format optimized for building chat UIs
151
+ * Contains parts that can be text, tool calls, or tool results
152
+ */
153
+ export interface UIMessage {
154
+ id: string;
155
+ role: 'system' | 'user' | 'assistant';
156
+ parts: Array<MessagePart>;
157
+ createdAt?: Date;
158
+ }
159
+ /**
160
+ * A ModelMessage with content constrained to only allow content parts
161
+ * matching the specified input modalities.
162
+ */
163
+ export type ConstrainedModelMessage<TModalities extends ReadonlyArray<Modality>, TImageMeta = unknown, TAudioMeta = unknown, TVideoMeta = unknown, TDocumentMeta = unknown> = Omit<ModelMessage, 'content'> & {
164
+ content: ConstrainedContent<TModalities, TImageMeta, TAudioMeta, TVideoMeta, TDocumentMeta>;
165
+ };
166
+ /**
167
+ * Tool/Function definition for function calling.
168
+ *
169
+ * Tools allow the model to interact with external systems, APIs, or perform computations.
170
+ * The model will decide when to call tools based on the user's request and the tool descriptions.
171
+ *
172
+ * Tools use Zod schemas for runtime validation and type safety.
173
+ *
174
+ * @see https://platform.openai.com/docs/guides/function-calling
175
+ * @see https://docs.anthropic.com/claude/docs/tool-use
176
+ */
177
+ export interface Tool<TInput extends z.ZodType = z.ZodType, TOutput extends z.ZodType = z.ZodType, TName extends string = string> {
178
+ /**
179
+ * Unique name of the tool (used by the model to call it).
180
+ *
181
+ * Should be descriptive and follow naming conventions (e.g., snake_case or camelCase).
182
+ * Must be unique within the tools array.
183
+ *
184
+ * @example "get_weather", "search_database", "sendEmail"
185
+ */
186
+ name: TName;
187
+ /**
188
+ * Clear description of what the tool does.
189
+ *
190
+ * This is crucial - the model uses this to decide when to call the tool.
191
+ * Be specific about what the tool does, what parameters it needs, and what it returns.
192
+ *
193
+ * @example "Get the current weather in a given location. Returns temperature, conditions, and forecast."
194
+ */
195
+ description: string;
196
+ /**
197
+ * Zod schema describing the tool's input parameters.
198
+ *
199
+ * Defines the structure and types of arguments the tool accepts.
200
+ * The model will generate arguments matching this schema.
201
+ * The schema is converted to JSON Schema for LLM providers.
202
+ *
203
+ * @see https://zod.dev/
204
+ *
205
+ * @example
206
+ * import { z } from 'zod';
207
+ *
208
+ * z.object({
209
+ * location: z.string().describe("City name or coordinates"),
210
+ * unit: z.enum(["celsius", "fahrenheit"]).optional()
211
+ * })
212
+ */
213
+ inputSchema?: TInput;
214
+ /**
215
+ * Optional Zod schema for validating tool output.
216
+ *
217
+ * If provided, tool results will be validated against this schema before
218
+ * being sent back to the model. This catches bugs in tool implementations
219
+ * and ensures consistent output formatting.
220
+ *
221
+ * Note: This is client-side validation only - not sent to LLM providers.
222
+ *
223
+ * @example
224
+ * z.object({
225
+ * temperature: z.number(),
226
+ * conditions: z.string(),
227
+ * forecast: z.array(z.string()).optional()
228
+ * })
229
+ */
230
+ outputSchema?: TOutput;
231
+ /**
232
+ * Optional function to execute when the model calls this tool.
233
+ *
234
+ * If provided, the SDK will automatically execute the function with the model's arguments
235
+ * and feed the result back to the model. This enables autonomous tool use loops.
236
+ *
237
+ * Can return any value - will be automatically stringified if needed.
238
+ *
239
+ * @param args - The arguments parsed from the model's tool call (validated against inputSchema)
240
+ * @returns Result to send back to the model (validated against outputSchema if provided)
241
+ *
242
+ * @example
243
+ * execute: async (args) => {
244
+ * const weather = await fetchWeather(args.location);
245
+ * return weather; // Can return object or string
246
+ * }
247
+ */
248
+ execute?: (args: any) => Promise<any> | any;
249
+ /** If true, tool execution requires user approval before running. Works with both server and client tools. */
250
+ needsApproval?: boolean;
251
+ /** Additional metadata for adapters or custom extensions */
252
+ metadata?: Record<string, any>;
253
+ }
254
+ export interface ToolConfig {
255
+ [key: string]: Tool;
256
+ }
257
+ /**
258
+ * Structured output format specification.
259
+ *
260
+ * Constrains the model's output to match a specific JSON structure.
261
+ * Useful for extracting structured data, form filling, or ensuring consistent response formats.
262
+ *
263
+ * @see https://platform.openai.com/docs/guides/structured-outputs
264
+ * @see https://sdk.vercel.ai/docs/ai-sdk-core/structured-outputs
265
+ *
266
+ * @template TData - TypeScript type of the expected data structure (for type safety)
267
+ */
268
+ export interface ResponseFormat<TData = any> {
269
+ /**
270
+ * Type of structured output.
271
+ *
272
+ * - "json_object": Forces the model to output valid JSON (any structure)
273
+ * - "json_schema": Validates output against a provided JSON Schema (strict structure)
274
+ *
275
+ * @see https://platform.openai.com/docs/api-reference/chat/create#chat-create-response_format
276
+ */
277
+ type: 'json_object' | 'json_schema';
278
+ /**
279
+ * JSON schema specification (required when type is "json_schema").
280
+ *
281
+ * Defines the exact structure the model's output must conform to.
282
+ * OpenAI's structured outputs will guarantee the output matches this schema.
283
+ */
284
+ json_schema?: {
285
+ /**
286
+ * Unique name for the schema.
287
+ *
288
+ * Used to identify the schema in logs and debugging.
289
+ * Should be descriptive (e.g., "user_profile", "search_results").
290
+ */
291
+ name: string;
292
+ /**
293
+ * Optional description of what the schema represents.
294
+ *
295
+ * Helps document the purpose of this structured output.
296
+ *
297
+ * @example "User profile information including name, email, and preferences"
298
+ */
299
+ description?: string;
300
+ /**
301
+ * JSON Schema definition for the expected output structure.
302
+ *
303
+ * Must be a valid JSON Schema (draft 2020-12 or compatible).
304
+ * The model's output will be validated against this schema.
305
+ *
306
+ * @see https://json-schema.org/
307
+ *
308
+ * @example
309
+ * {
310
+ * type: "object",
311
+ * properties: {
312
+ * name: { type: "string" },
313
+ * age: { type: "number" },
314
+ * email: { type: "string", format: "email" }
315
+ * },
316
+ * required: ["name", "email"],
317
+ * additionalProperties: false
318
+ * }
319
+ */
320
+ schema: Record<string, any>;
321
+ /**
322
+ * Whether to enforce strict schema validation.
323
+ *
324
+ * When true (recommended), the model guarantees output will match the schema exactly.
325
+ * When false, the model will "best effort" match the schema.
326
+ *
327
+ * Default: true (for providers that support it)
328
+ *
329
+ * @see https://platform.openai.com/docs/guides/structured-outputs#strict-mode
330
+ */
331
+ strict?: boolean;
332
+ };
333
+ /**
334
+ * Type-only property to carry the inferred data type.
335
+ *
336
+ * This is never set at runtime - it only exists for TypeScript type inference.
337
+ * Allows the SDK to know what type to expect when parsing the response.
338
+ *
339
+ * @internal
340
+ */
341
+ __data?: TData;
342
+ }
343
+ /**
344
+ * State passed to agent loop strategy for determining whether to continue
345
+ */
346
+ export interface AgentLoopState {
347
+ /** Current iteration count (0-indexed) */
348
+ iterationCount: number;
349
+ /** Current messages array */
350
+ messages: Array<ModelMessage>;
351
+ /** Finish reason from the last response */
352
+ finishReason: string | null;
353
+ }
354
+ /**
355
+ * Strategy function that determines whether the agent loop should continue
356
+ *
357
+ * @param state - Current state of the agent loop
358
+ * @returns true to continue looping, false to stop
359
+ *
360
+ * @example
361
+ * ```typescript
362
+ * // Continue for up to 5 iterations
363
+ * const strategy: AgentLoopStrategy = ({ iterationCount }) => iterationCount < 5;
364
+ * ```
365
+ */
366
+ export type AgentLoopStrategy = (state: AgentLoopState) => boolean;
367
+ /**
368
+ * Options passed into the SDK and further piped to the AI provider.
369
+ */
370
+ export interface ChatOptions<TModel extends string = string, TProviderOptionsSuperset extends Record<string, any> = Record<string, any>, TOutput extends ResponseFormat<any> | undefined = undefined, TProviderOptionsForModel = TProviderOptionsSuperset> {
371
+ model: TModel;
372
+ messages: Array<ModelMessage>;
373
+ tools?: Array<Tool>;
374
+ systemPrompts?: Array<string>;
375
+ agentLoopStrategy?: AgentLoopStrategy;
376
+ options?: CommonOptions;
377
+ providerOptions?: TProviderOptionsForModel;
378
+ request?: Request | RequestInit;
379
+ output?: TOutput;
380
+ /**
381
+ * Conversation ID for correlating client and server-side devtools events.
382
+ * When provided, server-side events will be linked to the client conversation in devtools.
383
+ */
384
+ conversationId?: string;
385
+ /**
386
+ * AbortController for request cancellation.
387
+ *
388
+ * Allows you to cancel an in-progress request using an AbortController.
389
+ * Useful for implementing timeouts or user-initiated cancellations.
390
+ *
391
+ * @example
392
+ * const abortController = new AbortController();
393
+ * setTimeout(() => abortController.abort(), 5000); // Cancel after 5 seconds
394
+ * await chat({ ..., abortController });
395
+ *
396
+ * @see https://developer.mozilla.org/en-US/docs/Web/API/AbortController
397
+ */
398
+ abortController?: AbortController;
399
+ }
400
+ export type StreamChunkType = 'content' | 'tool_call' | 'tool_result' | 'done' | 'error' | 'approval-requested' | 'tool-input-available' | 'thinking';
401
+ export interface BaseStreamChunk {
402
+ type: StreamChunkType;
403
+ id: string;
404
+ model: string;
405
+ timestamp: number;
406
+ }
407
+ export interface ContentStreamChunk extends BaseStreamChunk {
408
+ type: 'content';
409
+ delta: string;
410
+ content: string;
411
+ role?: 'assistant';
412
+ }
413
+ export interface ToolCallStreamChunk extends BaseStreamChunk {
414
+ type: 'tool_call';
415
+ toolCall: {
416
+ id: string;
417
+ type: 'function';
418
+ function: {
419
+ name: string;
420
+ arguments: string;
421
+ };
422
+ };
423
+ index: number;
424
+ }
425
+ export interface ToolResultStreamChunk extends BaseStreamChunk {
426
+ type: 'tool_result';
427
+ toolCallId: string;
428
+ content: string;
429
+ }
430
+ export interface DoneStreamChunk extends BaseStreamChunk {
431
+ type: 'done';
432
+ finishReason: 'stop' | 'length' | 'content_filter' | 'tool_calls' | null;
433
+ usage?: {
434
+ promptTokens: number;
435
+ completionTokens: number;
436
+ totalTokens: number;
437
+ };
438
+ }
439
+ export interface ErrorStreamChunk extends BaseStreamChunk {
440
+ type: 'error';
441
+ error: {
442
+ message: string;
443
+ code?: string;
444
+ };
445
+ }
446
+ export interface ApprovalRequestedStreamChunk extends BaseStreamChunk {
447
+ type: 'approval-requested';
448
+ toolCallId: string;
449
+ toolName: string;
450
+ input: any;
451
+ approval: {
452
+ id: string;
453
+ needsApproval: true;
454
+ };
455
+ }
456
+ export interface ToolInputAvailableStreamChunk extends BaseStreamChunk {
457
+ type: 'tool-input-available';
458
+ toolCallId: string;
459
+ toolName: string;
460
+ input: any;
461
+ }
462
+ export interface ThinkingStreamChunk extends BaseStreamChunk {
463
+ type: 'thinking';
464
+ delta?: string;
465
+ content: string;
466
+ }
467
+ /**
468
+ * Chunk returned by the sdk during streaming chat completions.
469
+ */
470
+ export type StreamChunk = ContentStreamChunk | ToolCallStreamChunk | ToolResultStreamChunk | DoneStreamChunk | ErrorStreamChunk | ApprovalRequestedStreamChunk | ToolInputAvailableStreamChunk | ThinkingStreamChunk;
471
+ export interface ChatCompletionChunk {
472
+ id: string;
473
+ model: string;
474
+ content: string;
475
+ role?: 'assistant';
476
+ finishReason?: 'stop' | 'length' | 'content_filter' | null;
477
+ usage?: {
478
+ promptTokens: number;
479
+ completionTokens: number;
480
+ totalTokens: number;
481
+ };
482
+ }
483
+ export interface SummarizationOptions {
484
+ model: string;
485
+ text: string;
486
+ maxLength?: number;
487
+ style?: 'bullet-points' | 'paragraph' | 'concise';
488
+ focus?: Array<string>;
489
+ }
490
+ export interface SummarizationResult {
491
+ id: string;
492
+ model: string;
493
+ summary: string;
494
+ usage: {
495
+ promptTokens: number;
496
+ completionTokens: number;
497
+ totalTokens: number;
498
+ };
499
+ }
500
+ export interface EmbeddingOptions {
501
+ model: string;
502
+ input: string | Array<string>;
503
+ dimensions?: number;
504
+ }
505
+ export interface EmbeddingResult {
506
+ id: string;
507
+ model: string;
508
+ embeddings: Array<Array<number>>;
509
+ usage: {
510
+ promptTokens: number;
511
+ totalTokens: number;
512
+ };
513
+ }
514
+ /**
515
+ * Default metadata type for adapters that don't define custom metadata.
516
+ * Uses unknown for all modalities.
517
+ */
518
+ export interface DefaultMessageMetadataByModality {
519
+ image: unknown;
520
+ audio: unknown;
521
+ video: unknown;
522
+ document: unknown;
523
+ }
524
+ /**
525
+ * AI adapter interface with support for endpoint-specific models and provider options.
526
+ *
527
+ * Generic parameters:
528
+ * - TChatModels: Models that support chat/text completion
529
+ * - TEmbeddingModels: Models that support embeddings
530
+ * - TChatProviderOptions: Provider-specific options for chat endpoint
531
+ * - TEmbeddingProviderOptions: Provider-specific options for embedding endpoint
532
+ * - TModelProviderOptionsByName: Map from model name to its specific provider options
533
+ * - TModelInputModalitiesByName: Map from model name to its supported input modalities
534
+ * - TMessageMetadataByModality: Map from modality type to adapter-specific metadata types
535
+ */
536
+ export interface AIAdapter<TChatModels extends ReadonlyArray<string> = ReadonlyArray<string>, TEmbeddingModels extends ReadonlyArray<string> = ReadonlyArray<string>, TChatProviderOptions extends Record<string, any> = Record<string, any>, TEmbeddingProviderOptions extends Record<string, any> = Record<string, any>, TModelProviderOptionsByName extends Record<string, any> = Record<string, any>, TModelInputModalitiesByName extends Record<string, ReadonlyArray<Modality>> = Record<string, ReadonlyArray<Modality>>, TMessageMetadataByModality extends {
537
+ image: unknown;
538
+ audio: unknown;
539
+ video: unknown;
540
+ document: unknown;
541
+ } = DefaultMessageMetadataByModality> {
542
+ name: string;
543
+ /** Models that support chat/text completion */
544
+ models: TChatModels;
545
+ /** Models that support embeddings */
546
+ embeddingModels?: TEmbeddingModels;
547
+ _providerOptions?: TChatProviderOptions;
548
+ _chatProviderOptions?: TChatProviderOptions;
549
+ _embeddingProviderOptions?: TEmbeddingProviderOptions;
550
+ /**
551
+ * Type-only map from model name to its specific provider options.
552
+ * Used by the core AI types to narrow providerOptions based on the selected model.
553
+ * Must be provided by all adapters.
554
+ */
555
+ _modelProviderOptionsByName: TModelProviderOptionsByName;
556
+ /**
557
+ * Type-only map from model name to its supported input modalities.
558
+ * Used by the core AI types to narrow ContentPart types based on the selected model.
559
+ * Must be provided by all adapters.
560
+ */
561
+ _modelInputModalitiesByName?: TModelInputModalitiesByName;
562
+ /**
563
+ * Type-only map from modality type to adapter-specific metadata types.
564
+ * Used to provide type-safe autocomplete for metadata on content parts.
565
+ */
566
+ _messageMetadataByModality?: TMessageMetadataByModality;
567
+ chatStream: (options: ChatOptions<string, TChatProviderOptions>) => AsyncIterable<StreamChunk>;
568
+ summarize: (options: SummarizationOptions) => Promise<SummarizationResult>;
569
+ createEmbeddings: (options: EmbeddingOptions) => Promise<EmbeddingResult>;
570
+ }
571
+ export interface AIAdapterConfig {
572
+ apiKey?: string;
573
+ baseUrl?: string;
574
+ timeout?: number;
575
+ maxRetries?: number;
576
+ headers?: Record<string, string>;
577
+ }
578
+ export type ChatStreamOptionsUnion<TAdapter extends AIAdapter<any, any, any, any, any, any, any>> = TAdapter extends AIAdapter<infer Models, any, any, any, infer ModelProviderOptions, infer ModelInputModalities, infer MessageMetadata> ? Models[number] extends infer TModel ? TModel extends string ? Omit<ChatOptions, 'model' | 'providerOptions' | 'responseFormat' | 'messages'> & {
579
+ adapter: TAdapter;
580
+ model: TModel;
581
+ providerOptions?: TModel extends keyof ModelProviderOptions ? ModelProviderOptions[TModel] : never;
582
+ /**
583
+ * Messages array with content constrained to the model's supported input modalities.
584
+ * For example, if a model only supports ['text', 'image'], you cannot pass audio or video content.
585
+ * Metadata types are also constrained based on the adapter's metadata type definitions.
586
+ */
587
+ messages: TModel extends keyof ModelInputModalities ? ModelInputModalities[TModel] extends ReadonlyArray<Modality> ? MessageMetadata extends {
588
+ image: infer TImageMeta;
589
+ audio: infer TAudioMeta;
590
+ video: infer TVideoMeta;
591
+ document: infer TDocumentMeta;
592
+ } ? Array<ConstrainedModelMessage<ModelInputModalities[TModel], TImageMeta, TAudioMeta, TVideoMeta, TDocumentMeta>> : Array<ConstrainedModelMessage<ModelInputModalities[TModel]>> : Array<ModelMessage> : Array<ModelMessage>;
593
+ } : never : never : never;
594
+ /**
595
+ * Chat options constrained by a specific model's capabilities.
596
+ * Unlike ChatStreamOptionsUnion which creates a union over all models,
597
+ * this type takes a specific model and constrains messages accordingly.
598
+ */
599
+ export type ChatStreamOptionsForModel<TAdapter extends AIAdapter<any, any, any, any, any, any, any>, TModel extends string> = TAdapter extends AIAdapter<any, any, any, any, infer ModelProviderOptions, infer ModelInputModalities, infer MessageMetadata> ? Omit<ChatOptions, 'model' | 'providerOptions' | 'responseFormat' | 'messages'> & {
600
+ adapter: TAdapter;
601
+ model: TModel;
602
+ providerOptions?: TModel extends keyof ModelProviderOptions ? ModelProviderOptions[TModel] : never;
603
+ /**
604
+ * Messages array with content constrained to the model's supported input modalities.
605
+ * For example, if a model only supports ['text', 'image'], you cannot pass audio or video content.
606
+ * Metadata types are also constrained based on the adapter's metadata type definitions.
607
+ */
608
+ messages: TModel extends keyof ModelInputModalities ? ModelInputModalities[TModel] extends ReadonlyArray<Modality> ? MessageMetadata extends {
609
+ image: infer TImageMeta;
610
+ audio: infer TAudioMeta;
611
+ video: infer TVideoMeta;
612
+ document: infer TDocumentMeta;
613
+ } ? Array<ConstrainedModelMessage<ModelInputModalities[TModel], TImageMeta, TAudioMeta, TVideoMeta, TDocumentMeta>> : Array<ConstrainedModelMessage<ModelInputModalities[TModel]>> : Array<ModelMessage> : Array<ModelMessage>;
614
+ } : never;
615
+ export type ExtractModelsFromAdapter<T> = T extends AIAdapter<infer M, any, any, any, any, any> ? M[number] : never;
616
+ /**
617
+ * Extract the supported input modalities for a specific model from an adapter.
618
+ */
619
+ export type ExtractModalitiesForModel<TAdapter extends AIAdapter<any, any, any, any, any, any>, TModel extends string> = TAdapter extends AIAdapter<any, any, any, any, any, infer ModelInputModalities> ? TModel extends keyof ModelInputModalities ? ModelInputModalities[TModel] : ReadonlyArray<Modality> : ReadonlyArray<Modality>;
@@ -0,0 +1,59 @@
1
+ import { AgentLoopStrategy } from '../types.js';
2
+ /**
3
+ * Creates a strategy that continues for a maximum number of iterations
4
+ *
5
+ * @param max - Maximum number of iterations to allow
6
+ * @returns AgentLoopStrategy that stops after max iterations
7
+ *
8
+ * @example
9
+ * ```typescript
10
+ * const stream = chat({
11
+ * adapter: openai(),
12
+ * model: "gpt-4o",
13
+ * messages: [...],
14
+ * tools: [weatherTool],
15
+ * agentLoopStrategy: maxIterations(3), // Max 3 iterations
16
+ * });
17
+ * ```
18
+ */
19
+ export declare function maxIterations(max: number): AgentLoopStrategy;
20
+ /**
21
+ * Creates a strategy that continues until a specific finish reason is encountered
22
+ *
23
+ * @param stopReasons - Finish reasons that should stop the loop
24
+ * @returns AgentLoopStrategy that stops on specific finish reasons
25
+ *
26
+ * @example
27
+ * ```typescript
28
+ * const stream = chat({
29
+ * adapter: openai(),
30
+ * model: "gpt-4o",
31
+ * messages: [...],
32
+ * tools: [weatherTool],
33
+ * agentLoopStrategy: untilFinishReason(["stop", "length"]),
34
+ * });
35
+ * ```
36
+ */
37
+ export declare function untilFinishReason(stopReasons: Array<string>): AgentLoopStrategy;
38
+ /**
39
+ * Creates a strategy that combines multiple strategies with AND logic
40
+ * All strategies must return true to continue
41
+ *
42
+ * @param strategies - Array of strategies to combine
43
+ * @returns AgentLoopStrategy that continues only if all strategies return true
44
+ *
45
+ * @example
46
+ * ```typescript
47
+ * const stream = chat({
48
+ * adapter: openai(),
49
+ * model: "gpt-4o",
50
+ * messages: [...],
51
+ * tools: [weatherTool],
52
+ * agentLoopStrategy: combineStrategies([
53
+ * maxIterations(10),
54
+ * ({ messages }) => messages.length < 100,
55
+ * ]),
56
+ * });
57
+ * ```
58
+ */
59
+ export declare function combineStrategies(strategies: Array<AgentLoopStrategy>): AgentLoopStrategy;
@@ -0,0 +1,23 @@
1
+ function maxIterations(max) {
2
+ return ({ iterationCount }) => iterationCount < max;
3
+ }
4
+ function untilFinishReason(stopReasons) {
5
+ return ({ finishReason, iterationCount }) => {
6
+ if (iterationCount === 0) return true;
7
+ if (finishReason && stopReasons.includes(finishReason)) {
8
+ return false;
9
+ }
10
+ return true;
11
+ };
12
+ }
13
+ function combineStrategies(strategies) {
14
+ return (state) => {
15
+ return strategies.every((strategy) => strategy(state));
16
+ };
17
+ }
18
+ export {
19
+ combineStrategies,
20
+ maxIterations,
21
+ untilFinishReason
22
+ };
23
+ //# sourceMappingURL=agent-loop-strategies.js.map