@tanstack/ai-svelte 0.10.8 → 0.10.10

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.
@@ -1,4 +1,5 @@
1
1
  import { ChatClient } from '@tanstack/ai-client';
2
+ import { createChatDevtoolsBridge } from '@tanstack/ai-client/devtools';
2
3
  /**
3
4
  * Creates a reactive chat instance for Svelte 5.
4
5
  *
@@ -51,8 +52,12 @@ export function createChat(options) {
51
52
  // rather than `field?: T | undefined`. Under `exactOptionalPropertyTypes`,
52
53
  // passing an explicit `undefined` for an absent-only optional is a type
53
54
  // error, so we omit the key when the caller's value is undefined.
55
+ const transport = options.connection
56
+ ? { connection: options.connection }
57
+ : { fetcher: options.fetcher };
54
58
  const client = new ChatClient({
55
- connection: options.connection,
59
+ devtoolsBridgeFactory: createChatDevtoolsBridge,
60
+ ...transport,
56
61
  id: clientId,
57
62
  ...(options.initialMessages !== undefined && {
58
63
  initialMessages: options.initialMessages,
@@ -61,6 +66,12 @@ export function createChat(options) {
61
66
  ...(options.forwardedProps !== undefined && {
62
67
  forwardedProps: options.forwardedProps,
63
68
  }),
69
+ devtools: {
70
+ ...options.devtools,
71
+ framework: 'svelte',
72
+ hookName: 'useChat',
73
+ outputKind: options.outputSchema ? 'structured' : 'chat',
74
+ },
64
75
  ...(options.onResponse !== undefined && { onResponse: options.onResponse }),
65
76
  onChunk: (chunk) => {
66
77
  options.onChunk?.(chunk);
@@ -103,6 +114,7 @@ export function createChat(options) {
103
114
  if (options.live) {
104
115
  client.subscribe();
105
116
  }
117
+ client.mountDevtools();
106
118
  // Note: Cleanup is handled by calling stop() directly when needed.
107
119
  // Unlike React/Vue/Solid, Svelte 5 runes like $effect can only be used
108
120
  // during component initialization, so we don't add automatic cleanup here.
@@ -120,6 +132,9 @@ export function createChat(options) {
120
132
  const stop = () => {
121
133
  client.stop();
122
134
  };
135
+ const dispose = () => {
136
+ client.dispose();
137
+ };
123
138
  const clear = () => {
124
139
  client.clear();
125
140
  };
@@ -212,6 +227,7 @@ export function createChat(options) {
212
227
  append,
213
228
  reload,
214
229
  stop,
230
+ dispose,
215
231
  setMessages,
216
232
  clear,
217
233
  addToolResult,
@@ -1,5 +1,5 @@
1
1
  import type { AudioGenerationResult, StreamChunk } from '@tanstack/ai';
2
- import type { AudioGenerateInput, ConnectConnectionAdapter, GenerationClientState, GenerationFetcher, InferGenerationOutput } from '@tanstack/ai-client';
2
+ import type { AIDevtoolsDisplayOptions, AudioGenerateInput, ConnectConnectionAdapter, GenerationClientState, GenerationFetcher, InferGenerationOutput } from '@tanstack/ai-client';
3
3
  /**
4
4
  * Options for the createGenerateAudio function.
5
5
  *
@@ -14,6 +14,8 @@ export interface CreateGenerateAudioOptions<TOutput = AudioGenerationResult> {
14
14
  id?: string;
15
15
  /** Additional body parameters to send with connect-based adapter requests */
16
16
  body?: Record<string, any>;
17
+ /** Display options for TanStack AI Devtools. */
18
+ devtools?: AIDevtoolsDisplayOptions;
17
19
  /**
18
20
  * Callback when audio is generated. Can optionally return a transformed value.
19
21
  *
@@ -26,7 +26,16 @@ import { createGeneration } from './create-generation.svelte';
26
26
  * ```
27
27
  */
28
28
  export function createGenerateAudio(options) {
29
- const gen = createGeneration(options);
29
+ const devtools = {
30
+ ...options.devtools,
31
+ framework: 'svelte',
32
+ hookName: 'createGenerateAudio',
33
+ outputKind: 'audio',
34
+ };
35
+ const gen = createGeneration({
36
+ ...options,
37
+ devtools,
38
+ });
30
39
  return {
31
40
  get result() {
32
41
  return gen.result;
@@ -1,5 +1,5 @@
1
1
  import type { ImageGenerationResult, StreamChunk } from '@tanstack/ai';
2
- import type { ConnectConnectionAdapter, GenerationClientState, GenerationFetcher, ImageGenerateInput, InferGenerationOutput } from '@tanstack/ai-client';
2
+ import type { AIDevtoolsDisplayOptions, ConnectConnectionAdapter, GenerationClientState, GenerationFetcher, ImageGenerateInput, InferGenerationOutput } from '@tanstack/ai-client';
3
3
  /**
4
4
  * Options for the createGenerateImage function.
5
5
  *
@@ -14,6 +14,8 @@ export interface CreateGenerateImageOptions<TOutput = ImageGenerationResult> {
14
14
  id?: string;
15
15
  /** Additional body parameters to send with connect-based adapter requests */
16
16
  body?: Record<string, any>;
17
+ /** Display options for TanStack AI Devtools. */
18
+ devtools?: AIDevtoolsDisplayOptions;
17
19
  /**
18
20
  * Callback when images are generated. Can optionally return a transformed value.
19
21
  *
@@ -35,7 +35,16 @@ import { createGeneration } from './create-generation.svelte';
35
35
  * ```
36
36
  */
37
37
  export function createGenerateImage(options) {
38
- const gen = createGeneration(options);
38
+ const devtools = {
39
+ ...options.devtools,
40
+ framework: 'svelte',
41
+ hookName: 'createGenerateImage',
42
+ outputKind: 'image',
43
+ };
44
+ const gen = createGeneration({
45
+ ...options,
46
+ devtools,
47
+ });
39
48
  return {
40
49
  get result() {
41
50
  return gen.result;
@@ -1,5 +1,5 @@
1
1
  import type { StreamChunk, TTSResult } from '@tanstack/ai';
2
- import type { ConnectConnectionAdapter, GenerationClientState, GenerationFetcher, InferGenerationOutput, SpeechGenerateInput } from '@tanstack/ai-client';
2
+ import type { AIDevtoolsDisplayOptions, ConnectConnectionAdapter, GenerationClientState, GenerationFetcher, InferGenerationOutput, SpeechGenerateInput } from '@tanstack/ai-client';
3
3
  /**
4
4
  * Options for the createGenerateSpeech function.
5
5
  *
@@ -14,6 +14,8 @@ export interface CreateGenerateSpeechOptions<TOutput = TTSResult> {
14
14
  id?: string;
15
15
  /** Additional body parameters to send with connect-based adapter requests */
16
16
  body?: Record<string, any>;
17
+ /** Display options for TanStack AI Devtools. */
18
+ devtools?: AIDevtoolsDisplayOptions;
17
19
  /**
18
20
  * Callback when speech is generated. Can optionally return a transformed value.
19
21
  *
@@ -26,7 +26,16 @@ import { createGeneration } from './create-generation.svelte';
26
26
  * ```
27
27
  */
28
28
  export function createGenerateSpeech(options) {
29
- const gen = createGeneration(options);
29
+ const devtools = {
30
+ ...options.devtools,
31
+ framework: 'svelte',
32
+ hookName: 'createGenerateSpeech',
33
+ outputKind: 'audio',
34
+ };
35
+ const gen = createGeneration({
36
+ ...options,
37
+ devtools,
38
+ });
30
39
  return {
31
40
  get result() {
32
41
  return gen.result;
@@ -1,5 +1,5 @@
1
1
  import type { StreamChunk } from '@tanstack/ai';
2
- import type { ConnectConnectionAdapter, GenerationClientState, GenerationFetcher, InferGenerationOutput, VideoGenerateInput, VideoGenerateResult, VideoStatusInfo } from '@tanstack/ai-client';
2
+ import type { AIDevtoolsDisplayOptions, ConnectConnectionAdapter, GenerationClientState, GenerationFetcher, InferGenerationOutput, VideoGenerateInput, VideoGenerateResult, VideoStatusInfo } from '@tanstack/ai-client';
3
3
  /**
4
4
  * Options for the createGenerateVideo function.
5
5
  *
@@ -14,6 +14,8 @@ export interface CreateGenerateVideoOptions<TOutput = VideoGenerateResult> {
14
14
  id?: string;
15
15
  /** Additional body parameters to send with connect-based adapter requests */
16
16
  body?: Record<string, any>;
17
+ /** Display options for TanStack AI Devtools. */
18
+ devtools?: AIDevtoolsDisplayOptions;
17
19
  /**
18
20
  * Callback when video generation completes. Can optionally return a transformed value.
19
21
  *
@@ -57,6 +59,8 @@ export interface CreateGenerateVideoReturn<TOutput = VideoGenerateResult> {
57
59
  stop: () => void;
58
60
  /** Clear all state and return to idle */
59
61
  reset: () => void;
62
+ /** Stop in-flight work and unregister devtools listeners */
63
+ dispose: () => void;
60
64
  /** Update additional body parameters */
61
65
  updateBody: (body: Record<string, any>) => void;
62
66
  }
@@ -1,4 +1,5 @@
1
1
  import { VideoGenerationClient } from '@tanstack/ai-client';
2
+ import { createVideoDevtoolsBridge } from '@tanstack/ai-client/devtools';
2
3
  /**
3
4
  * Creates a reactive video generation instance for Svelte 5.
4
5
  *
@@ -46,6 +47,13 @@ export function createGenerateVideo(options) {
46
47
  const baseOptions = {
47
48
  id: clientId,
48
49
  body: options.body,
50
+ devtoolsBridgeFactory: createVideoDevtoolsBridge,
51
+ devtools: {
52
+ ...options.devtools,
53
+ framework: 'svelte',
54
+ hookName: 'createGenerateVideo',
55
+ outputKind: 'video',
56
+ },
49
57
  onResult: (r) => options.onResult?.(r),
50
58
  onError: (e) => options.onError?.(e),
51
59
  onProgress: (p, m) => options.onProgress?.(p, m),
@@ -87,10 +95,11 @@ export function createGenerateVideo(options) {
87
95
  else {
88
96
  throw new Error('createGenerateVideo requires either a connection or fetcher option');
89
97
  }
90
- // Note: Cleanup is handled by calling stop() directly when needed.
98
+ client.mountDevtools();
99
+ // Note: Cleanup is handled by calling dispose() directly when needed.
91
100
  // Unlike React/Vue/Solid, Svelte 5 runes like $effect can only be used
92
101
  // during component initialization, so we don't add automatic cleanup here.
93
- // Users should call video.stop() in their component's cleanup if needed.
102
+ // Users should call video.dispose() in their component's cleanup if needed.
94
103
  const generate = async (input) => {
95
104
  await client.generate(input);
96
105
  };
@@ -100,6 +109,9 @@ export function createGenerateVideo(options) {
100
109
  const reset = () => {
101
110
  client.reset();
102
111
  };
112
+ const dispose = () => {
113
+ client.dispose();
114
+ };
103
115
  const updateBody = (newBody) => {
104
116
  client.updateOptions({ body: newBody });
105
117
  };
@@ -125,6 +137,7 @@ export function createGenerateVideo(options) {
125
137
  generate,
126
138
  stop,
127
139
  reset,
140
+ dispose,
128
141
  updateBody,
129
142
  };
130
143
  }
@@ -1,5 +1,5 @@
1
1
  import type { StreamChunk } from '@tanstack/ai';
2
- import type { ConnectConnectionAdapter, GenerationClientState, GenerationFetcher, InferGenerationOutput } from '@tanstack/ai-client';
2
+ import type { AIDevtoolsDisplayOptions, ConnectConnectionAdapter, GenerationClientState, GenerationFetcher, InferGenerationOutput } from '@tanstack/ai-client';
3
3
  /**
4
4
  * Options for the createGeneration function.
5
5
  *
@@ -18,6 +18,8 @@ export interface CreateGenerationOptions<TInput, TResult, TOutput = TResult> {
18
18
  id?: string;
19
19
  /** Additional body parameters to send with connect-based adapter requests */
20
20
  body?: Record<string, any>;
21
+ /** Display options for TanStack AI Devtools. */
22
+ devtools?: AIDevtoolsDisplayOptions;
21
23
  /**
22
24
  * Callback when a result is received. Can optionally return a transformed value.
23
25
  *
@@ -53,6 +55,8 @@ export interface CreateGenerationReturn<TOutput> {
53
55
  stop: () => void;
54
56
  /** Clear result, error, and return to idle */
55
57
  reset: () => void;
58
+ /** Stop in-flight work and unregister devtools listeners */
59
+ dispose: () => void;
56
60
  /** Update additional body parameters */
57
61
  updateBody: (body: Record<string, any>) => void;
58
62
  }
@@ -1,4 +1,5 @@
1
1
  import { GenerationClient } from '@tanstack/ai-client';
2
+ import { createGenerationDevtoolsBridge } from '@tanstack/ai-client/devtools';
2
3
  /**
3
4
  * Creates a reactive generation instance for Svelte 5.
4
5
  *
@@ -45,6 +46,12 @@ export function createGeneration(options) {
45
46
  const clientOptions = {
46
47
  id: clientId,
47
48
  body: options.body,
49
+ devtoolsBridgeFactory: createGenerationDevtoolsBridge,
50
+ devtools: {
51
+ ...options.devtools,
52
+ framework: 'svelte',
53
+ hookName: 'createGeneration',
54
+ },
48
55
  onResult: (r) => options.onResult?.(r),
49
56
  onError: (e) => options.onError?.(e),
50
57
  onProgress: (p, m) => options.onProgress?.(p, m),
@@ -78,10 +85,11 @@ export function createGeneration(options) {
78
85
  else {
79
86
  throw new Error('createGeneration requires either a connection or fetcher option');
80
87
  }
81
- // Note: Cleanup is handled by calling stop() directly when needed.
88
+ client.mountDevtools();
89
+ // Note: Cleanup is handled by calling dispose() directly when needed.
82
90
  // Unlike React/Vue/Solid, Svelte 5 runes like $effect can only be used
83
91
  // during component initialization, so we don't add automatic cleanup here.
84
- // Users should call gen.stop() in their component's cleanup if needed.
92
+ // Users should call gen.dispose() in their component's cleanup if needed.
85
93
  const generate = async (input) => {
86
94
  await client.generate(input);
87
95
  };
@@ -91,6 +99,9 @@ export function createGeneration(options) {
91
99
  const reset = () => {
92
100
  client.reset();
93
101
  };
102
+ const dispose = () => {
103
+ client.dispose();
104
+ };
94
105
  const updateBody = (newBody) => {
95
106
  client.updateOptions({ body: newBody });
96
107
  };
@@ -110,6 +121,7 @@ export function createGeneration(options) {
110
121
  generate: generate,
111
122
  stop,
112
123
  reset,
124
+ dispose,
113
125
  updateBody,
114
126
  };
115
127
  }
@@ -1,5 +1,5 @@
1
1
  import type { StreamChunk, SummarizationResult } from '@tanstack/ai';
2
- import type { ConnectConnectionAdapter, GenerationClientState, GenerationFetcher, InferGenerationOutput, SummarizeGenerateInput } from '@tanstack/ai-client';
2
+ import type { AIDevtoolsDisplayOptions, ConnectConnectionAdapter, GenerationClientState, GenerationFetcher, InferGenerationOutput, SummarizeGenerateInput } from '@tanstack/ai-client';
3
3
  /**
4
4
  * Options for the createSummarize function.
5
5
  *
@@ -14,6 +14,8 @@ export interface CreateSummarizeOptions<TOutput = SummarizationResult> {
14
14
  id?: string;
15
15
  /** Additional body parameters to send with connect-based adapter requests */
16
16
  body?: Record<string, any>;
17
+ /** Display options for TanStack AI Devtools. */
18
+ devtools?: AIDevtoolsDisplayOptions;
17
19
  /**
18
20
  * Callback when summarization is complete. Can optionally return a transformed value.
19
21
  *
@@ -30,7 +30,16 @@ import { createGeneration } from './create-generation.svelte';
30
30
  * ```
31
31
  */
32
32
  export function createSummarize(options) {
33
- const gen = createGeneration(options);
33
+ const devtools = {
34
+ ...options.devtools,
35
+ framework: 'svelte',
36
+ hookName: 'createSummarize',
37
+ outputKind: 'text',
38
+ };
39
+ const gen = createGeneration({
40
+ ...options,
41
+ devtools,
42
+ });
34
43
  return {
35
44
  get result() {
36
45
  return gen.result;
@@ -1,5 +1,5 @@
1
1
  import type { StreamChunk, TranscriptionResult } from '@tanstack/ai';
2
- import type { ConnectConnectionAdapter, GenerationClientState, GenerationFetcher, InferGenerationOutput, TranscriptionGenerateInput } from '@tanstack/ai-client';
2
+ import type { AIDevtoolsDisplayOptions, ConnectConnectionAdapter, GenerationClientState, GenerationFetcher, InferGenerationOutput, TranscriptionGenerateInput } from '@tanstack/ai-client';
3
3
  /**
4
4
  * Options for the createTranscription function.
5
5
  *
@@ -14,6 +14,8 @@ export interface CreateTranscriptionOptions<TOutput = TranscriptionResult> {
14
14
  id?: string;
15
15
  /** Additional body parameters to send with connect-based adapter requests */
16
16
  body?: Record<string, any>;
17
+ /** Display options for TanStack AI Devtools. */
18
+ devtools?: AIDevtoolsDisplayOptions;
17
19
  /**
18
20
  * Callback when transcription is complete. Can optionally return a transformed value.
19
21
  *
@@ -35,7 +35,16 @@ import { createGeneration } from './create-generation.svelte';
35
35
  * ```
36
36
  */
37
37
  export function createTranscription(options) {
38
- const gen = createGeneration(options);
38
+ const devtools = {
39
+ ...options.devtools,
40
+ framework: 'svelte',
41
+ hookName: 'createTranscription',
42
+ outputKind: 'text',
43
+ };
44
+ const gen = createGeneration({
45
+ ...options,
46
+ devtools,
47
+ });
39
48
  return {
40
49
  get result() {
41
50
  return gen.result;
package/dist/types.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import type { AnyClientTool, InferSchemaType, ModelMessage, SchemaInput } from '@tanstack/ai';
2
- import type { ChatClientOptions, ChatClientState, ChatRequestBody, ConnectionStatus, MultimodalContent, UIMessage } from '@tanstack/ai-client';
2
+ import type { AIDevtoolsDisplayOptions, ChatClientOptions, ChatClientState, ChatRequestBody, ConnectionStatus, DistributedOmit, MultimodalContent, UIMessage } from '@tanstack/ai-client';
3
3
  export type { ChatRequestBody, MultimodalContent, UIMessage };
4
4
  /**
5
5
  * Recursive partial — every property and every nested array element is
@@ -30,8 +30,10 @@ 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> = Omit<ChatClientOptions<TTools>, 'onMessagesChange' | 'onLoadingChange' | 'onErrorChange' | 'onStatusChange' | 'onSubscriptionChange' | 'onConnectionStatusChange' | 'onSessionGeneratingChange'> & {
33
+ export type CreateChatOptions<TTools extends ReadonlyArray<AnyClientTool> = any, TSchema extends SchemaInput | undefined = undefined> = DistributedOmit<ChatClientOptions<TTools>, 'onMessagesChange' | 'onLoadingChange' | 'onErrorChange' | 'onStatusChange' | 'onSubscriptionChange' | 'onConnectionStatusChange' | 'onSessionGeneratingChange' | 'devtools'> & {
34
34
  live?: boolean;
35
+ /** Display options for TanStack AI Devtools. */
36
+ devtools?: AIDevtoolsDisplayOptions;
35
37
  /**
36
38
  * Standard-schema-compatible schema (Zod, Valibot, ArkType, or plain JSON
37
39
  * Schema). Used to infer the shape of `partial` and `final`.
@@ -98,6 +100,10 @@ interface BaseCreateChatReturn<TTools extends ReadonlyArray<AnyClientTool> = any
98
100
  * Stop the current response generation
99
101
  */
100
102
  stop: () => void;
103
+ /**
104
+ * Dispose the chat client and unregister it from devtools.
105
+ */
106
+ dispose: () => void;
101
107
  /**
102
108
  * Whether a response is currently being generated (reactive getter)
103
109
  */
package/package.json CHANGED
@@ -1,13 +1,13 @@
1
1
  {
2
2
  "name": "@tanstack/ai-svelte",
3
- "version": "0.10.8",
3
+ "version": "0.10.10",
4
4
  "description": "Svelte 5 bindings for TanStack AI streaming chat, structured outputs, and media generation.",
5
5
  "author": "",
6
6
  "license": "MIT",
7
7
  "repository": {
8
8
  "type": "git",
9
9
  "url": "git+https://github.com/TanStack/ai.git",
10
- "directory": "packages/typescript/ai-svelte"
10
+ "directory": "packages/ai-svelte"
11
11
  },
12
12
  "type": "module",
13
13
  "svelte": "./dist/index.js",
@@ -38,11 +38,11 @@
38
38
  "media-generation"
39
39
  ],
40
40
  "dependencies": {
41
- "@tanstack/ai-client": "0.11.8"
41
+ "@tanstack/ai-client": "0.13.0"
42
42
  },
43
43
  "peerDependencies": {
44
44
  "svelte": "^5.0.0",
45
- "@tanstack/ai": "^0.22.0"
45
+ "@tanstack/ai": "^0.22.1"
46
46
  },
47
47
  "devDependencies": {
48
48
  "@standard-schema/spec": "^1.1.0",
@@ -55,7 +55,7 @@
55
55
  "svelte-check": "^4.2.0",
56
56
  "typescript": "5.9.3",
57
57
  "vite": "^7.3.3",
58
- "@tanstack/ai": "0.22.0"
58
+ "@tanstack/ai": "0.22.1"
59
59
  },
60
60
  "scripts": {
61
61
  "clean": "rm -rf ./dist",
@@ -1,4 +1,5 @@
1
1
  import { ChatClient } from '@tanstack/ai-client'
2
+ import { createChatDevtoolsBridge } from '@tanstack/ai-client/devtools'
2
3
  import type {
3
4
  ChatClientState,
4
5
  ConnectionStatus,
@@ -86,8 +87,13 @@ export function createChat<
86
87
  // rather than `field?: T | undefined`. Under `exactOptionalPropertyTypes`,
87
88
  // passing an explicit `undefined` for an absent-only optional is a type
88
89
  // error, so we omit the key when the caller's value is undefined.
90
+ const transport = options.connection
91
+ ? { connection: options.connection }
92
+ : { fetcher: options.fetcher }
93
+
89
94
  const client = new ChatClient({
90
- connection: options.connection,
95
+ devtoolsBridgeFactory: createChatDevtoolsBridge,
96
+ ...transport,
91
97
  id: clientId,
92
98
  ...(options.initialMessages !== undefined && {
93
99
  initialMessages: options.initialMessages,
@@ -96,6 +102,12 @@ export function createChat<
96
102
  ...(options.forwardedProps !== undefined && {
97
103
  forwardedProps: options.forwardedProps,
98
104
  }),
105
+ devtools: {
106
+ ...options.devtools,
107
+ framework: 'svelte',
108
+ hookName: 'useChat',
109
+ outputKind: options.outputSchema ? 'structured' : 'chat',
110
+ },
99
111
  ...(options.onResponse !== undefined && { onResponse: options.onResponse }),
100
112
  onChunk: (chunk: StreamChunk) => {
101
113
  options.onChunk?.(chunk)
@@ -140,6 +152,8 @@ export function createChat<
140
152
  client.subscribe()
141
153
  }
142
154
 
155
+ client.mountDevtools()
156
+
143
157
  // Note: Cleanup is handled by calling stop() directly when needed.
144
158
  // Unlike React/Vue/Solid, Svelte 5 runes like $effect can only be used
145
159
  // during component initialization, so we don't add automatic cleanup here.
@@ -162,6 +176,10 @@ export function createChat<
162
176
  client.stop()
163
177
  }
164
178
 
179
+ const dispose = () => {
180
+ client.dispose()
181
+ }
182
+
165
183
  const clear = () => {
166
184
  client.clear()
167
185
  }
@@ -272,6 +290,7 @@ export function createChat<
272
290
  append,
273
291
  reload,
274
292
  stop,
293
+ dispose,
275
294
  setMessages,
276
295
  clear,
277
296
  addToolResult,
@@ -1,6 +1,7 @@
1
1
  import { createGeneration } from './create-generation.svelte'
2
2
  import type { AudioGenerationResult, StreamChunk } from '@tanstack/ai'
3
3
  import type {
4
+ AIDevtoolsDisplayOptions,
4
5
  AudioGenerateInput,
5
6
  ConnectConnectionAdapter,
6
7
  GenerationClientState,
@@ -22,6 +23,8 @@ export interface CreateGenerateAudioOptions<TOutput = AudioGenerationResult> {
22
23
  id?: string
23
24
  /** Additional body parameters to send with connect-based adapter requests */
24
25
  body?: Record<string, any>
26
+ /** Display options for TanStack AI Devtools. */
27
+ devtools?: AIDevtoolsDisplayOptions
25
28
  /**
26
29
  * Callback when audio is generated. Can optionally return a transformed value.
27
30
  *
@@ -98,11 +101,20 @@ export function createGenerateAudio<
98
101
  ): CreateGenerateAudioReturn<
99
102
  InferGenerationOutput<AudioGenerationResult, TOnResult>
100
103
  > {
104
+ const devtools = {
105
+ ...options.devtools,
106
+ framework: 'svelte',
107
+ hookName: 'createGenerateAudio',
108
+ outputKind: 'audio' as const,
109
+ }
101
110
  const gen = createGeneration<
102
111
  AudioGenerateInput,
103
112
  AudioGenerationResult,
104
113
  TOnResult
105
- >(options)
114
+ >({
115
+ ...options,
116
+ devtools,
117
+ })
106
118
 
107
119
  return {
108
120
  get result() {
@@ -1,6 +1,7 @@
1
1
  import { createGeneration } from './create-generation.svelte'
2
2
  import type { ImageGenerationResult, StreamChunk } from '@tanstack/ai'
3
3
  import type {
4
+ AIDevtoolsDisplayOptions,
4
5
  ConnectConnectionAdapter,
5
6
  GenerationClientState,
6
7
  GenerationFetcher,
@@ -22,6 +23,8 @@ export interface CreateGenerateImageOptions<TOutput = ImageGenerationResult> {
22
23
  id?: string
23
24
  /** Additional body parameters to send with connect-based adapter requests */
24
25
  body?: Record<string, any>
26
+ /** Display options for TanStack AI Devtools. */
27
+ devtools?: AIDevtoolsDisplayOptions
25
28
  /**
26
29
  * Callback when images are generated. Can optionally return a transformed value.
27
30
  *
@@ -107,11 +110,20 @@ export function createGenerateImage<
107
110
  ): CreateGenerateImageReturn<
108
111
  InferGenerationOutput<ImageGenerationResult, TOnResult>
109
112
  > {
113
+ const devtools = {
114
+ ...options.devtools,
115
+ framework: 'svelte',
116
+ hookName: 'createGenerateImage',
117
+ outputKind: 'image' as const,
118
+ }
110
119
  const gen = createGeneration<
111
120
  ImageGenerateInput,
112
121
  ImageGenerationResult,
113
122
  TOnResult
114
- >(options)
123
+ >({
124
+ ...options,
125
+ devtools,
126
+ })
115
127
 
116
128
  return {
117
129
  get result() {
@@ -1,6 +1,7 @@
1
1
  import { createGeneration } from './create-generation.svelte'
2
2
  import type { StreamChunk, TTSResult } from '@tanstack/ai'
3
3
  import type {
4
+ AIDevtoolsDisplayOptions,
4
5
  ConnectConnectionAdapter,
5
6
  GenerationClientState,
6
7
  GenerationFetcher,
@@ -22,6 +23,8 @@ export interface CreateGenerateSpeechOptions<TOutput = TTSResult> {
22
23
  id?: string
23
24
  /** Additional body parameters to send with connect-based adapter requests */
24
25
  body?: Record<string, any>
26
+ /** Display options for TanStack AI Devtools. */
27
+ devtools?: AIDevtoolsDisplayOptions
25
28
  /**
26
29
  * Callback when speech is generated. Can optionally return a transformed value.
27
30
  *
@@ -95,9 +98,16 @@ export function createGenerateSpeech<
95
98
  onResult?: TOnResult
96
99
  },
97
100
  ): CreateGenerateSpeechReturn<InferGenerationOutput<TTSResult, TOnResult>> {
98
- const gen = createGeneration<SpeechGenerateInput, TTSResult, TOnResult>(
99
- options,
100
- )
101
+ const devtools = {
102
+ ...options.devtools,
103
+ framework: 'svelte',
104
+ hookName: 'createGenerateSpeech',
105
+ outputKind: 'audio' as const,
106
+ }
107
+ const gen = createGeneration<SpeechGenerateInput, TTSResult, TOnResult>({
108
+ ...options,
109
+ devtools,
110
+ })
101
111
 
102
112
  return {
103
113
  get result() {
@@ -1,6 +1,8 @@
1
1
  import { VideoGenerationClient } from '@tanstack/ai-client'
2
+ import { createVideoDevtoolsBridge } from '@tanstack/ai-client/devtools'
2
3
  import type { StreamChunk } from '@tanstack/ai'
3
4
  import type {
5
+ AIDevtoolsDisplayOptions,
4
6
  ConnectConnectionAdapter,
5
7
  GenerationClientState,
6
8
  GenerationFetcher,
@@ -24,6 +26,8 @@ export interface CreateGenerateVideoOptions<TOutput = VideoGenerateResult> {
24
26
  id?: string
25
27
  /** Additional body parameters to send with connect-based adapter requests */
26
28
  body?: Record<string, any>
29
+ /** Display options for TanStack AI Devtools. */
30
+ devtools?: AIDevtoolsDisplayOptions
27
31
  /**
28
32
  * Callback when video generation completes. Can optionally return a transformed value.
29
33
  *
@@ -68,6 +72,8 @@ export interface CreateGenerateVideoReturn<TOutput = VideoGenerateResult> {
68
72
  stop: () => void
69
73
  /** Clear all state and return to idle */
70
74
  reset: () => void
75
+ /** Stop in-flight work and unregister devtools listeners */
76
+ dispose: () => void
71
77
  /** Update additional body parameters */
72
78
  updateBody: (body: Record<string, any>) => void
73
79
  }
@@ -132,6 +138,13 @@ export function createGenerateVideo<
132
138
  const baseOptions = {
133
139
  id: clientId,
134
140
  body: options.body,
141
+ devtoolsBridgeFactory: createVideoDevtoolsBridge,
142
+ devtools: {
143
+ ...options.devtools,
144
+ framework: 'svelte',
145
+ hookName: 'createGenerateVideo',
146
+ outputKind: 'video' as const,
147
+ },
135
148
  onResult: (r: VideoGenerateResult) => options.onResult?.(r),
136
149
  onError: (e: Error) => options.onError?.(e),
137
150
  onProgress: (p: number, m?: string) => options.onProgress?.(p, m),
@@ -176,10 +189,12 @@ export function createGenerateVideo<
176
189
  )
177
190
  }
178
191
 
179
- // Note: Cleanup is handled by calling stop() directly when needed.
192
+ client.mountDevtools()
193
+
194
+ // Note: Cleanup is handled by calling dispose() directly when needed.
180
195
  // Unlike React/Vue/Solid, Svelte 5 runes like $effect can only be used
181
196
  // during component initialization, so we don't add automatic cleanup here.
182
- // Users should call video.stop() in their component's cleanup if needed.
197
+ // Users should call video.dispose() in their component's cleanup if needed.
183
198
 
184
199
  const generate = async (input: VideoGenerateInput) => {
185
200
  await client.generate(input)
@@ -193,6 +208,10 @@ export function createGenerateVideo<
193
208
  client.reset()
194
209
  }
195
210
 
211
+ const dispose = () => {
212
+ client.dispose()
213
+ }
214
+
196
215
  const updateBody = (newBody: Record<string, any>) => {
197
216
  client.updateOptions({ body: newBody })
198
217
  }
@@ -219,6 +238,7 @@ export function createGenerateVideo<
219
238
  generate,
220
239
  stop,
221
240
  reset,
241
+ dispose,
222
242
  updateBody,
223
243
  }
224
244
  }
@@ -1,6 +1,8 @@
1
1
  import { GenerationClient } from '@tanstack/ai-client'
2
+ import { createGenerationDevtoolsBridge } from '@tanstack/ai-client/devtools'
2
3
  import type { StreamChunk } from '@tanstack/ai'
3
4
  import type {
5
+ AIDevtoolsDisplayOptions,
4
6
  ConnectConnectionAdapter,
5
7
  GenerationClientOptions,
6
8
  GenerationClientState,
@@ -26,6 +28,8 @@ export interface CreateGenerationOptions<TInput, TResult, TOutput = TResult> {
26
28
  id?: string
27
29
  /** Additional body parameters to send with connect-based adapter requests */
28
30
  body?: Record<string, any>
31
+ /** Display options for TanStack AI Devtools. */
32
+ devtools?: AIDevtoolsDisplayOptions
29
33
  /**
30
34
  * Callback when a result is received. Can optionally return a transformed value.
31
35
  *
@@ -62,6 +66,8 @@ export interface CreateGenerationReturn<TOutput> {
62
66
  stop: () => void
63
67
  /** Clear result, error, and return to idle */
64
68
  reset: () => void
69
+ /** Stop in-flight work and unregister devtools listeners */
70
+ dispose: () => void
65
71
  /** Update additional body parameters */
66
72
  updateBody: (body: Record<string, any>) => void
67
73
  }
@@ -124,6 +130,12 @@ export function createGeneration<
124
130
  const clientOptions: GenerationClientOptions<TInput, TResult, TOutput> = {
125
131
  id: clientId,
126
132
  body: options.body,
133
+ devtoolsBridgeFactory: createGenerationDevtoolsBridge,
134
+ devtools: {
135
+ ...options.devtools,
136
+ framework: 'svelte',
137
+ hookName: 'createGeneration',
138
+ },
127
139
  onResult: (r: TResult) => options.onResult?.(r),
128
140
  onError: (e: Error) => options.onError?.(e),
129
141
  onProgress: (p: number, m?: string) => options.onProgress?.(p, m),
@@ -160,10 +172,12 @@ export function createGeneration<
160
172
  )
161
173
  }
162
174
 
163
- // Note: Cleanup is handled by calling stop() directly when needed.
175
+ client.mountDevtools()
176
+
177
+ // Note: Cleanup is handled by calling dispose() directly when needed.
164
178
  // Unlike React/Vue/Solid, Svelte 5 runes like $effect can only be used
165
179
  // during component initialization, so we don't add automatic cleanup here.
166
- // Users should call gen.stop() in their component's cleanup if needed.
180
+ // Users should call gen.dispose() in their component's cleanup if needed.
167
181
 
168
182
  const generate = async (input: TInput) => {
169
183
  await client.generate(input)
@@ -177,6 +191,10 @@ export function createGeneration<
177
191
  client.reset()
178
192
  }
179
193
 
194
+ const dispose = () => {
195
+ client.dispose()
196
+ }
197
+
180
198
  const updateBody = (newBody: Record<string, any>) => {
181
199
  client.updateOptions({ body: newBody })
182
200
  }
@@ -197,6 +215,7 @@ export function createGeneration<
197
215
  generate: generate as (input: Record<string, any>) => Promise<void>,
198
216
  stop,
199
217
  reset,
218
+ dispose,
200
219
  updateBody,
201
220
  }
202
221
  }
@@ -1,6 +1,7 @@
1
1
  import { createGeneration } from './create-generation.svelte'
2
2
  import type { StreamChunk, SummarizationResult } from '@tanstack/ai'
3
3
  import type {
4
+ AIDevtoolsDisplayOptions,
4
5
  ConnectConnectionAdapter,
5
6
  GenerationClientState,
6
7
  GenerationFetcher,
@@ -22,6 +23,8 @@ export interface CreateSummarizeOptions<TOutput = SummarizationResult> {
22
23
  id?: string
23
24
  /** Additional body parameters to send with connect-based adapter requests */
24
25
  body?: Record<string, any>
26
+ /** Display options for TanStack AI Devtools. */
27
+ devtools?: AIDevtoolsDisplayOptions
25
28
  /**
26
29
  * Callback when summarization is complete. Can optionally return a transformed value.
27
30
  *
@@ -102,11 +105,20 @@ export function createSummarize<
102
105
  ): CreateSummarizeReturn<
103
106
  InferGenerationOutput<SummarizationResult, TOnResult>
104
107
  > {
108
+ const devtools = {
109
+ ...options.devtools,
110
+ framework: 'svelte',
111
+ hookName: 'createSummarize',
112
+ outputKind: 'text' as const,
113
+ }
105
114
  const gen = createGeneration<
106
115
  SummarizeGenerateInput,
107
116
  SummarizationResult,
108
117
  TOnResult
109
- >(options)
118
+ >({
119
+ ...options,
120
+ devtools,
121
+ })
110
122
 
111
123
  return {
112
124
  get result() {
@@ -1,6 +1,7 @@
1
1
  import { createGeneration } from './create-generation.svelte'
2
2
  import type { StreamChunk, TranscriptionResult } from '@tanstack/ai'
3
3
  import type {
4
+ AIDevtoolsDisplayOptions,
4
5
  ConnectConnectionAdapter,
5
6
  GenerationClientState,
6
7
  GenerationFetcher,
@@ -22,6 +23,8 @@ export interface CreateTranscriptionOptions<TOutput = TranscriptionResult> {
22
23
  id?: string
23
24
  /** Additional body parameters to send with connect-based adapter requests */
24
25
  body?: Record<string, any>
26
+ /** Display options for TanStack AI Devtools. */
27
+ devtools?: AIDevtoolsDisplayOptions
25
28
  /**
26
29
  * Callback when transcription is complete. Can optionally return a transformed value.
27
30
  *
@@ -107,11 +110,20 @@ export function createTranscription<
107
110
  ): CreateTranscriptionReturn<
108
111
  InferGenerationOutput<TranscriptionResult, TOnResult>
109
112
  > {
113
+ const devtools = {
114
+ ...options.devtools,
115
+ framework: 'svelte',
116
+ hookName: 'createTranscription',
117
+ outputKind: 'text' as const,
118
+ }
110
119
  const gen = createGeneration<
111
120
  TranscriptionGenerateInput,
112
121
  TranscriptionResult,
113
122
  TOnResult
114
- >(options)
123
+ >({
124
+ ...options,
125
+ devtools,
126
+ })
115
127
 
116
128
  return {
117
129
  get result() {
package/src/types.ts CHANGED
@@ -5,10 +5,12 @@ import type {
5
5
  SchemaInput,
6
6
  } from '@tanstack/ai'
7
7
  import type {
8
+ AIDevtoolsDisplayOptions,
8
9
  ChatClientOptions,
9
10
  ChatClientState,
10
11
  ChatRequestBody,
11
12
  ConnectionStatus,
13
+ DistributedOmit,
12
14
  MultimodalContent,
13
15
  UIMessage,
14
16
  } from '@tanstack/ai-client'
@@ -52,7 +54,7 @@ export type DeepPartial<T> =
52
54
  export type CreateChatOptions<
53
55
  TTools extends ReadonlyArray<AnyClientTool> = any,
54
56
  TSchema extends SchemaInput | undefined = undefined,
55
- > = Omit<
57
+ > = DistributedOmit<
56
58
  ChatClientOptions<TTools>,
57
59
  | 'onMessagesChange'
58
60
  | 'onLoadingChange'
@@ -61,8 +63,11 @@ export type CreateChatOptions<
61
63
  | 'onSubscriptionChange'
62
64
  | 'onConnectionStatusChange'
63
65
  | 'onSessionGeneratingChange'
66
+ | 'devtools'
64
67
  > & {
65
68
  live?: boolean
69
+ /** Display options for TanStack AI Devtools. */
70
+ devtools?: AIDevtoolsDisplayOptions
66
71
  /**
67
72
  * Standard-schema-compatible schema (Zod, Valibot, ArkType, or plain JSON
68
73
  * Schema). Used to infer the shape of `partial` and `final`.
@@ -150,6 +155,11 @@ interface BaseCreateChatReturn<
150
155
  */
151
156
  stop: () => void
152
157
 
158
+ /**
159
+ * Dispose the chat client and unregister it from devtools.
160
+ */
161
+ dispose: () => void
162
+
153
163
  /**
154
164
  * Whether a response is currently being generated (reactive getter)
155
165
  */