@tanstack/ai 0.52.3 → 0.54.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 (74) hide show
  1. package/README.md +14 -13
  2. package/dist/esm/activities/chat/index.js +5 -3
  3. package/dist/esm/activities/chat/index.js.map +1 -1
  4. package/dist/esm/activities/generateLiveVideo/adapter.d.ts +69 -0
  5. package/dist/esm/activities/generateLiveVideo/adapter.js +23 -0
  6. package/dist/esm/activities/generateLiveVideo/adapter.js.map +1 -0
  7. package/dist/esm/activities/generateLiveVideo/index.d.ts +99 -0
  8. package/dist/esm/activities/generateLiveVideo/index.js +162 -0
  9. package/dist/esm/activities/generateLiveVideo/index.js.map +1 -0
  10. package/dist/esm/activities/generateVideo/index.js +3 -1
  11. package/dist/esm/activities/generateVideo/index.js.map +1 -1
  12. package/dist/esm/activities/generateWorld/adapter.d.ts +69 -0
  13. package/dist/esm/activities/generateWorld/adapter.js +23 -0
  14. package/dist/esm/activities/generateWorld/adapter.js.map +1 -0
  15. package/dist/esm/activities/generateWorld/index.d.ts +99 -0
  16. package/dist/esm/activities/generateWorld/index.js +162 -0
  17. package/dist/esm/activities/generateWorld/index.js.map +1 -0
  18. package/dist/esm/activities/index.d.ts +8 -2
  19. package/dist/esm/activities/index.js +11 -7
  20. package/dist/esm/activities/middleware/types.d.ts +1 -1
  21. package/dist/esm/activities/summarize/chat-stream-summarize.js +2 -1
  22. package/dist/esm/activities/summarize/chat-stream-summarize.js.map +1 -1
  23. package/dist/esm/byok/define-provider.d.ts +6 -0
  24. package/dist/esm/byok/define-provider.js +2 -1
  25. package/dist/esm/byok/define-provider.js.map +1 -1
  26. package/dist/esm/byok/get-key.d.ts +7 -0
  27. package/dist/esm/byok/get-key.js +8 -1
  28. package/dist/esm/byok/get-key.js.map +1 -1
  29. package/dist/esm/byok/server.d.ts +1 -1
  30. package/dist/esm/byok/server.js +2 -2
  31. package/dist/esm/client.d.ts +4 -2
  32. package/dist/esm/client.js +3 -1
  33. package/dist/esm/client.js.map +1 -1
  34. package/dist/esm/index.d.ts +4 -2
  35. package/dist/esm/index.js +3 -1
  36. package/dist/esm/middlewares/otel.js +3 -1
  37. package/dist/esm/middlewares/otel.js.map +1 -1
  38. package/dist/esm/types.d.ts +112 -0
  39. package/package.json +2 -2
  40. package/skills/ai-core/adapter-configuration/SKILL.md +103 -54
  41. package/skills/ai-core/adapter-configuration/references/anthropic-adapter.md +39 -21
  42. package/skills/ai-core/adapter-configuration/references/byteplus-adapter.md +5 -0
  43. package/skills/ai-core/adapter-configuration/references/gemini-adapter.md +14 -6
  44. package/skills/ai-core/adapter-configuration/references/grok-adapter.md +33 -25
  45. package/skills/ai-core/adapter-configuration/references/groq-adapter.md +7 -2
  46. package/skills/ai-core/adapter-configuration/references/ollama-adapter.md +25 -12
  47. package/skills/ai-core/adapter-configuration/references/openai-adapter.md +19 -9
  48. package/skills/ai-core/adapter-configuration/references/openrouter-adapter.md +34 -21
  49. package/skills/ai-core/ag-ui-protocol/SKILL.md +16 -10
  50. package/skills/ai-core/chat-experience/SKILL.md +228 -108
  51. package/skills/ai-core/client-persistence/SKILL.md +21 -9
  52. package/skills/ai-core/custom-backend-integration/SKILL.md +86 -52
  53. package/skills/ai-core/debug-logging/SKILL.md +100 -18
  54. package/skills/ai-core/locks/SKILL.md +35 -7
  55. package/skills/ai-core/media-generation/SKILL.md +114 -49
  56. package/skills/ai-core/middleware/SKILL.md +174 -69
  57. package/skills/ai-core/structured-outputs/SKILL.md +99 -49
  58. package/skills/ai-core/tool-calling/SKILL.md +245 -158
  59. package/src/activities/chat/index.ts +6 -7
  60. package/src/activities/generateLiveVideo/adapter.ts +99 -0
  61. package/src/activities/generateLiveVideo/index.ts +339 -0
  62. package/src/activities/generateVideo/index.ts +3 -4
  63. package/src/activities/generateWorld/adapter.ts +96 -0
  64. package/src/activities/generateWorld/index.ts +339 -0
  65. package/src/activities/index.ts +44 -0
  66. package/src/activities/middleware/types.ts +2 -0
  67. package/src/activities/summarize/chat-stream-summarize.ts +2 -0
  68. package/src/byok/define-provider.ts +7 -0
  69. package/src/byok/get-key.ts +18 -0
  70. package/src/byok/server.ts +1 -1
  71. package/src/client.ts +8 -0
  72. package/src/index.ts +8 -0
  73. package/src/middlewares/otel.ts +2 -0
  74. package/src/types.ts +128 -0
@@ -0,0 +1,339 @@
1
+ /**
2
+ * World Activity (Experimental)
3
+ *
4
+ * Mints a session token for a live, prompt-steerable world. Unlike
5
+ * generateVideo (a job that finishes with a URL), the browser then connects
6
+ * with the token, sets the prompt, and streams until pause/reset/close.
7
+ *
8
+ * @experimental World generation is an experimental feature and may change.
9
+ */
10
+
11
+ import { aiEventClient } from '@tanstack/ai-event-client'
12
+ import { streamGenerationResult } from '../stream-generation-result.js'
13
+ import { resolveDebugOption } from '../../logger/resolve'
14
+ import {
15
+ applyGenerationResultTransforms,
16
+ createGenerationContext,
17
+ runGenerationAbort,
18
+ runGenerationError,
19
+ runGenerationFinish,
20
+ runGenerationStart,
21
+ runGenerationUsage,
22
+ } from '../middleware/run'
23
+ import {
24
+ abortReasonMessage,
25
+ createActivityAbortControls,
26
+ isActivityAbortError,
27
+ raceWithAbort,
28
+ } from '../../utilities/activity-abort'
29
+ import type { InternalLogger } from '../../logger/internal-logger'
30
+ import type { DebugOption } from '../../logger/types'
31
+ import type { GenerationMiddleware } from '../middleware/types'
32
+ import type { WorldAdapter } from './adapter'
33
+ import type { StreamChunk, WorldGenerationResult } from '../../types'
34
+
35
+ // ===========================
36
+ // Activity Kind
37
+ // ===========================
38
+
39
+ /** The adapter kind this activity handles */
40
+ export const kind = 'world' as const
41
+
42
+ // ===========================
43
+ // Type Extraction Helpers
44
+ // ===========================
45
+
46
+ /**
47
+ * Extract provider options from a WorldAdapter via ~types.
48
+ */
49
+ export type WorldProviderOptions<TAdapter> = TAdapter extends {
50
+ '~types': { providerOptions: infer P extends object }
51
+ }
52
+ ? P
53
+ : object
54
+
55
+ // ===========================
56
+ // Activity Options Type
57
+ // ===========================
58
+
59
+ /**
60
+ * Options for the world generation activity.
61
+ * The model is extracted from the adapter's model property.
62
+ *
63
+ * @template TAdapter - The world adapter type
64
+ * @template TStream - Whether to stream the output
65
+ *
66
+ * @experimental World generation is an experimental feature and may change.
67
+ */
68
+ export interface WorldActivityOptions<
69
+ TAdapter extends WorldAdapter<string, WorldProviderOptions<TAdapter>>,
70
+ TStream extends boolean = false,
71
+ > {
72
+ /** The world adapter to use (must be created with a model) */
73
+ adapter: TAdapter & { kind: typeof kind }
74
+ /** Natural-language description of the world or scene */
75
+ prompt: string
76
+ /** Provider-specific options for world generation */
77
+ modelOptions?: WorldProviderOptions<TAdapter>
78
+ /**
79
+ * Whether to wrap the token result as StreamChunks for SSE transport.
80
+ * This is not the live video. When false or omitted, returns
81
+ * Promise<WorldGenerationResult>.
82
+ *
83
+ * @default false
84
+ */
85
+ stream?: TStream
86
+ /**
87
+ * Enable debug logging. Pass `true` to enable all categories, `false` to
88
+ * silence everything including errors, or a `DebugConfig` object for granular
89
+ * control and/or a custom `Logger`.
90
+ */
91
+ debug?: DebugOption
92
+ /**
93
+ * Observe-only middleware notified on start, usage, success, and error. Pass
94
+ * `otelMiddleware()` to emit OpenTelemetry spans, or implement the
95
+ * `GenerationMiddleware` contract for a custom backend.
96
+ */
97
+ middleware?: Array<GenerationMiddleware>
98
+ /** Stable conversation/thread id for correlating this run when persisted. */
99
+ threadId?: string
100
+ /** Stable run id for correlating this run when persisted. */
101
+ runId?: string
102
+ /**
103
+ * Maximum duration of the token mint in milliseconds.
104
+ * No SDK-wide default. Composed with {@link abortSignal}; the first abort wins.
105
+ */
106
+ timeout?: number
107
+ /**
108
+ * Caller cancellation signal (request disconnects, job/runtime cancellation).
109
+ * Composed with {@link timeout} into an effective signal forwarded to the
110
+ * adapter. Request-specific — not stored on global provider client config.
111
+ */
112
+ abortSignal?: AbortSignal
113
+ }
114
+
115
+ // ===========================
116
+ // Activity Result Type
117
+ // ===========================
118
+
119
+ /**
120
+ * Result type for the world generation activity.
121
+ * - If stream is true: AsyncIterable<StreamChunk>
122
+ * - Otherwise: Promise<WorldGenerationResult>
123
+ */
124
+ export type WorldActivityResult<TStream extends boolean = false> =
125
+ TStream extends true
126
+ ? AsyncIterable<StreamChunk>
127
+ : Promise<WorldGenerationResult>
128
+
129
+ function createId(prefix: string): string {
130
+ return `${prefix}-${Date.now()}-${Math.random().toString(36).slice(2, 9)}`
131
+ }
132
+
133
+ // ===========================
134
+ // Activity Implementation
135
+ // ===========================
136
+
137
+ /**
138
+ * World generation activity - opens a live, prompt-steerable world session.
139
+ *
140
+ * @example Mint a session token on the server
141
+ * ```ts
142
+ * import { generateWorld } from '@tanstack/ai'
143
+ * import { reactorWorld } from '@tanstack/ai-reactor'
144
+ *
145
+ * const world = await generateWorld({
146
+ * adapter: reactorWorld('visko-orbis-stable'),
147
+ * prompt: 'A neon cyberpunk city at night, slow aerial drift',
148
+ * })
149
+ *
150
+ * // Hand world.token, world.model, and world.prompt to the browser.
151
+ * ```
152
+ *
153
+ * @experimental World generation is an experimental feature and may change.
154
+ */
155
+ export function generateWorld<
156
+ TAdapter extends WorldAdapter<string, WorldProviderOptions<TAdapter>>,
157
+ TStream extends boolean = false,
158
+ >(
159
+ options: WorldActivityOptions<TAdapter, TStream>,
160
+ ): WorldActivityResult<TStream> {
161
+ if (options.stream) {
162
+ return streamGenerationResult(
163
+ (resolved) => runGenerateWorld({ ...options, runId: resolved.runId }),
164
+ options,
165
+ ) as WorldActivityResult<TStream>
166
+ }
167
+ return runGenerateWorld(options) as WorldActivityResult<TStream>
168
+ }
169
+
170
+ /**
171
+ * Run the core world generation logic (non-streaming).
172
+ */
173
+ async function runGenerateWorld<
174
+ TAdapter extends WorldAdapter<string, WorldProviderOptions<TAdapter>>,
175
+ >(
176
+ options: WorldActivityOptions<TAdapter, boolean>,
177
+ ): Promise<WorldGenerationResult> {
178
+ const {
179
+ adapter,
180
+ stream: _stream,
181
+ debug: _debug,
182
+ middleware,
183
+ threadId,
184
+ runId,
185
+ timeout,
186
+ abortSignal: callerAbortSignal,
187
+ ...rest
188
+ } = options
189
+ const model = adapter.model
190
+ const requestId = createId('world')
191
+ const startTime = Date.now()
192
+ const logger: InternalLogger = resolveDebugOption(options.debug)
193
+ const abortControls = createActivityAbortControls({
194
+ timeout,
195
+ abortSignal: callerAbortSignal,
196
+ })
197
+ const providerName =
198
+ (adapter as { name?: string; provider?: string }).provider ??
199
+ (adapter as { name?: string }).name ??
200
+ 'unknown'
201
+
202
+ const mwCtx = createGenerationContext({
203
+ requestId,
204
+ activity: 'world',
205
+ provider: adapter.name,
206
+ model,
207
+ modelOptions: rest.modelOptions,
208
+ threadId,
209
+ runId,
210
+ artifactInputs: { prompt: rest.prompt },
211
+ createId,
212
+ })
213
+
214
+ await runGenerationStart(middleware, mwCtx)
215
+
216
+ aiEventClient.emit('world:request:started', {
217
+ requestId,
218
+ provider: adapter.name,
219
+ model,
220
+ prompt: rest.prompt,
221
+ timestamp: startTime,
222
+ ...(rest.modelOptions !== undefined && {
223
+ modelOptions: rest.modelOptions as Record<string, unknown>,
224
+ }),
225
+ })
226
+
227
+ logger.request(`activity=generateWorld provider=${providerName}`, {
228
+ provider: providerName,
229
+ model,
230
+ })
231
+
232
+ try {
233
+ const rawResult = await raceWithAbort(
234
+ adapter.createWorld({
235
+ ...rest,
236
+ model,
237
+ logger,
238
+ ...(abortControls.signal ? { abortSignal: abortControls.signal } : {}),
239
+ }),
240
+ abortControls.signal,
241
+ )
242
+ abortControls.clear()
243
+ const result = await applyGenerationResultTransforms(mwCtx, rawResult)
244
+ const elapsedMs = Date.now() - startTime
245
+
246
+ aiEventClient.emit('world:request:completed', {
247
+ requestId,
248
+ provider: adapter.name,
249
+ model: result.model,
250
+ prompt: result.prompt,
251
+ status: result.status,
252
+ duration: elapsedMs,
253
+ timestamp: Date.now(),
254
+ ...(rest.modelOptions !== undefined && {
255
+ modelOptions: rest.modelOptions as Record<string, unknown>,
256
+ }),
257
+ })
258
+
259
+ if (result.usage) {
260
+ aiEventClient.emit('world:usage', {
261
+ requestId,
262
+ model: result.model,
263
+ usage: result.usage,
264
+ timestamp: Date.now(),
265
+ ...(rest.modelOptions !== undefined && {
266
+ modelOptions: rest.modelOptions as Record<string, unknown>,
267
+ }),
268
+ })
269
+ }
270
+
271
+ logger.output(`activity=generateWorld provider=${providerName}`, {
272
+ model: result.model,
273
+ status: result.status,
274
+ })
275
+
276
+ if (result.usage) await runGenerationUsage(middleware, mwCtx, result.usage)
277
+ await runGenerationFinish(middleware, mwCtx, {
278
+ duration: elapsedMs,
279
+ usage: result.usage,
280
+ })
281
+
282
+ return result
283
+ } catch (error) {
284
+ abortControls.clear()
285
+ const elapsedMs = Date.now() - startTime
286
+ const err = error as Error
287
+ aiEventClient.emit('world:request:error', {
288
+ requestId,
289
+ provider: adapter.name,
290
+ model,
291
+ error: { message: err.message, name: err.name },
292
+ duration: elapsedMs,
293
+ timestamp: Date.now(),
294
+ ...(rest.modelOptions !== undefined && {
295
+ modelOptions: rest.modelOptions as Record<string, unknown>,
296
+ }),
297
+ })
298
+ if (isActivityAbortError(error, abortControls.signal)) {
299
+ await runGenerationAbort(middleware, mwCtx, {
300
+ reason: abortReasonMessage(error, abortControls.signal),
301
+ duration: elapsedMs,
302
+ })
303
+ } else {
304
+ await runGenerationError(middleware, mwCtx, {
305
+ error,
306
+ duration: elapsedMs,
307
+ })
308
+ }
309
+ logger.errors('generateWorld activity failed', {
310
+ error,
311
+ source: 'generateWorld',
312
+ })
313
+ throw error
314
+ }
315
+ }
316
+
317
+ // ===========================
318
+ // Options Factory
319
+ // ===========================
320
+
321
+ /**
322
+ * Create typed options for the generateWorld() function without executing.
323
+ */
324
+ export function createWorldOptions<
325
+ TAdapter extends WorldAdapter<string, WorldProviderOptions<TAdapter>>,
326
+ TStream extends boolean = false,
327
+ >(
328
+ options: WorldActivityOptions<TAdapter, TStream>,
329
+ ): WorldActivityOptions<TAdapter, TStream> {
330
+ return options
331
+ }
332
+
333
+ // Re-export adapter types
334
+ export type {
335
+ WorldAdapter,
336
+ WorldAdapterConfig,
337
+ AnyWorldAdapter,
338
+ } from './adapter'
339
+ export { BaseWorldAdapter } from './adapter'
@@ -23,6 +23,8 @@ import type { AnyTTSAdapter } from './generateSpeech/adapter'
23
23
  import type { AnyTranscriptionAdapter } from './generateTranscription/adapter'
24
24
  import type { AnyEmbeddingAdapter } from './embed/adapter'
25
25
  import type { AnyRerankAdapter } from './rerank/adapter'
26
+ import type { AnyWorldAdapter } from './generateWorld/adapter'
27
+ import type { AnyLiveVideoAdapter } from './generateLiveVideo/adapter'
26
28
 
27
29
  // ===========================
28
30
  // Chat Activity
@@ -210,6 +212,44 @@ export {
210
212
  type AnyEmbeddingAdapter,
211
213
  } from './embed/adapter'
212
214
 
215
+ // ===========================
216
+ // World Activity (Experimental)
217
+ // ===========================
218
+
219
+ export {
220
+ kind as worldKind,
221
+ generateWorld,
222
+ type WorldActivityOptions,
223
+ type WorldActivityResult,
224
+ type WorldProviderOptions,
225
+ } from './generateWorld/index'
226
+
227
+ export {
228
+ BaseWorldAdapter,
229
+ type WorldAdapter,
230
+ type WorldAdapterConfig,
231
+ type AnyWorldAdapter,
232
+ } from './generateWorld/adapter'
233
+
234
+ // ===========================
235
+ // Live Activity (Experimental)
236
+ // ===========================
237
+
238
+ export {
239
+ kind as liveVideoKind,
240
+ generateLiveVideo,
241
+ type LiveVideoActivityOptions,
242
+ type LiveVideoActivityResult,
243
+ type LiveVideoProviderOptions,
244
+ } from './generateLiveVideo/index'
245
+
246
+ export {
247
+ BaseLiveVideoAdapter,
248
+ type LiveVideoAdapter,
249
+ type LiveVideoAdapterConfig,
250
+ type AnyLiveVideoAdapter,
251
+ } from './generateLiveVideo/adapter'
252
+
213
253
  // ===========================
214
254
  // Adapter Union Types
215
255
  // ===========================
@@ -225,6 +265,8 @@ export type AIAdapter =
225
265
  | AnyTranscriptionAdapter
226
266
  | AnyEmbeddingAdapter
227
267
  | AnyRerankAdapter
268
+ | AnyWorldAdapter
269
+ | AnyLiveVideoAdapter
228
270
 
229
271
  /** Union type of all adapter kinds */
230
272
  export type AdapterKind =
@@ -237,3 +279,5 @@ export type AdapterKind =
237
279
  | 'transcription'
238
280
  | 'embedding'
239
281
  | 'rerank'
282
+ | 'world'
283
+ | 'liveVideo'
@@ -44,6 +44,8 @@ export type GenerationActivity =
44
44
  | 'embedding'
45
45
  | 'rerank'
46
46
  | 'summarize'
47
+ | 'world'
48
+ | 'liveVideo'
47
49
 
48
50
  /**
49
51
  * Stable context passed to every {@link GenerationMiddleware} hook. Created
@@ -95,6 +95,8 @@ const MAX_TOKENS_KEY_BY_ADAPTER: Record<string, string> = {
95
95
  // LLM Gateway exposes an OpenAI-compatible Chat Completions surface whose
96
96
  // only output cap is `max_tokens` — it does not read `max_completion_tokens`.
97
97
  llmgateway: 'max_tokens',
98
+ // Workers AI's OpenAI-compatible Chat Completions surface reads `max_tokens`.
99
+ cloudflare: 'max_tokens',
98
100
  }
99
101
 
100
102
  /**
@@ -12,6 +12,11 @@ export interface ByokProvider<TId extends string = string> {
12
12
  * values here. This object is imported on the client.
13
13
  */
14
14
  readonly env?: ReadonlyArray<string>
15
+ /**
16
+ * Other descriptors this credential needs. A send for this provider also
17
+ * carries their headers and prompts for each one that is missing.
18
+ */
19
+ readonly with?: ReadonlyArray<ByokProvider>
15
20
  }
16
21
 
17
22
  /**
@@ -22,6 +27,7 @@ export type ByokProviderInit<TId extends string> = {
22
27
  readonly id: undefined extends TId ? never : TId
23
28
  readonly label: string
24
29
  readonly env?: string | ReadonlyArray<string>
30
+ readonly with?: ReadonlyArray<ByokProvider>
25
31
  }
26
32
 
27
33
  function normalizeEnv(
@@ -42,5 +48,6 @@ export function defineByokProvider<const TId extends string>(
42
48
  id: provider.id,
43
49
  label: provider.label,
44
50
  ...(env ? { env } : {}),
51
+ ...(provider.with ? { with: provider.with } : {}),
45
52
  }
46
53
  }
@@ -25,3 +25,21 @@ export function getByokKey(
25
25
  }
26
26
  return null
27
27
  }
28
+
29
+ /**
30
+ * Read several keys at once, one per name. Same rules as {@link getByokKey}
31
+ * for each entry. Use it for a credential made of more than one value.
32
+ */
33
+ export function getByokKeys<
34
+ const TProviders extends Record<string, ProviderId | ByokProvider>,
35
+ >(
36
+ request: Request,
37
+ providers: TProviders,
38
+ ): { [K in keyof TProviders]: string | null } {
39
+ return Object.fromEntries(
40
+ Object.entries(providers).map(([name, provider]) => [
41
+ name,
42
+ getByokKey(request, provider),
43
+ ]),
44
+ ) as { [K in keyof TProviders]: string | null }
45
+ }
@@ -1,3 +1,3 @@
1
- export { getByokKey } from './get-key'
1
+ export { getByokKey, getByokKeys } from './get-key'
2
2
  export { byokMissing, isByokMissingBody } from './missing'
3
3
  export type { ByokMissingBody } from './missing'
package/src/client.ts CHANGED
@@ -4,6 +4,8 @@ import type {
4
4
  TTSOptions,
5
5
  TranscriptionOptions,
6
6
  VideoGenerationOptions,
7
+ WorldGenerationOptions,
8
+ LiveVideoGenerationOptions,
7
9
  } from './types'
8
10
 
9
11
  export type GenerationKind =
@@ -12,6 +14,8 @@ export type GenerationKind =
12
14
  | 'tts'
13
15
  | 'video'
14
16
  | 'transcription'
17
+ | 'world'
18
+ | 'liveVideo'
15
19
 
16
20
  type GenerationInputByKind = {
17
21
  image: Omit<ImageGenerationOptions, 'logger' | 'model'>
@@ -19,6 +23,8 @@ type GenerationInputByKind = {
19
23
  tts: Omit<TTSOptions, 'logger' | 'model'>
20
24
  video: Omit<VideoGenerationOptions, 'logger' | 'model'>
21
25
  transcription: Omit<TranscriptionOptions, 'logger' | 'model'>
26
+ world: Omit<WorldGenerationOptions, 'logger' | 'model'>
27
+ liveVideo: Omit<LiveVideoGenerationOptions, 'logger' | 'model'>
22
28
  }
23
29
 
24
30
  export interface GenerationParams<TKind extends GenerationKind> {
@@ -34,6 +40,8 @@ const generationKinds = [
34
40
  'tts',
35
41
  'video',
36
42
  'transcription',
43
+ 'world',
44
+ 'liveVideo',
37
45
  ] as const satisfies ReadonlyArray<GenerationKind>
38
46
 
39
47
  function isRecord(value: unknown): value is Record<string, unknown> {
package/src/index.ts CHANGED
@@ -10,6 +10,8 @@ export {
10
10
  generateSpeech,
11
11
  generateTranscription,
12
12
  embed,
13
+ generateWorld,
14
+ generateLiveVideo,
13
15
  } from './activities/index'
14
16
 
15
17
  // Create options functions - for pre-defining typed configurations
@@ -22,6 +24,8 @@ export { createVideoOptions } from './activities/generateVideo/index'
22
24
  export { createSpeechOptions } from './activities/generateSpeech/index'
23
25
  export { createTranscriptionOptions } from './activities/generateTranscription/index'
24
26
  export { createEmbedOptions } from './activities/embed/index'
27
+ export { createWorldOptions } from './activities/generateWorld/index'
28
+ export { createLiveVideoOptions } from './activities/generateLiveVideo/index'
25
29
 
26
30
  // Re-export types
27
31
  export type {
@@ -44,6 +48,10 @@ export type {
44
48
  EmbeddingAdapter,
45
49
  AnyRerankAdapter,
46
50
  RerankAdapter,
51
+ AnyWorldAdapter,
52
+ WorldAdapter,
53
+ AnyLiveVideoAdapter,
54
+ LiveVideoAdapter,
47
55
  } from './activities/index'
48
56
 
49
57
  // Rerank adapter base + types
@@ -91,6 +91,8 @@ const OPERATION_NAME: Record<GenerationActivity, string> = {
91
91
  embedding: 'embeddings',
92
92
  rerank: 'rerank',
93
93
  summarize: 'summarize',
94
+ world: 'world_generation',
95
+ liveVideo: 'live_video_generation',
94
96
  }
95
97
 
96
98
  export interface OtelMiddlewareOptions {
package/src/types.ts CHANGED
@@ -2218,6 +2218,134 @@ export interface VideoUrlResult {
2218
2218
  artifacts?: Array<PersistedArtifactRef>
2219
2219
  }
2220
2220
 
2221
+ // ============================================================================
2222
+ // World Generation Types (Experimental)
2223
+ // ============================================================================
2224
+
2225
+ /**
2226
+ * Options for world generation (live, prompt-steerable sessions).
2227
+ *
2228
+ * @experimental World generation is an experimental feature and may change.
2229
+ */
2230
+ export interface WorldGenerationOptions<
2231
+ TProviderOptions extends object = object,
2232
+ > {
2233
+ /** The model to use for world generation */
2234
+ model: string
2235
+ /** Natural-language description of the world or scene */
2236
+ prompt: string
2237
+ /**
2238
+ * Provider mint options. Reactor resolution/seed/audio are browser
2239
+ * `sendCommand` fields, not token-mint fields.
2240
+ */
2241
+ modelOptions?: TProviderOptions
2242
+ /**
2243
+ * Internal logger threaded from the generateWorld() entry point. Adapters
2244
+ * must call logger.request() before the SDK call and logger.errors() in
2245
+ * catch blocks.
2246
+ */
2247
+ logger: InternalLogger
2248
+ /**
2249
+ * Effective abort signal composed by the activity from caller `abortSignal`
2250
+ * and/or `timeout`. Adapters should forward this to the provider SDK when
2251
+ * supported. Request-specific — never store on a global client config.
2252
+ */
2253
+ abortSignal?: AbortSignal
2254
+ }
2255
+
2256
+ /**
2257
+ * Result of world generation. JSON-serializable so a server route can return
2258
+ * it to a browser. The browser uses `token` + `model` to open the live
2259
+ * session (set the prompt, start streaming, steer mid-run).
2260
+ *
2261
+ * @experimental World generation is an experimental feature and may change.
2262
+ */
2263
+ export interface WorldGenerationResult {
2264
+ /** Unique identifier for this generation */
2265
+ id: string
2266
+ /** Model used for generation (provider connect slug) */
2267
+ model: string
2268
+ /** Short-lived session token for the client connection */
2269
+ token: string
2270
+ /** Token expiry as milliseconds since epoch */
2271
+ expiresAt: number
2272
+ /** Prompt the client should send when it starts the session */
2273
+ prompt: string
2274
+ /** Session status after the server half finishes */
2275
+ status: 'ready' | 'waiting'
2276
+ /** Provider session id, when the adapter created one */
2277
+ sessionId?: string
2278
+ /** Token usage / billing, when the adapter can report it */
2279
+ usage?: TokenUsage
2280
+ }
2281
+
2282
+ // ============================================================================
2283
+ // Live Generation Types (Experimental)
2284
+ // ============================================================================
2285
+
2286
+ /**
2287
+ * Options for live generation (prompt-steerable video sessions).
2288
+ *
2289
+ * @experimental Live generation is an experimental feature and may change.
2290
+ */
2291
+ export interface LiveVideoGenerationOptions<
2292
+ TProviderOptions extends object = object,
2293
+ > {
2294
+ /** The model to use for live generation */
2295
+ model: string
2296
+ /** Natural-language description of the shot or scene */
2297
+ prompt: string
2298
+ /**
2299
+ * Provider mint options. For fal live this is `tokenDuration`. Reactor
2300
+ * resolution/seed/audio are browser `sendCommand` fields.
2301
+ */
2302
+ modelOptions?: TProviderOptions
2303
+ /**
2304
+ * Internal logger threaded from the generateLiveVideo() entry point. Adapters
2305
+ * must call logger.request() before the SDK call and logger.errors() in
2306
+ * catch blocks.
2307
+ */
2308
+ logger: InternalLogger
2309
+ /**
2310
+ * Effective abort signal composed by the activity from caller `abortSignal`
2311
+ * and/or `timeout`. Adapters should forward this to the provider SDK when
2312
+ * supported. Request-specific — never store on a global client config.
2313
+ */
2314
+ abortSignal?: AbortSignal
2315
+ }
2316
+
2317
+ /**
2318
+ * Result of live generation. JSON-serializable so a server route can return
2319
+ * it to a browser.
2320
+ *
2321
+ * Reactor: connect with `token` and `model` (the connect slug).
2322
+ * fal: `model` is the WMA app id. Open `wma(model)` through a server proxy
2323
+ * that attaches `FAL_KEY`. Do not send `token` as Key credentials.
2324
+ *
2325
+ * @experimental Live generation is an experimental feature and may change.
2326
+ */
2327
+ export interface LiveVideoGenerationResult {
2328
+ /** Unique identifier for this generation */
2329
+ id: string
2330
+ /**
2331
+ * Connect id for the browser client. Reactor: `reactor/helios`.
2332
+ * fal: WMA app id `fal-ai/minimax-h3-max-director`.
2333
+ */
2334
+ model: string
2335
+ /** Short-lived session token. Reactor uses this to connect. fal does not. */
2336
+ token: string
2337
+ /** Token expiry as milliseconds since epoch */
2338
+ expiresAt: number
2339
+ /** Prompt the client should send when it starts the session */
2340
+ prompt: string
2341
+ /** Session status after the server half finishes */
2342
+ status: 'ready' | 'waiting'
2343
+ /** Provider session id, when the adapter created one */
2344
+ sessionId?: string
2345
+ /** Token usage / billing, when the adapter can report it */
2346
+ usage?: TokenUsage
2347
+ }
2348
+
2221
2349
  // ============================================================================
2222
2350
  // Text-to-Speech (TTS) Types
2223
2351
  // ============================================================================