@tanstack/ai 0.0.2 → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +26 -0
- package/dist/esm/activities/chat/adapter.d.ts +100 -0
- package/dist/esm/activities/chat/adapter.js +14 -0
- package/dist/esm/activities/chat/adapter.js.map +1 -0
- package/dist/esm/{utilities → activities/chat}/agent-loop-strategies.d.ts +4 -4
- package/dist/esm/activities/chat/agent-loop-strategies.js.map +1 -0
- package/dist/esm/activities/chat/index.d.ts +165 -0
- package/dist/esm/{core/chat.js → activities/chat/index.js} +131 -33
- package/dist/esm/activities/chat/index.js.map +1 -0
- package/dist/esm/{message-converters.d.ts → activities/chat/messages.d.ts} +1 -1
- package/dist/esm/{message-converters.js → activities/chat/messages.js} +7 -7
- package/dist/esm/activities/chat/messages.js.map +1 -0
- package/dist/esm/activities/chat/stream/json-parser.js.map +1 -0
- package/dist/esm/{stream → activities/chat/stream}/message-updaters.d.ts +1 -1
- package/dist/esm/activities/chat/stream/message-updaters.js.map +1 -0
- package/dist/esm/{stream → activities/chat/stream}/processor.d.ts +1 -1
- package/dist/esm/{stream → activities/chat/stream}/processor.js +1 -1
- package/dist/esm/activities/chat/stream/processor.js.map +1 -0
- package/dist/esm/activities/chat/stream/strategies.js.map +1 -0
- package/dist/esm/{stream → activities/chat/stream}/types.d.ts +2 -9
- package/dist/esm/{tools → activities/chat/tools}/tool-calls.d.ts +1 -1
- package/dist/esm/{tools → activities/chat/tools}/tool-calls.js +9 -5
- package/dist/esm/activities/chat/tools/tool-calls.js.map +1 -0
- package/dist/esm/{tools → activities/chat/tools}/tool-definition.d.ts +14 -14
- package/dist/esm/activities/chat/tools/tool-definition.js.map +1 -0
- package/dist/esm/activities/chat/tools/zod-converter.d.ts +69 -0
- package/dist/esm/activities/chat/tools/zod-converter.js +99 -0
- package/dist/esm/activities/chat/tools/zod-converter.js.map +1 -0
- package/dist/esm/activities/generateImage/adapter.d.ts +68 -0
- package/dist/esm/activities/generateImage/adapter.js +14 -0
- package/dist/esm/activities/generateImage/adapter.js.map +1 -0
- package/dist/esm/activities/generateImage/index.d.ts +89 -0
- package/dist/esm/activities/generateImage/index.js +15 -0
- package/dist/esm/activities/generateImage/index.js.map +1 -0
- package/dist/esm/activities/generateSpeech/adapter.d.ts +62 -0
- package/dist/esm/activities/generateSpeech/adapter.js +14 -0
- package/dist/esm/activities/generateSpeech/adapter.js.map +1 -0
- package/dist/esm/activities/generateSpeech/index.d.ts +69 -0
- package/dist/esm/activities/generateSpeech/index.js +15 -0
- package/dist/esm/activities/generateSpeech/index.js.map +1 -0
- package/dist/esm/activities/generateTranscription/adapter.d.ts +62 -0
- package/dist/esm/activities/generateTranscription/adapter.js +14 -0
- package/dist/esm/activities/generateTranscription/adapter.js.map +1 -0
- package/dist/esm/activities/generateTranscription/index.d.ts +71 -0
- package/dist/esm/activities/generateTranscription/index.js +15 -0
- package/dist/esm/activities/generateTranscription/index.js.map +1 -0
- package/dist/esm/activities/generateVideo/adapter.d.ts +80 -0
- package/dist/esm/activities/generateVideo/adapter.js +14 -0
- package/dist/esm/activities/generateVideo/adapter.js.map +1 -0
- package/dist/esm/activities/generateVideo/index.d.ts +136 -0
- package/dist/esm/activities/generateVideo/index.js +47 -0
- package/dist/esm/activities/generateVideo/index.js.map +1 -0
- package/dist/esm/activities/index.d.ts +22 -0
- package/dist/esm/activities/index.js +34 -0
- package/dist/esm/activities/index.js.map +1 -0
- package/dist/esm/activities/summarize/adapter.d.ts +74 -0
- package/dist/esm/activities/summarize/adapter.js +14 -0
- package/dist/esm/activities/summarize/adapter.js.map +1 -0
- package/dist/esm/activities/summarize/index.d.ts +100 -0
- package/dist/esm/activities/summarize/index.js +90 -0
- package/dist/esm/activities/summarize/index.js.map +1 -0
- package/dist/esm/event-client.d.ts +4 -45
- package/dist/esm/event-client.js +0 -49
- package/dist/esm/event-client.js.map +1 -1
- package/dist/esm/index.d.ts +16 -14
- package/dist/esm/index.js +28 -19
- package/dist/esm/stream-to-response.d.ts +95 -0
- package/dist/esm/stream-to-response.js +118 -0
- package/dist/esm/stream-to-response.js.map +1 -0
- package/dist/esm/types.d.ts +347 -129
- package/package.json +6 -2
- package/src/activities/chat/adapter.ts +150 -0
- package/src/{utilities → activities/chat}/agent-loop-strategies.ts +4 -4
- package/src/{core/chat.ts → activities/chat/index.ts} +427 -79
- package/src/{message-converters.ts → activities/chat/messages.ts} +10 -13
- package/src/{stream → activities/chat/stream}/message-updaters.ts +1 -1
- package/src/{stream → activities/chat/stream}/processor.ts +2 -5
- package/src/{stream → activities/chat/stream}/types.ts +8 -18
- package/src/{tools → activities/chat/tools}/tool-calls.ts +36 -11
- package/src/{tools → activities/chat/tools}/tool-definition.ts +36 -27
- package/src/activities/chat/tools/zod-converter.ts +235 -0
- package/src/activities/generateImage/adapter.ts +104 -0
- package/src/activities/generateImage/index.ts +162 -0
- package/src/activities/generateSpeech/adapter.ts +87 -0
- package/src/activities/generateSpeech/index.ts +122 -0
- package/src/activities/generateTranscription/adapter.ts +89 -0
- package/src/activities/generateTranscription/index.ts +132 -0
- package/src/activities/generateVideo/adapter.ts +116 -0
- package/src/activities/generateVideo/index.ts +261 -0
- package/src/activities/index.ts +164 -0
- package/src/activities/summarize/adapter.ts +107 -0
- package/src/activities/summarize/index.ts +287 -0
- package/src/event-client.ts +5 -101
- package/src/index.ts +58 -15
- package/src/stream-to-response.ts +237 -0
- package/src/types.ts +404 -280
- package/dist/esm/base-adapter.d.ts +0 -36
- package/dist/esm/base-adapter.js +0 -12
- package/dist/esm/base-adapter.js.map +0 -1
- package/dist/esm/core/chat-common-options.d.ts +0 -52
- package/dist/esm/core/chat.d.ts +0 -30
- package/dist/esm/core/chat.js.map +0 -1
- package/dist/esm/core/embedding.d.ts +0 -8
- package/dist/esm/core/embedding.js +0 -33
- package/dist/esm/core/embedding.js.map +0 -1
- package/dist/esm/core/summarize.d.ts +0 -9
- package/dist/esm/core/summarize.js +0 -36
- package/dist/esm/core/summarize.js.map +0 -1
- package/dist/esm/message-converters.js.map +0 -1
- package/dist/esm/stream/json-parser.js.map +0 -1
- package/dist/esm/stream/message-updaters.js.map +0 -1
- package/dist/esm/stream/processor.js.map +0 -1
- package/dist/esm/stream/strategies.js.map +0 -1
- package/dist/esm/tools/tool-calls.js.map +0 -1
- package/dist/esm/tools/tool-definition.js.map +0 -1
- package/dist/esm/tools/zod-converter.d.ts +0 -30
- package/dist/esm/tools/zod-converter.js +0 -36
- package/dist/esm/tools/zod-converter.js.map +0 -1
- package/dist/esm/utilities/agent-loop-strategies.js.map +0 -1
- package/dist/esm/utilities/chat-options.d.ts +0 -6
- package/dist/esm/utilities/chat-options.js +0 -7
- package/dist/esm/utilities/chat-options.js.map +0 -1
- package/dist/esm/utilities/messages.d.ts +0 -30
- package/dist/esm/utilities/messages.js +0 -7
- package/dist/esm/utilities/messages.js.map +0 -1
- package/dist/esm/utilities/stream-to-response.d.ts +0 -48
- package/dist/esm/utilities/stream-to-response.js +0 -62
- package/dist/esm/utilities/stream-to-response.js.map +0 -1
- package/src/base-adapter.ts +0 -86
- package/src/core/chat-common-options.ts +0 -55
- package/src/core/embedding.ts +0 -54
- package/src/core/summarize.ts +0 -56
- package/src/tools/zod-converter.ts +0 -85
- package/src/utilities/chat-options.ts +0 -35
- package/src/utilities/messages.ts +0 -63
- package/src/utilities/stream-to-response.ts +0 -116
- /package/dist/esm/{utilities → activities/chat}/agent-loop-strategies.js +0 -0
- /package/dist/esm/{stream → activities/chat/stream}/index.d.ts +0 -0
- /package/dist/esm/{stream → activities/chat/stream}/json-parser.d.ts +0 -0
- /package/dist/esm/{stream → activities/chat/stream}/json-parser.js +0 -0
- /package/dist/esm/{stream → activities/chat/stream}/message-updaters.js +0 -0
- /package/dist/esm/{stream → activities/chat/stream}/strategies.d.ts +0 -0
- /package/dist/esm/{stream → activities/chat/stream}/strategies.js +0 -0
- /package/dist/esm/{tools → activities/chat/tools}/tool-definition.js +0 -0
- /package/src/{stream → activities/chat/stream}/index.ts +0 -0
- /package/src/{stream → activities/chat/stream}/json-parser.ts +0 -0
- /package/src/{stream → activities/chat/stream}/strategies.ts +0 -0
|
@@ -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'
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import type { TranscriptionOptions, TranscriptionResult } from '../../types'
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Configuration for transcription adapter instances
|
|
5
|
+
*/
|
|
6
|
+
export interface TranscriptionAdapterConfig {
|
|
7
|
+
apiKey?: string
|
|
8
|
+
baseUrl?: string
|
|
9
|
+
timeout?: number
|
|
10
|
+
maxRetries?: number
|
|
11
|
+
headers?: Record<string, string>
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Transcription 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., 'whisper-1')
|
|
22
|
+
* - TProviderOptions: Provider-specific options (already resolved)
|
|
23
|
+
*/
|
|
24
|
+
export interface TranscriptionAdapter<
|
|
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: 'transcription'
|
|
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
|
+
* Transcribe audio to text
|
|
44
|
+
*/
|
|
45
|
+
transcribe: (
|
|
46
|
+
options: TranscriptionOptions<TProviderOptions>,
|
|
47
|
+
) => Promise<TranscriptionResult>
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* A TranscriptionAdapter with any/unknown type parameters.
|
|
52
|
+
* Useful as a constraint in generic functions and interfaces.
|
|
53
|
+
*/
|
|
54
|
+
export type AnyTranscriptionAdapter = TranscriptionAdapter<any, any>
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Abstract base class for audio transcription adapters.
|
|
58
|
+
* Extend this class to implement a transcription adapter for a specific provider.
|
|
59
|
+
*
|
|
60
|
+
* Generic parameters match TranscriptionAdapter - all pre-resolved by the provider function.
|
|
61
|
+
*/
|
|
62
|
+
export abstract class BaseTranscriptionAdapter<
|
|
63
|
+
TModel extends string = string,
|
|
64
|
+
TProviderOptions extends object = Record<string, unknown>,
|
|
65
|
+
> implements TranscriptionAdapter<TModel, TProviderOptions> {
|
|
66
|
+
readonly kind = 'transcription' as const
|
|
67
|
+
abstract readonly name: string
|
|
68
|
+
readonly model: TModel
|
|
69
|
+
|
|
70
|
+
// Type-only property - never assigned at runtime
|
|
71
|
+
declare '~types': {
|
|
72
|
+
providerOptions: TProviderOptions
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
protected config: TranscriptionAdapterConfig
|
|
76
|
+
|
|
77
|
+
constructor(config: TranscriptionAdapterConfig = {}, model: TModel) {
|
|
78
|
+
this.config = config
|
|
79
|
+
this.model = model
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
abstract transcribe(
|
|
83
|
+
options: TranscriptionOptions<TProviderOptions>,
|
|
84
|
+
): Promise<TranscriptionResult>
|
|
85
|
+
|
|
86
|
+
protected generateId(): string {
|
|
87
|
+
return `${this.name}-${Date.now()}-${Math.random().toString(36).substring(7)}`
|
|
88
|
+
}
|
|
89
|
+
}
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Transcription Activity
|
|
3
|
+
*
|
|
4
|
+
* Transcribes audio to text using speech-to-text models.
|
|
5
|
+
* This is a self-contained module with implementation, types, and JSDoc.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import type { TranscriptionAdapter } from './adapter'
|
|
9
|
+
import type { TranscriptionResult } from '../../types'
|
|
10
|
+
|
|
11
|
+
// ===========================
|
|
12
|
+
// Activity Kind
|
|
13
|
+
// ===========================
|
|
14
|
+
|
|
15
|
+
/** The adapter kind this activity handles */
|
|
16
|
+
export const kind = 'transcription' as const
|
|
17
|
+
|
|
18
|
+
// ===========================
|
|
19
|
+
// Type Extraction Helpers
|
|
20
|
+
// ===========================
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Extract provider options from a TranscriptionAdapter via ~types.
|
|
24
|
+
*/
|
|
25
|
+
export type TranscriptionProviderOptions<TAdapter> =
|
|
26
|
+
TAdapter extends TranscriptionAdapter<any, any>
|
|
27
|
+
? TAdapter['~types']['providerOptions']
|
|
28
|
+
: object
|
|
29
|
+
|
|
30
|
+
// ===========================
|
|
31
|
+
// Activity Options Type
|
|
32
|
+
// ===========================
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Options for the transcription activity.
|
|
36
|
+
* The model is extracted from the adapter's model property.
|
|
37
|
+
*
|
|
38
|
+
* @template TAdapter - The transcription adapter type
|
|
39
|
+
*/
|
|
40
|
+
export interface TranscriptionActivityOptions<
|
|
41
|
+
TAdapter extends TranscriptionAdapter<string, object>,
|
|
42
|
+
> {
|
|
43
|
+
/** The transcription adapter to use (must be created with a model) */
|
|
44
|
+
adapter: TAdapter & { kind: typeof kind }
|
|
45
|
+
/** The audio data to transcribe - can be base64 string, File, Blob, or Buffer */
|
|
46
|
+
audio: string | File | Blob | ArrayBuffer
|
|
47
|
+
/** The language of the audio in ISO-639-1 format (e.g., 'en') */
|
|
48
|
+
language?: string
|
|
49
|
+
/** An optional prompt to guide the transcription */
|
|
50
|
+
prompt?: string
|
|
51
|
+
/** The format of the transcription output */
|
|
52
|
+
responseFormat?: 'json' | 'text' | 'srt' | 'verbose_json' | 'vtt'
|
|
53
|
+
/** Provider-specific options for transcription */
|
|
54
|
+
modelOptions?: TranscriptionProviderOptions<TAdapter>
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
// ===========================
|
|
58
|
+
// Activity Result Type
|
|
59
|
+
// ===========================
|
|
60
|
+
|
|
61
|
+
/** Result type for the transcription activity */
|
|
62
|
+
export type TranscriptionActivityResult = Promise<TranscriptionResult>
|
|
63
|
+
|
|
64
|
+
// ===========================
|
|
65
|
+
// Activity Implementation
|
|
66
|
+
// ===========================
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* Transcription activity - converts audio to text.
|
|
70
|
+
*
|
|
71
|
+
* Uses AI speech-to-text models to transcribe audio content.
|
|
72
|
+
*
|
|
73
|
+
* @example Transcribe an audio file
|
|
74
|
+
* ```ts
|
|
75
|
+
* import { generateTranscription } from '@tanstack/ai'
|
|
76
|
+
* import { openaiTranscription } from '@tanstack/ai-openai'
|
|
77
|
+
*
|
|
78
|
+
* const result = await generateTranscription({
|
|
79
|
+
* adapter: openaiTranscription('whisper-1'),
|
|
80
|
+
* audio: audioFile, // File, Blob, or base64 string
|
|
81
|
+
* language: 'en'
|
|
82
|
+
* })
|
|
83
|
+
*
|
|
84
|
+
* console.log(result.text)
|
|
85
|
+
* ```
|
|
86
|
+
*
|
|
87
|
+
* @example With verbose output for timestamps
|
|
88
|
+
* ```ts
|
|
89
|
+
* const result = await generateTranscription({
|
|
90
|
+
* adapter: openaiTranscription('whisper-1'),
|
|
91
|
+
* audio: audioFile,
|
|
92
|
+
* responseFormat: 'verbose_json'
|
|
93
|
+
* })
|
|
94
|
+
*
|
|
95
|
+
* result.segments?.forEach(segment => {
|
|
96
|
+
* console.log(`[${segment.start}s - ${segment.end}s]: ${segment.text}`)
|
|
97
|
+
* })
|
|
98
|
+
* ```
|
|
99
|
+
*/
|
|
100
|
+
export async function generateTranscription<
|
|
101
|
+
TAdapter extends TranscriptionAdapter<string, object>,
|
|
102
|
+
>(
|
|
103
|
+
options: TranscriptionActivityOptions<TAdapter>,
|
|
104
|
+
): TranscriptionActivityResult {
|
|
105
|
+
const { adapter, ...rest } = options
|
|
106
|
+
const model = adapter.model
|
|
107
|
+
|
|
108
|
+
return adapter.transcribe({ ...rest, model })
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
// ===========================
|
|
112
|
+
// Options Factory
|
|
113
|
+
// ===========================
|
|
114
|
+
|
|
115
|
+
/**
|
|
116
|
+
* Create typed options for the generateTranscription() function without executing.
|
|
117
|
+
*/
|
|
118
|
+
export function createTranscriptionOptions<
|
|
119
|
+
TAdapter extends TranscriptionAdapter<string, object>,
|
|
120
|
+
>(
|
|
121
|
+
options: TranscriptionActivityOptions<TAdapter>,
|
|
122
|
+
): TranscriptionActivityOptions<TAdapter> {
|
|
123
|
+
return options
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
// Re-export adapter types
|
|
127
|
+
export type {
|
|
128
|
+
TranscriptionAdapter,
|
|
129
|
+
TranscriptionAdapterConfig,
|
|
130
|
+
AnyTranscriptionAdapter,
|
|
131
|
+
} from './adapter'
|
|
132
|
+
export { BaseTranscriptionAdapter } from './adapter'
|