@tanstack/ai 0.13.0 → 0.14.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 (57) hide show
  1. package/dist/esm/activities/error-payload.d.ts +12 -0
  2. package/dist/esm/activities/error-payload.js +25 -0
  3. package/dist/esm/activities/error-payload.js.map +1 -0
  4. package/dist/esm/activities/generateAudio/adapter.d.ts +62 -0
  5. package/dist/esm/activities/generateAudio/adapter.js +14 -0
  6. package/dist/esm/activities/generateAudio/adapter.js.map +1 -0
  7. package/dist/esm/activities/generateAudio/index.d.ts +74 -0
  8. package/dist/esm/activities/generateAudio/index.js +80 -0
  9. package/dist/esm/activities/generateAudio/index.js.map +1 -0
  10. package/dist/esm/activities/generateImage/adapter.d.ts +1 -1
  11. package/dist/esm/activities/generateImage/adapter.js +1 -1
  12. package/dist/esm/activities/generateImage/adapter.js.map +1 -1
  13. package/dist/esm/activities/generateSpeech/adapter.d.ts +1 -1
  14. package/dist/esm/activities/generateSpeech/adapter.js +1 -1
  15. package/dist/esm/activities/generateSpeech/adapter.js.map +1 -1
  16. package/dist/esm/activities/generateSpeech/index.d.ts +3 -3
  17. package/dist/esm/activities/generateSpeech/index.js +11 -0
  18. package/dist/esm/activities/generateSpeech/index.js.map +1 -1
  19. package/dist/esm/activities/generateTranscription/adapter.d.ts +1 -1
  20. package/dist/esm/activities/generateTranscription/adapter.js +1 -1
  21. package/dist/esm/activities/generateTranscription/adapter.js.map +1 -1
  22. package/dist/esm/activities/generateTranscription/index.d.ts +3 -3
  23. package/dist/esm/activities/generateTranscription/index.js +11 -0
  24. package/dist/esm/activities/generateTranscription/index.js.map +1 -1
  25. package/dist/esm/activities/generateVideo/index.js +7 -7
  26. package/dist/esm/activities/generateVideo/index.js.map +1 -1
  27. package/dist/esm/activities/index.d.ts +5 -2
  28. package/dist/esm/activities/index.js +11 -6
  29. package/dist/esm/activities/index.js.map +1 -1
  30. package/dist/esm/activities/stream-generation-result.js +5 -6
  31. package/dist/esm/activities/stream-generation-result.js.map +1 -1
  32. package/dist/esm/adapter-internals.d.ts +1 -0
  33. package/dist/esm/adapter-internals.js +3 -1
  34. package/dist/esm/adapter-internals.js.map +1 -1
  35. package/dist/esm/index.d.ts +3 -2
  36. package/dist/esm/index.js +3 -0
  37. package/dist/esm/index.js.map +1 -1
  38. package/dist/esm/stream-to-response.js +3 -8
  39. package/dist/esm/stream-to-response.js.map +1 -1
  40. package/dist/esm/types.d.ts +63 -6
  41. package/package.json +2 -2
  42. package/skills/ai-core/media-generation/SKILL.md +154 -10
  43. package/src/activities/error-payload.ts +35 -0
  44. package/src/activities/generateAudio/adapter.ts +89 -0
  45. package/src/activities/generateAudio/index.ts +224 -0
  46. package/src/activities/generateImage/adapter.ts +1 -1
  47. package/src/activities/generateSpeech/adapter.ts +1 -1
  48. package/src/activities/generateSpeech/index.ts +17 -7
  49. package/src/activities/generateTranscription/adapter.ts +1 -1
  50. package/src/activities/generateTranscription/index.ts +27 -4
  51. package/src/activities/generateVideo/index.ts +8 -8
  52. package/src/activities/index.ts +22 -0
  53. package/src/activities/stream-generation-result.ts +6 -7
  54. package/src/adapter-internals.ts +1 -0
  55. package/src/index.ts +4 -0
  56. package/src/stream-to-response.ts +5 -10
  57. package/src/types.ts +74 -5
@@ -44,7 +44,10 @@ export type TranscriptionProviderOptions<TAdapter> =
44
44
  * @template TStream - Whether to stream the output
45
45
  */
46
46
  export interface TranscriptionActivityOptions<
47
- TAdapter extends TranscriptionAdapter<string, object>,
47
+ TAdapter extends TranscriptionAdapter<
48
+ string,
49
+ TranscriptionProviderOptions<TAdapter>
50
+ >,
48
51
  TStream extends boolean = false,
49
52
  > {
50
53
  /** The transcription adapter to use (must be created with a model) */
@@ -141,7 +144,10 @@ function createId(prefix: string): string {
141
144
  * ```
142
145
  */
143
146
  export function generateTranscription<
144
- TAdapter extends TranscriptionAdapter<string, object>,
147
+ TAdapter extends TranscriptionAdapter<
148
+ string,
149
+ TranscriptionProviderOptions<TAdapter>
150
+ >,
145
151
  TStream extends boolean = false,
146
152
  >(
147
153
  options: TranscriptionActivityOptions<TAdapter, TStream>,
@@ -161,7 +167,10 @@ export function generateTranscription<
161
167
  * Run non-streaming transcription
162
168
  */
163
169
  async function runGenerateTranscription<
164
- TAdapter extends TranscriptionAdapter<string, object>,
170
+ TAdapter extends TranscriptionAdapter<
171
+ string,
172
+ TranscriptionProviderOptions<TAdapter>
173
+ >,
165
174
  >(
166
175
  options: TranscriptionActivityOptions<TAdapter, boolean>,
167
176
  ): Promise<TranscriptionResult> {
@@ -213,6 +222,17 @@ async function runGenerateTranscription<
213
222
 
214
223
  return result
215
224
  } catch (error) {
225
+ const duration = Date.now() - startTime
226
+ const err = error as Error
227
+ aiEventClient.emit('transcription:request:error', {
228
+ requestId,
229
+ provider: adapter.name,
230
+ model,
231
+ error: { message: err.message, name: err.name },
232
+ duration,
233
+ modelOptions: rest.modelOptions as Record<string, unknown> | undefined,
234
+ timestamp: Date.now(),
235
+ })
216
236
  logger.errors('generateTranscription activity failed', {
217
237
  error,
218
238
  source: 'generateTranscription',
@@ -229,7 +249,10 @@ async function runGenerateTranscription<
229
249
  * Create typed options for the generateTranscription() function without executing.
230
250
  */
231
251
  export function createTranscriptionOptions<
232
- TAdapter extends TranscriptionAdapter<string, object>,
252
+ TAdapter extends TranscriptionAdapter<
253
+ string,
254
+ TranscriptionProviderOptions<TAdapter>
255
+ >,
233
256
  TStream extends boolean = false,
234
257
  >(
235
258
  options: TranscriptionActivityOptions<TAdapter, TStream>,
@@ -8,6 +8,7 @@
8
8
  */
9
9
 
10
10
  import { aiEventClient } from '@tanstack/ai-event-client'
11
+ import { toRunErrorPayload } from '../error-payload'
11
12
  import { resolveDebugOption } from '../../logger/resolve'
12
13
  import type { InternalLogger } from '../../logger/internal-logger'
13
14
  import type { DebugOption } from '../../logger/types'
@@ -399,21 +400,20 @@ async function* runStreamingVideoGeneration<
399
400
  }
400
401
 
401
402
  throw new Error('Video generation timed out')
402
- } catch (error: any) {
403
+ } catch (error: unknown) {
404
+ const payload = toRunErrorPayload(error, 'Video generation failed')
403
405
  logger.errors('generateVideo activity failed', {
404
- error,
406
+ message: payload.message,
407
+ code: payload.code,
405
408
  source: 'generateVideo',
406
409
  })
407
410
  yield {
408
411
  type: 'RUN_ERROR',
409
412
  runId,
410
413
  threadId,
411
- message: error.message || 'Video generation failed',
412
- code: error.code,
413
- error: {
414
- message: error.message || 'Video generation failed',
415
- code: error.code,
416
- },
414
+ message: payload.message,
415
+ code: payload.code,
416
+ error: payload,
417
417
  timestamp: Date.now(),
418
418
  } as StreamChunk
419
419
  }
@@ -17,6 +17,7 @@
17
17
  import type { AnyTextAdapter } from './chat/adapter'
18
18
  import type { AnySummarizeAdapter } from './summarize/adapter'
19
19
  import type { AnyImageAdapter } from './generateImage/adapter'
20
+ import type { AnyAudioAdapter } from './generateAudio/adapter'
20
21
  import type { AnyVideoAdapter } from './generateVideo/adapter'
21
22
  import type { AnyTTSAdapter } from './generateSpeech/adapter'
22
23
  import type { AnyTranscriptionAdapter } from './generateTranscription/adapter'
@@ -80,6 +81,25 @@ export {
80
81
  type AnyImageAdapter,
81
82
  } from './generateImage/adapter'
82
83
 
84
+ // ===========================
85
+ // Audio Activity
86
+ // ===========================
87
+
88
+ export {
89
+ kind as audioKind,
90
+ generateAudio,
91
+ type AudioActivityOptions,
92
+ type AudioActivityResult,
93
+ type AudioProviderOptions,
94
+ } from './generateAudio/index'
95
+
96
+ export {
97
+ BaseAudioAdapter,
98
+ type AudioAdapter,
99
+ type AudioAdapterConfig,
100
+ type AnyAudioAdapter,
101
+ } from './generateAudio/adapter'
102
+
83
103
  // ===========================
84
104
  // Video Activity (Experimental)
85
105
  // ===========================
@@ -150,6 +170,7 @@ export type AIAdapter =
150
170
  | AnyTextAdapter
151
171
  | AnySummarizeAdapter
152
172
  | AnyImageAdapter
173
+ | AnyAudioAdapter
153
174
  | AnyVideoAdapter
154
175
  | AnyTTSAdapter
155
176
  | AnyTranscriptionAdapter
@@ -159,6 +180,7 @@ export type AdapterKind =
159
180
  | 'text'
160
181
  | 'summarize'
161
182
  | 'image'
183
+ | 'audio'
162
184
  | 'video'
163
185
  | 'tts'
164
186
  | 'transcription'
@@ -5,6 +5,7 @@
5
5
  */
6
6
 
7
7
  import { EventType } from '@ag-ui/core'
8
+ import { toRunErrorPayload } from './error-payload'
8
9
  import type { StreamChunk } from '../types'
9
10
 
10
11
  function createId(prefix: string): string {
@@ -52,18 +53,16 @@ export async function* streamGenerationResult<TResult>(
52
53
  finishReason: 'stop',
53
54
  timestamp: Date.now(),
54
55
  } as StreamChunk
55
- } catch (error: any) {
56
+ } catch (error: unknown) {
57
+ const payload = toRunErrorPayload(error, 'Generation failed')
56
58
  yield {
57
59
  type: EventType.RUN_ERROR,
58
60
  runId,
59
61
  threadId,
60
- message: error.message || 'Generation failed',
61
- code: error.code,
62
+ message: payload.message,
63
+ code: payload.code,
62
64
  // Deprecated nested form for backward compatibility
63
- error: {
64
- message: error.message || 'Generation failed',
65
- code: error.code,
66
- },
65
+ error: payload,
67
66
  timestamp: Date.now(),
68
67
  } as StreamChunk
69
68
  }
@@ -5,3 +5,4 @@
5
5
  export type { ResolvedCategories } from './logger/internal-logger'
6
6
  export { InternalLogger } from './logger/internal-logger'
7
7
  export { resolveDebugOption } from './logger/resolve'
8
+ export { toRunErrorPayload } from './activities/error-payload'
package/src/index.ts CHANGED
@@ -3,6 +3,7 @@ export {
3
3
  chat,
4
4
  summarize,
5
5
  generateImage,
6
+ generateAudio,
6
7
  generateVideo,
7
8
  getVideoJobStatus,
8
9
  generateSpeech,
@@ -13,6 +14,7 @@ export {
13
14
  export { createChatOptions } from './activities/chat/index'
14
15
  export { createSummarizeOptions } from './activities/summarize/index'
15
16
  export { createImageOptions } from './activities/generateImage/index'
17
+ export { createAudioOptions } from './activities/generateAudio/index'
16
18
  export { createVideoOptions } from './activities/generateVideo/index'
17
19
  export { createSpeechOptions } from './activities/generateSpeech/index'
18
20
  export { createTranscriptionOptions } from './activities/generateTranscription/index'
@@ -26,6 +28,8 @@ export type {
26
28
  AnyTextAdapter,
27
29
  AnySummarizeAdapter,
28
30
  SummarizeAdapter,
31
+ AnyAudioAdapter,
32
+ AudioAdapter,
29
33
  AnyTTSAdapter,
30
34
  TTSAdapter,
31
35
  AnyTranscriptionAdapter,
@@ -1,3 +1,4 @@
1
+ import { toRunErrorPayload } from './activities/error-payload'
1
2
  import type { StreamChunk } from './types'
2
3
 
3
4
  /**
@@ -68,7 +69,7 @@ export function toServerSentEventsStream(
68
69
  }
69
70
 
70
71
  controller.close()
71
- } catch (error: any) {
72
+ } catch (error: unknown) {
72
73
  // Don't send error if aborted
73
74
  if (abortController?.signal.aborted) {
74
75
  controller.close()
@@ -81,10 +82,7 @@ export function toServerSentEventsStream(
81
82
  `data: ${JSON.stringify({
82
83
  type: 'RUN_ERROR',
83
84
  timestamp: Date.now(),
84
- error: {
85
- message: error.message || 'Unknown error occurred',
86
- code: error.code,
87
- },
85
+ error: toRunErrorPayload(error),
88
86
  })}\n\n`,
89
87
  ),
90
88
  )
@@ -190,7 +188,7 @@ export function toHttpStream(
190
188
  }
191
189
 
192
190
  controller.close()
193
- } catch (error: any) {
191
+ } catch (error: unknown) {
194
192
  // Don't send error if aborted
195
193
  if (abortController?.signal.aborted) {
196
194
  controller.close()
@@ -203,10 +201,7 @@ export function toHttpStream(
203
201
  `${JSON.stringify({
204
202
  type: 'RUN_ERROR',
205
203
  timestamp: Date.now(),
206
- error: {
207
- message: error.message || 'Unknown error occurred',
208
- code: error.code,
209
- },
204
+ error: toRunErrorPayload(error),
210
205
  })}\n`,
211
206
  ),
212
207
  )
package/src/types.ts CHANGED
@@ -1219,14 +1219,28 @@ export interface ImageGenerationOptions<
1219
1219
  logger: InternalLogger
1220
1220
  }
1221
1221
 
1222
+ /**
1223
+ * Source of a generated media asset. Exactly one of `url` or `b64Json` is
1224
+ * present; the other is absent. Modeled as a mutually-exclusive union so the
1225
+ * type rejects `{}` and `{ url, b64Json }` together at compile time while
1226
+ * preserving the flat `.url` / `.b64Json` access patterns.
1227
+ */
1228
+ export type GeneratedMediaSource =
1229
+ | {
1230
+ /** URL to the generated asset (may be temporary) */
1231
+ url: string
1232
+ b64Json?: never
1233
+ }
1234
+ | {
1235
+ /** Base64-encoded asset data */
1236
+ b64Json: string
1237
+ url?: never
1238
+ }
1239
+
1222
1240
  /**
1223
1241
  * A single generated image
1224
1242
  */
1225
- export interface GeneratedImage {
1226
- /** Base64-encoded image data */
1227
- b64Json?: string
1228
- /** URL to the generated image (may be temporary) */
1229
- url?: string
1243
+ export type GeneratedImage = GeneratedMediaSource & {
1230
1244
  /** Revised prompt used by the model (if applicable) */
1231
1245
  revisedPrompt?: string
1232
1246
  }
@@ -1249,6 +1263,61 @@ export interface ImageGenerationResult {
1249
1263
  }
1250
1264
  }
1251
1265
 
1266
+ // ============================================================================
1267
+ // Audio Generation Types
1268
+ // ============================================================================
1269
+
1270
+ /**
1271
+ * Options for audio generation (music, sound effects, etc.).
1272
+ * These are the common options supported across providers.
1273
+ */
1274
+ export interface AudioGenerationOptions<
1275
+ TProviderOptions extends object = object,
1276
+ > {
1277
+ /** The model to use for audio generation */
1278
+ model: string
1279
+ /** Text description of the desired audio */
1280
+ prompt: string
1281
+ /** Desired duration in seconds */
1282
+ duration?: number
1283
+ /** Model-specific options for audio generation */
1284
+ modelOptions?: TProviderOptions
1285
+ /**
1286
+ * Internal logger threaded from the generateAudio() entry point. Adapters
1287
+ * must call logger.request() before the SDK call and logger.errors() in
1288
+ * catch blocks.
1289
+ */
1290
+ logger: InternalLogger
1291
+ }
1292
+
1293
+ /**
1294
+ * A single generated audio output
1295
+ */
1296
+ export type GeneratedAudio = GeneratedMediaSource & {
1297
+ /** Content type of the audio (e.g., 'audio/wav', 'audio/mp3') */
1298
+ contentType?: string
1299
+ /** Duration of the generated audio in seconds */
1300
+ duration?: number
1301
+ }
1302
+
1303
+ /**
1304
+ * Result of audio generation
1305
+ */
1306
+ export interface AudioGenerationResult {
1307
+ /** Unique identifier for the generation */
1308
+ id: string
1309
+ /** Model used for generation */
1310
+ model: string
1311
+ /** The generated audio */
1312
+ audio: GeneratedAudio
1313
+ /** Token usage information (if available) */
1314
+ usage?: {
1315
+ inputTokens?: number
1316
+ outputTokens?: number
1317
+ totalTokens?: number
1318
+ }
1319
+ }
1320
+
1252
1321
  // ============================================================================
1253
1322
  // Video Generation Types (Experimental)
1254
1323
  // ============================================================================