@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.
Files changed (49) hide show
  1. package/README.md +15 -1
  2. package/dist/esm/index.d.ts +1 -1
  3. package/dist/esm/index.js +2 -23
  4. package/dist/esm/mcp-app-resource.js +45 -45
  5. package/dist/esm/mcp-app-resource.js.map +1 -1
  6. package/dist/esm/mcp-apps.js +1 -4
  7. package/dist/esm/types.d.ts +29 -3
  8. package/dist/esm/use-audio-recorder.js +41 -46
  9. package/dist/esm/use-audio-recorder.js.map +1 -1
  10. package/dist/esm/use-chat.js +330 -275
  11. package/dist/esm/use-chat.js.map +1 -1
  12. package/dist/esm/use-generate-audio.d.ts +50 -4
  13. package/dist/esm/use-generate-audio.js +47 -23
  14. package/dist/esm/use-generate-audio.js.map +1 -1
  15. package/dist/esm/use-generate-image.d.ts +50 -4
  16. package/dist/esm/use-generate-image.js +49 -23
  17. package/dist/esm/use-generate-image.js.map +1 -1
  18. package/dist/esm/use-generate-speech.d.ts +50 -4
  19. package/dist/esm/use-generate-speech.js +43 -23
  20. package/dist/esm/use-generate-speech.js.map +1 -1
  21. package/dist/esm/use-generate-video.d.ts +50 -4
  22. package/dist/esm/use-generate-video.js +141 -103
  23. package/dist/esm/use-generate-video.js.map +1 -1
  24. package/dist/esm/use-generation.d.ts +59 -6
  25. package/dist/esm/use-generation.js +113 -90
  26. package/dist/esm/use-generation.js.map +1 -1
  27. package/dist/esm/use-mcp-app-bridge.js +46 -23
  28. package/dist/esm/use-mcp-app-bridge.js.map +1 -1
  29. package/dist/esm/use-realtime-chat.js +185 -185
  30. package/dist/esm/use-realtime-chat.js.map +1 -1
  31. package/dist/esm/use-summarize.d.ts +50 -4
  32. package/dist/esm/use-summarize.js +46 -23
  33. package/dist/esm/use-summarize.js.map +1 -1
  34. package/dist/esm/use-transcription.d.ts +50 -4
  35. package/dist/esm/use-transcription.js +51 -20
  36. package/dist/esm/use-transcription.js.map +1 -1
  37. package/package.json +7 -7
  38. package/src/index.ts +10 -0
  39. package/src/types.ts +44 -0
  40. package/src/use-chat.ts +221 -35
  41. package/src/use-generate-audio.ts +64 -17
  42. package/src/use-generate-image.ts +64 -17
  43. package/src/use-generate-speech.ts +64 -17
  44. package/src/use-generate-video.ts +99 -18
  45. package/src/use-generation.ts +112 -18
  46. package/src/use-summarize.ts +64 -17
  47. package/src/use-transcription.ts +60 -18
  48. package/dist/esm/index.js.map +0 -1
  49. package/dist/esm/mcp-apps.js.map +0 -1
@@ -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
- /** Unique identifier for this generation instance */
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<TOutput> {
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: Record<string, any>) => Promise<void>
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<UseGenerationOptions<TInput, TResult>, 'onResult'> & {
160
+ options: Omit<
161
+ UseGenerationOptions<TInput, TResult>,
162
+ 'onResult' | 'persistence' | 'threadId' | 'id'
163
+ > & {
103
164
  onResult?: (result: TResult) => TTransformed
104
- },
105
- ): UseGenerationReturn<InferGenerationOutputFromReturn<TResult, TTransformed>> {
165
+ } & GenerationPersistenceOptions,
166
+ ): UseGenerationReturn<
167
+ InferGenerationOutputFromReturn<TResult, TTransformed>,
168
+ TInput
169
+ > {
106
170
  type TOutput = InferGenerationOutputFromReturn<TResult, TTransformed>
107
171
  const hookId = useId()
108
- const clientId = options.id || hookId
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
- }, [clientId])
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
- // Cleanup on unmount
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: generate as (input: Record<string, any>) => Promise<void>,
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
  }
@@ -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
- /** Unique identifier for this generation instance */
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<UseSummarizeOptions, 'onResult'> & {
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 { generate, result, isLoading, error, status, stop, reset } =
109
- useGeneration<SummarizeGenerateInput, SummarizationResult, TTransformed>({
110
- ...options,
111
- devtools,
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
  }
@@ -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
- /** Unique identifier for this generation instance */
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<UseTranscriptionOptions, 'onResult'> & {
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 { generate, result, isLoading, error, status, stop, reset } =
114
- useGeneration<
115
- TranscriptionGenerateInput,
116
- TranscriptionResult,
117
- TTransformed
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
  }
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"mcp-apps.js","sources":[],"sourcesContent":[],"names":[],"mappings":";"}