@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
package/README.md
CHANGED
|
@@ -1,3 +1,20 @@
|
|
|
1
|
+
<div align="center">
|
|
2
|
+
<picture>
|
|
3
|
+
<source
|
|
4
|
+
media="(prefers-color-scheme: dark)"
|
|
5
|
+
srcset="https://tanstack.com/api/readme/ai.png?framework=svelte&theme=dark"
|
|
6
|
+
/>
|
|
7
|
+
<source
|
|
8
|
+
media="(prefers-color-scheme: light)"
|
|
9
|
+
srcset="https://tanstack.com/api/readme/ai.png?framework=svelte"
|
|
10
|
+
/>
|
|
11
|
+
<img
|
|
12
|
+
src="https://tanstack.com/api/readme/ai.png?framework=svelte"
|
|
13
|
+
alt="TanStack Svelte AI"
|
|
14
|
+
width="900"
|
|
15
|
+
/>
|
|
16
|
+
</picture>
|
|
17
|
+
</div>
|
|
1
18
|
# @tanstack/ai-svelte
|
|
2
19
|
|
|
3
20
|
Svelte bindings for TanStack AI.
|
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
import { ChatClient } from '@tanstack/ai-client';
|
|
2
2
|
import { createChatDevtoolsBridge } from '@tanstack/ai-client/devtools';
|
|
3
|
+
import { onMount } from 'svelte';
|
|
4
|
+
const EMPTY_INTERRUPTS = Object.freeze([]);
|
|
5
|
+
const EMPTY_INTERRUPT_ERRORS = Object.freeze([]);
|
|
3
6
|
/**
|
|
4
7
|
* Creates a reactive chat instance for Svelte 5.
|
|
5
8
|
*
|
|
@@ -31,9 +34,6 @@ import { createChatDevtoolsBridge } from '@tanstack/ai-client/devtools';
|
|
|
31
34
|
* ```
|
|
32
35
|
*/
|
|
33
36
|
export function createChat(options) {
|
|
34
|
-
// Generate a unique ID for this chat instance
|
|
35
|
-
const clientId = options.id ||
|
|
36
|
-
`chat-${Date.now()}-${Math.random().toString(36).substring(7)}`;
|
|
37
37
|
// Create reactive state using Svelte 5 runes
|
|
38
38
|
let messages = $state(options.initialMessages || []);
|
|
39
39
|
let isLoading = $state(false);
|
|
@@ -43,6 +43,13 @@ export function createChat(options) {
|
|
|
43
43
|
let connectionStatus = $state('disconnected');
|
|
44
44
|
let sessionGenerating = $state(false);
|
|
45
45
|
let queue = $state([]);
|
|
46
|
+
let runId = $state(null);
|
|
47
|
+
let interruptState = $state.raw({
|
|
48
|
+
interrupts: EMPTY_INTERRUPTS,
|
|
49
|
+
pendingInterrupts: EMPTY_INTERRUPTS,
|
|
50
|
+
interruptErrors: EMPTY_INTERRUPT_ERRORS,
|
|
51
|
+
resuming: false,
|
|
52
|
+
});
|
|
46
53
|
// Create ChatClient instance.
|
|
47
54
|
// Note: Svelte's createChat runs once per instance and `options` is captured
|
|
48
55
|
// by reference. Callbacks are therefore frozen to whatever the caller passed
|
|
@@ -56,16 +63,21 @@ export function createChat(options) {
|
|
|
56
63
|
const transport = options.connection
|
|
57
64
|
? { connection: options.connection }
|
|
58
65
|
: { fetcher: options.fetcher };
|
|
66
|
+
// The hook's identity is its `threadId`, which ChatClient also uses as the
|
|
67
|
+
// persistence key — no separate `id`. When no `threadId` is given the client
|
|
68
|
+
// generates one, so an ephemeral chat still works but is not restored on reload.
|
|
59
69
|
const client = new ChatClient({
|
|
60
70
|
devtoolsBridgeFactory: createChatDevtoolsBridge,
|
|
61
71
|
...transport,
|
|
62
|
-
id: clientId,
|
|
63
72
|
...(options.initialMessages !== undefined && {
|
|
64
73
|
initialMessages: options.initialMessages,
|
|
65
74
|
}),
|
|
66
75
|
...(options.persistence !== undefined && {
|
|
67
76
|
persistence: options.persistence,
|
|
68
77
|
}),
|
|
78
|
+
...(options.initialResumeSnapshot !== undefined && {
|
|
79
|
+
initialResumeSnapshot: options.initialResumeSnapshot,
|
|
80
|
+
}),
|
|
69
81
|
...(options.body !== undefined && { body: options.body }),
|
|
70
82
|
...(options.threadId !== undefined && { threadId: options.threadId }),
|
|
71
83
|
...(options.forwardedProps !== undefined && {
|
|
@@ -100,6 +112,7 @@ export function createChat(options) {
|
|
|
100
112
|
},
|
|
101
113
|
onLoadingChange: (newIsLoading) => {
|
|
102
114
|
isLoading = newIsLoading;
|
|
115
|
+
syncResumeState();
|
|
103
116
|
},
|
|
104
117
|
onStatusChange: (newStatus) => {
|
|
105
118
|
status = newStatus;
|
|
@@ -120,26 +133,78 @@ export function createChat(options) {
|
|
|
120
133
|
onQueueChange: (nextQueue) => {
|
|
121
134
|
queue = nextQueue;
|
|
122
135
|
},
|
|
136
|
+
onRunIdChange: (nextRunId) => {
|
|
137
|
+
runId = nextRunId;
|
|
138
|
+
},
|
|
139
|
+
onInterruptStateChange: (nextInterruptState) => {
|
|
140
|
+
interruptState = nextInterruptState;
|
|
141
|
+
options.onInterruptStateChange?.(nextInterruptState);
|
|
142
|
+
},
|
|
123
143
|
});
|
|
144
|
+
function syncResumeState() {
|
|
145
|
+
runId = client.getCurrentRunId();
|
|
146
|
+
interruptState = client.getInterruptState();
|
|
147
|
+
}
|
|
124
148
|
messages = client.getMessages();
|
|
149
|
+
interruptState = client.getInterruptState();
|
|
125
150
|
if (options.live) {
|
|
126
151
|
client.subscribe();
|
|
127
152
|
}
|
|
128
153
|
client.mountDevtools();
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
154
|
+
if (typeof window !== 'undefined') {
|
|
155
|
+
try {
|
|
156
|
+
onMount(() => {
|
|
157
|
+
// Delivery-durability resume is transparent: the resumable SSE
|
|
158
|
+
// connection adapter reattaches via the browser's native
|
|
159
|
+
// Last-Event-ID on reconnect. We only seed interrupt (state) resume.
|
|
160
|
+
syncResumeState();
|
|
161
|
+
client.attach();
|
|
162
|
+
// ONLY THE VIEW ON SCREEN HOLDS A STREAM. `onMount`'s returned function
|
|
163
|
+
// runs when the component is destroyed, which is the one automatic
|
|
164
|
+
// teardown Svelte gives us here — and it is enough, because a connection
|
|
165
|
+
// is all that must go. A page can own many chats and a browser allows
|
|
166
|
+
// only ~6 connections per origin, so one long-lived stream per chat
|
|
167
|
+
// starves every other request once a few views have been open.
|
|
168
|
+
//
|
|
169
|
+
// `detach` keeps the transcript and the resume pointer, so re-entering
|
|
170
|
+
// the view picks the run back up from the durable log.
|
|
171
|
+
return () => {
|
|
172
|
+
client.detach();
|
|
173
|
+
};
|
|
174
|
+
});
|
|
175
|
+
}
|
|
176
|
+
catch {
|
|
177
|
+
// Svelte lifecycle hooks are only valid during component initialization.
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
// Note: `dispose()` remains manual — it releases devtools and marks the client
|
|
181
|
+
// dead, which only the owner can decide. The CONNECTION is released
|
|
182
|
+
// automatically by the `onMount` teardown above.
|
|
133
183
|
// Define methods
|
|
134
184
|
const sendMessage = async (content, sendOptions) => {
|
|
135
|
-
|
|
185
|
+
try {
|
|
186
|
+
await client.sendMessage(content, undefined, sendOptions);
|
|
187
|
+
}
|
|
188
|
+
finally {
|
|
189
|
+
syncResumeState();
|
|
190
|
+
}
|
|
136
191
|
};
|
|
137
192
|
const cancelQueued = (id) => client.cancelQueued(id);
|
|
138
193
|
const append = async (message) => {
|
|
139
|
-
|
|
194
|
+
try {
|
|
195
|
+
await client.append(message);
|
|
196
|
+
}
|
|
197
|
+
finally {
|
|
198
|
+
syncResumeState();
|
|
199
|
+
}
|
|
140
200
|
};
|
|
141
201
|
const reload = async () => {
|
|
142
|
-
|
|
202
|
+
try {
|
|
203
|
+
await client.reload();
|
|
204
|
+
}
|
|
205
|
+
finally {
|
|
206
|
+
syncResumeState();
|
|
207
|
+
}
|
|
143
208
|
};
|
|
144
209
|
const stop = () => {
|
|
145
210
|
client.stop();
|
|
@@ -149,6 +214,7 @@ export function createChat(options) {
|
|
|
149
214
|
};
|
|
150
215
|
const clear = () => {
|
|
151
216
|
client.clear();
|
|
217
|
+
syncResumeState();
|
|
152
218
|
};
|
|
153
219
|
const setMessages = (newMessages) => {
|
|
154
220
|
client.setMessagesManually(newMessages);
|
|
@@ -158,7 +224,28 @@ export function createChat(options) {
|
|
|
158
224
|
};
|
|
159
225
|
const addToolApprovalResponse = async (response) => {
|
|
160
226
|
await client.addToolApprovalResponse(response);
|
|
227
|
+
syncResumeState();
|
|
228
|
+
};
|
|
229
|
+
const resumeInterrupts = async (resumeItems, state) => {
|
|
230
|
+
const result = await client.resumeInterrupts(resumeItems, state);
|
|
231
|
+
syncResumeState();
|
|
232
|
+
return result;
|
|
233
|
+
};
|
|
234
|
+
const resolveInterrupts = (resolution) => {
|
|
235
|
+
if (typeof resolution === 'boolean') {
|
|
236
|
+
client.resolveInterrupts(resolution);
|
|
237
|
+
}
|
|
238
|
+
else {
|
|
239
|
+
client.resolveInterrupts(resolution);
|
|
240
|
+
}
|
|
241
|
+
};
|
|
242
|
+
const cancelInterrupts = () => {
|
|
243
|
+
client.cancelInterrupts();
|
|
161
244
|
};
|
|
245
|
+
const retryInterrupts = () => {
|
|
246
|
+
client.retryInterrupts();
|
|
247
|
+
};
|
|
248
|
+
const resumeInterruptsUnsafe = (resumeItems, state) => client.resumeInterruptsUnsafe(resumeItems, state);
|
|
162
249
|
/**
|
|
163
250
|
* @deprecated Use `updateForwardedProps` instead.
|
|
164
251
|
* Both populate the same wire payload.
|
|
@@ -209,7 +296,7 @@ export function createChat(options) {
|
|
|
209
296
|
: null);
|
|
210
297
|
// Return the chat interface with reactive getters
|
|
211
298
|
// Using getters allows Svelte to track reactivity without needing $ prefix
|
|
212
|
-
//
|
|
299
|
+
// 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.
|
|
213
300
|
return {
|
|
214
301
|
get messages() {
|
|
215
302
|
return messages;
|
|
@@ -235,6 +322,21 @@ export function createChat(options) {
|
|
|
235
322
|
get queue() {
|
|
236
323
|
return queue;
|
|
237
324
|
},
|
|
325
|
+
get runId() {
|
|
326
|
+
return runId;
|
|
327
|
+
},
|
|
328
|
+
get interrupts() {
|
|
329
|
+
return interruptState.interrupts;
|
|
330
|
+
},
|
|
331
|
+
get pendingInterrupts() {
|
|
332
|
+
return interruptState.interrupts;
|
|
333
|
+
},
|
|
334
|
+
get interruptErrors() {
|
|
335
|
+
return interruptState.interruptErrors;
|
|
336
|
+
},
|
|
337
|
+
get resuming() {
|
|
338
|
+
return interruptState.resuming;
|
|
339
|
+
},
|
|
238
340
|
get partial() {
|
|
239
341
|
return partial;
|
|
240
342
|
},
|
|
@@ -251,6 +353,11 @@ export function createChat(options) {
|
|
|
251
353
|
clear,
|
|
252
354
|
addToolResult,
|
|
253
355
|
addToolApprovalResponse,
|
|
356
|
+
resolveInterrupts,
|
|
357
|
+
cancelInterrupts,
|
|
358
|
+
retryInterrupts,
|
|
359
|
+
resumeInterruptsUnsafe,
|
|
360
|
+
resumeInterrupts,
|
|
254
361
|
updateBody,
|
|
255
362
|
updateForwardedProps,
|
|
256
363
|
updateContext,
|
|
@@ -1,16 +1,19 @@
|
|
|
1
|
+
import type { CreateGenerationOptions, CreateGenerationReturn } from './create-generation.svelte';
|
|
1
2
|
import type { AudioGenerationResult, StreamChunk } from '@tanstack/ai';
|
|
2
|
-
import type { AIDevtoolsDisplayOptions, AudioGenerateInput, ConnectConnectionAdapter, GenerationClientState, GenerationFetcher, InferGenerationOutputFromReturn } from '@tanstack/ai-client';
|
|
3
|
+
import type { AIDevtoolsDisplayOptions, AudioGenerateInput, ConnectConnectionAdapter, GenerationClientState, GenerationFetcher, GenerationPersistenceOptions, InferGenerationOutputFromReturn } from '@tanstack/ai-client';
|
|
3
4
|
/**
|
|
4
5
|
* Options for the createGenerateAudio function.
|
|
5
6
|
*
|
|
6
7
|
* @template TOutput - The output type after optional transform (defaults to AudioGenerationResult)
|
|
7
8
|
*/
|
|
8
|
-
export interface CreateGenerateAudioOptions<TOutput = AudioGenerationResult> {
|
|
9
|
+
export interface CreateGenerateAudioOptions<TOutput = AudioGenerationResult> extends Pick<CreateGenerationOptions<AudioGenerateInput, AudioGenerationResult, TOutput>, 'persistence' | 'threadId' | 'hydrateGeneration' | 'joinRun'> {
|
|
9
10
|
/** Connect-based adapter for streaming transport (SSE, HTTP stream, custom) */
|
|
10
11
|
connection?: ConnectConnectionAdapter;
|
|
11
12
|
/** Direct async function for audio generation */
|
|
12
13
|
fetcher?: GenerationFetcher<AudioGenerateInput, AudioGenerationResult>;
|
|
13
|
-
/**
|
|
14
|
+
/**
|
|
15
|
+
* @deprecated Prefer `threadId`. Only allowed when `threadId` is omitted (see `GenerationPersistenceOptions`).
|
|
16
|
+
*/
|
|
14
17
|
id?: string;
|
|
15
18
|
/** Additional body parameters to send with connect-based adapter requests */
|
|
16
19
|
body?: Record<string, any>;
|
|
@@ -36,7 +39,7 @@ export interface CreateGenerateAudioOptions<TOutput = AudioGenerationResult> {
|
|
|
36
39
|
*
|
|
37
40
|
* @template TOutput - The output type (after optional transform)
|
|
38
41
|
*/
|
|
39
|
-
export interface CreateGenerateAudioReturn<TOutput = AudioGenerationResult> {
|
|
42
|
+
export interface CreateGenerateAudioReturn<TOutput = AudioGenerationResult> extends Omit<CreateGenerationReturn<TOutput>, 'generate'> {
|
|
40
43
|
/** The generation result containing audio, or null */
|
|
41
44
|
readonly result: TOutput | null;
|
|
42
45
|
/** Whether generation is in progress */
|
|
@@ -47,12 +50,6 @@ export interface CreateGenerateAudioReturn<TOutput = AudioGenerationResult> {
|
|
|
47
50
|
readonly status: GenerationClientState;
|
|
48
51
|
/** Trigger audio generation */
|
|
49
52
|
generate: (input: AudioGenerateInput) => Promise<void>;
|
|
50
|
-
/** Abort the current generation */
|
|
51
|
-
stop: () => void;
|
|
52
|
-
/** Clear result, error, and return to idle */
|
|
53
|
-
reset: () => void;
|
|
54
|
-
/** Update additional body parameters */
|
|
55
|
-
updateBody: (body: Record<string, any>) => void;
|
|
56
53
|
}
|
|
57
54
|
/**
|
|
58
55
|
* Creates a reactive audio generation instance for Svelte 5.
|
|
@@ -80,6 +77,6 @@ export interface CreateGenerateAudioReturn<TOutput = AudioGenerationResult> {
|
|
|
80
77
|
* </div>
|
|
81
78
|
* ```
|
|
82
79
|
*/
|
|
83
|
-
export declare function createGenerateAudio<TTransformed = void>(options: Omit<CreateGenerateAudioOptions, 'onResult'> & {
|
|
80
|
+
export declare function createGenerateAudio<TTransformed = void>(options: Omit<CreateGenerateAudioOptions, 'onResult' | 'persistence' | 'threadId' | 'id'> & {
|
|
84
81
|
onResult?: (result: AudioGenerationResult) => TTransformed;
|
|
85
|
-
}): CreateGenerateAudioReturn<InferGenerationOutputFromReturn<AudioGenerationResult, TTransformed>>;
|
|
82
|
+
} & GenerationPersistenceOptions): CreateGenerateAudioReturn<InferGenerationOutputFromReturn<AudioGenerationResult, TTransformed>>;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { createGeneration } from './create-generation.svelte';
|
|
2
|
+
import { reconstructAudioResult } from '@tanstack/ai-client';
|
|
2
3
|
/**
|
|
3
4
|
* Creates a reactive audio generation instance for Svelte 5.
|
|
4
5
|
*
|
|
@@ -35,6 +36,7 @@ export function createGenerateAudio(options) {
|
|
|
35
36
|
const gen = createGeneration({
|
|
36
37
|
...options,
|
|
37
38
|
devtools,
|
|
39
|
+
reconstructResult: reconstructAudioResult,
|
|
38
40
|
});
|
|
39
41
|
return {
|
|
40
42
|
get result() {
|
|
@@ -53,5 +55,9 @@ export function createGenerateAudio(options) {
|
|
|
53
55
|
stop: gen.stop,
|
|
54
56
|
reset: gen.reset,
|
|
55
57
|
updateBody: gen.updateBody,
|
|
58
|
+
dispose: gen.dispose,
|
|
59
|
+
get runId() {
|
|
60
|
+
return gen.runId;
|
|
61
|
+
},
|
|
56
62
|
};
|
|
57
63
|
}
|
|
@@ -1,16 +1,19 @@
|
|
|
1
|
+
import type { CreateGenerationOptions, CreateGenerationReturn } from './create-generation.svelte';
|
|
1
2
|
import type { ImageGenerationResult, StreamChunk } from '@tanstack/ai';
|
|
2
|
-
import type { AIDevtoolsDisplayOptions, ConnectConnectionAdapter, GenerationClientState, GenerationFetcher, ImageGenerateInput, InferGenerationOutputFromReturn } from '@tanstack/ai-client';
|
|
3
|
+
import type { AIDevtoolsDisplayOptions, ConnectConnectionAdapter, GenerationClientState, GenerationFetcher, GenerationPersistenceOptions, ImageGenerateInput, InferGenerationOutputFromReturn } from '@tanstack/ai-client';
|
|
3
4
|
/**
|
|
4
5
|
* Options for the createGenerateImage function.
|
|
5
6
|
*
|
|
6
7
|
* @template TOutput - The output type after optional transform (defaults to ImageGenerationResult)
|
|
7
8
|
*/
|
|
8
|
-
export interface CreateGenerateImageOptions<TOutput = ImageGenerationResult> {
|
|
9
|
+
export interface CreateGenerateImageOptions<TOutput = ImageGenerationResult> extends Pick<CreateGenerationOptions<ImageGenerateInput, ImageGenerationResult, TOutput>, 'persistence' | 'threadId' | 'hydrateGeneration' | 'joinRun'> {
|
|
9
10
|
/** Connect-based adapter for streaming transport (SSE, HTTP stream, custom) */
|
|
10
11
|
connection?: ConnectConnectionAdapter;
|
|
11
12
|
/** Direct async function for image generation */
|
|
12
13
|
fetcher?: GenerationFetcher<ImageGenerateInput, ImageGenerationResult>;
|
|
13
|
-
/**
|
|
14
|
+
/**
|
|
15
|
+
* @deprecated Prefer `threadId`. Only allowed when `threadId` is omitted (see `GenerationPersistenceOptions`).
|
|
16
|
+
*/
|
|
14
17
|
id?: string;
|
|
15
18
|
/** Additional body parameters to send with connect-based adapter requests */
|
|
16
19
|
body?: Record<string, any>;
|
|
@@ -36,7 +39,7 @@ export interface CreateGenerateImageOptions<TOutput = ImageGenerationResult> {
|
|
|
36
39
|
*
|
|
37
40
|
* @template TOutput - The output type (after optional transform)
|
|
38
41
|
*/
|
|
39
|
-
export interface CreateGenerateImageReturn<TOutput = ImageGenerationResult> {
|
|
42
|
+
export interface CreateGenerateImageReturn<TOutput = ImageGenerationResult> extends Omit<CreateGenerationReturn<TOutput>, 'generate'> {
|
|
40
43
|
/** The generation result containing images, or null */
|
|
41
44
|
readonly result: TOutput | null;
|
|
42
45
|
/** Whether generation is in progress */
|
|
@@ -47,12 +50,6 @@ export interface CreateGenerateImageReturn<TOutput = ImageGenerationResult> {
|
|
|
47
50
|
readonly status: GenerationClientState;
|
|
48
51
|
/** Trigger image generation */
|
|
49
52
|
generate: (input: ImageGenerateInput) => Promise<void>;
|
|
50
|
-
/** Abort the current generation */
|
|
51
|
-
stop: () => void;
|
|
52
|
-
/** Clear result, error, and return to idle */
|
|
53
|
-
reset: () => void;
|
|
54
|
-
/** Update additional body parameters */
|
|
55
|
-
updateBody: (body: Record<string, any>) => void;
|
|
56
53
|
}
|
|
57
54
|
/**
|
|
58
55
|
* Creates a reactive image generation instance for Svelte 5.
|
|
@@ -89,6 +86,6 @@ export interface CreateGenerateImageReturn<TOutput = ImageGenerationResult> {
|
|
|
89
86
|
* </div>
|
|
90
87
|
* ```
|
|
91
88
|
*/
|
|
92
|
-
export declare function createGenerateImage<TTransformed = void>(options: Omit<CreateGenerateImageOptions, 'onResult'> & {
|
|
89
|
+
export declare function createGenerateImage<TTransformed = void>(options: Omit<CreateGenerateImageOptions, 'onResult' | 'persistence' | 'threadId' | 'id'> & {
|
|
93
90
|
onResult?: (result: ImageGenerationResult) => TTransformed;
|
|
94
|
-
}): CreateGenerateImageReturn<InferGenerationOutputFromReturn<ImageGenerationResult, TTransformed>>;
|
|
91
|
+
} & GenerationPersistenceOptions): CreateGenerateImageReturn<InferGenerationOutputFromReturn<ImageGenerationResult, TTransformed>>;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { createGeneration } from './create-generation.svelte';
|
|
2
|
+
import { reconstructImageResult } from '@tanstack/ai-client';
|
|
2
3
|
/**
|
|
3
4
|
* Creates a reactive image generation instance for Svelte 5.
|
|
4
5
|
*
|
|
@@ -44,6 +45,7 @@ export function createGenerateImage(options) {
|
|
|
44
45
|
const gen = createGeneration({
|
|
45
46
|
...options,
|
|
46
47
|
devtools,
|
|
48
|
+
reconstructResult: reconstructImageResult,
|
|
47
49
|
});
|
|
48
50
|
return {
|
|
49
51
|
get result() {
|
|
@@ -62,5 +64,9 @@ export function createGenerateImage(options) {
|
|
|
62
64
|
stop: gen.stop,
|
|
63
65
|
reset: gen.reset,
|
|
64
66
|
updateBody: gen.updateBody,
|
|
67
|
+
dispose: gen.dispose,
|
|
68
|
+
get runId() {
|
|
69
|
+
return gen.runId;
|
|
70
|
+
},
|
|
65
71
|
};
|
|
66
72
|
}
|
|
@@ -1,16 +1,19 @@
|
|
|
1
|
+
import type { CreateGenerationOptions, CreateGenerationReturn } from './create-generation.svelte';
|
|
1
2
|
import type { StreamChunk, TTSResult } from '@tanstack/ai';
|
|
2
|
-
import type { AIDevtoolsDisplayOptions, ConnectConnectionAdapter, GenerationClientState, GenerationFetcher, InferGenerationOutputFromReturn, SpeechGenerateInput } from '@tanstack/ai-client';
|
|
3
|
+
import type { AIDevtoolsDisplayOptions, ConnectConnectionAdapter, GenerationClientState, GenerationFetcher, GenerationPersistenceOptions, InferGenerationOutputFromReturn, SpeechGenerateInput } from '@tanstack/ai-client';
|
|
3
4
|
/**
|
|
4
5
|
* Options for the createGenerateSpeech function.
|
|
5
6
|
*
|
|
6
7
|
* @template TOutput - The output type after optional transform (defaults to TTSResult)
|
|
7
8
|
*/
|
|
8
|
-
export interface CreateGenerateSpeechOptions<TOutput = TTSResult> {
|
|
9
|
+
export interface CreateGenerateSpeechOptions<TOutput = TTSResult> extends Pick<CreateGenerationOptions<SpeechGenerateInput, TTSResult, TOutput>, 'persistence' | 'threadId' | 'hydrateGeneration' | 'joinRun'> {
|
|
9
10
|
/** Connect-based adapter for streaming transport (SSE, HTTP stream, custom) */
|
|
10
11
|
connection?: ConnectConnectionAdapter;
|
|
11
12
|
/** Direct async function for speech generation */
|
|
12
13
|
fetcher?: GenerationFetcher<SpeechGenerateInput, TTSResult>;
|
|
13
|
-
/**
|
|
14
|
+
/**
|
|
15
|
+
* @deprecated Prefer `threadId`. Only allowed when `threadId` is omitted (see `GenerationPersistenceOptions`).
|
|
16
|
+
*/
|
|
14
17
|
id?: string;
|
|
15
18
|
/** Additional body parameters to send with connect-based adapter requests */
|
|
16
19
|
body?: Record<string, any>;
|
|
@@ -36,7 +39,7 @@ export interface CreateGenerateSpeechOptions<TOutput = TTSResult> {
|
|
|
36
39
|
*
|
|
37
40
|
* @template TOutput - The output type (after optional transform)
|
|
38
41
|
*/
|
|
39
|
-
export interface CreateGenerateSpeechReturn<TOutput = TTSResult> {
|
|
42
|
+
export interface CreateGenerateSpeechReturn<TOutput = TTSResult> extends Omit<CreateGenerationReturn<TOutput>, 'generate'> {
|
|
40
43
|
/** The TTS result containing audio data, or null */
|
|
41
44
|
readonly result: TOutput | null;
|
|
42
45
|
/** Whether generation is in progress */
|
|
@@ -47,12 +50,6 @@ export interface CreateGenerateSpeechReturn<TOutput = TTSResult> {
|
|
|
47
50
|
readonly status: GenerationClientState;
|
|
48
51
|
/** Trigger speech generation */
|
|
49
52
|
generate: (input: SpeechGenerateInput) => Promise<void>;
|
|
50
|
-
/** Abort the current generation */
|
|
51
|
-
stop: () => void;
|
|
52
|
-
/** Clear result, error, and return to idle */
|
|
53
|
-
reset: () => void;
|
|
54
|
-
/** Update additional body parameters */
|
|
55
|
-
updateBody: (body: Record<string, any>) => void;
|
|
56
53
|
}
|
|
57
54
|
/**
|
|
58
55
|
* Creates a reactive speech generation (text-to-speech) instance for Svelte 5.
|
|
@@ -80,6 +77,6 @@ export interface CreateGenerateSpeechReturn<TOutput = TTSResult> {
|
|
|
80
77
|
* </div>
|
|
81
78
|
* ```
|
|
82
79
|
*/
|
|
83
|
-
export declare function createGenerateSpeech<TTransformed = void>(options: Omit<CreateGenerateSpeechOptions, 'onResult'> & {
|
|
80
|
+
export declare function createGenerateSpeech<TTransformed = void>(options: Omit<CreateGenerateSpeechOptions, 'onResult' | 'persistence' | 'threadId' | 'id'> & {
|
|
84
81
|
onResult?: (result: TTSResult) => TTransformed;
|
|
85
|
-
}): CreateGenerateSpeechReturn<InferGenerationOutputFromReturn<TTSResult, TTransformed>>;
|
|
82
|
+
} & GenerationPersistenceOptions): CreateGenerateSpeechReturn<InferGenerationOutputFromReturn<TTSResult, TTransformed>>;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { createGeneration } from './create-generation.svelte';
|
|
2
|
+
import { reconstructSpeechResult } from '@tanstack/ai-client';
|
|
2
3
|
/**
|
|
3
4
|
* Creates a reactive speech generation (text-to-speech) instance for Svelte 5.
|
|
4
5
|
*
|
|
@@ -35,6 +36,7 @@ export function createGenerateSpeech(options) {
|
|
|
35
36
|
const gen = createGeneration({
|
|
36
37
|
...options,
|
|
37
38
|
devtools,
|
|
39
|
+
reconstructResult: reconstructSpeechResult,
|
|
38
40
|
});
|
|
39
41
|
return {
|
|
40
42
|
get result() {
|
|
@@ -53,5 +55,9 @@ export function createGenerateSpeech(options) {
|
|
|
53
55
|
stop: gen.stop,
|
|
54
56
|
reset: gen.reset,
|
|
55
57
|
updateBody: gen.updateBody,
|
|
58
|
+
dispose: gen.dispose,
|
|
59
|
+
get runId() {
|
|
60
|
+
return gen.runId;
|
|
61
|
+
},
|
|
56
62
|
};
|
|
57
63
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { StreamChunk } from '@tanstack/ai';
|
|
2
|
-
import type { AIDevtoolsDisplayOptions, ConnectConnectionAdapter, GenerationClientState, GenerationFetcher, InferGenerationOutputFromReturn, VideoGenerateInput, VideoGenerateResult, VideoStatusInfo } from '@tanstack/ai-client';
|
|
2
|
+
import type { AIDevtoolsDisplayOptions, ConnectConnectionAdapter, GenerationClientState, GenerationFetcher, GenerationPersistenceOptions, InferGenerationOutputFromReturn, VideoGenerateInput, VideoGenerateResult, VideoStatusInfo } from '@tanstack/ai-client';
|
|
3
3
|
/**
|
|
4
4
|
* Options for the createGenerateVideo function.
|
|
5
5
|
*
|
|
@@ -10,12 +10,51 @@ export interface CreateGenerateVideoOptions<TOutput = VideoGenerateResult> {
|
|
|
10
10
|
connection?: ConnectConnectionAdapter;
|
|
11
11
|
/** Direct async function that returns a completed video result */
|
|
12
12
|
fetcher?: GenerationFetcher<VideoGenerateInput, VideoGenerateResult>;
|
|
13
|
-
/**
|
|
13
|
+
/**
|
|
14
|
+
* @deprecated Prefer `threadId`. Only allowed when `threadId` is omitted (see `GenerationPersistenceOptions`).
|
|
15
|
+
*/
|
|
14
16
|
id?: string;
|
|
15
17
|
/** Additional body parameters to send with connect-based adapter requests */
|
|
16
18
|
body?: Record<string, any>;
|
|
17
19
|
/** Display options for TanStack AI Devtools. */
|
|
18
20
|
devtools?: AIDevtoolsDisplayOptions;
|
|
21
|
+
/**
|
|
22
|
+
* How this generation persists across reloads.
|
|
23
|
+
* - Omit / `false`: ephemeral, in-memory only.
|
|
24
|
+
* - `true`: server-driven — on mount the client hydrates the last generation
|
|
25
|
+
* for its `threadId` from the server (needs a connection with a
|
|
26
|
+
* `hydrateGeneration` handler) and repaints it; it never auto-starts a run.
|
|
27
|
+
*/
|
|
28
|
+
persistence?: boolean;
|
|
29
|
+
/**
|
|
30
|
+
* The **scope** this generation belongs to: a stable, app-chosen name for the
|
|
31
|
+
* slot successive runs fill — not a link to a chat conversation.
|
|
32
|
+
*
|
|
33
|
+
* The hook starts empty and produces many runs over its life; each gets its
|
|
34
|
+
* own `runId`, but all belong to one scope. Persistence keys on this, so
|
|
35
|
+
* derive it from your own domain and keep it identical across reloads (e.g.
|
|
36
|
+
* `` `video-${videoId}-start-frame` ``). It is also sent as the AG-UI thread
|
|
37
|
+
* id on the wire, which the protocol requires.
|
|
38
|
+
*
|
|
39
|
+
* **Required whenever `persistence` is set** — an app that cannot name the
|
|
40
|
+
* scope has nothing to restore to. Optional for ephemeral generations, where
|
|
41
|
+
* it falls back to `id` purely to satisfy the wire.
|
|
42
|
+
*/
|
|
43
|
+
threadId?: string;
|
|
44
|
+
/**
|
|
45
|
+
* Server-driven hydration handler for `persistence: true` when the
|
|
46
|
+
* connection doesn't carry one (e.g. alongside `fetcher`, or a `stream()` /
|
|
47
|
+
* `rpcStream()` adapter built without handlers) — typically a one-line
|
|
48
|
+
* server-function call. The connection's own handler takes precedence.
|
|
49
|
+
*/
|
|
50
|
+
hydrateGeneration?: ConnectConnectionAdapter['hydrateGeneration'];
|
|
51
|
+
/**
|
|
52
|
+
* Re-attach handler that replays a run still generating to completion on
|
|
53
|
+
* mount, when the connection doesn't carry one. Without it, a restored
|
|
54
|
+
* `running` snapshot surfaces as an (interrupted) error. The connection's
|
|
55
|
+
* own handler takes precedence.
|
|
56
|
+
*/
|
|
57
|
+
joinRun?: ConnectConnectionAdapter['joinRun'];
|
|
19
58
|
/**
|
|
20
59
|
* Callback when video generation completes. Can optionally return a transformed value.
|
|
21
60
|
*
|
|
@@ -63,6 +102,13 @@ export interface CreateGenerateVideoReturn<TOutput = VideoGenerateResult> {
|
|
|
63
102
|
dispose: () => void;
|
|
64
103
|
/** Update additional body parameters */
|
|
65
104
|
updateBody: (body: Record<string, any>) => void;
|
|
105
|
+
/**
|
|
106
|
+
* The id of the generation job currently running, or `null` when nothing is in
|
|
107
|
+
* flight. Each call to `generate` is one job with its own id. Pass it to your
|
|
108
|
+
* own endpoint to cancel or poll the provider job — `stop()` only aborts the
|
|
109
|
+
* local stream, it does not stop work already running on the provider.
|
|
110
|
+
*/
|
|
111
|
+
readonly runId: string | null;
|
|
66
112
|
}
|
|
67
113
|
/**
|
|
68
114
|
* Creates a reactive video generation instance for Svelte 5.
|
|
@@ -94,6 +140,6 @@ export interface CreateGenerateVideoReturn<TOutput = VideoGenerateResult> {
|
|
|
94
140
|
* </div>
|
|
95
141
|
* ```
|
|
96
142
|
*/
|
|
97
|
-
export declare function createGenerateVideo<TTransformed = void>(options: Omit<CreateGenerateVideoOptions, 'onResult'> & {
|
|
143
|
+
export declare function createGenerateVideo<TTransformed = void>(options: Omit<CreateGenerateVideoOptions, 'onResult' | 'persistence' | 'threadId' | 'id'> & {
|
|
98
144
|
onResult?: (result: VideoGenerateResult) => TTransformed;
|
|
99
|
-
}): CreateGenerateVideoReturn<InferGenerationOutputFromReturn<VideoGenerateResult, TTransformed>>;
|
|
145
|
+
} & GenerationPersistenceOptions): CreateGenerateVideoReturn<InferGenerationOutputFromReturn<VideoGenerateResult, TTransformed>>;
|