@tanstack/ai-svelte 0.15.1 → 0.16.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +17 -0
- package/dist/create-chat.svelte.js +119 -12
- package/dist/create-generate-audio.svelte.d.ts +9 -12
- package/dist/create-generate-audio.svelte.js +6 -0
- package/dist/create-generate-image.svelte.d.ts +9 -12
- package/dist/create-generate-image.svelte.js +6 -0
- package/dist/create-generate-speech.svelte.d.ts +9 -12
- package/dist/create-generate-speech.svelte.js +6 -0
- package/dist/create-generate-video.svelte.d.ts +50 -4
- package/dist/create-generate-video.svelte.js +63 -8
- package/dist/create-generation.svelte.d.ts +59 -6
- package/dist/create-generation.svelte.js +55 -6
- package/dist/create-summarize.svelte.d.ts +9 -12
- package/dist/create-summarize.svelte.js +6 -0
- package/dist/create-transcription.svelte.d.ts +9 -12
- package/dist/create-transcription.svelte.js +6 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/types.d.ts +29 -3
- package/package.json +7 -7
- package/src/create-chat.svelte.ts +134 -14
- package/src/create-generate-audio.svelte.ts +29 -12
- package/src/create-generate-image.svelte.ts +29 -12
- package/src/create-generate-speech.svelte.ts +28 -12
- package/src/create-generate-video.svelte.ts +104 -12
- package/src/create-generation.svelte.ts +115 -13
- package/src/create-summarize.svelte.ts +29 -12
- package/src/create-transcription.svelte.ts +33 -14
- package/src/index.ts +10 -0
- package/src/types.ts +44 -0
|
@@ -1,7 +1,11 @@
|
|
|
1
1
|
import { ChatClient } from '@tanstack/ai-client'
|
|
2
2
|
import { createChatDevtoolsBridge } from '@tanstack/ai-client/devtools'
|
|
3
|
+
import { onMount } from 'svelte'
|
|
3
4
|
import type {
|
|
4
5
|
ChatClientState,
|
|
6
|
+
ChatInterrupt,
|
|
7
|
+
ChatInterruptState,
|
|
8
|
+
ChatResumeState,
|
|
5
9
|
ConnectionStatus,
|
|
6
10
|
InferredClientContext,
|
|
7
11
|
QueuedMessage,
|
|
@@ -12,6 +16,7 @@ import type {
|
|
|
12
16
|
AnyClientTool,
|
|
13
17
|
InferSchemaType,
|
|
14
18
|
ModelMessage,
|
|
19
|
+
RunAgentResumeItem,
|
|
15
20
|
SchemaInput,
|
|
16
21
|
StreamChunk,
|
|
17
22
|
} from '@tanstack/ai'
|
|
@@ -23,6 +28,9 @@ import type {
|
|
|
23
28
|
UIMessage,
|
|
24
29
|
} from './types'
|
|
25
30
|
|
|
31
|
+
const EMPTY_INTERRUPTS = Object.freeze([])
|
|
32
|
+
const EMPTY_INTERRUPT_ERRORS = Object.freeze([])
|
|
33
|
+
|
|
26
34
|
/**
|
|
27
35
|
* Creates a reactive chat instance for Svelte 5.
|
|
28
36
|
*
|
|
@@ -60,11 +68,6 @@ export function createChat<
|
|
|
60
68
|
>(
|
|
61
69
|
options: CreateChatOptions<TTools, TSchema, TContext>,
|
|
62
70
|
): CreateChatReturn<TTools, TSchema, TContext> {
|
|
63
|
-
// Generate a unique ID for this chat instance
|
|
64
|
-
const clientId =
|
|
65
|
-
options.id ||
|
|
66
|
-
`chat-${Date.now()}-${Math.random().toString(36).substring(7)}`
|
|
67
|
-
|
|
68
71
|
// Create reactive state using Svelte 5 runes
|
|
69
72
|
let messages = $state<Array<UIMessage<TTools>>>(options.initialMessages || [])
|
|
70
73
|
let isLoading = $state(false)
|
|
@@ -74,6 +77,13 @@ export function createChat<
|
|
|
74
77
|
let connectionStatus = $state<ConnectionStatus>('disconnected')
|
|
75
78
|
let sessionGenerating = $state(false)
|
|
76
79
|
let queue = $state<Array<QueuedMessage>>([])
|
|
80
|
+
let runId = $state<string | null>(null)
|
|
81
|
+
let interruptState = $state.raw<ChatInterruptState<TTools>>({
|
|
82
|
+
interrupts: EMPTY_INTERRUPTS,
|
|
83
|
+
pendingInterrupts: EMPTY_INTERRUPTS,
|
|
84
|
+
interruptErrors: EMPTY_INTERRUPT_ERRORS,
|
|
85
|
+
resuming: false,
|
|
86
|
+
})
|
|
77
87
|
|
|
78
88
|
// Structured-output `partial` / `final` are derived from `messages` —
|
|
79
89
|
// specifically from the structured-output part on the latest assistant
|
|
@@ -96,16 +106,21 @@ export function createChat<
|
|
|
96
106
|
? { connection: options.connection }
|
|
97
107
|
: { fetcher: options.fetcher }
|
|
98
108
|
|
|
109
|
+
// The hook's identity is its `threadId`, which ChatClient also uses as the
|
|
110
|
+
// persistence key — no separate `id`. When no `threadId` is given the client
|
|
111
|
+
// generates one, so an ephemeral chat still works but is not restored on reload.
|
|
99
112
|
const client = new ChatClient<TTools, TContext>({
|
|
100
113
|
devtoolsBridgeFactory: createChatDevtoolsBridge,
|
|
101
114
|
...transport,
|
|
102
|
-
id: clientId,
|
|
103
115
|
...(options.initialMessages !== undefined && {
|
|
104
116
|
initialMessages: options.initialMessages,
|
|
105
117
|
}),
|
|
106
118
|
...(options.persistence !== undefined && {
|
|
107
119
|
persistence: options.persistence,
|
|
108
120
|
}),
|
|
121
|
+
...(options.initialResumeSnapshot !== undefined && {
|
|
122
|
+
initialResumeSnapshot: options.initialResumeSnapshot,
|
|
123
|
+
}),
|
|
109
124
|
...(options.body !== undefined && { body: options.body }),
|
|
110
125
|
...(options.threadId !== undefined && { threadId: options.threadId }),
|
|
111
126
|
...(options.forwardedProps !== undefined && {
|
|
@@ -140,6 +155,7 @@ export function createChat<
|
|
|
140
155
|
},
|
|
141
156
|
onLoadingChange: (newIsLoading: boolean) => {
|
|
142
157
|
isLoading = newIsLoading
|
|
158
|
+
syncResumeState()
|
|
143
159
|
},
|
|
144
160
|
onStatusChange: (newStatus: ChatClientState) => {
|
|
145
161
|
status = newStatus
|
|
@@ -160,9 +176,22 @@ export function createChat<
|
|
|
160
176
|
onQueueChange: (nextQueue: Array<QueuedMessage>) => {
|
|
161
177
|
queue = nextQueue
|
|
162
178
|
},
|
|
179
|
+
onRunIdChange: (nextRunId) => {
|
|
180
|
+
runId = nextRunId
|
|
181
|
+
},
|
|
182
|
+
onInterruptStateChange: (nextInterruptState) => {
|
|
183
|
+
interruptState = nextInterruptState
|
|
184
|
+
options.onInterruptStateChange?.(nextInterruptState)
|
|
185
|
+
},
|
|
163
186
|
})
|
|
164
187
|
|
|
188
|
+
function syncResumeState() {
|
|
189
|
+
runId = client.getCurrentRunId()
|
|
190
|
+
interruptState = client.getInterruptState()
|
|
191
|
+
}
|
|
192
|
+
|
|
165
193
|
messages = client.getMessages()
|
|
194
|
+
interruptState = client.getInterruptState()
|
|
166
195
|
|
|
167
196
|
if (options.live) {
|
|
168
197
|
client.subscribe()
|
|
@@ -170,27 +199,64 @@ export function createChat<
|
|
|
170
199
|
|
|
171
200
|
client.mountDevtools()
|
|
172
201
|
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
202
|
+
if (typeof window !== 'undefined') {
|
|
203
|
+
try {
|
|
204
|
+
onMount(() => {
|
|
205
|
+
// Delivery-durability resume is transparent: the resumable SSE
|
|
206
|
+
// connection adapter reattaches via the browser's native
|
|
207
|
+
// Last-Event-ID on reconnect. We only seed interrupt (state) resume.
|
|
208
|
+
syncResumeState()
|
|
209
|
+
client.attach()
|
|
210
|
+
// ONLY THE VIEW ON SCREEN HOLDS A STREAM. `onMount`'s returned function
|
|
211
|
+
// runs when the component is destroyed, which is the one automatic
|
|
212
|
+
// teardown Svelte gives us here — and it is enough, because a connection
|
|
213
|
+
// is all that must go. A page can own many chats and a browser allows
|
|
214
|
+
// only ~6 connections per origin, so one long-lived stream per chat
|
|
215
|
+
// starves every other request once a few views have been open.
|
|
216
|
+
//
|
|
217
|
+
// `detach` keeps the transcript and the resume pointer, so re-entering
|
|
218
|
+
// the view picks the run back up from the durable log.
|
|
219
|
+
return () => {
|
|
220
|
+
client.detach()
|
|
221
|
+
}
|
|
222
|
+
})
|
|
223
|
+
} catch {
|
|
224
|
+
// Svelte lifecycle hooks are only valid during component initialization.
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
// Note: `dispose()` remains manual — it releases devtools and marks the client
|
|
229
|
+
// dead, which only the owner can decide. The CONNECTION is released
|
|
230
|
+
// automatically by the `onMount` teardown above.
|
|
177
231
|
|
|
178
232
|
// Define methods
|
|
179
233
|
const sendMessage = async (
|
|
180
234
|
content: string | MultimodalContent,
|
|
181
235
|
sendOptions?: SendMessageOptions,
|
|
182
236
|
) => {
|
|
183
|
-
|
|
237
|
+
try {
|
|
238
|
+
await client.sendMessage(content, undefined, sendOptions)
|
|
239
|
+
} finally {
|
|
240
|
+
syncResumeState()
|
|
241
|
+
}
|
|
184
242
|
}
|
|
185
243
|
|
|
186
244
|
const cancelQueued = (id: string) => client.cancelQueued(id)
|
|
187
245
|
|
|
188
246
|
const append = async (message: ModelMessage | UIMessage<TTools>) => {
|
|
189
|
-
|
|
247
|
+
try {
|
|
248
|
+
await client.append(message)
|
|
249
|
+
} finally {
|
|
250
|
+
syncResumeState()
|
|
251
|
+
}
|
|
190
252
|
}
|
|
191
253
|
|
|
192
254
|
const reload = async () => {
|
|
193
|
-
|
|
255
|
+
try {
|
|
256
|
+
await client.reload()
|
|
257
|
+
} finally {
|
|
258
|
+
syncResumeState()
|
|
259
|
+
}
|
|
194
260
|
}
|
|
195
261
|
|
|
196
262
|
const stop = () => {
|
|
@@ -203,6 +269,7 @@ export function createChat<
|
|
|
203
269
|
|
|
204
270
|
const clear = () => {
|
|
205
271
|
client.clear()
|
|
272
|
+
syncResumeState()
|
|
206
273
|
}
|
|
207
274
|
|
|
208
275
|
const setMessages = (newMessages: Array<UIMessage<TTools>>) => {
|
|
@@ -224,8 +291,41 @@ export function createChat<
|
|
|
224
291
|
approved: boolean
|
|
225
292
|
}) => {
|
|
226
293
|
await client.addToolApprovalResponse(response)
|
|
294
|
+
syncResumeState()
|
|
227
295
|
}
|
|
228
296
|
|
|
297
|
+
const resumeInterrupts = async (
|
|
298
|
+
resumeItems: Array<RunAgentResumeItem>,
|
|
299
|
+
state?: ChatResumeState,
|
|
300
|
+
) => {
|
|
301
|
+
const result = await client.resumeInterrupts(resumeItems, state)
|
|
302
|
+
syncResumeState()
|
|
303
|
+
return result
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
const resolveInterrupts = (
|
|
307
|
+
resolution: boolean | ((interrupt: ChatInterrupt<TTools>) => undefined),
|
|
308
|
+
) => {
|
|
309
|
+
if (typeof resolution === 'boolean') {
|
|
310
|
+
client.resolveInterrupts(resolution)
|
|
311
|
+
} else {
|
|
312
|
+
client.resolveInterrupts(resolution)
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
const cancelInterrupts = () => {
|
|
317
|
+
client.cancelInterrupts()
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
const retryInterrupts = () => {
|
|
321
|
+
client.retryInterrupts()
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
const resumeInterruptsUnsafe = (
|
|
325
|
+
resumeItems: Array<RunAgentResumeItem>,
|
|
326
|
+
state?: ChatResumeState,
|
|
327
|
+
) => client.resumeInterruptsUnsafe(resumeItems, state)
|
|
328
|
+
|
|
229
329
|
/**
|
|
230
330
|
* @deprecated Use `updateForwardedProps` instead.
|
|
231
331
|
* Both populate the same wire payload.
|
|
@@ -282,7 +382,7 @@ export function createChat<
|
|
|
282
382
|
|
|
283
383
|
// Return the chat interface with reactive getters
|
|
284
384
|
// Using getters allows Svelte to track reactivity without needing $ prefix
|
|
285
|
-
//
|
|
385
|
+
// oxlint-disable-next-line eslint-js/no-restricted-syntax -- rune return shape diverges from generic CreateChatReturn<TTools, TSchema, TContext> due to TSchema conditional partial/final fields; TS can't structurally narrow.
|
|
286
386
|
return {
|
|
287
387
|
get messages() {
|
|
288
388
|
return messages
|
|
@@ -308,6 +408,21 @@ export function createChat<
|
|
|
308
408
|
get queue() {
|
|
309
409
|
return queue
|
|
310
410
|
},
|
|
411
|
+
get runId() {
|
|
412
|
+
return runId
|
|
413
|
+
},
|
|
414
|
+
get interrupts() {
|
|
415
|
+
return interruptState.interrupts
|
|
416
|
+
},
|
|
417
|
+
get pendingInterrupts() {
|
|
418
|
+
return interruptState.interrupts
|
|
419
|
+
},
|
|
420
|
+
get interruptErrors() {
|
|
421
|
+
return interruptState.interruptErrors
|
|
422
|
+
},
|
|
423
|
+
get resuming() {
|
|
424
|
+
return interruptState.resuming
|
|
425
|
+
},
|
|
311
426
|
get partial() {
|
|
312
427
|
return partial
|
|
313
428
|
},
|
|
@@ -324,6 +439,11 @@ export function createChat<
|
|
|
324
439
|
clear,
|
|
325
440
|
addToolResult,
|
|
326
441
|
addToolApprovalResponse,
|
|
442
|
+
resolveInterrupts,
|
|
443
|
+
cancelInterrupts,
|
|
444
|
+
retryInterrupts,
|
|
445
|
+
resumeInterruptsUnsafe,
|
|
446
|
+
resumeInterrupts,
|
|
327
447
|
updateBody,
|
|
328
448
|
updateForwardedProps,
|
|
329
449
|
updateContext,
|
|
@@ -1,4 +1,9 @@
|
|
|
1
1
|
import { createGeneration } from './create-generation.svelte'
|
|
2
|
+
import { reconstructAudioResult } from '@tanstack/ai-client'
|
|
3
|
+
import type {
|
|
4
|
+
CreateGenerationOptions,
|
|
5
|
+
CreateGenerationReturn,
|
|
6
|
+
} from './create-generation.svelte'
|
|
2
7
|
import type { AudioGenerationResult, StreamChunk } from '@tanstack/ai'
|
|
3
8
|
import type {
|
|
4
9
|
AIDevtoolsDisplayOptions,
|
|
@@ -6,6 +11,7 @@ import type {
|
|
|
6
11
|
ConnectConnectionAdapter,
|
|
7
12
|
GenerationClientState,
|
|
8
13
|
GenerationFetcher,
|
|
14
|
+
GenerationPersistenceOptions,
|
|
9
15
|
InferGenerationOutputFromReturn,
|
|
10
16
|
} from '@tanstack/ai-client'
|
|
11
17
|
|
|
@@ -14,12 +20,19 @@ import type {
|
|
|
14
20
|
*
|
|
15
21
|
* @template TOutput - The output type after optional transform (defaults to AudioGenerationResult)
|
|
16
22
|
*/
|
|
17
|
-
export interface CreateGenerateAudioOptions<
|
|
23
|
+
export interface CreateGenerateAudioOptions<
|
|
24
|
+
TOutput = AudioGenerationResult,
|
|
25
|
+
> extends Pick<
|
|
26
|
+
CreateGenerationOptions<AudioGenerateInput, AudioGenerationResult, TOutput>,
|
|
27
|
+
'persistence' | 'threadId' | 'hydrateGeneration' | 'joinRun'
|
|
28
|
+
> {
|
|
18
29
|
/** Connect-based adapter for streaming transport (SSE, HTTP stream, custom) */
|
|
19
30
|
connection?: ConnectConnectionAdapter
|
|
20
31
|
/** Direct async function for audio generation */
|
|
21
32
|
fetcher?: GenerationFetcher<AudioGenerateInput, AudioGenerationResult>
|
|
22
|
-
/**
|
|
33
|
+
/**
|
|
34
|
+
* @deprecated Prefer `threadId`. Only allowed when `threadId` is omitted (see `GenerationPersistenceOptions`).
|
|
35
|
+
*/
|
|
23
36
|
id?: string
|
|
24
37
|
/** Additional body parameters to send with connect-based adapter requests */
|
|
25
38
|
body?: Record<string, any>
|
|
@@ -46,7 +59,9 @@ export interface CreateGenerateAudioOptions<TOutput = AudioGenerationResult> {
|
|
|
46
59
|
*
|
|
47
60
|
* @template TOutput - The output type (after optional transform)
|
|
48
61
|
*/
|
|
49
|
-
export interface CreateGenerateAudioReturn<
|
|
62
|
+
export interface CreateGenerateAudioReturn<
|
|
63
|
+
TOutput = AudioGenerationResult,
|
|
64
|
+
> extends Omit<CreateGenerationReturn<TOutput>, 'generate'> {
|
|
50
65
|
/** The generation result containing audio, or null */
|
|
51
66
|
readonly result: TOutput | null
|
|
52
67
|
/** Whether generation is in progress */
|
|
@@ -57,12 +72,6 @@ export interface CreateGenerateAudioReturn<TOutput = AudioGenerationResult> {
|
|
|
57
72
|
readonly status: GenerationClientState
|
|
58
73
|
/** Trigger audio generation */
|
|
59
74
|
generate: (input: AudioGenerateInput) => Promise<void>
|
|
60
|
-
/** Abort the current generation */
|
|
61
|
-
stop: () => void
|
|
62
|
-
/** Clear result, error, and return to idle */
|
|
63
|
-
reset: () => void
|
|
64
|
-
/** Update additional body parameters */
|
|
65
|
-
updateBody: (body: Record<string, any>) => void
|
|
66
75
|
}
|
|
67
76
|
|
|
68
77
|
/**
|
|
@@ -92,9 +101,12 @@ export interface CreateGenerateAudioReturn<TOutput = AudioGenerationResult> {
|
|
|
92
101
|
* ```
|
|
93
102
|
*/
|
|
94
103
|
export function createGenerateAudio<TTransformed = void>(
|
|
95
|
-
options: Omit<
|
|
104
|
+
options: Omit<
|
|
105
|
+
CreateGenerateAudioOptions,
|
|
106
|
+
'onResult' | 'persistence' | 'threadId' | 'id'
|
|
107
|
+
> & {
|
|
96
108
|
onResult?: (result: AudioGenerationResult) => TTransformed
|
|
97
|
-
},
|
|
109
|
+
} & GenerationPersistenceOptions,
|
|
98
110
|
): CreateGenerateAudioReturn<
|
|
99
111
|
InferGenerationOutputFromReturn<AudioGenerationResult, TTransformed>
|
|
100
112
|
> {
|
|
@@ -111,6 +123,7 @@ export function createGenerateAudio<TTransformed = void>(
|
|
|
111
123
|
>({
|
|
112
124
|
...options,
|
|
113
125
|
devtools,
|
|
126
|
+
reconstructResult: reconstructAudioResult,
|
|
114
127
|
})
|
|
115
128
|
|
|
116
129
|
return {
|
|
@@ -126,9 +139,13 @@ export function createGenerateAudio<TTransformed = void>(
|
|
|
126
139
|
get status() {
|
|
127
140
|
return gen.status
|
|
128
141
|
},
|
|
129
|
-
generate: gen.generate
|
|
142
|
+
generate: gen.generate,
|
|
130
143
|
stop: gen.stop,
|
|
131
144
|
reset: gen.reset,
|
|
132
145
|
updateBody: gen.updateBody,
|
|
146
|
+
dispose: gen.dispose,
|
|
147
|
+
get runId() {
|
|
148
|
+
return gen.runId
|
|
149
|
+
},
|
|
133
150
|
}
|
|
134
151
|
}
|
|
@@ -1,10 +1,16 @@
|
|
|
1
1
|
import { createGeneration } from './create-generation.svelte'
|
|
2
|
+
import { reconstructImageResult } from '@tanstack/ai-client'
|
|
3
|
+
import type {
|
|
4
|
+
CreateGenerationOptions,
|
|
5
|
+
CreateGenerationReturn,
|
|
6
|
+
} from './create-generation.svelte'
|
|
2
7
|
import type { ImageGenerationResult, StreamChunk } from '@tanstack/ai'
|
|
3
8
|
import type {
|
|
4
9
|
AIDevtoolsDisplayOptions,
|
|
5
10
|
ConnectConnectionAdapter,
|
|
6
11
|
GenerationClientState,
|
|
7
12
|
GenerationFetcher,
|
|
13
|
+
GenerationPersistenceOptions,
|
|
8
14
|
ImageGenerateInput,
|
|
9
15
|
InferGenerationOutputFromReturn,
|
|
10
16
|
} from '@tanstack/ai-client'
|
|
@@ -14,12 +20,19 @@ import type {
|
|
|
14
20
|
*
|
|
15
21
|
* @template TOutput - The output type after optional transform (defaults to ImageGenerationResult)
|
|
16
22
|
*/
|
|
17
|
-
export interface CreateGenerateImageOptions<
|
|
23
|
+
export interface CreateGenerateImageOptions<
|
|
24
|
+
TOutput = ImageGenerationResult,
|
|
25
|
+
> extends Pick<
|
|
26
|
+
CreateGenerationOptions<ImageGenerateInput, ImageGenerationResult, TOutput>,
|
|
27
|
+
'persistence' | 'threadId' | 'hydrateGeneration' | 'joinRun'
|
|
28
|
+
> {
|
|
18
29
|
/** Connect-based adapter for streaming transport (SSE, HTTP stream, custom) */
|
|
19
30
|
connection?: ConnectConnectionAdapter
|
|
20
31
|
/** Direct async function for image generation */
|
|
21
32
|
fetcher?: GenerationFetcher<ImageGenerateInput, ImageGenerationResult>
|
|
22
|
-
/**
|
|
33
|
+
/**
|
|
34
|
+
* @deprecated Prefer `threadId`. Only allowed when `threadId` is omitted (see `GenerationPersistenceOptions`).
|
|
35
|
+
*/
|
|
23
36
|
id?: string
|
|
24
37
|
/** Additional body parameters to send with connect-based adapter requests */
|
|
25
38
|
body?: Record<string, any>
|
|
@@ -46,7 +59,9 @@ export interface CreateGenerateImageOptions<TOutput = ImageGenerationResult> {
|
|
|
46
59
|
*
|
|
47
60
|
* @template TOutput - The output type (after optional transform)
|
|
48
61
|
*/
|
|
49
|
-
export interface CreateGenerateImageReturn<
|
|
62
|
+
export interface CreateGenerateImageReturn<
|
|
63
|
+
TOutput = ImageGenerationResult,
|
|
64
|
+
> extends Omit<CreateGenerationReturn<TOutput>, 'generate'> {
|
|
50
65
|
/** The generation result containing images, or null */
|
|
51
66
|
readonly result: TOutput | null
|
|
52
67
|
/** Whether generation is in progress */
|
|
@@ -57,12 +72,6 @@ export interface CreateGenerateImageReturn<TOutput = ImageGenerationResult> {
|
|
|
57
72
|
readonly status: GenerationClientState
|
|
58
73
|
/** Trigger image generation */
|
|
59
74
|
generate: (input: ImageGenerateInput) => Promise<void>
|
|
60
|
-
/** Abort the current generation */
|
|
61
|
-
stop: () => void
|
|
62
|
-
/** Clear result, error, and return to idle */
|
|
63
|
-
reset: () => void
|
|
64
|
-
/** Update additional body parameters */
|
|
65
|
-
updateBody: (body: Record<string, any>) => void
|
|
66
75
|
}
|
|
67
76
|
|
|
68
77
|
/**
|
|
@@ -101,9 +110,12 @@ export interface CreateGenerateImageReturn<TOutput = ImageGenerationResult> {
|
|
|
101
110
|
* ```
|
|
102
111
|
*/
|
|
103
112
|
export function createGenerateImage<TTransformed = void>(
|
|
104
|
-
options: Omit<
|
|
113
|
+
options: Omit<
|
|
114
|
+
CreateGenerateImageOptions,
|
|
115
|
+
'onResult' | 'persistence' | 'threadId' | 'id'
|
|
116
|
+
> & {
|
|
105
117
|
onResult?: (result: ImageGenerationResult) => TTransformed
|
|
106
|
-
},
|
|
118
|
+
} & GenerationPersistenceOptions,
|
|
107
119
|
): CreateGenerateImageReturn<
|
|
108
120
|
InferGenerationOutputFromReturn<ImageGenerationResult, TTransformed>
|
|
109
121
|
> {
|
|
@@ -120,6 +132,7 @@ export function createGenerateImage<TTransformed = void>(
|
|
|
120
132
|
>({
|
|
121
133
|
...options,
|
|
122
134
|
devtools,
|
|
135
|
+
reconstructResult: reconstructImageResult,
|
|
123
136
|
})
|
|
124
137
|
|
|
125
138
|
return {
|
|
@@ -135,9 +148,13 @@ export function createGenerateImage<TTransformed = void>(
|
|
|
135
148
|
get status() {
|
|
136
149
|
return gen.status
|
|
137
150
|
},
|
|
138
|
-
generate: gen.generate
|
|
151
|
+
generate: gen.generate,
|
|
139
152
|
stop: gen.stop,
|
|
140
153
|
reset: gen.reset,
|
|
141
154
|
updateBody: gen.updateBody,
|
|
155
|
+
dispose: gen.dispose,
|
|
156
|
+
get runId() {
|
|
157
|
+
return gen.runId
|
|
158
|
+
},
|
|
142
159
|
}
|
|
143
160
|
}
|
|
@@ -1,10 +1,16 @@
|
|
|
1
1
|
import { createGeneration } from './create-generation.svelte'
|
|
2
|
+
import { reconstructSpeechResult } from '@tanstack/ai-client'
|
|
3
|
+
import type {
|
|
4
|
+
CreateGenerationOptions,
|
|
5
|
+
CreateGenerationReturn,
|
|
6
|
+
} from './create-generation.svelte'
|
|
2
7
|
import type { StreamChunk, TTSResult } from '@tanstack/ai'
|
|
3
8
|
import type {
|
|
4
9
|
AIDevtoolsDisplayOptions,
|
|
5
10
|
ConnectConnectionAdapter,
|
|
6
11
|
GenerationClientState,
|
|
7
12
|
GenerationFetcher,
|
|
13
|
+
GenerationPersistenceOptions,
|
|
8
14
|
InferGenerationOutputFromReturn,
|
|
9
15
|
SpeechGenerateInput,
|
|
10
16
|
} from '@tanstack/ai-client'
|
|
@@ -14,12 +20,17 @@ import type {
|
|
|
14
20
|
*
|
|
15
21
|
* @template TOutput - The output type after optional transform (defaults to TTSResult)
|
|
16
22
|
*/
|
|
17
|
-
export interface CreateGenerateSpeechOptions<TOutput = TTSResult>
|
|
23
|
+
export interface CreateGenerateSpeechOptions<TOutput = TTSResult> extends Pick<
|
|
24
|
+
CreateGenerationOptions<SpeechGenerateInput, TTSResult, TOutput>,
|
|
25
|
+
'persistence' | 'threadId' | 'hydrateGeneration' | 'joinRun'
|
|
26
|
+
> {
|
|
18
27
|
/** Connect-based adapter for streaming transport (SSE, HTTP stream, custom) */
|
|
19
28
|
connection?: ConnectConnectionAdapter
|
|
20
29
|
/** Direct async function for speech generation */
|
|
21
30
|
fetcher?: GenerationFetcher<SpeechGenerateInput, TTSResult>
|
|
22
|
-
/**
|
|
31
|
+
/**
|
|
32
|
+
* @deprecated Prefer `threadId`. Only allowed when `threadId` is omitted (see `GenerationPersistenceOptions`).
|
|
33
|
+
*/
|
|
23
34
|
id?: string
|
|
24
35
|
/** Additional body parameters to send with connect-based adapter requests */
|
|
25
36
|
body?: Record<string, any>
|
|
@@ -46,7 +57,10 @@ export interface CreateGenerateSpeechOptions<TOutput = TTSResult> {
|
|
|
46
57
|
*
|
|
47
58
|
* @template TOutput - The output type (after optional transform)
|
|
48
59
|
*/
|
|
49
|
-
export interface CreateGenerateSpeechReturn<TOutput = TTSResult>
|
|
60
|
+
export interface CreateGenerateSpeechReturn<TOutput = TTSResult> extends Omit<
|
|
61
|
+
CreateGenerationReturn<TOutput>,
|
|
62
|
+
'generate'
|
|
63
|
+
> {
|
|
50
64
|
/** The TTS result containing audio data, or null */
|
|
51
65
|
readonly result: TOutput | null
|
|
52
66
|
/** Whether generation is in progress */
|
|
@@ -57,12 +71,6 @@ export interface CreateGenerateSpeechReturn<TOutput = TTSResult> {
|
|
|
57
71
|
readonly status: GenerationClientState
|
|
58
72
|
/** Trigger speech generation */
|
|
59
73
|
generate: (input: SpeechGenerateInput) => Promise<void>
|
|
60
|
-
/** Abort the current generation */
|
|
61
|
-
stop: () => void
|
|
62
|
-
/** Clear result, error, and return to idle */
|
|
63
|
-
reset: () => void
|
|
64
|
-
/** Update additional body parameters */
|
|
65
|
-
updateBody: (body: Record<string, any>) => void
|
|
66
74
|
}
|
|
67
75
|
|
|
68
76
|
/**
|
|
@@ -92,9 +100,12 @@ export interface CreateGenerateSpeechReturn<TOutput = TTSResult> {
|
|
|
92
100
|
* ```
|
|
93
101
|
*/
|
|
94
102
|
export function createGenerateSpeech<TTransformed = void>(
|
|
95
|
-
options: Omit<
|
|
103
|
+
options: Omit<
|
|
104
|
+
CreateGenerateSpeechOptions,
|
|
105
|
+
'onResult' | 'persistence' | 'threadId' | 'id'
|
|
106
|
+
> & {
|
|
96
107
|
onResult?: (result: TTSResult) => TTransformed
|
|
97
|
-
},
|
|
108
|
+
} & GenerationPersistenceOptions,
|
|
98
109
|
): CreateGenerateSpeechReturn<
|
|
99
110
|
InferGenerationOutputFromReturn<TTSResult, TTransformed>
|
|
100
111
|
> {
|
|
@@ -107,6 +118,7 @@ export function createGenerateSpeech<TTransformed = void>(
|
|
|
107
118
|
const gen = createGeneration<SpeechGenerateInput, TTSResult, TTransformed>({
|
|
108
119
|
...options,
|
|
109
120
|
devtools,
|
|
121
|
+
reconstructResult: reconstructSpeechResult,
|
|
110
122
|
})
|
|
111
123
|
|
|
112
124
|
return {
|
|
@@ -122,9 +134,13 @@ export function createGenerateSpeech<TTransformed = void>(
|
|
|
122
134
|
get status() {
|
|
123
135
|
return gen.status
|
|
124
136
|
},
|
|
125
|
-
generate: gen.generate
|
|
137
|
+
generate: gen.generate,
|
|
126
138
|
stop: gen.stop,
|
|
127
139
|
reset: gen.reset,
|
|
128
140
|
updateBody: gen.updateBody,
|
|
141
|
+
dispose: gen.dispose,
|
|
142
|
+
get runId() {
|
|
143
|
+
return gen.runId
|
|
144
|
+
},
|
|
129
145
|
}
|
|
130
146
|
}
|