@tanstack/ai-react 0.18.1 → 0.19.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 +15 -1
- package/dist/esm/index.d.ts +1 -1
- package/dist/esm/index.js +2 -23
- package/dist/esm/mcp-app-resource.js +45 -45
- package/dist/esm/mcp-app-resource.js.map +1 -1
- package/dist/esm/mcp-apps.js +1 -4
- package/dist/esm/types.d.ts +29 -3
- package/dist/esm/use-audio-recorder.js +41 -46
- package/dist/esm/use-audio-recorder.js.map +1 -1
- package/dist/esm/use-chat.js +330 -275
- package/dist/esm/use-chat.js.map +1 -1
- package/dist/esm/use-generate-audio.d.ts +50 -4
- package/dist/esm/use-generate-audio.js +47 -23
- package/dist/esm/use-generate-audio.js.map +1 -1
- package/dist/esm/use-generate-image.d.ts +50 -4
- package/dist/esm/use-generate-image.js +49 -23
- package/dist/esm/use-generate-image.js.map +1 -1
- package/dist/esm/use-generate-speech.d.ts +50 -4
- package/dist/esm/use-generate-speech.js +43 -23
- package/dist/esm/use-generate-speech.js.map +1 -1
- package/dist/esm/use-generate-video.d.ts +50 -4
- package/dist/esm/use-generate-video.js +141 -103
- package/dist/esm/use-generate-video.js.map +1 -1
- package/dist/esm/use-generation.d.ts +59 -6
- package/dist/esm/use-generation.js +113 -90
- package/dist/esm/use-generation.js.map +1 -1
- package/dist/esm/use-mcp-app-bridge.js +46 -23
- package/dist/esm/use-mcp-app-bridge.js.map +1 -1
- package/dist/esm/use-realtime-chat.js +185 -185
- package/dist/esm/use-realtime-chat.js.map +1 -1
- package/dist/esm/use-summarize.d.ts +50 -4
- package/dist/esm/use-summarize.js +46 -23
- package/dist/esm/use-summarize.js.map +1 -1
- package/dist/esm/use-transcription.d.ts +50 -4
- package/dist/esm/use-transcription.js +51 -20
- package/dist/esm/use-transcription.js.map +1 -1
- package/package.json +7 -7
- package/src/index.ts +10 -0
- package/src/types.ts +44 -0
- package/src/use-chat.ts +221 -35
- package/src/use-generate-audio.ts +64 -17
- package/src/use-generate-image.ts +64 -17
- package/src/use-generate-speech.ts +64 -17
- package/src/use-generate-video.ts +99 -18
- package/src/use-generation.ts +112 -18
- package/src/use-summarize.ts +64 -17
- package/src/use-transcription.ts +60 -18
- package/dist/esm/index.js.map +0 -1
- package/dist/esm/mcp-apps.js.map +0 -1
package/src/use-generation.ts
CHANGED
|
@@ -8,6 +8,8 @@ import type {
|
|
|
8
8
|
GenerationClientOptions,
|
|
9
9
|
GenerationClientState,
|
|
10
10
|
GenerationFetcher,
|
|
11
|
+
GenerationPersistenceOptions,
|
|
12
|
+
GenerationRestoredResult,
|
|
11
13
|
InferGenerationOutputFromReturn,
|
|
12
14
|
} from '@tanstack/ai-client'
|
|
13
15
|
|
|
@@ -25,12 +27,51 @@ export interface UseGenerationOptions<TInput, TResult, TOutput = TResult> {
|
|
|
25
27
|
connection?: ConnectConnectionAdapter
|
|
26
28
|
/** Direct async function for one-shot generation (no streaming protocol needed) */
|
|
27
29
|
fetcher?: GenerationFetcher<TInput, TResult>
|
|
28
|
-
/**
|
|
30
|
+
/**
|
|
31
|
+
* @deprecated Prefer `threadId`. Only allowed when `threadId` is omitted (see `GenerationPersistenceOptions`).
|
|
32
|
+
*/
|
|
29
33
|
id?: string
|
|
30
34
|
/** Additional body parameters to send with connect-based adapter requests */
|
|
31
35
|
body?: Record<string, any>
|
|
32
36
|
/** Display options for TanStack AI Devtools. */
|
|
33
37
|
devtools?: AIDevtoolsDisplayOptions
|
|
38
|
+
/**
|
|
39
|
+
* How this generation persists across reloads.
|
|
40
|
+
* - Omit / `false`: ephemeral, in-memory only.
|
|
41
|
+
* - `true`: server-driven — on mount the client hydrates the last generation
|
|
42
|
+
* for its `threadId` from the server (needs a connection with a
|
|
43
|
+
* `hydrateGeneration` handler) and repaints it; it never auto-starts a run.
|
|
44
|
+
*/
|
|
45
|
+
persistence?: boolean
|
|
46
|
+
/**
|
|
47
|
+
* The **scope** this generation belongs to: a stable, app-chosen name for the
|
|
48
|
+
* slot successive runs fill — not a link to a chat conversation.
|
|
49
|
+
*
|
|
50
|
+
* The hook starts empty and produces many runs over its life; each gets its
|
|
51
|
+
* own `runId`, but all belong to one scope. Persistence keys on this, so
|
|
52
|
+
* derive it from your own domain and keep it identical across reloads (e.g.
|
|
53
|
+
* `` `video-${videoId}-start-frame` ``). It is also sent as the AG-UI thread
|
|
54
|
+
* id on the wire, which the protocol requires.
|
|
55
|
+
*
|
|
56
|
+
* **Required whenever `persistence` is set** — an app that cannot name the
|
|
57
|
+
* scope has nothing to restore to. Optional for ephemeral generations, where
|
|
58
|
+
* it falls back to `id` purely to satisfy the wire.
|
|
59
|
+
*/
|
|
60
|
+
threadId?: string
|
|
61
|
+
/**
|
|
62
|
+
* Server-driven hydration handler for `persistence: true` when the
|
|
63
|
+
* connection doesn't carry one (e.g. alongside `fetcher`, or a `stream()` /
|
|
64
|
+
* `rpcStream()` adapter built without handlers) — typically a one-line
|
|
65
|
+
* server-function call. The connection's own handler takes precedence.
|
|
66
|
+
*/
|
|
67
|
+
hydrateGeneration?: ConnectConnectionAdapter['hydrateGeneration']
|
|
68
|
+
/**
|
|
69
|
+
* Re-attach handler that replays a run still generating to completion on
|
|
70
|
+
* mount, when the connection doesn't carry one. Without it, a restored
|
|
71
|
+
* `running` snapshot surfaces as an (interrupted) error. The connection's
|
|
72
|
+
* own handler takes precedence.
|
|
73
|
+
*/
|
|
74
|
+
joinRun?: ConnectConnectionAdapter['joinRun']
|
|
34
75
|
/**
|
|
35
76
|
* Callback when a result is received. Can optionally return a transformed value.
|
|
36
77
|
*
|
|
@@ -45,16 +86,26 @@ export interface UseGenerationOptions<TInput, TResult, TOutput = TResult> {
|
|
|
45
86
|
onProgress?: (progress: number, message?: string) => void
|
|
46
87
|
/** Callback for each stream chunk (connect-based adapter mode only) */
|
|
47
88
|
onChunk?: (chunk: StreamChunk) => void
|
|
89
|
+
/**
|
|
90
|
+
* @internal Rebuild a typed result from a restored snapshot, injected by each
|
|
91
|
+
* specialized hook (image / speech / audio / transcription / summarize).
|
|
92
|
+
* Forwarded to the client so a server-hydrate restore repaints `result`.
|
|
93
|
+
*/
|
|
94
|
+
reconstructResult?: (restored: GenerationRestoredResult) => TResult | null
|
|
48
95
|
}
|
|
49
96
|
|
|
50
97
|
/**
|
|
51
98
|
* Return type for the useGeneration hook.
|
|
52
99
|
*
|
|
53
100
|
* @template TOutput - The output type (after optional transform)
|
|
101
|
+
* @template TInput - The input type accepted by `generate` (defaults to any object)
|
|
54
102
|
*/
|
|
55
|
-
export interface UseGenerationReturn<
|
|
103
|
+
export interface UseGenerationReturn<
|
|
104
|
+
TOutput,
|
|
105
|
+
TInput extends Record<string, any> = Record<string, any>,
|
|
106
|
+
> {
|
|
56
107
|
/** Trigger a generation request */
|
|
57
|
-
generate: (input:
|
|
108
|
+
generate: (input: TInput) => Promise<void>
|
|
58
109
|
/** The generation result, or null if not yet generated */
|
|
59
110
|
result: TOutput | null
|
|
60
111
|
/** Whether a generation is currently in progress */
|
|
@@ -67,6 +118,13 @@ export interface UseGenerationReturn<TOutput> {
|
|
|
67
118
|
stop: () => void
|
|
68
119
|
/** Clear result, error, and return to idle */
|
|
69
120
|
reset: () => void
|
|
121
|
+
/**
|
|
122
|
+
* The id of the generation job currently running, or `null` when nothing is in
|
|
123
|
+
* flight. Each call to `generate` is one job with its own id. Pass it to your
|
|
124
|
+
* own endpoint to cancel or poll the provider job — `stop()` only aborts the
|
|
125
|
+
* local stream, it does not stop work already running on the provider.
|
|
126
|
+
*/
|
|
127
|
+
runId: string | null
|
|
70
128
|
}
|
|
71
129
|
|
|
72
130
|
/**
|
|
@@ -99,21 +157,30 @@ export function useGeneration<
|
|
|
99
157
|
TResult,
|
|
100
158
|
TTransformed = void,
|
|
101
159
|
>(
|
|
102
|
-
options: Omit<
|
|
160
|
+
options: Omit<
|
|
161
|
+
UseGenerationOptions<TInput, TResult>,
|
|
162
|
+
'onResult' | 'persistence' | 'threadId' | 'id'
|
|
163
|
+
> & {
|
|
103
164
|
onResult?: (result: TResult) => TTransformed
|
|
104
|
-
},
|
|
105
|
-
): UseGenerationReturn<
|
|
165
|
+
} & GenerationPersistenceOptions,
|
|
166
|
+
): UseGenerationReturn<
|
|
167
|
+
InferGenerationOutputFromReturn<TResult, TTransformed>,
|
|
168
|
+
TInput
|
|
169
|
+
> {
|
|
106
170
|
type TOutput = InferGenerationOutputFromReturn<TResult, TTransformed>
|
|
107
171
|
const hookId = useId()
|
|
108
|
-
|
|
172
|
+
// Single identity: prefer `threadId`; deprecated `id` only when no threadId.
|
|
173
|
+
const clientIdentity = options.threadId ?? options.id ?? hookId
|
|
109
174
|
|
|
110
175
|
const [result, setResult] = useState<TOutput | null>(null)
|
|
111
176
|
const [isLoading, setIsLoading] = useState(false)
|
|
112
177
|
const [error, setError] = useState<Error | undefined>(undefined)
|
|
113
178
|
const [status, setStatus] = useState<GenerationClientState>('idle')
|
|
179
|
+
const [runId, setRunId] = useState<string | null>(null)
|
|
114
180
|
|
|
115
181
|
const optionsRef = useRef(options)
|
|
116
182
|
optionsRef.current = options
|
|
183
|
+
const disposedRef = useRef(false)
|
|
117
184
|
|
|
118
185
|
const client = useMemo(() => {
|
|
119
186
|
const opts = optionsRef.current
|
|
@@ -122,9 +189,20 @@ export function useGeneration<
|
|
|
122
189
|
// local source is `Record<string, any> | undefined`). Callbacks
|
|
123
190
|
// wrap optional ones in non-returning bodies so `?.()`'s
|
|
124
191
|
// implicit `undefined` doesn't pollute the function return type.
|
|
192
|
+
// Identity: pass `threadId` alone when set (never also pass deprecated `id`).
|
|
125
193
|
const clientOptions: GenerationClientOptions<TInput, TResult, TOutput> = {
|
|
126
|
-
id: clientId,
|
|
127
194
|
body: opts.body,
|
|
195
|
+
...(opts.threadId !== undefined
|
|
196
|
+
? { threadId: opts.threadId }
|
|
197
|
+
: { id: opts.id ?? hookId }),
|
|
198
|
+
...(opts.persistence !== undefined && { persistence: opts.persistence }),
|
|
199
|
+
...(opts.hydrateGeneration !== undefined && {
|
|
200
|
+
hydrateGeneration: opts.hydrateGeneration,
|
|
201
|
+
}),
|
|
202
|
+
...(opts.joinRun !== undefined && { joinRun: opts.joinRun }),
|
|
203
|
+
...(opts.reconstructResult
|
|
204
|
+
? { reconstructResult: opts.reconstructResult }
|
|
205
|
+
: {}),
|
|
128
206
|
devtoolsBridgeFactory: createGenerationDevtoolsBridge,
|
|
129
207
|
devtools: {
|
|
130
208
|
hookName: 'useGeneration',
|
|
@@ -138,18 +216,29 @@ export function useGeneration<
|
|
|
138
216
|
result: TResult,
|
|
139
217
|
) => TOutput | null | void,
|
|
140
218
|
onError: (e: Error) => {
|
|
141
|
-
optionsRef.current.onError?.(e)
|
|
219
|
+
if (!disposedRef.current) optionsRef.current.onError?.(e)
|
|
142
220
|
},
|
|
143
221
|
onProgress: (p: number, m?: string) => {
|
|
144
|
-
optionsRef.current.onProgress?.(p, m)
|
|
222
|
+
if (!disposedRef.current) optionsRef.current.onProgress?.(p, m)
|
|
145
223
|
},
|
|
146
224
|
onChunk: (c: StreamChunk) => {
|
|
147
|
-
optionsRef.current.onChunk?.(c)
|
|
225
|
+
if (!disposedRef.current) optionsRef.current.onChunk?.(c)
|
|
226
|
+
},
|
|
227
|
+
onResultChange: (r) => {
|
|
228
|
+
if (!disposedRef.current) setResult(r)
|
|
229
|
+
},
|
|
230
|
+
onLoadingChange: (l) => {
|
|
231
|
+
if (!disposedRef.current) setIsLoading(l)
|
|
232
|
+
},
|
|
233
|
+
onErrorChange: (e) => {
|
|
234
|
+
if (!disposedRef.current) setError(e)
|
|
235
|
+
},
|
|
236
|
+
onStatusChange: (s) => {
|
|
237
|
+
if (!disposedRef.current) setStatus(s)
|
|
238
|
+
},
|
|
239
|
+
onResumeStateChange: (rs) => {
|
|
240
|
+
if (!disposedRef.current) setRunId(rs?.runId ?? null)
|
|
148
241
|
},
|
|
149
|
-
onResultChange: setResult,
|
|
150
|
-
onLoadingChange: setIsLoading,
|
|
151
|
-
onErrorChange: setError,
|
|
152
|
-
onStatusChange: setStatus,
|
|
153
242
|
}
|
|
154
243
|
|
|
155
244
|
if (opts.connection) {
|
|
@@ -169,7 +258,7 @@ export function useGeneration<
|
|
|
169
258
|
throw new Error(
|
|
170
259
|
'useGeneration requires either a connection or fetcher option',
|
|
171
260
|
)
|
|
172
|
-
}, [
|
|
261
|
+
}, [clientIdentity, hookId])
|
|
173
262
|
|
|
174
263
|
// Sync body changes without recreating client
|
|
175
264
|
useEffect(() => {
|
|
@@ -179,11 +268,15 @@ export function useGeneration<
|
|
|
179
268
|
})
|
|
180
269
|
}, [client, options.body])
|
|
181
270
|
|
|
182
|
-
//
|
|
271
|
+
// Mount devtools and clean up on unmount. Generation runs are never
|
|
272
|
+
// auto-started on mount — persisted state is only displayed. Mounting
|
|
273
|
+
// revives the client after a StrictMode dispose → remount replay.
|
|
183
274
|
useEffect(() => {
|
|
275
|
+
disposedRef.current = false
|
|
184
276
|
client.mountDevtools()
|
|
185
277
|
|
|
186
278
|
return () => {
|
|
279
|
+
disposedRef.current = true
|
|
187
280
|
client.dispose()
|
|
188
281
|
}
|
|
189
282
|
}, [client])
|
|
@@ -204,12 +297,13 @@ export function useGeneration<
|
|
|
204
297
|
}, [client])
|
|
205
298
|
|
|
206
299
|
return {
|
|
207
|
-
generate
|
|
300
|
+
generate,
|
|
208
301
|
result,
|
|
209
302
|
isLoading,
|
|
210
303
|
error,
|
|
211
304
|
status,
|
|
212
305
|
stop,
|
|
213
306
|
reset,
|
|
307
|
+
runId,
|
|
214
308
|
}
|
|
215
309
|
}
|
package/src/use-summarize.ts
CHANGED
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
import { useGeneration } from './use-generation'
|
|
2
|
+
import { reconstructSummarizeResult } from '@tanstack/ai-client'
|
|
2
3
|
import type { StreamChunk, SummarizationResult } from '@tanstack/ai'
|
|
3
4
|
import type {
|
|
4
5
|
AIDevtoolsDisplayOptions,
|
|
5
6
|
ConnectConnectionAdapter,
|
|
6
7
|
GenerationClientState,
|
|
7
8
|
GenerationFetcher,
|
|
9
|
+
GenerationPersistenceOptions,
|
|
8
10
|
InferGenerationOutputFromReturn,
|
|
9
11
|
SummarizeGenerateInput,
|
|
10
12
|
} from '@tanstack/ai-client'
|
|
@@ -19,12 +21,51 @@ export interface UseSummarizeOptions<TOutput = SummarizationResult> {
|
|
|
19
21
|
connection?: ConnectConnectionAdapter
|
|
20
22
|
/** Direct async function for summarization */
|
|
21
23
|
fetcher?: GenerationFetcher<SummarizeGenerateInput, SummarizationResult>
|
|
22
|
-
/**
|
|
24
|
+
/**
|
|
25
|
+
* @deprecated Prefer `threadId`. Only allowed when `threadId` is omitted (see `GenerationPersistenceOptions`).
|
|
26
|
+
*/
|
|
23
27
|
id?: string
|
|
24
28
|
/** Additional body parameters to send with connect-based adapter requests */
|
|
25
29
|
body?: Record<string, any>
|
|
26
30
|
/** Display options for TanStack AI Devtools. */
|
|
27
31
|
devtools?: AIDevtoolsDisplayOptions
|
|
32
|
+
/**
|
|
33
|
+
* How this generation persists across reloads.
|
|
34
|
+
* - Omit / `false`: ephemeral, in-memory only.
|
|
35
|
+
* - `true`: server-driven — on mount the client hydrates the last generation
|
|
36
|
+
* for its `threadId` from the server (needs a connection with a
|
|
37
|
+
* `hydrateGeneration` handler) and repaints it; it never auto-starts a run.
|
|
38
|
+
*/
|
|
39
|
+
persistence?: boolean
|
|
40
|
+
/**
|
|
41
|
+
* The **scope** this generation belongs to: a stable, app-chosen name for the
|
|
42
|
+
* slot successive runs fill — not a link to a chat conversation.
|
|
43
|
+
*
|
|
44
|
+
* The hook starts empty and produces many runs over its life; each gets its
|
|
45
|
+
* own `runId`, but all belong to one scope. Persistence keys on this, so
|
|
46
|
+
* derive it from your own domain and keep it identical across reloads (e.g.
|
|
47
|
+
* `` `video-${videoId}-start-frame` ``). It is also sent as the AG-UI thread
|
|
48
|
+
* id on the wire, which the protocol requires.
|
|
49
|
+
*
|
|
50
|
+
* **Required whenever `persistence` is set** — an app that cannot name the
|
|
51
|
+
* scope has nothing to restore to. Optional for ephemeral generations, where
|
|
52
|
+
* it falls back to `id` purely to satisfy the wire.
|
|
53
|
+
*/
|
|
54
|
+
threadId?: string
|
|
55
|
+
/**
|
|
56
|
+
* Server-driven hydration handler for `persistence: true` when the
|
|
57
|
+
* connection doesn't carry one (e.g. alongside `fetcher`, or a `stream()` /
|
|
58
|
+
* `rpcStream()` adapter built without handlers) — typically a one-line
|
|
59
|
+
* server-function call. The connection's own handler takes precedence.
|
|
60
|
+
*/
|
|
61
|
+
hydrateGeneration?: ConnectConnectionAdapter['hydrateGeneration']
|
|
62
|
+
/**
|
|
63
|
+
* Re-attach handler that replays a run still generating to completion on
|
|
64
|
+
* mount, when the connection doesn't carry one. Without it, a restored
|
|
65
|
+
* `running` snapshot surfaces as an (interrupted) error. The connection's
|
|
66
|
+
* own handler takes precedence.
|
|
67
|
+
*/
|
|
68
|
+
joinRun?: ConnectConnectionAdapter['joinRun']
|
|
28
69
|
/**
|
|
29
70
|
* Callback when summarization is complete. Can optionally return a transformed value.
|
|
30
71
|
*
|
|
@@ -61,6 +102,13 @@ export interface UseSummarizeReturn<TOutput = SummarizationResult> {
|
|
|
61
102
|
stop: () => void
|
|
62
103
|
/** Clear result, error, and return to idle */
|
|
63
104
|
reset: () => 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
|
+
runId: string | null
|
|
64
112
|
}
|
|
65
113
|
|
|
66
114
|
/**
|
|
@@ -93,9 +141,12 @@ export interface UseSummarizeReturn<TOutput = SummarizationResult> {
|
|
|
93
141
|
* ```
|
|
94
142
|
*/
|
|
95
143
|
export function useSummarize<TTransformed = void>(
|
|
96
|
-
options: Omit<
|
|
144
|
+
options: Omit<
|
|
145
|
+
UseSummarizeOptions,
|
|
146
|
+
'onResult' | 'persistence' | 'threadId' | 'id'
|
|
147
|
+
> & {
|
|
97
148
|
onResult?: (result: SummarizationResult) => TTransformed
|
|
98
|
-
},
|
|
149
|
+
} & GenerationPersistenceOptions,
|
|
99
150
|
): UseSummarizeReturn<
|
|
100
151
|
InferGenerationOutputFromReturn<SummarizationResult, TTransformed>
|
|
101
152
|
> {
|
|
@@ -105,19 +156,15 @@ export function useSummarize<TTransformed = void>(
|
|
|
105
156
|
hookName: 'useSummarize',
|
|
106
157
|
outputKind: 'text' as const,
|
|
107
158
|
}
|
|
108
|
-
const
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
159
|
+
const generation = useGeneration<
|
|
160
|
+
SummarizeGenerateInput,
|
|
161
|
+
SummarizationResult,
|
|
162
|
+
TTransformed
|
|
163
|
+
>({
|
|
164
|
+
...options,
|
|
165
|
+
devtools,
|
|
166
|
+
reconstructResult: reconstructSummarizeResult,
|
|
167
|
+
})
|
|
113
168
|
|
|
114
|
-
return
|
|
115
|
-
generate: generate as (input: SummarizeGenerateInput) => Promise<void>,
|
|
116
|
-
result,
|
|
117
|
-
isLoading,
|
|
118
|
-
error,
|
|
119
|
-
status,
|
|
120
|
-
stop,
|
|
121
|
-
reset,
|
|
122
|
-
}
|
|
169
|
+
return generation
|
|
123
170
|
}
|
package/src/use-transcription.ts
CHANGED
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
import { useGeneration } from './use-generation'
|
|
2
|
+
import { reconstructTranscriptionResult } from '@tanstack/ai-client'
|
|
2
3
|
import type { StreamChunk, TranscriptionResult } from '@tanstack/ai'
|
|
3
4
|
import type {
|
|
4
5
|
AIDevtoolsDisplayOptions,
|
|
5
6
|
ConnectConnectionAdapter,
|
|
6
7
|
GenerationClientState,
|
|
7
8
|
GenerationFetcher,
|
|
9
|
+
GenerationPersistenceOptions,
|
|
8
10
|
InferGenerationOutputFromReturn,
|
|
9
11
|
TranscriptionGenerateInput,
|
|
10
12
|
} from '@tanstack/ai-client'
|
|
@@ -19,12 +21,51 @@ export interface UseTranscriptionOptions<TOutput = TranscriptionResult> {
|
|
|
19
21
|
connection?: ConnectConnectionAdapter
|
|
20
22
|
/** Direct async function for transcription */
|
|
21
23
|
fetcher?: GenerationFetcher<TranscriptionGenerateInput, TranscriptionResult>
|
|
22
|
-
/**
|
|
24
|
+
/**
|
|
25
|
+
* @deprecated Prefer `threadId`. Only allowed when `threadId` is omitted (see `GenerationPersistenceOptions`).
|
|
26
|
+
*/
|
|
23
27
|
id?: string
|
|
24
28
|
/** Additional body parameters to send with connect-based adapter requests */
|
|
25
29
|
body?: Record<string, any>
|
|
26
30
|
/** Display options for TanStack AI Devtools. */
|
|
27
31
|
devtools?: AIDevtoolsDisplayOptions
|
|
32
|
+
/**
|
|
33
|
+
* How this generation persists across reloads.
|
|
34
|
+
* - Omit / `false`: ephemeral, in-memory only.
|
|
35
|
+
* - `true`: server-driven — on mount the client hydrates the last generation
|
|
36
|
+
* for its `threadId` from the server (needs a connection with a
|
|
37
|
+
* `hydrateGeneration` handler) and repaints it; it never auto-starts a run.
|
|
38
|
+
*/
|
|
39
|
+
persistence?: boolean
|
|
40
|
+
/**
|
|
41
|
+
* The **scope** this generation belongs to: a stable, app-chosen name for the
|
|
42
|
+
* slot successive runs fill — not a link to a chat conversation.
|
|
43
|
+
*
|
|
44
|
+
* The hook starts empty and produces many runs over its life; each gets its
|
|
45
|
+
* own `runId`, but all belong to one scope. Persistence keys on this, so
|
|
46
|
+
* derive it from your own domain and keep it identical across reloads (e.g.
|
|
47
|
+
* `` `video-${videoId}-start-frame` ``). It is also sent as the AG-UI thread
|
|
48
|
+
* id on the wire, which the protocol requires.
|
|
49
|
+
*
|
|
50
|
+
* **Required whenever `persistence` is set** — an app that cannot name the
|
|
51
|
+
* scope has nothing to restore to. Optional for ephemeral generations, where
|
|
52
|
+
* it falls back to `id` purely to satisfy the wire.
|
|
53
|
+
*/
|
|
54
|
+
threadId?: string
|
|
55
|
+
/**
|
|
56
|
+
* Server-driven hydration handler for `persistence: true` when the
|
|
57
|
+
* connection doesn't carry one (e.g. alongside `fetcher`, or a `stream()` /
|
|
58
|
+
* `rpcStream()` adapter built without handlers) — typically a one-line
|
|
59
|
+
* server-function call. The connection's own handler takes precedence.
|
|
60
|
+
*/
|
|
61
|
+
hydrateGeneration?: ConnectConnectionAdapter['hydrateGeneration']
|
|
62
|
+
/**
|
|
63
|
+
* Re-attach handler that replays a run still generating to completion on
|
|
64
|
+
* mount, when the connection doesn't carry one. Without it, a restored
|
|
65
|
+
* `running` snapshot surfaces as an (interrupted) error. The connection's
|
|
66
|
+
* own handler takes precedence.
|
|
67
|
+
*/
|
|
68
|
+
joinRun?: ConnectConnectionAdapter['joinRun']
|
|
28
69
|
/**
|
|
29
70
|
* Callback when transcription is complete. Can optionally return a transformed value.
|
|
30
71
|
*
|
|
@@ -61,6 +102,13 @@ export interface UseTranscriptionReturn<TOutput = TranscriptionResult> {
|
|
|
61
102
|
stop: () => void
|
|
62
103
|
/** Clear result, error, and return to idle */
|
|
63
104
|
reset: () => 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
|
+
runId: string | null
|
|
64
112
|
}
|
|
65
113
|
|
|
66
114
|
/**
|
|
@@ -98,9 +146,12 @@ export interface UseTranscriptionReturn<TOutput = TranscriptionResult> {
|
|
|
98
146
|
* ```
|
|
99
147
|
*/
|
|
100
148
|
export function useTranscription<TTransformed = void>(
|
|
101
|
-
options: Omit<
|
|
149
|
+
options: Omit<
|
|
150
|
+
UseTranscriptionOptions,
|
|
151
|
+
'onResult' | 'persistence' | 'threadId' | 'id'
|
|
152
|
+
> & {
|
|
102
153
|
onResult?: (result: TranscriptionResult) => TTransformed
|
|
103
|
-
},
|
|
154
|
+
} & GenerationPersistenceOptions,
|
|
104
155
|
): UseTranscriptionReturn<
|
|
105
156
|
InferGenerationOutputFromReturn<TranscriptionResult, TTransformed>
|
|
106
157
|
> {
|
|
@@ -110,20 +161,11 @@ export function useTranscription<TTransformed = void>(
|
|
|
110
161
|
hookName: 'useTranscription',
|
|
111
162
|
outputKind: 'text' as const,
|
|
112
163
|
}
|
|
113
|
-
const
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
>({ ...options, devtools })
|
|
164
|
+
const generation = useGeneration<
|
|
165
|
+
TranscriptionGenerateInput,
|
|
166
|
+
TranscriptionResult,
|
|
167
|
+
TTransformed
|
|
168
|
+
>({ ...options, devtools, reconstructResult: reconstructTranscriptionResult })
|
|
119
169
|
|
|
120
|
-
return
|
|
121
|
-
generate: generate as (input: TranscriptionGenerateInput) => Promise<void>,
|
|
122
|
-
result,
|
|
123
|
-
isLoading,
|
|
124
|
-
error,
|
|
125
|
-
status,
|
|
126
|
-
stop,
|
|
127
|
-
reset,
|
|
128
|
-
}
|
|
170
|
+
return generation
|
|
129
171
|
}
|
package/dist/esm/index.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;"}
|
package/dist/esm/mcp-apps.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"mcp-apps.js","sources":[],"sourcesContent":[],"names":[],"mappings":";"}
|