@tanstack/ai-svelte 0.15.0 → 0.16.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +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
|
@@ -34,8 +34,7 @@ import { createVideoDevtoolsBridge } from '@tanstack/ai-client/devtools';
|
|
|
34
34
|
// parameter is typed as `VideoGenerateResult` and `result` narrows to the
|
|
35
35
|
// transform's return. See issue #848.
|
|
36
36
|
export function createGenerateVideo(options) {
|
|
37
|
-
const
|
|
38
|
-
`video-${Date.now()}-${Math.random().toString(36).substring(7)}`;
|
|
37
|
+
const fallbackId = `video-${Date.now()}-${Math.random().toString(36).substring(7)}`;
|
|
39
38
|
// Create reactive state using Svelte 5 runes
|
|
40
39
|
let result = $state(null);
|
|
41
40
|
let jobId = $state(null);
|
|
@@ -43,13 +42,25 @@ export function createGenerateVideo(options) {
|
|
|
43
42
|
let isLoading = $state(false);
|
|
44
43
|
let error = $state(undefined);
|
|
45
44
|
let status = $state('idle');
|
|
45
|
+
let runId = $state(null);
|
|
46
|
+
let disposed = false;
|
|
46
47
|
// `body` uses a conditional spread because `VideoGenerationClientOptions.body`
|
|
47
48
|
// is declared `body?: Record<string, any>` (absent vs. present) under
|
|
48
49
|
// `exactOptionalPropertyTypes`. The optional caller `options.body` may be
|
|
49
50
|
// undefined, in which case we want the key to be absent on the target.
|
|
51
|
+
// Identity: pass `threadId` alone when set (never also pass deprecated `id`).
|
|
50
52
|
const baseOptions = {
|
|
51
|
-
id: clientId,
|
|
52
53
|
body: options.body,
|
|
54
|
+
...(options.threadId !== undefined
|
|
55
|
+
? { threadId: options.threadId }
|
|
56
|
+
: { id: options.id ?? fallbackId }),
|
|
57
|
+
...(options.persistence !== undefined && {
|
|
58
|
+
persistence: options.persistence,
|
|
59
|
+
}),
|
|
60
|
+
...(options.hydrateGeneration !== undefined && {
|
|
61
|
+
hydrateGeneration: options.hydrateGeneration,
|
|
62
|
+
}),
|
|
63
|
+
...(options.joinRun !== undefined && { joinRun: options.joinRun }),
|
|
53
64
|
devtoolsBridgeFactory: createVideoDevtoolsBridge,
|
|
54
65
|
devtools: {
|
|
55
66
|
...options.devtools,
|
|
@@ -61,29 +72,61 @@ export function createGenerateVideo(options) {
|
|
|
61
72
|
// (`TOutput`, with null/void/undefined stripped) are identical at runtime;
|
|
62
73
|
// the cast bridges the relationship that the conditional type hides.
|
|
63
74
|
onResult: ((r) => options.onResult?.(r)),
|
|
64
|
-
onError: (e) =>
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
75
|
+
onError: (e) => {
|
|
76
|
+
if (!disposed)
|
|
77
|
+
options.onError?.(e);
|
|
78
|
+
},
|
|
79
|
+
onProgress: (p, m) => {
|
|
80
|
+
if (!disposed)
|
|
81
|
+
options.onProgress?.(p, m);
|
|
82
|
+
},
|
|
83
|
+
onChunk: (c) => {
|
|
84
|
+
if (!disposed)
|
|
85
|
+
options.onChunk?.(c);
|
|
86
|
+
},
|
|
87
|
+
onJobCreated: (id) => {
|
|
88
|
+
if (!disposed)
|
|
89
|
+
options.onJobCreated?.(id);
|
|
90
|
+
},
|
|
91
|
+
onStatusUpdate: (s) => {
|
|
92
|
+
if (!disposed)
|
|
93
|
+
options.onStatusUpdate?.(s);
|
|
94
|
+
},
|
|
69
95
|
onResultChange: (r) => {
|
|
96
|
+
if (disposed)
|
|
97
|
+
return;
|
|
70
98
|
result = r;
|
|
71
99
|
},
|
|
72
100
|
onLoadingChange: (l) => {
|
|
101
|
+
if (disposed)
|
|
102
|
+
return;
|
|
73
103
|
isLoading = l;
|
|
74
104
|
},
|
|
75
105
|
onErrorChange: (e) => {
|
|
106
|
+
if (disposed)
|
|
107
|
+
return;
|
|
76
108
|
error = e;
|
|
77
109
|
},
|
|
78
110
|
onStatusChange: (s) => {
|
|
111
|
+
if (disposed)
|
|
112
|
+
return;
|
|
79
113
|
status = s;
|
|
80
114
|
},
|
|
81
115
|
onJobIdChange: (id) => {
|
|
116
|
+
if (disposed)
|
|
117
|
+
return;
|
|
82
118
|
jobId = id;
|
|
83
119
|
},
|
|
84
120
|
onVideoStatusChange: (s) => {
|
|
121
|
+
if (disposed)
|
|
122
|
+
return;
|
|
85
123
|
videoStatus = s;
|
|
86
124
|
},
|
|
125
|
+
onResumeStateChange: (rs) => {
|
|
126
|
+
if (disposed)
|
|
127
|
+
return;
|
|
128
|
+
runId = rs?.runId ?? null;
|
|
129
|
+
},
|
|
87
130
|
};
|
|
88
131
|
let client;
|
|
89
132
|
if (options.connection) {
|
|
@@ -101,12 +144,20 @@ export function createGenerateVideo(options) {
|
|
|
101
144
|
else {
|
|
102
145
|
throw new Error('createGenerateVideo requires either a connection or fetcher option');
|
|
103
146
|
}
|
|
147
|
+
// Mount devtools only. Generation runs are never auto-started on setup —
|
|
148
|
+
// persisted state is read-only for display.
|
|
104
149
|
client.mountDevtools();
|
|
105
150
|
// Note: Cleanup is handled by calling dispose() directly when needed.
|
|
106
151
|
// Unlike React/Vue/Solid, Svelte 5 runes like $effect can only be used
|
|
107
152
|
// during component initialization, so we don't add automatic cleanup here.
|
|
108
153
|
// Users should call video.dispose() in their component's cleanup if needed.
|
|
109
154
|
const generate = async (input) => {
|
|
155
|
+
// Svelte has no remount effect to revive a disposed client (the other
|
|
156
|
+
// frameworks revive via mountDevtools() in their mount effects), so an
|
|
157
|
+
// explicit generate() after dispose() is the Svelte revive path: bring
|
|
158
|
+
// the client and the reactive bindings back together.
|
|
159
|
+
disposed = false;
|
|
160
|
+
client.mountDevtools();
|
|
110
161
|
await client.generate(input);
|
|
111
162
|
};
|
|
112
163
|
const stop = () => {
|
|
@@ -116,6 +167,7 @@ export function createGenerateVideo(options) {
|
|
|
116
167
|
client.reset();
|
|
117
168
|
};
|
|
118
169
|
const dispose = () => {
|
|
170
|
+
disposed = true;
|
|
119
171
|
client.dispose();
|
|
120
172
|
};
|
|
121
173
|
const updateBody = (newBody) => {
|
|
@@ -145,5 +197,8 @@ export function createGenerateVideo(options) {
|
|
|
145
197
|
reset,
|
|
146
198
|
dispose,
|
|
147
199
|
updateBody,
|
|
200
|
+
get runId() {
|
|
201
|
+
return runId;
|
|
202
|
+
},
|
|
148
203
|
};
|
|
149
204
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { StreamChunk } from '@tanstack/ai';
|
|
2
|
-
import type { AIDevtoolsDisplayOptions, ConnectConnectionAdapter, GenerationClientState, GenerationFetcher, InferGenerationOutputFromReturn } from '@tanstack/ai-client';
|
|
2
|
+
import type { AIDevtoolsDisplayOptions, ConnectConnectionAdapter, GenerationClientState, GenerationFetcher, GenerationPersistenceOptions, GenerationRestoredResult, InferGenerationOutputFromReturn } from '@tanstack/ai-client';
|
|
3
3
|
/**
|
|
4
4
|
* Options for the createGeneration function.
|
|
5
5
|
*
|
|
@@ -14,12 +14,51 @@ export interface CreateGenerationOptions<TInput, TResult, TOutput = TResult> {
|
|
|
14
14
|
connection?: ConnectConnectionAdapter;
|
|
15
15
|
/** Direct async function for one-shot generation (no streaming protocol needed) */
|
|
16
16
|
fetcher?: GenerationFetcher<TInput, TResult>;
|
|
17
|
-
/**
|
|
17
|
+
/**
|
|
18
|
+
* @deprecated Prefer `threadId`. Only allowed when `threadId` is omitted (see `GenerationPersistenceOptions`).
|
|
19
|
+
*/
|
|
18
20
|
id?: string;
|
|
19
21
|
/** Additional body parameters to send with connect-based adapter requests */
|
|
20
22
|
body?: Record<string, any>;
|
|
21
23
|
/** Display options for TanStack AI Devtools. */
|
|
22
24
|
devtools?: AIDevtoolsDisplayOptions;
|
|
25
|
+
/**
|
|
26
|
+
* How this generation persists across reloads.
|
|
27
|
+
* - Omit / `false`: ephemeral, in-memory only.
|
|
28
|
+
* - `true`: server-driven — on mount the client hydrates the last generation
|
|
29
|
+
* for its `threadId` from the server (needs a connection with a
|
|
30
|
+
* `hydrateGeneration` handler) and repaints it; it never auto-starts a run.
|
|
31
|
+
*/
|
|
32
|
+
persistence?: boolean;
|
|
33
|
+
/**
|
|
34
|
+
* The **scope** this generation belongs to: a stable, app-chosen name for the
|
|
35
|
+
* slot successive runs fill — not a link to a chat conversation.
|
|
36
|
+
*
|
|
37
|
+
* The hook starts empty and produces many runs over its life; each gets its
|
|
38
|
+
* own `runId`, but all belong to one scope. Persistence keys on this, so
|
|
39
|
+
* derive it from your own domain and keep it identical across reloads (e.g.
|
|
40
|
+
* `` `video-${videoId}-start-frame` ``). It is also sent as the AG-UI thread
|
|
41
|
+
* id on the wire, which the protocol requires.
|
|
42
|
+
*
|
|
43
|
+
* **Required whenever `persistence` is set** — an app that cannot name the
|
|
44
|
+
* scope has nothing to restore to. Optional for ephemeral generations, where
|
|
45
|
+
* it falls back to `id` purely to satisfy the wire.
|
|
46
|
+
*/
|
|
47
|
+
threadId?: string;
|
|
48
|
+
/**
|
|
49
|
+
* Server-driven hydration handler for `persistence: true` when the
|
|
50
|
+
* connection doesn't carry one (e.g. alongside `fetcher`, or a `stream()` /
|
|
51
|
+
* `rpcStream()` adapter built without handlers) — typically a one-line
|
|
52
|
+
* server-function call. The connection's own handler takes precedence.
|
|
53
|
+
*/
|
|
54
|
+
hydrateGeneration?: ConnectConnectionAdapter['hydrateGeneration'];
|
|
55
|
+
/**
|
|
56
|
+
* Re-attach handler that replays a run still generating to completion on
|
|
57
|
+
* mount, when the connection doesn't carry one. Without it, a restored
|
|
58
|
+
* `running` snapshot surfaces as an (interrupted) error. The connection's
|
|
59
|
+
* own handler takes precedence.
|
|
60
|
+
*/
|
|
61
|
+
joinRun?: ConnectConnectionAdapter['joinRun'];
|
|
23
62
|
/**
|
|
24
63
|
* Callback when a result is received. Can optionally return a transformed value.
|
|
25
64
|
*
|
|
@@ -34,13 +73,20 @@ export interface CreateGenerationOptions<TInput, TResult, TOutput = TResult> {
|
|
|
34
73
|
onProgress?: (progress: number, message?: string) => void;
|
|
35
74
|
/** Callback for each stream chunk (connect-based adapter mode only) */
|
|
36
75
|
onChunk?: (chunk: StreamChunk) => void;
|
|
76
|
+
/**
|
|
77
|
+
* @internal Rebuild a typed result from a restored snapshot, injected by each
|
|
78
|
+
* specialized function (image / speech / audio / transcription / summarize).
|
|
79
|
+
* Forwarded to the client so a server-hydrate restore repaints `result`.
|
|
80
|
+
*/
|
|
81
|
+
reconstructResult?: (restored: GenerationRestoredResult) => TResult | null;
|
|
37
82
|
}
|
|
38
83
|
/**
|
|
39
84
|
* Return type for the createGeneration function.
|
|
40
85
|
*
|
|
41
86
|
* @template TOutput - The output type (after optional transform)
|
|
87
|
+
* @template TInput - The input type accepted by `generate` (defaults to any object)
|
|
42
88
|
*/
|
|
43
|
-
export interface CreateGenerationReturn<TOutput> {
|
|
89
|
+
export interface CreateGenerationReturn<TOutput, TInput extends Record<string, any> = Record<string, any>> {
|
|
44
90
|
/** The generation result, or null if not yet generated */
|
|
45
91
|
readonly result: TOutput | null;
|
|
46
92
|
/** Whether a generation is currently in progress */
|
|
@@ -50,7 +96,7 @@ export interface CreateGenerationReturn<TOutput> {
|
|
|
50
96
|
/** Current state of the generation client */
|
|
51
97
|
readonly status: GenerationClientState;
|
|
52
98
|
/** Trigger a generation request */
|
|
53
|
-
generate: (input:
|
|
99
|
+
generate: (input: TInput) => Promise<void>;
|
|
54
100
|
/** Abort the current generation */
|
|
55
101
|
stop: () => void;
|
|
56
102
|
/** Clear result, error, and return to idle */
|
|
@@ -59,6 +105,13 @@ export interface CreateGenerationReturn<TOutput> {
|
|
|
59
105
|
dispose: () => void;
|
|
60
106
|
/** Update additional body parameters */
|
|
61
107
|
updateBody: (body: Record<string, any>) => void;
|
|
108
|
+
/**
|
|
109
|
+
* The id of the generation job currently running, or `null` when nothing is in
|
|
110
|
+
* flight. Each call to `generate` is one job with its own id. Pass it to your
|
|
111
|
+
* own endpoint to cancel or poll the provider job — `stop()` only aborts the
|
|
112
|
+
* local stream, it does not stop work already running on the provider.
|
|
113
|
+
*/
|
|
114
|
+
readonly runId: string | null;
|
|
62
115
|
}
|
|
63
116
|
/**
|
|
64
117
|
* Creates a reactive generation instance for Svelte 5.
|
|
@@ -91,6 +144,6 @@ export interface CreateGenerationReturn<TOutput> {
|
|
|
91
144
|
* </div>
|
|
92
145
|
* ```
|
|
93
146
|
*/
|
|
94
|
-
export declare function createGeneration<TInput extends Record<string, any>, TResult, TTransformed = void>(options: Omit<CreateGenerationOptions<TInput, TResult>, 'onResult'> & {
|
|
147
|
+
export declare function createGeneration<TInput extends Record<string, any>, TResult, TTransformed = void>(options: Omit<CreateGenerationOptions<TInput, TResult>, 'onResult' | 'persistence' | 'threadId' | 'id'> & {
|
|
95
148
|
onResult?: (result: TResult) => TTransformed;
|
|
96
|
-
}): CreateGenerationReturn<InferGenerationOutputFromReturn<TResult, TTransformed
|
|
149
|
+
} & GenerationPersistenceOptions): CreateGenerationReturn<InferGenerationOutputFromReturn<TResult, TTransformed>, TInput>;
|
|
@@ -38,20 +38,35 @@ import { createGenerationDevtoolsBridge } from '@tanstack/ai-client/devtools';
|
|
|
38
38
|
// default, leaving the parameter `any` — a hard error under `strict`. See
|
|
39
39
|
// issue #848.
|
|
40
40
|
export function createGeneration(options) {
|
|
41
|
-
const
|
|
41
|
+
const fallbackId = `gen-${Date.now()}-${Math.random().toString(36).substring(7)}`;
|
|
42
42
|
// Create reactive state using Svelte 5 runes
|
|
43
43
|
let result = $state(null);
|
|
44
44
|
let isLoading = $state(false);
|
|
45
45
|
let error = $state(undefined);
|
|
46
46
|
let status = $state('idle');
|
|
47
|
+
let runId = $state(null);
|
|
48
|
+
let disposed = false;
|
|
47
49
|
// `body` uses a conditional spread because `GenerationClientOptions.body`
|
|
48
50
|
// is declared `body?: Record<string, any>` (absent vs. present) under
|
|
49
51
|
// `exactOptionalPropertyTypes`. Assigning `undefined` directly would be
|
|
50
52
|
// rejected — the optional caller `options.body` may be undefined, in which
|
|
51
53
|
// case we want the key to be absent.
|
|
54
|
+
// Identity: pass `threadId` alone when set (never also pass deprecated `id`).
|
|
52
55
|
const clientOptions = {
|
|
53
|
-
id: clientId,
|
|
54
56
|
body: options.body,
|
|
57
|
+
...(options.threadId !== undefined
|
|
58
|
+
? { threadId: options.threadId }
|
|
59
|
+
: { id: options.id ?? fallbackId }),
|
|
60
|
+
...(options.persistence !== undefined && {
|
|
61
|
+
persistence: options.persistence,
|
|
62
|
+
}),
|
|
63
|
+
...(options.hydrateGeneration !== undefined && {
|
|
64
|
+
hydrateGeneration: options.hydrateGeneration,
|
|
65
|
+
}),
|
|
66
|
+
...(options.joinRun !== undefined && { joinRun: options.joinRun }),
|
|
67
|
+
...(options.reconstructResult
|
|
68
|
+
? { reconstructResult: options.reconstructResult }
|
|
69
|
+
: {}),
|
|
55
70
|
devtoolsBridgeFactory: createGenerationDevtoolsBridge,
|
|
56
71
|
devtools: {
|
|
57
72
|
...options.devtools,
|
|
@@ -62,21 +77,43 @@ export function createGeneration(options) {
|
|
|
62
77
|
// (`TOutput`, with null/void/undefined stripped) are identical at runtime;
|
|
63
78
|
// the cast bridges the relationship that the conditional type hides.
|
|
64
79
|
onResult: ((r) => options.onResult?.(r)),
|
|
65
|
-
onError: (e) =>
|
|
66
|
-
|
|
67
|
-
|
|
80
|
+
onError: (e) => {
|
|
81
|
+
if (!disposed)
|
|
82
|
+
options.onError?.(e);
|
|
83
|
+
},
|
|
84
|
+
onProgress: (p, m) => {
|
|
85
|
+
if (!disposed)
|
|
86
|
+
options.onProgress?.(p, m);
|
|
87
|
+
},
|
|
88
|
+
onChunk: (c) => {
|
|
89
|
+
if (!disposed)
|
|
90
|
+
options.onChunk?.(c);
|
|
91
|
+
},
|
|
68
92
|
onResultChange: (r) => {
|
|
93
|
+
if (disposed)
|
|
94
|
+
return;
|
|
69
95
|
result = r;
|
|
70
96
|
},
|
|
71
97
|
onLoadingChange: (l) => {
|
|
98
|
+
if (disposed)
|
|
99
|
+
return;
|
|
72
100
|
isLoading = l;
|
|
73
101
|
},
|
|
74
102
|
onErrorChange: (e) => {
|
|
103
|
+
if (disposed)
|
|
104
|
+
return;
|
|
75
105
|
error = e;
|
|
76
106
|
},
|
|
77
107
|
onStatusChange: (s) => {
|
|
108
|
+
if (disposed)
|
|
109
|
+
return;
|
|
78
110
|
status = s;
|
|
79
111
|
},
|
|
112
|
+
onResumeStateChange: (rs) => {
|
|
113
|
+
if (disposed)
|
|
114
|
+
return;
|
|
115
|
+
runId = rs?.runId ?? null;
|
|
116
|
+
},
|
|
80
117
|
};
|
|
81
118
|
let client;
|
|
82
119
|
if (options.connection) {
|
|
@@ -94,12 +131,20 @@ export function createGeneration(options) {
|
|
|
94
131
|
else {
|
|
95
132
|
throw new Error('createGeneration requires either a connection or fetcher option');
|
|
96
133
|
}
|
|
134
|
+
// Mount devtools only. Generation runs are never auto-started on setup —
|
|
135
|
+
// persisted state is read-only for display.
|
|
97
136
|
client.mountDevtools();
|
|
98
137
|
// Note: Cleanup is handled by calling dispose() directly when needed.
|
|
99
138
|
// Unlike React/Vue/Solid, Svelte 5 runes like $effect can only be used
|
|
100
139
|
// during component initialization, so we don't add automatic cleanup here.
|
|
101
140
|
// Users should call gen.dispose() in their component's cleanup if needed.
|
|
102
141
|
const generate = async (input) => {
|
|
142
|
+
// Svelte has no remount effect to revive a disposed client (the other
|
|
143
|
+
// frameworks revive via mountDevtools() in their mount effects), so an
|
|
144
|
+
// explicit generate() after dispose() is the Svelte revive path: bring
|
|
145
|
+
// the client and the reactive bindings back together.
|
|
146
|
+
disposed = false;
|
|
147
|
+
client.mountDevtools();
|
|
103
148
|
await client.generate(input);
|
|
104
149
|
};
|
|
105
150
|
const stop = () => {
|
|
@@ -109,6 +154,7 @@ export function createGeneration(options) {
|
|
|
109
154
|
client.reset();
|
|
110
155
|
};
|
|
111
156
|
const dispose = () => {
|
|
157
|
+
disposed = true;
|
|
112
158
|
client.dispose();
|
|
113
159
|
};
|
|
114
160
|
const updateBody = (newBody) => {
|
|
@@ -127,10 +173,13 @@ export function createGeneration(options) {
|
|
|
127
173
|
get status() {
|
|
128
174
|
return status;
|
|
129
175
|
},
|
|
130
|
-
generate
|
|
176
|
+
generate,
|
|
131
177
|
stop,
|
|
132
178
|
reset,
|
|
133
179
|
dispose,
|
|
134
180
|
updateBody,
|
|
181
|
+
get runId() {
|
|
182
|
+
return runId;
|
|
183
|
+
},
|
|
135
184
|
};
|
|
136
185
|
}
|
|
@@ -1,16 +1,19 @@
|
|
|
1
|
+
import type { CreateGenerationOptions, CreateGenerationReturn } from './create-generation.svelte';
|
|
1
2
|
import type { StreamChunk, SummarizationResult } from '@tanstack/ai';
|
|
2
|
-
import type { AIDevtoolsDisplayOptions, ConnectConnectionAdapter, GenerationClientState, GenerationFetcher, InferGenerationOutputFromReturn, SummarizeGenerateInput } from '@tanstack/ai-client';
|
|
3
|
+
import type { AIDevtoolsDisplayOptions, ConnectConnectionAdapter, GenerationClientState, GenerationFetcher, GenerationPersistenceOptions, InferGenerationOutputFromReturn, SummarizeGenerateInput } from '@tanstack/ai-client';
|
|
3
4
|
/**
|
|
4
5
|
* Options for the createSummarize function.
|
|
5
6
|
*
|
|
6
7
|
* @template TOutput - The output type after optional transform (defaults to SummarizationResult)
|
|
7
8
|
*/
|
|
8
|
-
export interface CreateSummarizeOptions<TOutput = SummarizationResult> {
|
|
9
|
+
export interface CreateSummarizeOptions<TOutput = SummarizationResult> extends Pick<CreateGenerationOptions<SummarizeGenerateInput, SummarizationResult, 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 summarization */
|
|
12
13
|
fetcher?: GenerationFetcher<SummarizeGenerateInput, SummarizationResult>;
|
|
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 CreateSummarizeOptions<TOutput = SummarizationResult> {
|
|
|
36
39
|
*
|
|
37
40
|
* @template TOutput - The output type (after optional transform)
|
|
38
41
|
*/
|
|
39
|
-
export interface CreateSummarizeReturn<TOutput = SummarizationResult> {
|
|
42
|
+
export interface CreateSummarizeReturn<TOutput = SummarizationResult> extends Omit<CreateGenerationReturn<TOutput>, 'generate'> {
|
|
40
43
|
/** The summarization result, or null */
|
|
41
44
|
readonly result: TOutput | null;
|
|
42
45
|
/** Whether summarization is in progress */
|
|
@@ -47,12 +50,6 @@ export interface CreateSummarizeReturn<TOutput = SummarizationResult> {
|
|
|
47
50
|
readonly status: GenerationClientState;
|
|
48
51
|
/** Trigger summarization */
|
|
49
52
|
generate: (input: SummarizeGenerateInput) => Promise<void>;
|
|
50
|
-
/** Abort the current summarization */
|
|
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 text summarization instance for Svelte 5.
|
|
@@ -84,6 +81,6 @@ export interface CreateSummarizeReturn<TOutput = SummarizationResult> {
|
|
|
84
81
|
* </div>
|
|
85
82
|
* ```
|
|
86
83
|
*/
|
|
87
|
-
export declare function createSummarize<TTransformed = void>(options: Omit<CreateSummarizeOptions, 'onResult'> & {
|
|
84
|
+
export declare function createSummarize<TTransformed = void>(options: Omit<CreateSummarizeOptions, 'onResult' | 'persistence' | 'threadId' | 'id'> & {
|
|
88
85
|
onResult?: (result: SummarizationResult) => TTransformed;
|
|
89
|
-
}): CreateSummarizeReturn<InferGenerationOutputFromReturn<SummarizationResult, TTransformed>>;
|
|
86
|
+
} & GenerationPersistenceOptions): CreateSummarizeReturn<InferGenerationOutputFromReturn<SummarizationResult, TTransformed>>;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { createGeneration } from './create-generation.svelte';
|
|
2
|
+
import { reconstructSummarizeResult } from '@tanstack/ai-client';
|
|
2
3
|
/**
|
|
3
4
|
* Creates a reactive text summarization instance for Svelte 5.
|
|
4
5
|
*
|
|
@@ -39,6 +40,7 @@ export function createSummarize(options) {
|
|
|
39
40
|
const gen = createGeneration({
|
|
40
41
|
...options,
|
|
41
42
|
devtools,
|
|
43
|
+
reconstructResult: reconstructSummarizeResult,
|
|
42
44
|
});
|
|
43
45
|
return {
|
|
44
46
|
get result() {
|
|
@@ -57,5 +59,9 @@ export function createSummarize(options) {
|
|
|
57
59
|
stop: gen.stop,
|
|
58
60
|
reset: gen.reset,
|
|
59
61
|
updateBody: gen.updateBody,
|
|
62
|
+
dispose: gen.dispose,
|
|
63
|
+
get runId() {
|
|
64
|
+
return gen.runId;
|
|
65
|
+
},
|
|
60
66
|
};
|
|
61
67
|
}
|
|
@@ -1,16 +1,19 @@
|
|
|
1
|
+
import type { CreateGenerationOptions, CreateGenerationReturn } from './create-generation.svelte';
|
|
1
2
|
import type { StreamChunk, TranscriptionResult } from '@tanstack/ai';
|
|
2
|
-
import type { AIDevtoolsDisplayOptions, ConnectConnectionAdapter, GenerationClientState, GenerationFetcher, InferGenerationOutputFromReturn, TranscriptionGenerateInput } from '@tanstack/ai-client';
|
|
3
|
+
import type { AIDevtoolsDisplayOptions, ConnectConnectionAdapter, GenerationClientState, GenerationFetcher, GenerationPersistenceOptions, InferGenerationOutputFromReturn, TranscriptionGenerateInput } from '@tanstack/ai-client';
|
|
3
4
|
/**
|
|
4
5
|
* Options for the createTranscription function.
|
|
5
6
|
*
|
|
6
7
|
* @template TOutput - The output type after optional transform (defaults to TranscriptionResult)
|
|
7
8
|
*/
|
|
8
|
-
export interface CreateTranscriptionOptions<TOutput = TranscriptionResult> {
|
|
9
|
+
export interface CreateTranscriptionOptions<TOutput = TranscriptionResult> extends Pick<CreateGenerationOptions<TranscriptionGenerateInput, TranscriptionResult, 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 transcription */
|
|
12
13
|
fetcher?: GenerationFetcher<TranscriptionGenerateInput, TranscriptionResult>;
|
|
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 CreateTranscriptionOptions<TOutput = TranscriptionResult> {
|
|
|
36
39
|
*
|
|
37
40
|
* @template TOutput - The output type (after optional transform)
|
|
38
41
|
*/
|
|
39
|
-
export interface CreateTranscriptionReturn<TOutput = TranscriptionResult> {
|
|
42
|
+
export interface CreateTranscriptionReturn<TOutput = TranscriptionResult> extends Omit<CreateGenerationReturn<TOutput>, 'generate'> {
|
|
40
43
|
/** The transcription result, or null */
|
|
41
44
|
readonly result: TOutput | null;
|
|
42
45
|
/** Whether transcription is in progress */
|
|
@@ -47,12 +50,6 @@ export interface CreateTranscriptionReturn<TOutput = TranscriptionResult> {
|
|
|
47
50
|
readonly status: GenerationClientState;
|
|
48
51
|
/** Trigger transcription */
|
|
49
52
|
generate: (input: TranscriptionGenerateInput) => Promise<void>;
|
|
50
|
-
/** Abort the current transcription */
|
|
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 transcription instance for Svelte 5.
|
|
@@ -89,6 +86,6 @@ export interface CreateTranscriptionReturn<TOutput = TranscriptionResult> {
|
|
|
89
86
|
* </div>
|
|
90
87
|
* ```
|
|
91
88
|
*/
|
|
92
|
-
export declare function createTranscription<TTransformed = void>(options: Omit<CreateTranscriptionOptions, 'onResult'> & {
|
|
89
|
+
export declare function createTranscription<TTransformed = void>(options: Omit<CreateTranscriptionOptions, 'onResult' | 'persistence' | 'threadId' | 'id'> & {
|
|
93
90
|
onResult?: (result: TranscriptionResult) => TTransformed;
|
|
94
|
-
}): CreateTranscriptionReturn<InferGenerationOutputFromReturn<TranscriptionResult, TTransformed>>;
|
|
91
|
+
} & GenerationPersistenceOptions): CreateTranscriptionReturn<InferGenerationOutputFromReturn<TranscriptionResult, TTransformed>>;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { createGeneration } from './create-generation.svelte';
|
|
2
|
+
import { reconstructTranscriptionResult } from '@tanstack/ai-client';
|
|
2
3
|
/**
|
|
3
4
|
* Creates a reactive audio transcription instance for Svelte 5.
|
|
4
5
|
*
|
|
@@ -44,6 +45,7 @@ export function createTranscription(options) {
|
|
|
44
45
|
const gen = createGeneration({
|
|
45
46
|
...options,
|
|
46
47
|
devtools,
|
|
48
|
+
reconstructResult: reconstructTranscriptionResult,
|
|
47
49
|
});
|
|
48
50
|
return {
|
|
49
51
|
get result() {
|
|
@@ -62,5 +64,9 @@ export function createTranscription(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
|
}
|
package/dist/index.d.ts
CHANGED
|
@@ -16,4 +16,4 @@ export { createGenerateVideo } from './create-generate-video.svelte';
|
|
|
16
16
|
export type { CreateGenerateVideoOptions, CreateGenerateVideoReturn, } from './create-generate-video.svelte';
|
|
17
17
|
export { createAudioRecorder } from './create-audio-recorder.svelte';
|
|
18
18
|
export type { CreateAudioRecorderOptions, CreateAudioRecorderReturn, } from './create-audio-recorder.svelte';
|
|
19
|
-
export { fetchServerSentEvents, fetchHttpStream, xhrServerSentEvents, xhrHttpStream, stream, rpcStream, createChatClientOptions, clientTools, type ConnectionAdapter, type ConnectConnectionAdapter, type SubscribeConnectionAdapter, type RunAgentInputContext, type FetchConnectionOptions, type XhrConnectionOptions, type InferChatMessages, type GenerationClientState, type ImageGenerateInput, type AudioGenerateInput, type SpeechGenerateInput, type TranscriptionGenerateInput, type SummarizeGenerateInput, type VideoGenerateInput, type VideoGenerateResult, type VideoStatusInfo, } from '@tanstack/ai-client';
|
|
19
|
+
export { fetchServerSentEvents, localStoragePersistence, sessionStoragePersistence, indexedDBPersistence, StorageUnavailableError, type ChatClientPersistence, type ChatPersistedState, type ChatPersistenceOption, type ChatStorageAdapter, type WebStoragePersistenceOptions, type IndexedDBPersistenceOptions, fetchHttpStream, xhrServerSentEvents, xhrHttpStream, stream, rpcStream, createChatClientOptions, clientTools, type ConnectionAdapter, type ConnectConnectionAdapter, type SubscribeConnectionAdapter, type RunAgentInputContext, type FetchConnectionOptions, type XhrConnectionOptions, type InferChatMessages, type GenerationClientState, type ImageGenerateInput, type AudioGenerateInput, type SpeechGenerateInput, type TranscriptionGenerateInput, type SummarizeGenerateInput, type VideoGenerateInput, type VideoGenerateResult, type VideoStatusInfo, } from '@tanstack/ai-client';
|
package/dist/index.js
CHANGED
|
@@ -9,4 +9,4 @@ export { createSummarize } from './create-summarize.svelte';
|
|
|
9
9
|
export { createGenerateVideo } from './create-generate-video.svelte';
|
|
10
10
|
export { createAudioRecorder } from './create-audio-recorder.svelte';
|
|
11
11
|
// Re-export from ai-client for convenience
|
|
12
|
-
export { fetchServerSentEvents, fetchHttpStream, xhrServerSentEvents, xhrHttpStream, stream, rpcStream, createChatClientOptions, clientTools, } from '@tanstack/ai-client';
|
|
12
|
+
export { fetchServerSentEvents, localStoragePersistence, sessionStoragePersistence, indexedDBPersistence, StorageUnavailableError, fetchHttpStream, xhrServerSentEvents, xhrHttpStream, stream, rpcStream, createChatClientOptions, clientTools, } from '@tanstack/ai-client';
|
package/dist/types.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import type { AnyClientTool, InferSchemaType, ModelMessage, SchemaInput } from '@tanstack/ai';
|
|
2
|
-
import type { AIDevtoolsDisplayOptions, ChatClientOptions, ChatClientState, ChatRequestBody, ClientContextOptionFromTools, ConnectionStatus, DistributedOmit, InferredClientContext, MultimodalContent, QueueConfig, QueueOption, QueueStrategy, QueuedMessage, SendMessageOptions, UIMessage, WhenBusy } from '@tanstack/ai-client';
|
|
1
|
+
import type { AnyClientTool, InferSchemaType, ModelMessage, RunAgentResumeItem, SchemaInput } from '@tanstack/ai';
|
|
2
|
+
import type { AIDevtoolsDisplayOptions, BoundInterrupts, ChatClientOptions, ChatClientState, ChatInterrupt, ChatInterruptState, ChatRequestBody, ChatResumeState, ClientContextOptionFromTools, ConnectionStatus, DistributedOmit, InferredClientContext, MultimodalContent, QueueConfig, QueueOption, QueueStrategy, QueuedMessage, SendMessageOptions, UIMessage, WhenBusy } from '@tanstack/ai-client';
|
|
3
3
|
export type { ChatRequestBody, MultimodalContent, QueueConfig, QueuedMessage, QueueOption, QueueStrategy, SendMessageOptions, UIMessage, WhenBusy, };
|
|
4
4
|
/**
|
|
5
5
|
* Recursive partial — every property and every nested array element is
|
|
@@ -30,7 +30,7 @@ export type DeepPartial<T> = T extends ReadonlyArray<infer U> ? Array<DeepPartia
|
|
|
30
30
|
* Note: Connection and body changes will recreate the ChatClient instance.
|
|
31
31
|
* To update these options, remount the component or use a key prop.
|
|
32
32
|
*/
|
|
33
|
-
export type CreateChatOptions<TTools extends ReadonlyArray<AnyClientTool> = any, TSchema extends SchemaInput | undefined = undefined, TContext = InferredClientContext<TTools>> = DistributedOmit<ChatClientOptions<TTools, TContext>, 'onMessagesChange' | 'onLoadingChange' | 'onErrorChange' | 'onStatusChange' | 'onSubscriptionChange' | 'onConnectionStatusChange' | 'onSessionGeneratingChange' | 'onQueueChange' | 'context' | 'devtools'> & {
|
|
33
|
+
export type CreateChatOptions<TTools extends ReadonlyArray<AnyClientTool> = any, TSchema extends SchemaInput | undefined = undefined, TContext = InferredClientContext<TTools>> = DistributedOmit<ChatClientOptions<TTools, TContext>, 'onMessagesChange' | 'onLoadingChange' | 'onErrorChange' | 'onStatusChange' | 'onSubscriptionChange' | 'onConnectionStatusChange' | 'onSessionGeneratingChange' | 'onQueueChange' | 'onResumeStateChange' | 'onRunIdChange' | 'context' | 'devtools' | 'id'> & {
|
|
34
34
|
live?: boolean;
|
|
35
35
|
/** Display options for TanStack AI Devtools. */
|
|
36
36
|
devtools?: AIDevtoolsDisplayOptions;
|
|
@@ -100,6 +100,32 @@ interface BaseCreateChatReturn<TTools extends ReadonlyArray<AnyClientTool> = any
|
|
|
100
100
|
id: string;
|
|
101
101
|
approved: boolean;
|
|
102
102
|
}) => Promise<void>;
|
|
103
|
+
/**
|
|
104
|
+
* The id of the run this client has in flight — one it started or rejoined —
|
|
105
|
+
* or `null` when there is none (including while a run sits paused on an
|
|
106
|
+
* interrupt, waiting on approval).
|
|
107
|
+
*
|
|
108
|
+
* A run is one turn of the conversation, so this changes from turn to turn. A
|
|
109
|
+
* whole tool loop stays inside one run, while resuming after an interrupt
|
|
110
|
+
* continues the turn under a new id — so one user message can produce several
|
|
111
|
+
* run ids. Use it to talk to your own server about that run (cancel it, poll
|
|
112
|
+
* it, correlate a log line).
|
|
113
|
+
*/
|
|
114
|
+
readonly runId: string | null;
|
|
115
|
+
readonly interrupts: BoundInterrupts<TTools>;
|
|
116
|
+
/** @deprecated Use `interrupts`. */
|
|
117
|
+
readonly pendingInterrupts: BoundInterrupts<TTools>;
|
|
118
|
+
readonly interruptErrors: ChatInterruptState<TTools>['interruptErrors'];
|
|
119
|
+
readonly resuming: boolean;
|
|
120
|
+
resolveInterrupts: {
|
|
121
|
+
(approved: boolean): void;
|
|
122
|
+
(resolver: (interrupt: ChatInterrupt<TTools>) => undefined): void;
|
|
123
|
+
};
|
|
124
|
+
cancelInterrupts: () => void;
|
|
125
|
+
retryInterrupts: () => void;
|
|
126
|
+
resumeInterruptsUnsafe: (resume: Array<RunAgentResumeItem>, state?: ChatResumeState) => Promise<boolean>;
|
|
127
|
+
/** @deprecated Use bound interrupt methods or `resumeInterruptsUnsafe`. */
|
|
128
|
+
resumeInterrupts: (resume: Array<RunAgentResumeItem>, state?: ChatResumeState) => Promise<boolean>;
|
|
103
129
|
/**
|
|
104
130
|
* Reload the last assistant message
|
|
105
131
|
*/
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tanstack/ai-svelte",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.16.0",
|
|
4
4
|
"description": "Svelte 5 bindings for TanStack AI streaming chat, structured outputs, and media generation.",
|
|
5
5
|
"author": "Tanner Linsley",
|
|
6
6
|
"license": "MIT",
|
|
@@ -46,11 +46,11 @@
|
|
|
46
46
|
"media-generation"
|
|
47
47
|
],
|
|
48
48
|
"dependencies": {
|
|
49
|
-
"@tanstack/ai-client": "0.
|
|
49
|
+
"@tanstack/ai-client": "0.23.0"
|
|
50
50
|
},
|
|
51
51
|
"peerDependencies": {
|
|
52
52
|
"svelte": "^5.0.0",
|
|
53
|
-
"@tanstack/ai": "^0.
|
|
53
|
+
"@tanstack/ai": "^0.43.0"
|
|
54
54
|
},
|
|
55
55
|
"devDependencies": {
|
|
56
56
|
"@standard-schema/spec": "^1.1.0",
|
|
@@ -62,13 +62,13 @@
|
|
|
62
62
|
"svelte": "^5.20.0",
|
|
63
63
|
"svelte-check": "^4.2.0",
|
|
64
64
|
"typescript": "5.9.3",
|
|
65
|
-
"vite": "^
|
|
66
|
-
"@tanstack/ai": "0.
|
|
65
|
+
"vite": "^8.1.4",
|
|
66
|
+
"@tanstack/ai": "0.43.0"
|
|
67
67
|
},
|
|
68
68
|
"scripts": {
|
|
69
69
|
"clean": "rm -rf ./dist",
|
|
70
|
-
"lint:fix": "
|
|
71
|
-
"test:
|
|
70
|
+
"lint:fix": "oxlint src --type-aware --fix",
|
|
71
|
+
"test:oxlint": "oxlint src --type-aware",
|
|
72
72
|
"test:lib": "vitest run",
|
|
73
73
|
"test:lib:dev": "pnpm test:lib --watch",
|
|
74
74
|
"test:types": "svelte-check",
|