@tanstack/ai-svelte 0.16.3 → 0.17.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.
@@ -72,14 +72,18 @@ export function createChat(options) {
72
72
  ...(options.initialMessages !== undefined && {
73
73
  initialMessages: options.initialMessages,
74
74
  }),
75
- ...(options.persistence !== undefined && {
76
- persistence: options.persistence,
77
- }),
75
+ ...(typeof options.threadId === 'string' && options.persistence
76
+ ? {
77
+ persistence: options.persistence,
78
+ threadId: options.threadId,
79
+ }
80
+ : {
81
+ ...(options.threadId !== undefined && { threadId: options.threadId }),
82
+ }),
78
83
  ...(options.initialResumeSnapshot !== undefined && {
79
84
  initialResumeSnapshot: options.initialResumeSnapshot,
80
85
  }),
81
86
  ...(options.body !== undefined && { body: options.body }),
82
- ...(options.threadId !== undefined && { threadId: options.threadId }),
83
87
  ...(options.forwardedProps !== undefined && {
84
88
  forwardedProps: options.forwardedProps,
85
89
  }),
@@ -11,10 +11,6 @@ export interface CreateGenerateAudioOptions<TOutput = AudioGenerationResult> ext
11
11
  connection?: ConnectConnectionAdapter;
12
12
  /** Direct async function for audio generation */
13
13
  fetcher?: GenerationFetcher<AudioGenerateInput, AudioGenerationResult>;
14
- /**
15
- * @deprecated Prefer `threadId`. Only allowed when `threadId` is omitted (see `GenerationPersistenceOptions`).
16
- */
17
- id?: string;
18
14
  /** Additional body parameters to send with connect-based adapter requests */
19
15
  body?: Record<string, any>;
20
16
  /** Display options for TanStack AI Devtools. */
@@ -77,6 +73,6 @@ export interface CreateGenerateAudioReturn<TOutput = AudioGenerationResult> exte
77
73
  * </div>
78
74
  * ```
79
75
  */
80
- export declare function createGenerateAudio<TTransformed = void>(options: Omit<CreateGenerateAudioOptions, 'onResult' | 'persistence' | 'threadId' | 'id'> & {
76
+ export declare function createGenerateAudio<TTransformed = void>(options: Omit<CreateGenerateAudioOptions, 'onResult' | 'persistence' | 'threadId'> & {
81
77
  onResult?: (result: AudioGenerationResult) => TTransformed;
82
78
  } & GenerationPersistenceOptions): CreateGenerateAudioReturn<InferGenerationOutputFromReturn<AudioGenerationResult, TTransformed>>;
@@ -11,10 +11,6 @@ export interface CreateGenerateImageOptions<TOutput = ImageGenerationResult> ext
11
11
  connection?: ConnectConnectionAdapter;
12
12
  /** Direct async function for image generation */
13
13
  fetcher?: GenerationFetcher<ImageGenerateInput, ImageGenerationResult>;
14
- /**
15
- * @deprecated Prefer `threadId`. Only allowed when `threadId` is omitted (see `GenerationPersistenceOptions`).
16
- */
17
- id?: string;
18
14
  /** Additional body parameters to send with connect-based adapter requests */
19
15
  body?: Record<string, any>;
20
16
  /** Display options for TanStack AI Devtools. */
@@ -86,6 +82,6 @@ export interface CreateGenerateImageReturn<TOutput = ImageGenerationResult> exte
86
82
  * </div>
87
83
  * ```
88
84
  */
89
- export declare function createGenerateImage<TTransformed = void>(options: Omit<CreateGenerateImageOptions, 'onResult' | 'persistence' | 'threadId' | 'id'> & {
85
+ export declare function createGenerateImage<TTransformed = void>(options: Omit<CreateGenerateImageOptions, 'onResult' | 'persistence' | 'threadId'> & {
90
86
  onResult?: (result: ImageGenerationResult) => TTransformed;
91
87
  } & GenerationPersistenceOptions): CreateGenerateImageReturn<InferGenerationOutputFromReturn<ImageGenerationResult, TTransformed>>;
@@ -11,10 +11,6 @@ export interface CreateGenerateSpeechOptions<TOutput = TTSResult> extends Pick<C
11
11
  connection?: ConnectConnectionAdapter;
12
12
  /** Direct async function for speech generation */
13
13
  fetcher?: GenerationFetcher<SpeechGenerateInput, TTSResult>;
14
- /**
15
- * @deprecated Prefer `threadId`. Only allowed when `threadId` is omitted (see `GenerationPersistenceOptions`).
16
- */
17
- id?: string;
18
14
  /** Additional body parameters to send with connect-based adapter requests */
19
15
  body?: Record<string, any>;
20
16
  /** Display options for TanStack AI Devtools. */
@@ -77,6 +73,6 @@ export interface CreateGenerateSpeechReturn<TOutput = TTSResult> extends Omit<Cr
77
73
  * </div>
78
74
  * ```
79
75
  */
80
- export declare function createGenerateSpeech<TTransformed = void>(options: Omit<CreateGenerateSpeechOptions, 'onResult' | 'persistence' | 'threadId' | 'id'> & {
76
+ export declare function createGenerateSpeech<TTransformed = void>(options: Omit<CreateGenerateSpeechOptions, 'onResult' | 'persistence' | 'threadId'> & {
81
77
  onResult?: (result: TTSResult) => TTransformed;
82
78
  } & GenerationPersistenceOptions): CreateGenerateSpeechReturn<InferGenerationOutputFromReturn<TTSResult, TTransformed>>;
@@ -10,10 +10,6 @@ export interface CreateGenerateVideoOptions<TOutput = VideoGenerateResult> {
10
10
  connection?: ConnectConnectionAdapter;
11
11
  /** Direct async function that returns a completed video result */
12
12
  fetcher?: GenerationFetcher<VideoGenerateInput, VideoGenerateResult>;
13
- /**
14
- * @deprecated Prefer `threadId`. Only allowed when `threadId` is omitted (see `GenerationPersistenceOptions`).
15
- */
16
- id?: string;
17
13
  /** Additional body parameters to send with connect-based adapter requests */
18
14
  body?: Record<string, any>;
19
15
  /** Display options for TanStack AI Devtools. */
@@ -37,8 +33,8 @@ export interface CreateGenerateVideoOptions<TOutput = VideoGenerateResult> {
37
33
  * id on the wire, which the protocol requires.
38
34
  *
39
35
  * **Required whenever `persistence` is set** — an app that cannot name the
40
- * scope has nothing to restore to. Optional for ephemeral generations, where
41
- * it falls back to `id` purely to satisfy the wire.
36
+ * scope has nothing to restore to. Optional for ephemeral generations. If
37
+ * omitted, the client mints a wire id after mount.
42
38
  */
43
39
  threadId?: string;
44
40
  /**
@@ -140,6 +136,6 @@ export interface CreateGenerateVideoReturn<TOutput = VideoGenerateResult> {
140
136
  * </div>
141
137
  * ```
142
138
  */
143
- export declare function createGenerateVideo<TTransformed = void>(options: Omit<CreateGenerateVideoOptions, 'onResult' | 'persistence' | 'threadId' | 'id'> & {
139
+ export declare function createGenerateVideo<TTransformed = void>(options: Omit<CreateGenerateVideoOptions, 'onResult' | 'persistence' | 'threadId'> & {
144
140
  onResult?: (result: VideoGenerateResult) => TTransformed;
145
141
  } & GenerationPersistenceOptions): CreateGenerateVideoReturn<InferGenerationOutputFromReturn<VideoGenerateResult, TTransformed>>;
@@ -34,7 +34,6 @@ 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 fallbackId = `video-${Date.now()}-${Math.random().toString(36).substring(7)}`;
38
37
  // Create reactive state using Svelte 5 runes
39
38
  let result = $state(null);
40
39
  let jobId = $state(null);
@@ -48,15 +47,18 @@ export function createGenerateVideo(options) {
48
47
  // is declared `body?: Record<string, any>` (absent vs. present) under
49
48
  // `exactOptionalPropertyTypes`. The optional caller `options.body` may be
50
49
  // 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`).
52
50
  const baseOptions = {
53
51
  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
- }),
52
+ ...(typeof options.threadId === 'string' && options.persistence
53
+ ? {
54
+ persistence: options.persistence,
55
+ threadId: options.threadId,
56
+ }
57
+ : {
58
+ ...(options.threadId !== undefined && {
59
+ threadId: options.threadId,
60
+ }),
61
+ }),
60
62
  ...(options.hydrateGeneration !== undefined && {
61
63
  hydrateGeneration: options.hydrateGeneration,
62
64
  }),
@@ -14,10 +14,6 @@ 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
- /**
18
- * @deprecated Prefer `threadId`. Only allowed when `threadId` is omitted (see `GenerationPersistenceOptions`).
19
- */
20
- id?: string;
21
17
  /** Additional body parameters to send with connect-based adapter requests */
22
18
  body?: Record<string, any>;
23
19
  /** Display options for TanStack AI Devtools. */
@@ -41,8 +37,8 @@ export interface CreateGenerationOptions<TInput, TResult, TOutput = TResult> {
41
37
  * id on the wire, which the protocol requires.
42
38
  *
43
39
  * **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.
40
+ * scope has nothing to restore to. Optional for ephemeral generations. If
41
+ * omitted, the client mints a wire id after mount.
46
42
  */
47
43
  threadId?: string;
48
44
  /**
@@ -144,6 +140,6 @@ export interface CreateGenerationReturn<TOutput, TInput extends Record<string, a
144
140
  * </div>
145
141
  * ```
146
142
  */
147
- export declare function createGeneration<TInput extends Record<string, any>, TResult, TTransformed = void>(options: Omit<CreateGenerationOptions<TInput, TResult>, 'onResult' | 'persistence' | 'threadId' | 'id'> & {
143
+ export declare function createGeneration<TInput extends Record<string, any>, TResult, TTransformed = void>(options: Omit<CreateGenerationOptions<TInput, TResult>, 'onResult' | 'persistence' | 'threadId'> & {
148
144
  onResult?: (result: TResult) => TTransformed;
149
145
  } & GenerationPersistenceOptions): CreateGenerationReturn<InferGenerationOutputFromReturn<TResult, TTransformed>, TInput>;
@@ -38,7 +38,6 @@ 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 fallbackId = `gen-${Date.now()}-${Math.random().toString(36).substring(7)}`;
42
41
  // Create reactive state using Svelte 5 runes
43
42
  let result = $state(null);
44
43
  let isLoading = $state(false);
@@ -51,15 +50,8 @@ export function createGeneration(options) {
51
50
  // `exactOptionalPropertyTypes`. Assigning `undefined` directly would be
52
51
  // rejected — the optional caller `options.body` may be undefined, in which
53
52
  // case we want the key to be absent.
54
- // Identity: pass `threadId` alone when set (never also pass deprecated `id`).
55
53
  const clientOptions = {
56
54
  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
55
  ...(options.hydrateGeneration !== undefined && {
64
56
  hydrateGeneration: options.hydrateGeneration,
65
57
  }),
@@ -115,16 +107,28 @@ export function createGeneration(options) {
115
107
  runId = rs?.runId ?? null;
116
108
  },
117
109
  };
110
+ const persistenceProps = typeof options.threadId === 'string' && options.persistence
111
+ ? {
112
+ persistence: options.persistence,
113
+ threadId: options.threadId,
114
+ }
115
+ : {
116
+ ...(options.threadId !== undefined && {
117
+ threadId: options.threadId,
118
+ }),
119
+ };
118
120
  let client;
119
121
  if (options.connection) {
120
122
  client = new GenerationClient({
121
123
  ...clientOptions,
124
+ ...persistenceProps,
122
125
  connection: options.connection,
123
126
  });
124
127
  }
125
128
  else if (options.fetcher) {
126
129
  client = new GenerationClient({
127
130
  ...clientOptions,
131
+ ...persistenceProps,
128
132
  fetcher: options.fetcher,
129
133
  });
130
134
  }
@@ -11,10 +11,6 @@ export interface CreateSummarizeOptions<TOutput = SummarizationResult> extends P
11
11
  connection?: ConnectConnectionAdapter;
12
12
  /** Direct async function for summarization */
13
13
  fetcher?: GenerationFetcher<SummarizeGenerateInput, SummarizationResult>;
14
- /**
15
- * @deprecated Prefer `threadId`. Only allowed when `threadId` is omitted (see `GenerationPersistenceOptions`).
16
- */
17
- id?: string;
18
14
  /** Additional body parameters to send with connect-based adapter requests */
19
15
  body?: Record<string, any>;
20
16
  /** Display options for TanStack AI Devtools. */
@@ -81,6 +77,6 @@ export interface CreateSummarizeReturn<TOutput = SummarizationResult> extends Om
81
77
  * </div>
82
78
  * ```
83
79
  */
84
- export declare function createSummarize<TTransformed = void>(options: Omit<CreateSummarizeOptions, 'onResult' | 'persistence' | 'threadId' | 'id'> & {
80
+ export declare function createSummarize<TTransformed = void>(options: Omit<CreateSummarizeOptions, 'onResult' | 'persistence' | 'threadId'> & {
85
81
  onResult?: (result: SummarizationResult) => TTransformed;
86
82
  } & GenerationPersistenceOptions): CreateSummarizeReturn<InferGenerationOutputFromReturn<SummarizationResult, TTransformed>>;
@@ -11,10 +11,6 @@ export interface CreateTranscriptionOptions<TOutput = TranscriptionResult> exten
11
11
  connection?: ConnectConnectionAdapter;
12
12
  /** Direct async function for transcription */
13
13
  fetcher?: GenerationFetcher<TranscriptionGenerateInput, TranscriptionResult>;
14
- /**
15
- * @deprecated Prefer `threadId`. Only allowed when `threadId` is omitted (see `GenerationPersistenceOptions`).
16
- */
17
- id?: string;
18
14
  /** Additional body parameters to send with connect-based adapter requests */
19
15
  body?: Record<string, any>;
20
16
  /** Display options for TanStack AI Devtools. */
@@ -86,6 +82,6 @@ export interface CreateTranscriptionReturn<TOutput = TranscriptionResult> extend
86
82
  * </div>
87
83
  * ```
88
84
  */
89
- export declare function createTranscription<TTransformed = void>(options: Omit<CreateTranscriptionOptions, 'onResult' | 'persistence' | 'threadId' | 'id'> & {
85
+ export declare function createTranscription<TTransformed = void>(options: Omit<CreateTranscriptionOptions, 'onResult' | 'persistence' | 'threadId'> & {
90
86
  onResult?: (result: TranscriptionResult) => TTransformed;
91
87
  } & GenerationPersistenceOptions): CreateTranscriptionReturn<InferGenerationOutputFromReturn<TranscriptionResult, TTransformed>>;
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, 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';
19
+ export { fetchServerSentEvents, localStoragePersistence, sessionStoragePersistence, indexedDBPersistence, StorageUnavailableError, type ChatClientPersistence, type ChatPersistedState, type ChatPersistenceOption, type ChatStorageAdapter, type WebStoragePersistenceOptions, type IndexedDBPersistenceOptions, fetchHttpStream, xhrServerSentEvents, xhrHttpStream, stream, rpcStream, webSocket, createChatClientOptions, clientTools, type ConnectionAdapter, type ConnectConnectionAdapter, type SubscribeConnectionAdapter, type RunAgentInputContext, type FetchConnectionOptions, type XhrConnectionOptions, type WebSocketConnectionOptions, 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, localStoragePersistence, sessionStoragePersistence, indexedDBPersistence, StorageUnavailableError, fetchHttpStream, xhrServerSentEvents, xhrHttpStream, stream, rpcStream, createChatClientOptions, clientTools, } from '@tanstack/ai-client';
12
+ export { fetchServerSentEvents, localStoragePersistence, sessionStoragePersistence, indexedDBPersistence, StorageUnavailableError, fetchHttpStream, xhrServerSentEvents, xhrHttpStream, stream, rpcStream, webSocket, createChatClientOptions, clientTools, } from '@tanstack/ai-client';
package/dist/types.d.ts CHANGED
@@ -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' | 'onResumeStateChange' | 'onRunIdChange' | 'context' | 'devtools' | 'id'> & {
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'> & {
34
34
  live?: boolean;
35
35
  /** Display options for TanStack AI Devtools. */
36
36
  devtools?: AIDevtoolsDisplayOptions;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tanstack/ai-svelte",
3
- "version": "0.16.3",
3
+ "version": "0.17.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.23.3"
49
+ "@tanstack/ai-client": "^0.24.0"
50
50
  },
51
51
  "peerDependencies": {
52
52
  "svelte": "^5.0.0",
53
- "@tanstack/ai": "^0.45.0"
53
+ "@tanstack/ai": "^0.46.0"
54
54
  },
55
55
  "devDependencies": {
56
56
  "@standard-schema/spec": "^1.1.0",
@@ -63,7 +63,7 @@
63
63
  "svelte-check": "^4.2.0",
64
64
  "typescript": "5.9.3",
65
65
  "vite": "^8.2.1",
66
- "@tanstack/ai": "0.45.0"
66
+ "@tanstack/ai": "0.46.0"
67
67
  },
68
68
  "scripts": {
69
69
  "clean": "rm -rf ./dist",
@@ -115,14 +115,18 @@ export function createChat<
115
115
  ...(options.initialMessages !== undefined && {
116
116
  initialMessages: options.initialMessages,
117
117
  }),
118
- ...(options.persistence !== undefined && {
119
- persistence: options.persistence,
120
- }),
118
+ ...(typeof options.threadId === 'string' && options.persistence
119
+ ? {
120
+ persistence: options.persistence,
121
+ threadId: options.threadId,
122
+ }
123
+ : {
124
+ ...(options.threadId !== undefined && { threadId: options.threadId }),
125
+ }),
121
126
  ...(options.initialResumeSnapshot !== undefined && {
122
127
  initialResumeSnapshot: options.initialResumeSnapshot,
123
128
  }),
124
129
  ...(options.body !== undefined && { body: options.body }),
125
- ...(options.threadId !== undefined && { threadId: options.threadId }),
126
130
  ...(options.forwardedProps !== undefined && {
127
131
  forwardedProps: options.forwardedProps,
128
132
  }),
@@ -30,10 +30,6 @@ export interface CreateGenerateAudioOptions<
30
30
  connection?: ConnectConnectionAdapter
31
31
  /** Direct async function for audio generation */
32
32
  fetcher?: GenerationFetcher<AudioGenerateInput, AudioGenerationResult>
33
- /**
34
- * @deprecated Prefer `threadId`. Only allowed when `threadId` is omitted (see `GenerationPersistenceOptions`).
35
- */
36
- id?: string
37
33
  /** Additional body parameters to send with connect-based adapter requests */
38
34
  body?: Record<string, any>
39
35
  /** Display options for TanStack AI Devtools. */
@@ -103,7 +99,7 @@ export interface CreateGenerateAudioReturn<
103
99
  export function createGenerateAudio<TTransformed = void>(
104
100
  options: Omit<
105
101
  CreateGenerateAudioOptions,
106
- 'onResult' | 'persistence' | 'threadId' | 'id'
102
+ 'onResult' | 'persistence' | 'threadId'
107
103
  > & {
108
104
  onResult?: (result: AudioGenerationResult) => TTransformed
109
105
  } & GenerationPersistenceOptions,
@@ -30,10 +30,6 @@ export interface CreateGenerateImageOptions<
30
30
  connection?: ConnectConnectionAdapter
31
31
  /** Direct async function for image generation */
32
32
  fetcher?: GenerationFetcher<ImageGenerateInput, ImageGenerationResult>
33
- /**
34
- * @deprecated Prefer `threadId`. Only allowed when `threadId` is omitted (see `GenerationPersistenceOptions`).
35
- */
36
- id?: string
37
33
  /** Additional body parameters to send with connect-based adapter requests */
38
34
  body?: Record<string, any>
39
35
  /** Display options for TanStack AI Devtools. */
@@ -112,7 +108,7 @@ export interface CreateGenerateImageReturn<
112
108
  export function createGenerateImage<TTransformed = void>(
113
109
  options: Omit<
114
110
  CreateGenerateImageOptions,
115
- 'onResult' | 'persistence' | 'threadId' | 'id'
111
+ 'onResult' | 'persistence' | 'threadId'
116
112
  > & {
117
113
  onResult?: (result: ImageGenerationResult) => TTransformed
118
114
  } & GenerationPersistenceOptions,
@@ -28,10 +28,6 @@ export interface CreateGenerateSpeechOptions<TOutput = TTSResult> extends Pick<
28
28
  connection?: ConnectConnectionAdapter
29
29
  /** Direct async function for speech generation */
30
30
  fetcher?: GenerationFetcher<SpeechGenerateInput, TTSResult>
31
- /**
32
- * @deprecated Prefer `threadId`. Only allowed when `threadId` is omitted (see `GenerationPersistenceOptions`).
33
- */
34
- id?: string
35
31
  /** Additional body parameters to send with connect-based adapter requests */
36
32
  body?: Record<string, any>
37
33
  /** Display options for TanStack AI Devtools. */
@@ -102,7 +98,7 @@ export interface CreateGenerateSpeechReturn<TOutput = TTSResult> extends Omit<
102
98
  export function createGenerateSpeech<TTransformed = void>(
103
99
  options: Omit<
104
100
  CreateGenerateSpeechOptions,
105
- 'onResult' | 'persistence' | 'threadId' | 'id'
101
+ 'onResult' | 'persistence' | 'threadId'
106
102
  > & {
107
103
  onResult?: (result: TTSResult) => TTransformed
108
104
  } & GenerationPersistenceOptions,
@@ -23,10 +23,6 @@ export interface CreateGenerateVideoOptions<TOutput = VideoGenerateResult> {
23
23
  connection?: ConnectConnectionAdapter
24
24
  /** Direct async function that returns a completed video result */
25
25
  fetcher?: GenerationFetcher<VideoGenerateInput, VideoGenerateResult>
26
- /**
27
- * @deprecated Prefer `threadId`. Only allowed when `threadId` is omitted (see `GenerationPersistenceOptions`).
28
- */
29
- id?: string
30
26
  /** Additional body parameters to send with connect-based adapter requests */
31
27
  body?: Record<string, any>
32
28
  /** Display options for TanStack AI Devtools. */
@@ -50,8 +46,8 @@ export interface CreateGenerateVideoOptions<TOutput = VideoGenerateResult> {
50
46
  * id on the wire, which the protocol requires.
51
47
  *
52
48
  * **Required whenever `persistence` is set** — an app that cannot name the
53
- * scope has nothing to restore to. Optional for ephemeral generations, where
54
- * it falls back to `id` purely to satisfy the wire.
49
+ * scope has nothing to restore to. Optional for ephemeral generations. If
50
+ * omitted, the client mints a wire id after mount.
55
51
  */
56
52
  threadId?: string
57
53
  /**
@@ -161,7 +157,7 @@ export interface CreateGenerateVideoReturn<TOutput = VideoGenerateResult> {
161
157
  export function createGenerateVideo<TTransformed = void>(
162
158
  options: Omit<
163
159
  CreateGenerateVideoOptions,
164
- 'onResult' | 'persistence' | 'threadId' | 'id'
160
+ 'onResult' | 'persistence' | 'threadId'
165
161
  > & {
166
162
  onResult?: (result: VideoGenerateResult) => TTransformed
167
163
  } & GenerationPersistenceOptions,
@@ -172,7 +168,6 @@ export function createGenerateVideo<TTransformed = void>(
172
168
  VideoGenerateResult,
173
169
  TTransformed
174
170
  >
175
- const fallbackId = `video-${Date.now()}-${Math.random().toString(36).substring(7)}`
176
171
 
177
172
  // Create reactive state using Svelte 5 runes
178
173
  let result = $state<TOutput | null>(null)
@@ -188,15 +183,18 @@ export function createGenerateVideo<TTransformed = void>(
188
183
  // is declared `body?: Record<string, any>` (absent vs. present) under
189
184
  // `exactOptionalPropertyTypes`. The optional caller `options.body` may be
190
185
  // undefined, in which case we want the key to be absent on the target.
191
- // Identity: pass `threadId` alone when set (never also pass deprecated `id`).
192
186
  const baseOptions = {
193
187
  body: options.body,
194
- ...(options.threadId !== undefined
195
- ? { threadId: options.threadId }
196
- : { id: options.id ?? fallbackId }),
197
- ...(options.persistence !== undefined && {
198
- persistence: options.persistence,
199
- }),
188
+ ...(typeof options.threadId === 'string' && options.persistence
189
+ ? {
190
+ persistence: options.persistence,
191
+ threadId: options.threadId,
192
+ }
193
+ : {
194
+ ...(options.threadId !== undefined && {
195
+ threadId: options.threadId,
196
+ }),
197
+ }),
200
198
  ...(options.hydrateGeneration !== undefined && {
201
199
  hydrateGeneration: options.hydrateGeneration,
202
200
  }),
@@ -26,10 +26,6 @@ export interface CreateGenerationOptions<TInput, TResult, TOutput = TResult> {
26
26
  connection?: ConnectConnectionAdapter
27
27
  /** Direct async function for one-shot generation (no streaming protocol needed) */
28
28
  fetcher?: GenerationFetcher<TInput, TResult>
29
- /**
30
- * @deprecated Prefer `threadId`. Only allowed when `threadId` is omitted (see `GenerationPersistenceOptions`).
31
- */
32
- id?: string
33
29
  /** Additional body parameters to send with connect-based adapter requests */
34
30
  body?: Record<string, any>
35
31
  /** Display options for TanStack AI Devtools. */
@@ -53,8 +49,8 @@ export interface CreateGenerationOptions<TInput, TResult, TOutput = TResult> {
53
49
  * id on the wire, which the protocol requires.
54
50
  *
55
51
  * **Required whenever `persistence` is set** — an app that cannot name the
56
- * scope has nothing to restore to. Optional for ephemeral generations, where
57
- * it falls back to `id` purely to satisfy the wire.
52
+ * scope has nothing to restore to. Optional for ephemeral generations. If
53
+ * omitted, the client mints a wire id after mount.
58
54
  */
59
55
  threadId?: string
60
56
  /**
@@ -174,7 +170,7 @@ export function createGeneration<
174
170
  >(
175
171
  options: Omit<
176
172
  CreateGenerationOptions<TInput, TResult>,
177
- 'onResult' | 'persistence' | 'threadId' | 'id'
173
+ 'onResult' | 'persistence' | 'threadId'
178
174
  > & {
179
175
  onResult?: (result: TResult) => TTransformed
180
176
  } & GenerationPersistenceOptions,
@@ -183,8 +179,6 @@ export function createGeneration<
183
179
  TInput
184
180
  > {
185
181
  type TOutput = InferGenerationOutputFromReturn<TResult, TTransformed>
186
- const fallbackId = `gen-${Date.now()}-${Math.random().toString(36).substring(7)}`
187
-
188
182
  // Create reactive state using Svelte 5 runes
189
183
  let result = $state<TOutput | null>(null)
190
184
  let isLoading = $state(false)
@@ -198,15 +192,11 @@ export function createGeneration<
198
192
  // `exactOptionalPropertyTypes`. Assigning `undefined` directly would be
199
193
  // rejected — the optional caller `options.body` may be undefined, in which
200
194
  // case we want the key to be absent.
201
- // Identity: pass `threadId` alone when set (never also pass deprecated `id`).
202
- const clientOptions: GenerationClientOptions<TInput, TResult, TOutput> = {
195
+ const clientOptions: Omit<
196
+ GenerationClientOptions<TInput, TResult, TOutput>,
197
+ 'persistence' | 'threadId'
198
+ > = {
203
199
  body: options.body,
204
- ...(options.threadId !== undefined
205
- ? { threadId: options.threadId }
206
- : { id: options.id ?? fallbackId }),
207
- ...(options.persistence !== undefined && {
208
- persistence: options.persistence,
209
- }),
210
200
  ...(options.hydrateGeneration !== undefined && {
211
201
  hydrateGeneration: options.hydrateGeneration,
212
202
  }),
@@ -257,16 +247,30 @@ export function createGeneration<
257
247
  },
258
248
  }
259
249
 
250
+ const persistenceProps =
251
+ typeof options.threadId === 'string' && options.persistence
252
+ ? {
253
+ persistence: options.persistence,
254
+ threadId: options.threadId,
255
+ }
256
+ : {
257
+ ...(options.threadId !== undefined && {
258
+ threadId: options.threadId,
259
+ }),
260
+ }
261
+
260
262
  let client: GenerationClient<TInput, TResult, TOutput>
261
263
 
262
264
  if (options.connection) {
263
265
  client = new GenerationClient<TInput, TResult, TOutput>({
264
266
  ...clientOptions,
267
+ ...persistenceProps,
265
268
  connection: options.connection,
266
269
  })
267
270
  } else if (options.fetcher) {
268
271
  client = new GenerationClient<TInput, TResult, TOutput>({
269
272
  ...clientOptions,
273
+ ...persistenceProps,
270
274
  fetcher: options.fetcher,
271
275
  })
272
276
  } else {
@@ -30,10 +30,6 @@ export interface CreateSummarizeOptions<
30
30
  connection?: ConnectConnectionAdapter
31
31
  /** Direct async function for summarization */
32
32
  fetcher?: GenerationFetcher<SummarizeGenerateInput, SummarizationResult>
33
- /**
34
- * @deprecated Prefer `threadId`. Only allowed when `threadId` is omitted (see `GenerationPersistenceOptions`).
35
- */
36
- id?: string
37
33
  /** Additional body parameters to send with connect-based adapter requests */
38
34
  body?: Record<string, any>
39
35
  /** Display options for TanStack AI Devtools. */
@@ -107,7 +103,7 @@ export interface CreateSummarizeReturn<
107
103
  export function createSummarize<TTransformed = void>(
108
104
  options: Omit<
109
105
  CreateSummarizeOptions,
110
- 'onResult' | 'persistence' | 'threadId' | 'id'
106
+ 'onResult' | 'persistence' | 'threadId'
111
107
  > & {
112
108
  onResult?: (result: SummarizationResult) => TTransformed
113
109
  } & GenerationPersistenceOptions,
@@ -34,10 +34,6 @@ export interface CreateTranscriptionOptions<
34
34
  connection?: ConnectConnectionAdapter
35
35
  /** Direct async function for transcription */
36
36
  fetcher?: GenerationFetcher<TranscriptionGenerateInput, TranscriptionResult>
37
- /**
38
- * @deprecated Prefer `threadId`. Only allowed when `threadId` is omitted (see `GenerationPersistenceOptions`).
39
- */
40
- id?: string
41
37
  /** Additional body parameters to send with connect-based adapter requests */
42
38
  body?: Record<string, any>
43
39
  /** Display options for TanStack AI Devtools. */
@@ -116,7 +112,7 @@ export interface CreateTranscriptionReturn<
116
112
  export function createTranscription<TTransformed = void>(
117
113
  options: Omit<
118
114
  CreateTranscriptionOptions,
119
- 'onResult' | 'persistence' | 'threadId' | 'id'
115
+ 'onResult' | 'persistence' | 'threadId'
120
116
  > & {
121
117
  onResult?: (result: TranscriptionResult) => TTransformed
122
118
  } & GenerationPersistenceOptions,
package/src/index.ts CHANGED
@@ -80,6 +80,7 @@ export {
80
80
  xhrHttpStream,
81
81
  stream,
82
82
  rpcStream,
83
+ webSocket,
83
84
  createChatClientOptions,
84
85
  clientTools,
85
86
  type ConnectionAdapter,
@@ -88,6 +89,7 @@ export {
88
89
  type RunAgentInputContext,
89
90
  type FetchConnectionOptions,
90
91
  type XhrConnectionOptions,
92
+ type WebSocketConnectionOptions,
91
93
  type InferChatMessages,
92
94
  type GenerationClientState,
93
95
  type ImageGenerateInput,
package/src/types.ts CHANGED
@@ -92,10 +92,6 @@ export type CreateChatOptions<
92
92
  | 'onRunIdChange'
93
93
  | 'context'
94
94
  | 'devtools'
95
- // `id` is not a hook option: the hook's identity is its `threadId`, which is
96
- // also the persistence key. Persist across reloads by passing a stable
97
- // `threadId`; there is no separate id to set.
98
- | 'id'
99
95
  > & {
100
96
  live?: boolean
101
97
  /** Display options for TanStack AI Devtools. */