@tanstack/ai 0.0.3 → 0.2.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.
Files changed (146) hide show
  1. package/README.md +26 -0
  2. package/dist/esm/activities/chat/adapter.d.ts +100 -0
  3. package/dist/esm/activities/chat/adapter.js +14 -0
  4. package/dist/esm/activities/chat/adapter.js.map +1 -0
  5. package/dist/esm/{utilities → activities/chat}/agent-loop-strategies.d.ts +4 -4
  6. package/dist/esm/activities/chat/agent-loop-strategies.js.map +1 -0
  7. package/dist/esm/activities/chat/index.d.ts +166 -0
  8. package/dist/esm/{core/chat.js → activities/chat/index.js} +131 -33
  9. package/dist/esm/activities/chat/index.js.map +1 -0
  10. package/dist/esm/{message-converters.d.ts → activities/chat/messages.d.ts} +1 -1
  11. package/dist/esm/{message-converters.js → activities/chat/messages.js} +7 -7
  12. package/dist/esm/activities/chat/messages.js.map +1 -0
  13. package/dist/esm/activities/chat/stream/json-parser.js.map +1 -0
  14. package/dist/esm/{stream → activities/chat/stream}/message-updaters.d.ts +1 -1
  15. package/dist/esm/activities/chat/stream/message-updaters.js.map +1 -0
  16. package/dist/esm/{stream → activities/chat/stream}/processor.d.ts +1 -1
  17. package/dist/esm/{stream → activities/chat/stream}/processor.js +1 -1
  18. package/dist/esm/activities/chat/stream/processor.js.map +1 -0
  19. package/dist/esm/activities/chat/stream/strategies.js.map +1 -0
  20. package/dist/esm/{stream → activities/chat/stream}/types.d.ts +2 -9
  21. package/dist/esm/activities/chat/tools/schema-converter.d.ts +116 -0
  22. package/dist/esm/activities/chat/tools/schema-converter.js +115 -0
  23. package/dist/esm/activities/chat/tools/schema-converter.js.map +1 -0
  24. package/dist/esm/{tools → activities/chat/tools}/tool-calls.d.ts +1 -1
  25. package/dist/esm/{tools → activities/chat/tools}/tool-calls.js +23 -30
  26. package/dist/esm/activities/chat/tools/tool-calls.js.map +1 -0
  27. package/dist/esm/{tools → activities/chat/tools}/tool-definition.d.ts +22 -18
  28. package/dist/esm/activities/chat/tools/tool-definition.js.map +1 -0
  29. package/dist/esm/activities/generateImage/adapter.d.ts +68 -0
  30. package/dist/esm/activities/generateImage/adapter.js +14 -0
  31. package/dist/esm/activities/generateImage/adapter.js.map +1 -0
  32. package/dist/esm/activities/generateImage/index.d.ts +89 -0
  33. package/dist/esm/activities/generateImage/index.js +15 -0
  34. package/dist/esm/activities/generateImage/index.js.map +1 -0
  35. package/dist/esm/activities/generateSpeech/adapter.d.ts +62 -0
  36. package/dist/esm/activities/generateSpeech/adapter.js +14 -0
  37. package/dist/esm/activities/generateSpeech/adapter.js.map +1 -0
  38. package/dist/esm/activities/generateSpeech/index.d.ts +69 -0
  39. package/dist/esm/activities/generateSpeech/index.js +15 -0
  40. package/dist/esm/activities/generateSpeech/index.js.map +1 -0
  41. package/dist/esm/activities/generateTranscription/adapter.d.ts +62 -0
  42. package/dist/esm/activities/generateTranscription/adapter.js +14 -0
  43. package/dist/esm/activities/generateTranscription/adapter.js.map +1 -0
  44. package/dist/esm/activities/generateTranscription/index.d.ts +71 -0
  45. package/dist/esm/activities/generateTranscription/index.js +15 -0
  46. package/dist/esm/activities/generateTranscription/index.js.map +1 -0
  47. package/dist/esm/activities/generateVideo/adapter.d.ts +80 -0
  48. package/dist/esm/activities/generateVideo/adapter.js +14 -0
  49. package/dist/esm/activities/generateVideo/adapter.js.map +1 -0
  50. package/dist/esm/activities/generateVideo/index.d.ts +136 -0
  51. package/dist/esm/activities/generateVideo/index.js +47 -0
  52. package/dist/esm/activities/generateVideo/index.js.map +1 -0
  53. package/dist/esm/activities/index.d.ts +22 -0
  54. package/dist/esm/activities/index.js +34 -0
  55. package/dist/esm/activities/index.js.map +1 -0
  56. package/dist/esm/activities/summarize/adapter.d.ts +74 -0
  57. package/dist/esm/activities/summarize/adapter.js +14 -0
  58. package/dist/esm/activities/summarize/adapter.js.map +1 -0
  59. package/dist/esm/activities/summarize/index.d.ts +100 -0
  60. package/dist/esm/activities/summarize/index.js +90 -0
  61. package/dist/esm/activities/summarize/index.js.map +1 -0
  62. package/dist/esm/event-client.d.ts +4 -18
  63. package/dist/esm/event-client.js.map +1 -1
  64. package/dist/esm/index.d.ts +16 -14
  65. package/dist/esm/index.js +29 -20
  66. package/dist/esm/stream-to-response.d.ts +95 -0
  67. package/dist/esm/stream-to-response.js +118 -0
  68. package/dist/esm/stream-to-response.js.map +1 -0
  69. package/dist/esm/types.d.ts +370 -133
  70. package/package.json +7 -6
  71. package/src/activities/chat/adapter.ts +150 -0
  72. package/src/{utilities → activities/chat}/agent-loop-strategies.ts +4 -4
  73. package/src/{core/chat.ts → activities/chat/index.ts} +435 -79
  74. package/src/{message-converters.ts → activities/chat/messages.ts} +10 -13
  75. package/src/{stream → activities/chat/stream}/message-updaters.ts +1 -1
  76. package/src/{stream → activities/chat/stream}/processor.ts +2 -5
  77. package/src/{stream → activities/chat/stream}/types.ts +8 -18
  78. package/src/activities/chat/tools/schema-converter.ts +332 -0
  79. package/src/{tools → activities/chat/tools}/tool-calls.ts +63 -44
  80. package/src/{tools → activities/chat/tools}/tool-definition.ts +51 -38
  81. package/src/activities/generateImage/adapter.ts +104 -0
  82. package/src/activities/generateImage/index.ts +162 -0
  83. package/src/activities/generateSpeech/adapter.ts +87 -0
  84. package/src/activities/generateSpeech/index.ts +122 -0
  85. package/src/activities/generateTranscription/adapter.ts +89 -0
  86. package/src/activities/generateTranscription/index.ts +132 -0
  87. package/src/activities/generateVideo/adapter.ts +116 -0
  88. package/src/activities/generateVideo/index.ts +261 -0
  89. package/src/activities/index.ts +164 -0
  90. package/src/activities/summarize/adapter.ts +107 -0
  91. package/src/activities/summarize/index.ts +287 -0
  92. package/src/event-client.ts +5 -21
  93. package/src/index.ts +60 -15
  94. package/src/stream-to-response.ts +237 -0
  95. package/src/types.ts +429 -284
  96. package/dist/esm/base-adapter.d.ts +0 -36
  97. package/dist/esm/base-adapter.js +0 -12
  98. package/dist/esm/base-adapter.js.map +0 -1
  99. package/dist/esm/core/chat-common-options.d.ts +0 -52
  100. package/dist/esm/core/chat.d.ts +0 -30
  101. package/dist/esm/core/chat.js.map +0 -1
  102. package/dist/esm/core/embedding.d.ts +0 -8
  103. package/dist/esm/core/embedding.js +0 -33
  104. package/dist/esm/core/embedding.js.map +0 -1
  105. package/dist/esm/core/summarize.d.ts +0 -9
  106. package/dist/esm/core/summarize.js +0 -36
  107. package/dist/esm/core/summarize.js.map +0 -1
  108. package/dist/esm/message-converters.js.map +0 -1
  109. package/dist/esm/stream/json-parser.js.map +0 -1
  110. package/dist/esm/stream/message-updaters.js.map +0 -1
  111. package/dist/esm/stream/processor.js.map +0 -1
  112. package/dist/esm/stream/strategies.js.map +0 -1
  113. package/dist/esm/tools/tool-calls.js.map +0 -1
  114. package/dist/esm/tools/tool-definition.js.map +0 -1
  115. package/dist/esm/tools/zod-converter.d.ts +0 -30
  116. package/dist/esm/tools/zod-converter.js +0 -36
  117. package/dist/esm/tools/zod-converter.js.map +0 -1
  118. package/dist/esm/utilities/agent-loop-strategies.js.map +0 -1
  119. package/dist/esm/utilities/chat-options.d.ts +0 -6
  120. package/dist/esm/utilities/chat-options.js +0 -7
  121. package/dist/esm/utilities/chat-options.js.map +0 -1
  122. package/dist/esm/utilities/messages.d.ts +0 -30
  123. package/dist/esm/utilities/messages.js +0 -7
  124. package/dist/esm/utilities/messages.js.map +0 -1
  125. package/dist/esm/utilities/stream-to-response.d.ts +0 -48
  126. package/dist/esm/utilities/stream-to-response.js +0 -62
  127. package/dist/esm/utilities/stream-to-response.js.map +0 -1
  128. package/src/base-adapter.ts +0 -86
  129. package/src/core/chat-common-options.ts +0 -55
  130. package/src/core/embedding.ts +0 -54
  131. package/src/core/summarize.ts +0 -56
  132. package/src/tools/zod-converter.ts +0 -85
  133. package/src/utilities/chat-options.ts +0 -35
  134. package/src/utilities/messages.ts +0 -63
  135. package/src/utilities/stream-to-response.ts +0 -116
  136. /package/dist/esm/{utilities → activities/chat}/agent-loop-strategies.js +0 -0
  137. /package/dist/esm/{stream → activities/chat/stream}/index.d.ts +0 -0
  138. /package/dist/esm/{stream → activities/chat/stream}/json-parser.d.ts +0 -0
  139. /package/dist/esm/{stream → activities/chat/stream}/json-parser.js +0 -0
  140. /package/dist/esm/{stream → activities/chat/stream}/message-updaters.js +0 -0
  141. /package/dist/esm/{stream → activities/chat/stream}/strategies.d.ts +0 -0
  142. /package/dist/esm/{stream → activities/chat/stream}/strategies.js +0 -0
  143. /package/dist/esm/{tools → activities/chat/tools}/tool-definition.js +0 -0
  144. /package/src/{stream → activities/chat/stream}/index.ts +0 -0
  145. /package/src/{stream → activities/chat/stream}/json-parser.ts +0 -0
  146. /package/src/{stream → activities/chat/stream}/strategies.ts +0 -0
@@ -1,12 +1,17 @@
1
- import type { z } from 'zod'
2
- import type { Tool } from '../types'
1
+ import type { StandardJSONSchemaV1 } from '@standard-schema/spec'
2
+ import type {
3
+ InferSchemaType,
4
+ JSONSchema,
5
+ SchemaInput,
6
+ Tool,
7
+ } from '../../../types'
3
8
 
4
9
  /**
5
10
  * Marker type for server-side tools
6
11
  */
7
12
  export interface ServerTool<
8
- TInput extends z.ZodType = z.ZodType,
9
- TOutput extends z.ZodType = z.ZodType,
13
+ TInput extends SchemaInput = SchemaInput,
14
+ TOutput extends SchemaInput = SchemaInput,
10
15
  TName extends string = string,
11
16
  > extends Tool<TInput, TOutput, TName> {
12
17
  __toolSide: 'server'
@@ -16,8 +21,8 @@ export interface ServerTool<
16
21
  * Marker type for client-side tools
17
22
  */
18
23
  export interface ClientTool<
19
- TInput extends z.ZodType = z.ZodType,
20
- TOutput extends z.ZodType = z.ZodType,
24
+ TInput extends SchemaInput = SchemaInput,
25
+ TOutput extends SchemaInput = SchemaInput,
21
26
  TName extends string = string,
22
27
  > {
23
28
  __toolSide: 'client'
@@ -26,18 +31,18 @@ export interface ClientTool<
26
31
  inputSchema?: TInput
27
32
  outputSchema?: TOutput
28
33
  needsApproval?: boolean
29
- metadata?: Record<string, any>
34
+ metadata?: Record<string, unknown>
30
35
  execute?: (
31
- args: z.infer<TInput>,
32
- ) => Promise<z.infer<TOutput>> | z.infer<TOutput>
36
+ args: InferSchemaType<TInput>,
37
+ ) => Promise<InferSchemaType<TOutput>> | InferSchemaType<TOutput>
33
38
  }
34
39
 
35
40
  /**
36
41
  * Tool definition that can be used directly or instantiated for server/client
37
42
  */
38
43
  export interface ToolDefinitionInstance<
39
- TInput extends z.ZodType = z.ZodType,
40
- TOutput extends z.ZodType = z.ZodType,
44
+ TInput extends SchemaInput = SchemaInput,
45
+ TOutput extends SchemaInput = SchemaInput,
41
46
  TName extends string = string,
42
47
  > extends Tool<TInput, TOutput, TName> {
43
48
  __toolSide: 'definition'
@@ -47,8 +52,8 @@ export interface ToolDefinitionInstance<
47
52
  * Union type for any kind of client-side tool (client tool or definition)
48
53
  */
49
54
  export type AnyClientTool =
50
- | ClientTool<any, any>
51
- | ToolDefinitionInstance<any, any>
55
+ | ClientTool<SchemaInput, SchemaInput>
56
+ | ToolDefinitionInstance<SchemaInput, SchemaInput>
52
57
 
53
58
  /**
54
59
  * Extract the tool name as a literal type
@@ -56,29 +61,33 @@ export type AnyClientTool =
56
61
  export type InferToolName<T> = T extends { name: infer N } ? N : never
57
62
 
58
63
  /**
59
- * Extract the input type from a tool (inferred from Zod schema)
64
+ * Extract the input type from a tool (inferred from Standard JSON Schema, or `unknown` for plain JSONSchema)
60
65
  */
61
66
  export type InferToolInput<T> = T extends { inputSchema?: infer TInput }
62
- ? TInput extends z.ZodType
63
- ? z.infer<TInput>
64
- : any
65
- : any
67
+ ? TInput extends StandardJSONSchemaV1<infer TInferred, unknown>
68
+ ? TInferred
69
+ : TInput extends JSONSchema
70
+ ? unknown
71
+ : unknown
72
+ : unknown
66
73
 
67
74
  /**
68
- * Extract the output type from a tool (inferred from Zod schema)
75
+ * Extract the output type from a tool (inferred from Standard JSON Schema, or `unknown` for plain JSONSchema)
69
76
  */
70
77
  export type InferToolOutput<T> = T extends { outputSchema?: infer TOutput }
71
- ? TOutput extends z.ZodType
72
- ? z.infer<TOutput>
73
- : any
74
- : any
78
+ ? TOutput extends StandardJSONSchemaV1<infer TInferred, unknown>
79
+ ? TInferred
80
+ : TOutput extends JSONSchema
81
+ ? unknown
82
+ : unknown
83
+ : unknown
75
84
 
76
85
  /**
77
86
  * Tool definition configuration
78
87
  */
79
88
  export interface ToolDefinitionConfig<
80
- TInput extends z.ZodType = z.ZodType,
81
- TOutput extends z.ZodType = z.ZodType,
89
+ TInput extends SchemaInput = SchemaInput,
90
+ TOutput extends SchemaInput = SchemaInput,
82
91
  TName extends string = string,
83
92
  > {
84
93
  name: TName
@@ -86,15 +95,15 @@ export interface ToolDefinitionConfig<
86
95
  inputSchema?: TInput
87
96
  outputSchema?: TOutput
88
97
  needsApproval?: boolean
89
- metadata?: Record<string, any>
98
+ metadata?: Record<string, unknown>
90
99
  }
91
100
 
92
101
  /**
93
102
  * Tool definition builder that allows creating server or client tools from a shared definition
94
103
  */
95
104
  export interface ToolDefinition<
96
- TInput extends z.ZodType = z.ZodType,
97
- TOutput extends z.ZodType = z.ZodType,
105
+ TInput extends SchemaInput = SchemaInput,
106
+ TOutput extends SchemaInput = SchemaInput,
98
107
  TName extends string = string,
99
108
  > extends ToolDefinitionInstance<TInput, TOutput, TName> {
100
109
  /**
@@ -102,8 +111,8 @@ export interface ToolDefinition<
102
111
  */
103
112
  server: (
104
113
  execute: (
105
- args: z.infer<TInput>,
106
- ) => Promise<z.infer<TOutput>> | z.infer<TOutput>,
114
+ args: InferSchemaType<TInput>,
115
+ ) => Promise<InferSchemaType<TOutput>> | InferSchemaType<TOutput>,
107
116
  ) => ServerTool<TInput, TOutput, TName>
108
117
 
109
118
  /**
@@ -111,8 +120,8 @@ export interface ToolDefinition<
111
120
  */
112
121
  client: (
113
122
  execute?: (
114
- args: z.infer<TInput>,
115
- ) => Promise<z.infer<TOutput>> | z.infer<TOutput>,
123
+ args: InferSchemaType<TInput>,
124
+ ) => Promise<InferSchemaType<TOutput>> | InferSchemaType<TOutput>,
116
125
  ) => ClientTool<TInput, TOutput, TName>
117
126
  }
118
127
 
@@ -124,11 +133,15 @@ export interface ToolDefinition<
124
133
  * 2. Instantiated as a server tool with .server()
125
134
  * 3. Instantiated as a client tool with .client()
126
135
  *
136
+ * Supports any Standard JSON Schema compliant library (Zod v4+, ArkType, Valibot, etc.)
137
+ * or plain JSON Schema objects.
138
+ *
127
139
  * @example
128
140
  * ```typescript
129
141
  * import { toolDefinition } from '@tanstack/ai';
130
142
  * import { z } from 'zod';
131
143
  *
144
+ * // Using Zod (natively supports Standard JSON Schema)
132
145
  * const addToCartTool = toolDefinition({
133
146
  * name: 'addToCart',
134
147
  * description: 'Add a guitar to the shopping cart (requires approval)',
@@ -168,8 +181,8 @@ export interface ToolDefinition<
168
181
  * ```
169
182
  */
170
183
  export function toolDefinition<
171
- TInput extends z.ZodType = z.ZodAny,
172
- TOutput extends z.ZodType = z.ZodAny,
184
+ TInput extends SchemaInput = SchemaInput,
185
+ TOutput extends SchemaInput = SchemaInput,
173
186
  TName extends string = string,
174
187
  >(
175
188
  config: ToolDefinitionConfig<TInput, TOutput, TName>,
@@ -179,8 +192,8 @@ export function toolDefinition<
179
192
  ...config,
180
193
  server(
181
194
  execute: (
182
- args: z.infer<TInput>,
183
- ) => Promise<z.infer<TOutput>> | z.infer<TOutput>,
195
+ args: InferSchemaType<TInput>,
196
+ ) => Promise<InferSchemaType<TOutput>> | InferSchemaType<TOutput>,
184
197
  ): ServerTool<TInput, TOutput, TName> {
185
198
  return {
186
199
  __toolSide: 'server',
@@ -191,8 +204,8 @@ export function toolDefinition<
191
204
 
192
205
  client(
193
206
  execute?: (
194
- args: z.infer<TInput>,
195
- ) => Promise<z.infer<TOutput>> | z.infer<TOutput>,
207
+ args: InferSchemaType<TInput>,
208
+ ) => Promise<InferSchemaType<TOutput>> | InferSchemaType<TOutput>,
196
209
  ): ClientTool<TInput, TOutput, TName> {
197
210
  return {
198
211
  __toolSide: 'client',
@@ -0,0 +1,104 @@
1
+ import type { ImageGenerationOptions, ImageGenerationResult } from '../../types'
2
+
3
+ /**
4
+ * Configuration for image adapter instances
5
+ */
6
+ export interface ImageAdapterConfig {
7
+ apiKey?: string
8
+ baseUrl?: string
9
+ timeout?: number
10
+ maxRetries?: number
11
+ headers?: Record<string, string>
12
+ }
13
+
14
+ /**
15
+ * Image adapter interface with pre-resolved generics.
16
+ *
17
+ * An adapter is created by a provider function: `provider('model')` → `adapter`
18
+ * All type resolution happens at the provider call site, not in this interface.
19
+ *
20
+ * Generic parameters:
21
+ * - TModel: The specific model name (e.g., 'dall-e-3')
22
+ * - TProviderOptions: Base provider-specific options (already resolved)
23
+ * - TModelProviderOptionsByName: Map from model name to its specific provider options
24
+ * - TModelSizeByName: Map from model name to its supported sizes
25
+ */
26
+ export interface ImageAdapter<
27
+ TModel extends string = string,
28
+ TProviderOptions extends object = Record<string, unknown>,
29
+ TModelProviderOptionsByName extends Record<string, any> = Record<string, any>,
30
+ TModelSizeByName extends Record<string, string> = Record<string, string>,
31
+ > {
32
+ /** Discriminator for adapter kind - used by generate() to determine API shape */
33
+ readonly kind: 'image'
34
+ /** Adapter name identifier */
35
+ readonly name: string
36
+ /** The model this adapter is configured for */
37
+ readonly model: TModel
38
+
39
+ /**
40
+ * @internal Type-only properties for inference. Not assigned at runtime.
41
+ */
42
+ '~types': {
43
+ providerOptions: TProviderOptions
44
+ modelProviderOptionsByName: TModelProviderOptionsByName
45
+ modelSizeByName: TModelSizeByName
46
+ }
47
+
48
+ /**
49
+ * Generate images from a prompt
50
+ */
51
+ generateImages: (
52
+ options: ImageGenerationOptions<TProviderOptions>,
53
+ ) => Promise<ImageGenerationResult>
54
+ }
55
+
56
+ /**
57
+ * An ImageAdapter with any/unknown type parameters.
58
+ * Useful as a constraint in generic functions and interfaces.
59
+ */
60
+ export type AnyImageAdapter = ImageAdapter<any, any, any, any>
61
+
62
+ /**
63
+ * Abstract base class for image generation adapters.
64
+ * Extend this class to implement an image adapter for a specific provider.
65
+ *
66
+ * Generic parameters match ImageAdapter - all pre-resolved by the provider function.
67
+ */
68
+ export abstract class BaseImageAdapter<
69
+ TModel extends string = string,
70
+ TProviderOptions extends object = Record<string, unknown>,
71
+ TModelProviderOptionsByName extends Record<string, any> = Record<string, any>,
72
+ TModelSizeByName extends Record<string, string> = Record<string, string>,
73
+ > implements ImageAdapter<
74
+ TModel,
75
+ TProviderOptions,
76
+ TModelProviderOptionsByName,
77
+ TModelSizeByName
78
+ > {
79
+ readonly kind = 'image' as const
80
+ abstract readonly name: string
81
+ readonly model: TModel
82
+
83
+ // Type-only property - never assigned at runtime
84
+ declare '~types': {
85
+ providerOptions: TProviderOptions
86
+ modelProviderOptionsByName: TModelProviderOptionsByName
87
+ modelSizeByName: TModelSizeByName
88
+ }
89
+
90
+ protected config: ImageAdapterConfig
91
+
92
+ constructor(config: ImageAdapterConfig = {}, model: TModel) {
93
+ this.config = config
94
+ this.model = model
95
+ }
96
+
97
+ abstract generateImages(
98
+ options: ImageGenerationOptions<TProviderOptions>,
99
+ ): Promise<ImageGenerationResult>
100
+
101
+ protected generateId(): string {
102
+ return `${this.name}-${Date.now()}-${Math.random().toString(36).substring(7)}`
103
+ }
104
+ }
@@ -0,0 +1,162 @@
1
+ /**
2
+ * Image Activity
3
+ *
4
+ * Generates images from text prompts.
5
+ * This is a self-contained module with implementation, types, and JSDoc.
6
+ */
7
+
8
+ import type { ImageAdapter } from './adapter'
9
+ import type { ImageGenerationResult } from '../../types'
10
+
11
+ // ===========================
12
+ // Activity Kind
13
+ // ===========================
14
+
15
+ /** The adapter kind this activity handles */
16
+ export const kind = 'image' as const
17
+
18
+ // ===========================
19
+ // Type Extraction Helpers
20
+ // ===========================
21
+
22
+ /**
23
+ * Extract model-specific provider options from an ImageAdapter via ~types.
24
+ * If the model has specific options defined in ModelProviderOptions (and not just via index signature),
25
+ * use those; otherwise fall back to base provider options.
26
+ */
27
+ export type ImageProviderOptionsForModel<TAdapter, TModel extends string> =
28
+ TAdapter extends ImageAdapter<any, infer BaseOptions, infer ModelOptions, any>
29
+ ? string extends keyof ModelOptions
30
+ ? // ModelOptions is Record<string, unknown> or has index signature - use BaseOptions
31
+ BaseOptions
32
+ : // ModelOptions has explicit keys - check if TModel is one of them
33
+ TModel extends keyof ModelOptions
34
+ ? ModelOptions[TModel]
35
+ : BaseOptions
36
+ : object
37
+
38
+ /**
39
+ * Extract model-specific size options from an ImageAdapter via ~types.
40
+ * If the model has specific sizes defined, use those; otherwise fall back to string.
41
+ */
42
+ export type ImageSizeForModel<TAdapter, TModel extends string> =
43
+ TAdapter extends ImageAdapter<any, any, any, infer SizeByName>
44
+ ? string extends keyof SizeByName
45
+ ? // SizeByName has index signature - fall back to string
46
+ string
47
+ : // SizeByName has explicit keys - check if TModel is one of them
48
+ TModel extends keyof SizeByName
49
+ ? SizeByName[TModel]
50
+ : string
51
+ : string
52
+
53
+ // ===========================
54
+ // Activity Options Type
55
+ // ===========================
56
+
57
+ /**
58
+ * Options for the image activity.
59
+ * The model is extracted from the adapter's model property.
60
+ *
61
+ * @template TAdapter - The image adapter type
62
+ */
63
+ export interface ImageActivityOptions<
64
+ TAdapter extends ImageAdapter<string, object, any, any>,
65
+ > {
66
+ /** The image adapter to use (must be created with a model) */
67
+ adapter: TAdapter & { kind: typeof kind }
68
+ /** Text description of the desired image(s) */
69
+ prompt: string
70
+ /** Number of images to generate (default: 1) */
71
+ numberOfImages?: number
72
+ /** Image size in WIDTHxHEIGHT format (e.g., "1024x1024") */
73
+ size?: ImageSizeForModel<TAdapter, TAdapter['model']>
74
+ /** Provider-specific options for image generation */
75
+ modelOptions?: ImageProviderOptionsForModel<TAdapter, TAdapter['model']>
76
+ }
77
+
78
+ // ===========================
79
+ // Activity Result Type
80
+ // ===========================
81
+
82
+ /** Result type for the image activity */
83
+ export type ImageActivityResult = Promise<ImageGenerationResult>
84
+
85
+ // ===========================
86
+ // Activity Implementation
87
+ // ===========================
88
+
89
+ /**
90
+ * Image activity - generates images from text prompts.
91
+ *
92
+ * Uses AI image generation models to create images based on natural language descriptions.
93
+ *
94
+ * @example Generate a single image
95
+ * ```ts
96
+ * import { generateImage } from '@tanstack/ai'
97
+ * import { openaiImage } from '@tanstack/ai-openai'
98
+ *
99
+ * const result = await generateImage({
100
+ * adapter: openaiImage('dall-e-3'),
101
+ * prompt: 'A serene mountain landscape at sunset'
102
+ * })
103
+ *
104
+ * console.log(result.images[0].url)
105
+ * ```
106
+ *
107
+ * @example Generate multiple images
108
+ * ```ts
109
+ * const result = await generateImage({
110
+ * adapter: openaiImage('dall-e-2'),
111
+ * prompt: 'A cute robot mascot',
112
+ * numberOfImages: 4,
113
+ * size: '512x512'
114
+ * })
115
+ *
116
+ * result.images.forEach((image, i) => {
117
+ * console.log(`Image ${i + 1}: ${image.url}`)
118
+ * })
119
+ * ```
120
+ *
121
+ * @example With provider-specific options
122
+ * ```ts
123
+ * const result = await generateImage({
124
+ * adapter: openaiImage('dall-e-3'),
125
+ * prompt: 'A professional headshot photo',
126
+ * size: '1024x1024',
127
+ * modelOptions: {
128
+ * quality: 'hd',
129
+ * style: 'natural'
130
+ * }
131
+ * })
132
+ * ```
133
+ */
134
+ export async function generateImage<
135
+ TAdapter extends ImageAdapter<string, object, any, any>,
136
+ >(options: ImageActivityOptions<TAdapter>): ImageActivityResult {
137
+ const { adapter, ...rest } = options
138
+ const model = adapter.model
139
+
140
+ return adapter.generateImages({ ...rest, model })
141
+ }
142
+
143
+ // ===========================
144
+ // Options Factory
145
+ // ===========================
146
+
147
+ /**
148
+ * Create typed options for the generateImage() function without executing.
149
+ */
150
+ export function createImageOptions<
151
+ TAdapter extends ImageAdapter<string, object, any, any>,
152
+ >(options: ImageActivityOptions<TAdapter>): ImageActivityOptions<TAdapter> {
153
+ return options
154
+ }
155
+
156
+ // Re-export adapter types
157
+ export type {
158
+ ImageAdapter,
159
+ ImageAdapterConfig,
160
+ AnyImageAdapter,
161
+ } from './adapter'
162
+ export { BaseImageAdapter } from './adapter'
@@ -0,0 +1,87 @@
1
+ import type { TTSOptions, TTSResult } from '../../types'
2
+
3
+ /**
4
+ * Configuration for TTS adapter instances
5
+ */
6
+ export interface TTSAdapterConfig {
7
+ apiKey?: string
8
+ baseUrl?: string
9
+ timeout?: number
10
+ maxRetries?: number
11
+ headers?: Record<string, string>
12
+ }
13
+
14
+ /**
15
+ * TTS adapter interface with pre-resolved generics.
16
+ *
17
+ * An adapter is created by a provider function: `provider('model')` → `adapter`
18
+ * All type resolution happens at the provider call site, not in this interface.
19
+ *
20
+ * Generic parameters:
21
+ * - TModel: The specific model name (e.g., 'tts-1')
22
+ * - TProviderOptions: Provider-specific options (already resolved)
23
+ */
24
+ export interface TTSAdapter<
25
+ TModel extends string = string,
26
+ TProviderOptions extends object = Record<string, unknown>,
27
+ > {
28
+ /** Discriminator for adapter kind - used to determine API shape */
29
+ readonly kind: 'tts'
30
+ /** Adapter name identifier */
31
+ readonly name: string
32
+ /** The model this adapter is configured for */
33
+ readonly model: TModel
34
+
35
+ /**
36
+ * @internal Type-only properties for inference. Not assigned at runtime.
37
+ */
38
+ '~types': {
39
+ providerOptions: TProviderOptions
40
+ }
41
+
42
+ /**
43
+ * Generate speech from text
44
+ */
45
+ generateSpeech: (options: TTSOptions<TProviderOptions>) => Promise<TTSResult>
46
+ }
47
+
48
+ /**
49
+ * A TTSAdapter with any/unknown type parameters.
50
+ * Useful as a constraint in generic functions and interfaces.
51
+ */
52
+ export type AnyTTSAdapter = TTSAdapter<any, any>
53
+
54
+ /**
55
+ * Abstract base class for text-to-speech adapters.
56
+ * Extend this class to implement a TTS adapter for a specific provider.
57
+ *
58
+ * Generic parameters match TTSAdapter - all pre-resolved by the provider function.
59
+ */
60
+ export abstract class BaseTTSAdapter<
61
+ TModel extends string = string,
62
+ TProviderOptions extends object = Record<string, unknown>,
63
+ > implements TTSAdapter<TModel, TProviderOptions> {
64
+ readonly kind = 'tts' as const
65
+ abstract readonly name: string
66
+ readonly model: TModel
67
+
68
+ // Type-only property - never assigned at runtime
69
+ declare '~types': {
70
+ providerOptions: TProviderOptions
71
+ }
72
+
73
+ protected config: TTSAdapterConfig
74
+
75
+ constructor(config: TTSAdapterConfig = {}, model: TModel) {
76
+ this.config = config
77
+ this.model = model
78
+ }
79
+
80
+ abstract generateSpeech(
81
+ options: TTSOptions<TProviderOptions>,
82
+ ): Promise<TTSResult>
83
+
84
+ protected generateId(): string {
85
+ return `${this.name}-${Date.now()}-${Math.random().toString(36).substring(7)}`
86
+ }
87
+ }
@@ -0,0 +1,122 @@
1
+ /**
2
+ * TTS Activity
3
+ *
4
+ * Generates speech audio from text using text-to-speech models.
5
+ * This is a self-contained module with implementation, types, and JSDoc.
6
+ */
7
+
8
+ import type { TTSAdapter } from './adapter'
9
+ import type { TTSResult } from '../../types'
10
+
11
+ // ===========================
12
+ // Activity Kind
13
+ // ===========================
14
+
15
+ /** The adapter kind this activity handles */
16
+ export const kind = 'tts' as const
17
+
18
+ // ===========================
19
+ // Type Extraction Helpers
20
+ // ===========================
21
+
22
+ /**
23
+ * Extract provider options from a TTSAdapter via ~types.
24
+ */
25
+ export type TTSProviderOptions<TAdapter> =
26
+ TAdapter extends TTSAdapter<any, any>
27
+ ? TAdapter['~types']['providerOptions']
28
+ : object
29
+
30
+ // ===========================
31
+ // Activity Options Type
32
+ // ===========================
33
+
34
+ /**
35
+ * Options for the TTS activity.
36
+ * The model is extracted from the adapter's model property.
37
+ *
38
+ * @template TAdapter - The TTS adapter type
39
+ */
40
+ export interface TTSActivityOptions<
41
+ TAdapter extends TTSAdapter<string, object>,
42
+ > {
43
+ /** The TTS adapter to use (must be created with a model) */
44
+ adapter: TAdapter & { kind: typeof kind }
45
+ /** The text to convert to speech */
46
+ text: string
47
+ /** The voice to use for generation */
48
+ voice?: string
49
+ /** The output audio format */
50
+ format?: 'mp3' | 'opus' | 'aac' | 'flac' | 'wav' | 'pcm'
51
+ /** The speed of the generated audio (0.25 to 4.0) */
52
+ speed?: number
53
+ /** Provider-specific options for TTS generation */
54
+ modelOptions?: TTSProviderOptions<TAdapter>
55
+ }
56
+
57
+ // ===========================
58
+ // Activity Result Type
59
+ // ===========================
60
+
61
+ /** Result type for the TTS activity */
62
+ export type TTSActivityResult = Promise<TTSResult>
63
+
64
+ // ===========================
65
+ // Activity Implementation
66
+ // ===========================
67
+
68
+ /**
69
+ * TTS activity - generates speech from text.
70
+ *
71
+ * Uses AI text-to-speech models to create audio from natural language text.
72
+ *
73
+ * @example Generate speech from text
74
+ * ```ts
75
+ * import { generateSpeech } from '@tanstack/ai'
76
+ * import { openaiTTS } from '@tanstack/ai-openai'
77
+ *
78
+ * const result = await generateSpeech({
79
+ * adapter: openaiTTS('tts-1-hd'),
80
+ * text: 'Hello, welcome to TanStack AI!',
81
+ * voice: 'nova'
82
+ * })
83
+ *
84
+ * console.log(result.audio) // base64-encoded audio
85
+ * ```
86
+ *
87
+ * @example With format and speed options
88
+ * ```ts
89
+ * const result = await generateSpeech({
90
+ * adapter: openaiTTS('tts-1'),
91
+ * text: 'This is slower speech.',
92
+ * voice: 'alloy',
93
+ * format: 'wav',
94
+ * speed: 0.8
95
+ * })
96
+ * ```
97
+ */
98
+ export async function generateSpeech<
99
+ TAdapter extends TTSAdapter<string, object>,
100
+ >(options: TTSActivityOptions<TAdapter>): TTSActivityResult {
101
+ const { adapter, ...rest } = options
102
+ const model = adapter.model
103
+
104
+ return adapter.generateSpeech({ ...rest, model })
105
+ }
106
+
107
+ // ===========================
108
+ // Options Factory
109
+ // ===========================
110
+
111
+ /**
112
+ * Create typed options for the generateSpeech() function without executing.
113
+ */
114
+ export function createSpeechOptions<
115
+ TAdapter extends TTSAdapter<string, object>,
116
+ >(options: TTSActivityOptions<TAdapter>): TTSActivityOptions<TAdapter> {
117
+ return options
118
+ }
119
+
120
+ // Re-export adapter types
121
+ export type { TTSAdapter, TTSAdapterConfig, AnyTTSAdapter } from './adapter'
122
+ export { BaseTTSAdapter } from './adapter'