@ai-sdk/svelte 3.0.0-alpha.1 → 3.0.0-alpha.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.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,102 @@
1
1
  # @ai-sdk/svelte
2
2
 
3
+ ## 3.0.0-alpha.10
4
+
5
+ ### Major Changes
6
+
7
+ - 98f25e5: chore (ui): remove managed chat inputs
8
+
9
+ ### Patch Changes
10
+
11
+ - Updated dependencies [98f25e5]
12
+ - Updated dependencies [7bb58d4]
13
+ - ai@5.0.0-alpha.10
14
+ - @ai-sdk/provider-utils@3.0.0-alpha.10
15
+
16
+ ## 3.0.0-alpha.9
17
+
18
+ ### Patch Changes
19
+
20
+ - Updated dependencies [8255639]
21
+ - Updated dependencies [9ae327d]
22
+ - ai@5.0.0-alpha.9
23
+ - @ai-sdk/provider-utils@3.0.0-alpha.9
24
+
25
+ ## 3.0.0-alpha.8
26
+
27
+ ### Patch Changes
28
+
29
+ - Updated dependencies [4fef487]
30
+ - Updated dependencies [6b1c55c]
31
+ - Updated dependencies [2e4f9e4]
32
+ - Updated dependencies [c25cbce]
33
+ - @ai-sdk/provider-utils@3.0.0-alpha.8
34
+ - ai@5.0.0-alpha.8
35
+
36
+ ## 3.0.0-alpha.7
37
+
38
+ ### Patch Changes
39
+
40
+ - Updated dependencies [db345da]
41
+ - Updated dependencies [9b0da33]
42
+ - Updated dependencies [247ee0c]
43
+ - ai@5.0.0-alpha.7
44
+ - @ai-sdk/provider-utils@3.0.0-alpha.7
45
+
46
+ ## 3.0.0-alpha.6
47
+
48
+ ### Patch Changes
49
+
50
+ - Updated dependencies [0d2c085]
51
+ - Updated dependencies [48a7606]
52
+ - ai@5.0.0-alpha.6
53
+ - @ai-sdk/provider-utils@3.0.0-alpha.6
54
+
55
+ ## 3.0.0-alpha.5
56
+
57
+ ### Patch Changes
58
+
59
+ - Updated dependencies [655cf3c]
60
+ - Updated dependencies [1675396]
61
+ - Updated dependencies [cf9af6e]
62
+ - Updated dependencies [ef256ed]
63
+ - Updated dependencies [1ed0287]
64
+ - Updated dependencies [825e8d7]
65
+ - Updated dependencies [7324c21]
66
+ - ai@5.0.0-alpha.5
67
+
68
+ ## 3.0.0-alpha.4
69
+
70
+ ### Patch Changes
71
+
72
+ - Updated dependencies [b32c141]
73
+ - Updated dependencies [72d7d72]
74
+ - Updated dependencies [9315076]
75
+ - Updated dependencies [7d97ab6]
76
+ - Updated dependencies [37a916d]
77
+ - Updated dependencies [5f2b3d4]
78
+ - ai@5.0.0-alpha.4
79
+ - @ai-sdk/provider-utils@3.0.0-alpha.4
80
+
81
+ ## 3.0.0-alpha.3
82
+
83
+ ### Patch Changes
84
+
85
+ - Updated dependencies [ab7ccef]
86
+ - Updated dependencies [257224b]
87
+ - Updated dependencies [0463011]
88
+ - Updated dependencies [d306260]
89
+ - ai@5.0.0-alpha.3
90
+ - @ai-sdk/provider-utils@3.0.0-alpha.3
91
+
92
+ ## 3.0.0-alpha.2
93
+
94
+ ### Patch Changes
95
+
96
+ - Updated dependencies [82aa95d]
97
+ - ai@5.0.0-alpha.2
98
+ - @ai-sdk/provider-utils@3.0.0-alpha.2
99
+
3
100
  ## 3.0.0-alpha.1
4
101
 
5
102
  ### Patch Changes
@@ -1,61 +1,6 @@
1
- import { type ChatRequestOptions, type CreateUIMessage, type OriginalUseChatOptions, type UIMessage } from 'ai';
2
- export type ChatOptions<MESSAGE_METADATA = unknown> = Readonly<OriginalUseChatOptions<MESSAGE_METADATA>>;
1
+ import { AbstractChat, type ChatInit, type CreateUIMessage, type UIDataPartSchemas, type UIMessage } from 'ai';
3
2
  export type { CreateUIMessage, UIMessage };
4
- export declare class Chat<MESSAGE_METADATA = unknown> {
5
- #private;
6
- /**
7
- * The id of the chat. If not provided through the constructor, a random ID will be generated
8
- * using the provided `generateId` function, or a built-in function if not provided.
9
- */
10
- readonly chatId: string;
11
- /**
12
- * Hook status:
13
- *
14
- * - `submitted`: The message has been sent to the API and we're awaiting the start of the response stream.
15
- * - `streaming`: The response is actively streaming in from the API, receiving chunks of data.
16
- * - `ready`: The full response has been received and processed; a new user message can be submitted.
17
- * - `error`: An error occurred during the API request, preventing successful completion.
18
- */
19
- get status(): "submitted" | "streaming" | "ready" | "error";
20
- /** The error object of the API request */
21
- get error(): Error | undefined;
22
- /** The current value of the input. Writable, so it can be bound to form inputs. */
23
- input: string;
24
- /**
25
- * Current messages in the chat.
26
- *
27
- * This is writable, which is useful when you want to edit the messages on the client, and then
28
- * trigger {@link reload} to regenerate the AI response.
29
- */
30
- get messages(): UIMessage<MESSAGE_METADATA>[];
31
- set messages(value: UIMessage<MESSAGE_METADATA>[]);
32
- constructor(options?: ChatOptions<MESSAGE_METADATA>);
33
- /**
34
- * Append a user message to the chat list. This triggers the API call to fetch
35
- * the assistant's response.
36
- * @param message The message to append
37
- * @param options Additional options to pass to the API call
38
- */
39
- append: (message: UIMessage<MESSAGE_METADATA> | CreateUIMessage<MESSAGE_METADATA>, { headers, body }?: ChatRequestOptions) => Promise<void>;
40
- /**
41
- * Reload the last AI chat response for the given chat history. If the last
42
- * message isn't from the assistant, it will request the API to generate a
43
- * new response.
44
- */
45
- reload: ({ headers, body }?: ChatRequestOptions) => Promise<void>;
46
- /**
47
- * Abort the current request immediately, keep the generated tokens if any.
48
- */
49
- stop: () => void;
50
- /** Form submission handler to automatically reset input and append a user message */
51
- handleSubmit: (event?: {
52
- preventDefault?: () => void;
53
- }, options?: ChatRequestOptions & {
54
- files?: FileList;
55
- }) => Promise<void>;
56
- addToolResult: ({ toolCallId, result, }: {
57
- toolCallId: string;
58
- result: unknown;
59
- }) => Promise<void>;
3
+ export declare class Chat<MESSAGE_METADATA = unknown, DATA_PART_SCHEMAS extends UIDataPartSchemas = UIDataPartSchemas> extends AbstractChat<MESSAGE_METADATA, DATA_PART_SCHEMAS> {
4
+ constructor(init: ChatInit<MESSAGE_METADATA, DATA_PART_SCHEMAS>);
60
5
  }
61
6
  //# sourceMappingURL=chat.svelte.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"chat.svelte.d.ts","sourceRoot":"","sources":["../src/chat.svelte.ts"],"names":[],"mappings":"AACA,OAAO,EASL,KAAK,kBAAkB,EACvB,KAAK,eAAe,EACpB,KAAK,sBAAsB,EAC3B,KAAK,SAAS,EACf,MAAM,IAAI,CAAC;AAQZ,MAAM,MAAM,WAAW,CAAC,gBAAgB,GAAG,OAAO,IAAI,QAAQ,CAC5D,sBAAsB,CAAC,gBAAgB,CAAC,CACzC,CAAC;AAEF,YAAY,EAAE,eAAe,EAAE,SAAS,EAAE,CAAC;AAE3C,qBAAa,IAAI,CAAC,gBAAgB,GAAG,OAAO;;IAS1C;;;OAGG;IACH,QAAQ,CAAC,MAAM,SAAwD;IASvE;;;;;;;OAOG;IACH,IAAI,MAAM,kDAET;IAED,0CAA0C;IAC1C,IAAI,KAAK,sBAER;IAED,mFAAmF;IACnF,KAAK,SAAqB;IAE1B;;;;;OAKG;IACH,IAAI,QAAQ,IAAI,SAAS,CAAC,gBAAgB,CAAC,EAAE,CAE5C;IACD,IAAI,QAAQ,CAAC,KAAK,EAAE,SAAS,CAAC,gBAAgB,CAAC,EAAE,EAEhD;gBAEW,OAAO,GAAE,WAAW,CAAC,gBAAgB,CAAM;IAYvD;;;;;OAKG;IACH,MAAM,YACK,SAAS,CAAC,gBAAgB,CAAC,GAAG,eAAe,CAAC,gBAAgB,CAAC,sBACrD,kBAAkB,mBAQrC;IAEF;;;;OAIG;IACH,MAAM,uBAA6B,kBAAkB,mBAcnD;IAEF;;OAEG;IACH,IAAI,aASF;IAEF,qFAAqF;IACrF,YAAY,WACF;QAAE,cAAc,CAAC,EAAE,MAAM,IAAI,CAAA;KAAE,YAC9B,kBAAkB,GAAG;QAAE,KAAK,CAAC,EAAE,QAAQ,CAAA;KAAE,mBAwBlD;IAEF,aAAa,4BAGV;QACD,UAAU,EAAE,MAAM,CAAC;QACnB,MAAM,EAAE,OAAO,CAAC;KACjB,mBAmBC;CA4FH"}
1
+ {"version":3,"file":"chat.svelte.d.ts","sourceRoot":"","sources":["../src/chat.svelte.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,YAAY,EACZ,KAAK,QAAQ,EAGb,KAAK,eAAe,EACpB,KAAK,iBAAiB,EAEtB,KAAK,SAAS,EACf,MAAM,IAAI,CAAC;AAEZ,YAAY,EAAE,eAAe,EAAE,SAAS,EAAE,CAAC;AAE3C,qBAAa,IAAI,CACf,gBAAgB,GAAG,OAAO,EAC1B,iBAAiB,SAAS,iBAAiB,GAAG,iBAAiB,CAC/D,SAAQ,YAAY,CAAC,gBAAgB,EAAE,iBAAiB,CAAC;gBAC7C,IAAI,EAAE,QAAQ,CAAC,gBAAgB,EAAE,iBAAiB,CAAC;CAMhE"}
@@ -1,213 +1,30 @@
1
- import { isAbortError } from '@ai-sdk/provider-utils';
2
- import { callChatApi, convertFileListToFileUIParts, extractMaxToolInvocationStep, generateId, getToolInvocations, isAssistantMessageWithCompletedToolCalls, shouldResubmitMessages, updateToolCallResult, } from 'ai';
3
- import { untrack } from 'svelte';
4
- import { KeyedChatStore, getChatContext, hasChatContext, } from './chat-context.svelte.js';
5
- export class Chat {
6
- #options = {};
7
- #api = $derived(this.#options.api ?? '/api/chat');
8
- #generateId = $derived(this.#options.generateId ?? generateId);
9
- #maxSteps = $derived(this.#options.maxSteps ?? 1);
10
- #streamProtocol = $derived(this.#options.streamProtocol ?? 'ui-message');
11
- #keyedStore = $state();
12
- /**
13
- * The id of the chat. If not provided through the constructor, a random ID will be generated
14
- * using the provided `generateId` function, or a built-in function if not provided.
15
- */
16
- chatId = $derived(this.#options.chatId ?? this.#generateId());
17
- #store = $derived(this.#keyedStore.get(this.chatId));
18
- #messageMetadataSchema = $derived(this.#options.messageMetadataSchema);
19
- #abortController;
20
- /**
21
- * Hook status:
22
- *
23
- * - `submitted`: The message has been sent to the API and we're awaiting the start of the response stream.
24
- * - `streaming`: The response is actively streaming in from the API, receiving chunks of data.
25
- * - `ready`: The full response has been received and processed; a new user message can be submitted.
26
- * - `error`: An error occurred during the API request, preventing successful completion.
27
- */
28
- get status() {
29
- return this.#store.status;
30
- }
31
- /** The error object of the API request */
32
- get error() {
33
- return this.#store.error;
34
- }
35
- /** The current value of the input. Writable, so it can be bound to form inputs. */
36
- input = $state();
37
- /**
38
- * Current messages in the chat.
39
- *
40
- * This is writable, which is useful when you want to edit the messages on the client, and then
41
- * trigger {@link reload} to regenerate the AI response.
42
- */
43
- get messages() {
44
- return this.#store.messages;
45
- }
46
- set messages(value) {
47
- untrack(() => (this.#store.messages = value));
1
+ import { AbstractChat, } from 'ai';
2
+ export class Chat extends AbstractChat {
3
+ constructor(init) {
4
+ super({
5
+ ...init,
6
+ state: new SvelteChatState(init.messages),
7
+ });
48
8
  }
49
- constructor(options = {}) {
50
- if (hasChatContext()) {
51
- this.#keyedStore = getChatContext();
52
- }
53
- else {
54
- this.#keyedStore = new KeyedChatStore();
55
- }
56
- this.#options = options;
57
- this.messages = options.initialMessages ?? [];
58
- this.input = options.initialInput ?? '';
9
+ }
10
+ class SvelteChatState {
11
+ messages;
12
+ status = $state('ready');
13
+ error = $state(undefined);
14
+ constructor(messages = []) {
15
+ this.messages = $state(messages);
59
16
  }
60
- /**
61
- * Append a user message to the chat list. This triggers the API call to fetch
62
- * the assistant's response.
63
- * @param message The message to append
64
- * @param options Additional options to pass to the API call
65
- */
66
- append = async (message, { headers, body } = {}) => {
67
- const messages = this.messages.concat({
68
- ...message,
69
- id: message.id ?? this.#generateId(),
70
- });
71
- return this.#triggerRequest({ messages, headers, body });
17
+ setMessages = (messages) => {
18
+ this.messages = messages;
72
19
  };
73
- /**
74
- * Reload the last AI chat response for the given chat history. If the last
75
- * message isn't from the assistant, it will request the API to generate a
76
- * new response.
77
- */
78
- reload = async ({ headers, body } = {}) => {
79
- if (this.messages.length === 0) {
80
- return;
81
- }
82
- const lastMessage = this.messages[this.messages.length - 1];
83
- await this.#triggerRequest({
84
- messages: lastMessage.role === 'assistant'
85
- ? this.messages.slice(0, -1)
86
- : this.messages,
87
- headers,
88
- body,
89
- });
90
- };
91
- /**
92
- * Abort the current request immediately, keep the generated tokens if any.
93
- */
94
- stop = () => {
95
- try {
96
- this.#abortController?.abort();
97
- }
98
- catch {
99
- // ignore
100
- }
101
- finally {
102
- this.#store.status = 'ready';
103
- this.#abortController = undefined;
104
- }
105
- };
106
- /** Form submission handler to automatically reset input and append a user message */
107
- handleSubmit = async (event, options = {}) => {
108
- event?.preventDefault?.();
109
- const fileParts = Array.isArray(options?.files)
110
- ? options.files
111
- : await convertFileListToFileUIParts(options?.files);
112
- if (!this.input && fileParts.length === 0)
113
- return;
114
- const messages = this.messages.concat({
115
- id: this.#generateId(),
116
- role: 'user',
117
- parts: [...fileParts, { type: 'text', text: this.input }],
118
- });
119
- const request = this.#triggerRequest({
120
- messages,
121
- headers: options.headers,
122
- body: options.body,
123
- });
124
- this.input = '';
125
- await request;
20
+ pushMessage = (message) => {
21
+ this.messages.push(message);
126
22
  };
127
- addToolResult = async ({ toolCallId, result, }) => {
128
- updateToolCallResult({
129
- messages: this.messages,
130
- toolCallId,
131
- toolResult: result,
132
- });
133
- // when the request is ongoing, the auto-submit will be triggered after the request is finished
134
- if (this.#store.status === 'submitted' ||
135
- this.#store.status === 'streaming') {
136
- return;
137
- }
138
- const lastMessage = this.messages[this.messages.length - 1];
139
- if (isAssistantMessageWithCompletedToolCalls(lastMessage)) {
140
- await this.#triggerRequest({ messages: this.messages });
141
- }
23
+ popMessage = () => {
24
+ this.messages.pop();
142
25
  };
143
- #triggerRequest = async (chatRequest) => {
144
- this.#store.status = 'submitted';
145
- this.#store.error = undefined;
146
- const messages = chatRequest.messages;
147
- const messageCount = messages.length;
148
- const maxStep = extractMaxToolInvocationStep(getToolInvocations(messages[messages.length - 1]));
149
- try {
150
- const abortController = new AbortController();
151
- this.#abortController = abortController;
152
- // Optimistically update messages
153
- this.messages = messages;
154
- await callChatApi({
155
- api: this.#api,
156
- body: {
157
- id: this.chatId,
158
- messages,
159
- ...$state.snapshot(this.#options.body),
160
- ...chatRequest.body,
161
- },
162
- streamProtocol: this.#streamProtocol,
163
- credentials: this.#options.credentials,
164
- headers: {
165
- ...this.#options.headers,
166
- ...chatRequest.headers,
167
- },
168
- abortController: () => abortController,
169
- onUpdate: ({ message }) => {
170
- this.#store.status = 'streaming';
171
- const replaceLastMessage = message.id === messages[messages.length - 1].id;
172
- this.messages = messages;
173
- if (replaceLastMessage) {
174
- this.messages[this.messages.length - 1] = message;
175
- }
176
- else {
177
- this.messages.push(message);
178
- }
179
- },
180
- onToolCall: this.#options.onToolCall,
181
- onFinish: this.#options.onFinish,
182
- generateId: this.#generateId,
183
- fetch: this.#options.fetch,
184
- // callChatApi calls structuredClone on the message
185
- lastMessage: $state.snapshot(this.messages[this.messages.length - 1]),
186
- messageMetadataSchema: this.#messageMetadataSchema,
187
- });
188
- this.#abortController = undefined;
189
- this.#store.status = 'ready';
190
- }
191
- catch (error) {
192
- if (isAbortError(error)) {
193
- return;
194
- }
195
- const coalescedError = error instanceof Error ? error : new Error(String(error));
196
- if (this.#options.onError) {
197
- this.#options.onError(coalescedError);
198
- }
199
- this.#store.status = 'error';
200
- this.#store.error = coalescedError;
201
- }
202
- // auto-submit when all tool calls in the last assistant message have results
203
- // and assistant has not answered yet
204
- if (shouldResubmitMessages({
205
- originalMaxToolInvocationStep: maxStep,
206
- originalMessageCount: messageCount,
207
- maxSteps: this.#maxSteps,
208
- messages: this.messages,
209
- })) {
210
- await this.#triggerRequest({ messages: this.messages });
211
- }
26
+ replaceMessage = (index, message) => {
27
+ this.messages[index] = message;
212
28
  };
29
+ snapshot = (thing) => $state.snapshot(thing);
213
30
  }
@@ -1 +1 @@
1
- {"version":3,"file":"context-provider.d.ts","sourceRoot":"","sources":["../src/context-provider.ts"],"names":[],"mappings":"AAUA,wBAAgB,eAAe,SAS9B"}
1
+ {"version":3,"file":"context-provider.d.ts","sourceRoot":"","sources":["../src/context-provider.ts"],"names":[],"mappings":"AASA,wBAAgB,eAAe,SAM9B"}
@@ -1,9 +1,6 @@
1
- import { KeyedChatStore, setChatContext } from './chat-context.svelte.js';
2
1
  import { KeyedCompletionStore, setCompletionContext, } from './completion-context.svelte.js';
3
2
  import { KeyedStructuredObjectStore, setStructuredObjectContext, } from './structured-object-context.svelte.js';
4
3
  export function createAIContext() {
5
- const chatStore = new KeyedChatStore();
6
- setChatContext(chatStore);
7
4
  const completionStore = new KeyedCompletionStore();
8
5
  setCompletionContext(completionStore);
9
6
  const objectStore = new KeyedStructuredObjectStore();
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- export { Chat, type ChatOptions, type CreateUIMessage, type UIMessage, } from './chat.svelte.js';
2
- export { StructuredObject as Experimental_StructuredObject, type Experimental_StructuredObjectOptions, } from './structured-object.svelte.js';
1
+ export { Chat, type CreateUIMessage, type UIMessage } from './chat.svelte.js';
3
2
  export { Completion, type CompletionOptions } from './completion.svelte.js';
4
3
  export { createAIContext } from './context-provider.js';
4
+ export { StructuredObject as Experimental_StructuredObject, type Experimental_StructuredObjectOptions, } from './structured-object.svelte.js';
5
5
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,IAAI,EACJ,KAAK,WAAW,EAChB,KAAK,eAAe,EACpB,KAAK,SAAS,GACf,MAAM,kBAAkB,CAAC;AAE1B,OAAO,EACL,gBAAgB,IAAI,6BAA6B,EACjD,KAAK,oCAAoC,GAC1C,MAAM,+BAA+B,CAAC;AAEvC,OAAO,EAAE,UAAU,EAAE,KAAK,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAE5E,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,KAAK,eAAe,EAAE,KAAK,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAC9E,OAAO,EAAE,UAAU,EAAE,KAAK,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAC5E,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AACxD,OAAO,EACL,gBAAgB,IAAI,6BAA6B,EACjD,KAAK,oCAAoC,GAC1C,MAAM,+BAA+B,CAAC"}
package/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
- export { Chat, } from './chat.svelte.js';
2
- export { StructuredObject as Experimental_StructuredObject, } from './structured-object.svelte.js';
1
+ export { Chat } from './chat.svelte.js';
3
2
  export { Completion } from './completion.svelte.js';
4
3
  export { createAIContext } from './context-provider.js';
4
+ export { StructuredObject as Experimental_StructuredObject, } from './structured-object.svelte.js';
@@ -1,7 +1,8 @@
1
- import { type FetchFunction } from '@ai-sdk/provider-utils';
1
+ import { type FetchFunction, type InferSchema } from '@ai-sdk/provider-utils';
2
2
  import { type DeepPartial, type Schema } from 'ai';
3
- import { type z } from 'zod';
4
- export type Experimental_StructuredObjectOptions<RESULT> = {
3
+ import type * as z3 from 'zod/v3';
4
+ import type * as z4 from 'zod/v4/core';
5
+ export type Experimental_StructuredObjectOptions<SCHEMA extends z3.Schema | z4.$ZodType | Schema, RESULT = InferSchema<SCHEMA>> = {
5
6
  /**
6
7
  * The API endpoint. It should stream JSON that matches the schema as chunked text.
7
8
  */
@@ -9,7 +10,7 @@ export type Experimental_StructuredObjectOptions<RESULT> = {
9
10
  /**
10
11
  * A Zod schema that defines the shape of the complete object.
11
12
  */
12
- schema: z.Schema<RESULT, z.ZodTypeDef, unknown> | Schema<RESULT>;
13
+ schema: SCHEMA;
13
14
  /**
14
15
  * An unique identifier. If not provided, a random one will be
15
16
  * generated. When provided, the `useObject` hook with the same `id` will
@@ -54,7 +55,7 @@ export type Experimental_StructuredObjectOptions<RESULT> = {
54
55
  */
55
56
  credentials?: RequestCredentials;
56
57
  };
57
- export declare class StructuredObject<RESULT, INPUT = unknown> {
58
+ export declare class StructuredObject<SCHEMA extends z3.Schema | z4.$ZodType | Schema, RESULT = InferSchema<SCHEMA>, INPUT = unknown> {
58
59
  #private;
59
60
  /**
60
61
  * The current value for the generated object. Updated as the API streams JSON chunks.
@@ -66,7 +67,7 @@ export declare class StructuredObject<RESULT, INPUT = unknown> {
66
67
  * Flag that indicates whether an API request is in progress.
67
68
  */
68
69
  get loading(): boolean;
69
- constructor(options: Experimental_StructuredObjectOptions<RESULT>);
70
+ constructor(options: Experimental_StructuredObjectOptions<SCHEMA, RESULT>);
70
71
  /**
71
72
  * Abort the current request immediately, keep the current partial object if any.
72
73
  */
@@ -1 +1 @@
1
- {"version":3,"file":"structured-object.svelte.d.ts","sourceRoot":"","sources":["../src/structured-object.svelte.ts"],"names":[],"mappings":"AAAA,OAAO,EAIL,KAAK,aAAa,EACnB,MAAM,wBAAwB,CAAC;AAChC,OAAO,EAIL,KAAK,WAAW,EAChB,KAAK,MAAM,EACZ,MAAM,IAAI,CAAC;AACZ,OAAO,EAAE,KAAK,CAAC,EAAE,MAAM,KAAK,CAAC;AAQ7B,MAAM,MAAM,oCAAoC,CAAC,MAAM,IAAI;IACzD;;OAEG;IACH,GAAG,EAAE,MAAM,CAAC;IAEZ;;OAEG;IACH,MAAM,EAAE,CAAC,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,UAAU,EAAE,OAAO,CAAC,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC;IAEjE;;;;OAIG;IACH,EAAE,CAAC,EAAE,MAAM,CAAC;IAEZ;;OAEG;IACH,YAAY,CAAC,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;IAEnC;;;OAGG;IACH,KAAK,CAAC,EAAE,aAAa,CAAC;IAEtB;;OAEG;IACH,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE;QACjB;;;WAGG;QACH,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC;QAE3B;;WAEG;QACH,KAAK,EAAE,KAAK,GAAG,SAAS,CAAC;KAC1B,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;IAE3B;;OAEG;IACH,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;IAEjC;;OAEG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,OAAO,CAAC;IAE3C;;;;OAIG;IACH,WAAW,CAAC,EAAE,kBAAkB,CAAC;CAClC,CAAC;AAEF,qBAAa,gBAAgB,CAAC,MAAM,EAAE,KAAK,GAAG,OAAO;;IAUnD;;OAEG;IACH,IAAI,MAAM,IAAI,WAAW,CAAC,MAAM,CAAC,GAAG,SAAS,CAE5C;IAKD,0CAA0C;IAC1C,IAAI,KAAK,sBAER;IAED;;OAEG;IACH,IAAI,OAAO,YAEV;gBAEW,OAAO,EAAE,oCAAoC,CAAC,MAAM,CAAC;IAUjE;;OAEG;IACH,IAAI,aASF;IAEF;;OAEG;IACH,MAAM,UAAiB,KAAK,mBAqF1B;CACH"}
1
+ {"version":3,"file":"structured-object.svelte.d.ts","sourceRoot":"","sources":["../src/structured-object.svelte.ts"],"names":[],"mappings":"AAAA,OAAO,EAIL,KAAK,aAAa,EAClB,KAAK,WAAW,EACjB,MAAM,wBAAwB,CAAC;AAChC,OAAO,EAIL,KAAK,WAAW,EAChB,KAAK,MAAM,EACZ,MAAM,IAAI,CAAC;AACZ,OAAO,KAAK,KAAK,EAAE,MAAM,QAAQ,CAAC;AAClC,OAAO,KAAK,KAAK,EAAE,MAAM,aAAa,CAAC;AAQvC,MAAM,MAAM,oCAAoC,CAC9C,MAAM,SAAS,EAAE,CAAC,MAAM,GAAG,EAAE,CAAC,QAAQ,GAAG,MAAM,EAC/C,MAAM,GAAG,WAAW,CAAC,MAAM,CAAC,IAC1B;IACF;;OAEG;IACH,GAAG,EAAE,MAAM,CAAC;IAEZ;;OAEG;IACH,MAAM,EAAE,MAAM,CAAC;IAEf;;;;OAIG;IACH,EAAE,CAAC,EAAE,MAAM,CAAC;IAEZ;;OAEG;IACH,YAAY,CAAC,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;IAEnC;;;OAGG;IACH,KAAK,CAAC,EAAE,aAAa,CAAC;IAEtB;;OAEG;IACH,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE;QACjB;;;WAGG;QACH,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC;QAE3B;;WAEG;QACH,KAAK,EAAE,KAAK,GAAG,SAAS,CAAC;KAC1B,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;IAE3B;;OAEG;IACH,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;IAEjC;;OAEG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,OAAO,CAAC;IAE3C;;;;OAIG;IACH,WAAW,CAAC,EAAE,kBAAkB,CAAC;CAClC,CAAC;AAEF,qBAAa,gBAAgB,CAC3B,MAAM,SAAS,EAAE,CAAC,MAAM,GAAG,EAAE,CAAC,QAAQ,GAAG,MAAM,EAC/C,MAAM,GAAG,WAAW,CAAC,MAAM,CAAC,EAC5B,KAAK,GAAG,OAAO;;IAWf;;OAEG;IACH,IAAI,MAAM,IAAI,WAAW,CAAC,MAAM,CAAC,GAAG,SAAS,CAE5C;IAKD,0CAA0C;IAC1C,IAAI,KAAK,sBAER;IAED;;OAEG;IACH,IAAI,OAAO,YAEV;gBAEW,OAAO,EAAE,oCAAoC,CAAC,MAAM,EAAE,MAAM,CAAC;IAUzE;;OAEG;IACH,IAAI,aASF;IAEF;;OAEG;IACH,MAAM,UAAiB,KAAK,mBAqF1B;CACH"}
@@ -1,6 +1,5 @@
1
1
  import { generateId, isAbortError, safeValidateTypes, } from '@ai-sdk/provider-utils';
2
2
  import { asSchema, isDeepEqualData, parsePartialJson, } from 'ai';
3
- import {} from 'zod';
4
3
  import { getStructuredObjectContext, hasStructuredObjectContext, KeyedStructuredObjectStore, } from './structured-object-context.svelte.js';
5
4
  export class StructuredObject {
6
5
  #options = {};
@@ -11,8 +11,8 @@ declare class __sveltets_Render<RESULT> {
11
11
  slots(): {};
12
12
  bindings(): "";
13
13
  exports(): {
14
- object1: StructuredObject<RESULT, unknown>;
15
- object2: StructuredObject<RESULT, unknown>;
14
+ object1: StructuredObject<z.ZodType<RESULT, z.ZodTypeDef, unknown> | Schema<RESULT>, RESULT, unknown>;
15
+ object2: StructuredObject<z.ZodType<RESULT, z.ZodTypeDef, unknown> | Schema<RESULT>, RESULT, unknown>;
16
16
  };
17
17
  }
18
18
  interface $$IsomorphicComponent {
@@ -1,4 +1,4 @@
1
- import { hasContext, getContext, setContext, untrack } from 'svelte';
1
+ import { getContext, hasContext, setContext, untrack } from 'svelte';
2
2
  import { SvelteMap } from 'svelte/reactivity';
3
3
  export function createContext(name) {
4
4
  const key = Symbol(name);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ai-sdk/svelte",
3
- "version": "3.0.0-alpha.1",
3
+ "version": "3.0.0-alpha.10",
4
4
  "license": "Apache-2.0",
5
5
  "files": [
6
6
  "dist",
@@ -27,8 +27,8 @@
27
27
  "access": "public"
28
28
  },
29
29
  "peerDependencies": {
30
- "svelte": "^5.0.0",
31
- "zod": "^3.23.8"
30
+ "svelte": "^5.31.0",
31
+ "zod": "^3.25.49"
32
32
  },
33
33
  "peerDependenciesMeta": {
34
34
  "zod": {
@@ -36,8 +36,8 @@
36
36
  }
37
37
  },
38
38
  "dependencies": {
39
- "ai": "5.0.0-alpha.1",
40
- "@ai-sdk/provider-utils": "3.0.0-alpha.1"
39
+ "ai": "5.0.0-alpha.10",
40
+ "@ai-sdk/provider-utils": "3.0.0-alpha.10"
41
41
  },
42
42
  "devDependencies": {
43
43
  "@types/node": "20.17.24",
@@ -52,13 +52,13 @@
52
52
  "globals": "^16.0.0",
53
53
  "jsdom": "^26.0.0",
54
54
  "publint": "^0.3.2",
55
- "svelte": "^5.0.0",
55
+ "svelte": "^5.31.0",
56
56
  "svelte-check": "^4.0.0",
57
57
  "typescript": "^5.0.0",
58
58
  "typescript-eslint": "^8.20.0",
59
59
  "vite": "^6.0.0",
60
60
  "vitest": "^3.0.0",
61
- "zod": "3.24.4",
61
+ "zod": "3.25.49",
62
62
  "@vercel/ai-tsconfig": "0.0.0"
63
63
  },
64
64
  "homepage": "https://ai-sdk.dev/docs",
@@ -1,295 +1,57 @@
1
- import { isAbortError } from '@ai-sdk/provider-utils';
2
1
  import {
3
- callChatApi,
4
- convertFileListToFileUIParts,
5
- extractMaxToolInvocationStep,
6
- generateId,
7
- getToolInvocations,
8
- isAssistantMessageWithCompletedToolCalls,
9
- shouldResubmitMessages,
10
- updateToolCallResult,
11
- type ChatRequestOptions,
2
+ AbstractChat,
3
+ type ChatInit,
4
+ type ChatState,
5
+ type ChatStatus,
12
6
  type CreateUIMessage,
13
- type OriginalUseChatOptions,
7
+ type UIDataPartSchemas,
8
+ type UIDataTypes,
14
9
  type UIMessage,
15
10
  } from 'ai';
16
- import { untrack } from 'svelte';
17
- import {
18
- KeyedChatStore,
19
- getChatContext,
20
- hasChatContext,
21
- } from './chat-context.svelte.js';
22
-
23
- export type ChatOptions<MESSAGE_METADATA = unknown> = Readonly<
24
- OriginalUseChatOptions<MESSAGE_METADATA>
25
- >;
26
11
 
27
12
  export type { CreateUIMessage, UIMessage };
28
13
 
29
- export class Chat<MESSAGE_METADATA = unknown> {
30
- readonly #options: ChatOptions<MESSAGE_METADATA> = {};
31
- readonly #api = $derived(this.#options.api ?? '/api/chat');
32
- readonly #generateId = $derived(this.#options.generateId ?? generateId);
33
- readonly #maxSteps = $derived(this.#options.maxSteps ?? 1);
34
- readonly #streamProtocol = $derived(
35
- this.#options.streamProtocol ?? 'ui-message',
36
- );
37
- readonly #keyedStore = $state<KeyedChatStore<MESSAGE_METADATA>>()!;
38
- /**
39
- * The id of the chat. If not provided through the constructor, a random ID will be generated
40
- * using the provided `generateId` function, or a built-in function if not provided.
41
- */
42
- readonly chatId = $derived(this.#options.chatId ?? this.#generateId());
43
- readonly #store = $derived(this.#keyedStore.get(this.chatId));
44
-
45
- readonly #messageMetadataSchema = $derived(
46
- this.#options.messageMetadataSchema,
47
- );
48
-
49
- #abortController: AbortController | undefined;
50
-
51
- /**
52
- * Hook status:
53
- *
54
- * - `submitted`: The message has been sent to the API and we're awaiting the start of the response stream.
55
- * - `streaming`: The response is actively streaming in from the API, receiving chunks of data.
56
- * - `ready`: The full response has been received and processed; a new user message can be submitted.
57
- * - `error`: An error occurred during the API request, preventing successful completion.
58
- */
59
- get status() {
60
- return this.#store.status;
61
- }
62
-
63
- /** The error object of the API request */
64
- get error() {
65
- return this.#store.error;
66
- }
67
-
68
- /** The current value of the input. Writable, so it can be bound to form inputs. */
69
- input = $state<string>()!;
70
-
71
- /**
72
- * Current messages in the chat.
73
- *
74
- * This is writable, which is useful when you want to edit the messages on the client, and then
75
- * trigger {@link reload} to regenerate the AI response.
76
- */
77
- get messages(): UIMessage<MESSAGE_METADATA>[] {
78
- return this.#store.messages;
79
- }
80
- set messages(value: UIMessage<MESSAGE_METADATA>[]) {
81
- untrack(() => (this.#store.messages = value));
14
+ export class Chat<
15
+ MESSAGE_METADATA = unknown,
16
+ DATA_PART_SCHEMAS extends UIDataPartSchemas = UIDataPartSchemas,
17
+ > extends AbstractChat<MESSAGE_METADATA, DATA_PART_SCHEMAS> {
18
+ constructor(init: ChatInit<MESSAGE_METADATA, DATA_PART_SCHEMAS>) {
19
+ super({
20
+ ...init,
21
+ state: new SvelteChatState(init.messages),
22
+ });
82
23
  }
24
+ }
83
25
 
84
- constructor(options: ChatOptions<MESSAGE_METADATA> = {}) {
85
- if (hasChatContext()) {
86
- this.#keyedStore = getChatContext() as KeyedChatStore<MESSAGE_METADATA>;
87
- } else {
88
- this.#keyedStore = new KeyedChatStore<MESSAGE_METADATA>();
89
- }
26
+ class SvelteChatState<MESSAGE_METADATA, DATA_TYPES extends UIDataTypes>
27
+ implements ChatState<MESSAGE_METADATA, DATA_TYPES>
28
+ {
29
+ messages: UIMessage<MESSAGE_METADATA, DATA_TYPES>[];
30
+ status = $state<ChatStatus>('ready');
31
+ error = $state<Error | undefined>(undefined);
90
32
 
91
- this.#options = options;
92
- this.messages = options.initialMessages ?? [];
93
- this.input = options.initialInput ?? '';
33
+ constructor(messages: UIMessage<MESSAGE_METADATA, DATA_TYPES>[] = []) {
34
+ this.messages = $state(messages);
94
35
  }
95
36
 
96
- /**
97
- * Append a user message to the chat list. This triggers the API call to fetch
98
- * the assistant's response.
99
- * @param message The message to append
100
- * @param options Additional options to pass to the API call
101
- */
102
- append = async (
103
- message: UIMessage<MESSAGE_METADATA> | CreateUIMessage<MESSAGE_METADATA>,
104
- { headers, body }: ChatRequestOptions = {},
105
- ) => {
106
- const messages = this.messages.concat({
107
- ...message,
108
- id: message.id ?? this.#generateId(),
109
- });
110
-
111
- return this.#triggerRequest({ messages, headers, body });
37
+ setMessages = (messages: UIMessage<MESSAGE_METADATA, DATA_TYPES>[]) => {
38
+ this.messages = messages;
112
39
  };
113
40
 
114
- /**
115
- * Reload the last AI chat response for the given chat history. If the last
116
- * message isn't from the assistant, it will request the API to generate a
117
- * new response.
118
- */
119
- reload = async ({ headers, body }: ChatRequestOptions = {}) => {
120
- if (this.messages.length === 0) {
121
- return;
122
- }
123
-
124
- const lastMessage = this.messages[this.messages.length - 1];
125
- await this.#triggerRequest({
126
- messages:
127
- lastMessage.role === 'assistant'
128
- ? this.messages.slice(0, -1)
129
- : this.messages,
130
- headers,
131
- body,
132
- });
41
+ pushMessage = (message: UIMessage<MESSAGE_METADATA, DATA_TYPES>) => {
42
+ this.messages.push(message);
133
43
  };
134
44
 
135
- /**
136
- * Abort the current request immediately, keep the generated tokens if any.
137
- */
138
- stop = () => {
139
- try {
140
- this.#abortController?.abort();
141
- } catch {
142
- // ignore
143
- } finally {
144
- this.#store.status = 'ready';
145
- this.#abortController = undefined;
146
- }
45
+ popMessage = () => {
46
+ this.messages.pop();
147
47
  };
148
48
 
149
- /** Form submission handler to automatically reset input and append a user message */
150
- handleSubmit = async (
151
- event?: { preventDefault?: () => void },
152
- options: ChatRequestOptions & { files?: FileList } = {},
49
+ replaceMessage = (
50
+ index: number,
51
+ message: UIMessage<MESSAGE_METADATA, DATA_TYPES>,
153
52
  ) => {
154
- event?.preventDefault?.();
155
-
156
- const fileParts = Array.isArray(options?.files)
157
- ? options.files
158
- : await convertFileListToFileUIParts(options?.files);
159
-
160
- if (!this.input && fileParts.length === 0) return;
161
-
162
- const messages = this.messages.concat({
163
- id: this.#generateId(),
164
- role: 'user',
165
- parts: [...fileParts, { type: 'text', text: this.input }],
166
- });
167
-
168
- const request = this.#triggerRequest({
169
- messages,
170
- headers: options.headers,
171
- body: options.body,
172
- });
173
-
174
- this.input = '';
175
- await request;
53
+ this.messages[index] = message;
176
54
  };
177
55
 
178
- addToolResult = async ({
179
- toolCallId,
180
- result,
181
- }: {
182
- toolCallId: string;
183
- result: unknown;
184
- }) => {
185
- updateToolCallResult({
186
- messages: this.messages,
187
- toolCallId,
188
- toolResult: result,
189
- });
190
-
191
- // when the request is ongoing, the auto-submit will be triggered after the request is finished
192
- if (
193
- this.#store.status === 'submitted' ||
194
- this.#store.status === 'streaming'
195
- ) {
196
- return;
197
- }
198
-
199
- const lastMessage = this.messages[this.messages.length - 1];
200
- if (isAssistantMessageWithCompletedToolCalls(lastMessage)) {
201
- await this.#triggerRequest({ messages: this.messages });
202
- }
203
- };
204
-
205
- #triggerRequest = async (
206
- chatRequest: ChatRequestOptions & {
207
- messages: UIMessage<MESSAGE_METADATA>[];
208
- },
209
- ) => {
210
- this.#store.status = 'submitted';
211
- this.#store.error = undefined;
212
-
213
- const messages = chatRequest.messages;
214
- const messageCount = messages.length;
215
- const maxStep = extractMaxToolInvocationStep(
216
- getToolInvocations(messages[messages.length - 1]),
217
- );
218
-
219
- try {
220
- const abortController = new AbortController();
221
- this.#abortController = abortController;
222
-
223
- // Optimistically update messages
224
- this.messages = messages;
225
-
226
- await callChatApi({
227
- api: this.#api,
228
- body: {
229
- id: this.chatId,
230
- messages,
231
- ...$state.snapshot(this.#options.body),
232
- ...chatRequest.body,
233
- },
234
- streamProtocol: this.#streamProtocol,
235
- credentials: this.#options.credentials,
236
- headers: {
237
- ...this.#options.headers,
238
- ...chatRequest.headers,
239
- },
240
- abortController: () => abortController,
241
- onUpdate: ({ message }) => {
242
- this.#store.status = 'streaming';
243
-
244
- const replaceLastMessage =
245
- message.id === messages[messages.length - 1].id;
246
-
247
- this.messages = messages;
248
- if (replaceLastMessage) {
249
- this.messages[this.messages.length - 1] = message;
250
- } else {
251
- this.messages.push(message);
252
- }
253
- },
254
- onToolCall: this.#options.onToolCall,
255
- onFinish: this.#options.onFinish,
256
- generateId: this.#generateId,
257
- fetch: this.#options.fetch,
258
- // callChatApi calls structuredClone on the message
259
- lastMessage: $state.snapshot(
260
- this.messages[this.messages.length - 1],
261
- ) as UIMessage<MESSAGE_METADATA>,
262
- messageMetadataSchema: this.#messageMetadataSchema,
263
- });
264
-
265
- this.#abortController = undefined;
266
- this.#store.status = 'ready';
267
- } catch (error) {
268
- if (isAbortError(error)) {
269
- return;
270
- }
271
-
272
- const coalescedError =
273
- error instanceof Error ? error : new Error(String(error));
274
- if (this.#options.onError) {
275
- this.#options.onError(coalescedError);
276
- }
277
-
278
- this.#store.status = 'error';
279
- this.#store.error = coalescedError;
280
- }
281
-
282
- // auto-submit when all tool calls in the last assistant message have results
283
- // and assistant has not answered yet
284
- if (
285
- shouldResubmitMessages({
286
- originalMaxToolInvocationStep: maxStep,
287
- originalMessageCount: messageCount,
288
- maxSteps: this.#maxSteps,
289
- messages: this.messages,
290
- })
291
- ) {
292
- await this.#triggerRequest({ messages: this.messages });
293
- }
294
- };
56
+ snapshot = <T>(thing: T): T => $state.snapshot(thing) as T;
295
57
  }
@@ -1,4 +1,3 @@
1
- import { KeyedChatStore, setChatContext } from './chat-context.svelte.js';
2
1
  import {
3
2
  KeyedCompletionStore,
4
3
  setCompletionContext,
@@ -9,9 +8,6 @@ import {
9
8
  } from './structured-object-context.svelte.js';
10
9
 
11
10
  export function createAIContext() {
12
- const chatStore = new KeyedChatStore();
13
- setChatContext(chatStore);
14
-
15
11
  const completionStore = new KeyedCompletionStore();
16
12
  setCompletionContext(completionStore);
17
13
 
package/src/index.ts CHANGED
@@ -1,15 +1,7 @@
1
- export {
2
- Chat,
3
- type ChatOptions,
4
- type CreateUIMessage,
5
- type UIMessage,
6
- } from './chat.svelte.js';
7
-
1
+ export { Chat, type CreateUIMessage, type UIMessage } from './chat.svelte.js';
2
+ export { Completion, type CompletionOptions } from './completion.svelte.js';
3
+ export { createAIContext } from './context-provider.js';
8
4
  export {
9
5
  StructuredObject as Experimental_StructuredObject,
10
6
  type Experimental_StructuredObjectOptions,
11
7
  } from './structured-object.svelte.js';
12
-
13
- export { Completion, type CompletionOptions } from './completion.svelte.js';
14
-
15
- export { createAIContext } from './context-provider.js';
@@ -3,6 +3,7 @@ import {
3
3
  isAbortError,
4
4
  safeValidateTypes,
5
5
  type FetchFunction,
6
+ type InferSchema,
6
7
  } from '@ai-sdk/provider-utils';
7
8
  import {
8
9
  asSchema,
@@ -11,7 +12,8 @@ import {
11
12
  type DeepPartial,
12
13
  type Schema,
13
14
  } from 'ai';
14
- import { type z } from 'zod';
15
+ import type * as z3 from 'zod/v3';
16
+ import type * as z4 from 'zod/v4/core';
15
17
  import {
16
18
  getStructuredObjectContext,
17
19
  hasStructuredObjectContext,
@@ -19,7 +21,10 @@ import {
19
21
  type StructuredObjectStore,
20
22
  } from './structured-object-context.svelte.js';
21
23
 
22
- export type Experimental_StructuredObjectOptions<RESULT> = {
24
+ export type Experimental_StructuredObjectOptions<
25
+ SCHEMA extends z3.Schema | z4.$ZodType | Schema,
26
+ RESULT = InferSchema<SCHEMA>,
27
+ > = {
23
28
  /**
24
29
  * The API endpoint. It should stream JSON that matches the schema as chunked text.
25
30
  */
@@ -28,7 +33,7 @@ export type Experimental_StructuredObjectOptions<RESULT> = {
28
33
  /**
29
34
  * A Zod schema that defines the shape of the complete object.
30
35
  */
31
- schema: z.Schema<RESULT, z.ZodTypeDef, unknown> | Schema<RESULT>;
36
+ schema: SCHEMA;
32
37
 
33
38
  /**
34
39
  * An unique identifier. If not provided, a random one will be
@@ -82,9 +87,13 @@ export type Experimental_StructuredObjectOptions<RESULT> = {
82
87
  credentials?: RequestCredentials;
83
88
  };
84
89
 
85
- export class StructuredObject<RESULT, INPUT = unknown> {
86
- #options: Experimental_StructuredObjectOptions<RESULT> =
87
- {} as Experimental_StructuredObjectOptions<RESULT>;
90
+ export class StructuredObject<
91
+ SCHEMA extends z3.Schema | z4.$ZodType | Schema,
92
+ RESULT = InferSchema<SCHEMA>,
93
+ INPUT = unknown,
94
+ > {
95
+ #options: Experimental_StructuredObjectOptions<SCHEMA, RESULT> =
96
+ {} as Experimental_StructuredObjectOptions<SCHEMA, RESULT>;
88
97
  readonly #id = $derived(this.#options.id ?? generateId());
89
98
  readonly #keyedStore = $state<KeyedStructuredObjectStore>()!;
90
99
  readonly #store = $derived(
@@ -114,7 +123,7 @@ export class StructuredObject<RESULT, INPUT = unknown> {
114
123
  return this.#store.loading;
115
124
  }
116
125
 
117
- constructor(options: Experimental_StructuredObjectOptions<RESULT>) {
126
+ constructor(options: Experimental_StructuredObjectOptions<SCHEMA, RESULT>) {
118
127
  if (hasStructuredObjectContext()) {
119
128
  this.#keyedStore = getStructuredObjectContext();
120
129
  } else {
@@ -1,4 +1,4 @@
1
- import { hasContext, getContext, setContext, untrack } from 'svelte';
1
+ import { getContext, hasContext, setContext, untrack } from 'svelte';
2
2
  import { SvelteMap } from 'svelte/reactivity';
3
3
 
4
4
  export function createContext<T>(name: string) {
@@ -1,13 +0,0 @@
1
- import { createContext, KeyedStore } from './utils.svelte.js';
2
- class ChatStore {
3
- messages = $state([]);
4
- data = $state();
5
- status = $state('ready');
6
- error = $state();
7
- }
8
- export class KeyedChatStore extends KeyedStore {
9
- constructor(value) {
10
- super(ChatStore, value);
11
- }
12
- }
13
- export const { hasContext: hasChatContext, getContext: getChatContext, setContext: setChatContext, } = createContext('Chat');
@@ -1,12 +0,0 @@
1
- <script lang="ts">
2
- import { Chat } from '../chat.svelte.js';
3
- import { createAIContext } from '../context-provider.js';
4
-
5
- let { chatId }: { chatId?: string } = $props();
6
-
7
- createAIContext();
8
- const chat1 = new Chat({ chatId });
9
- const chat2 = new Chat({ chatId });
10
-
11
- export { chat1, chat2 };
12
- </script>
@@ -1,11 +0,0 @@
1
- import { Chat } from '../chat.svelte.js';
2
- type $$ComponentProps = {
3
- chatId?: string;
4
- };
5
- declare const ChatSynchronization: import("svelte").Component<$$ComponentProps, {
6
- chat1: Chat<unknown>;
7
- chat2: Chat<unknown>;
8
- }, "">;
9
- type ChatSynchronization = ReturnType<typeof ChatSynchronization>;
10
- export default ChatSynchronization;
11
- //# sourceMappingURL=chat-synchronization.svelte.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"chat-synchronization.svelte.d.ts","sourceRoot":"","sources":["../../src/tests/chat-synchronization.svelte.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,IAAI,EAAE,MAAM,mBAAmB,CAAC;AAGxC,KAAK,gBAAgB,GAAI;IAAE,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC;AAgB9C,QAAA,MAAM,mBAAmB;;;MAAsC,CAAC;AAChE,KAAK,mBAAmB,GAAG,UAAU,CAAC,OAAO,mBAAmB,CAAC,CAAC;AAClE,eAAe,mBAAmB,CAAC"}
@@ -1,28 +0,0 @@
1
- import type { JSONValue, UIMessage } from 'ai';
2
- import { createContext, KeyedStore } from './utils.svelte.js';
3
-
4
- class ChatStore<MESSAGE_METADATA = unknown> {
5
- messages = $state<UIMessage<MESSAGE_METADATA>[]>([]);
6
- data = $state<JSONValue[]>();
7
- status = $state<'submitted' | 'streaming' | 'ready' | 'error'>('ready');
8
- error = $state<Error>();
9
- }
10
-
11
- export class KeyedChatStore<MESSAGE_METADATA = unknown> extends KeyedStore<
12
- ChatStore<MESSAGE_METADATA>
13
- > {
14
- constructor(
15
- value?:
16
- | Iterable<readonly [string, ChatStore<MESSAGE_METADATA>]>
17
- | null
18
- | undefined,
19
- ) {
20
- super(ChatStore, value);
21
- }
22
- }
23
-
24
- export const {
25
- hasContext: hasChatContext,
26
- getContext: getChatContext,
27
- setContext: setChatContext,
28
- } = createContext<KeyedChatStore>('Chat');
@@ -1,12 +0,0 @@
1
- <script lang="ts">
2
- import { Chat } from '../chat.svelte.js';
3
- import { createAIContext } from '../context-provider.js';
4
-
5
- let { chatId }: { chatId?: string } = $props();
6
-
7
- createAIContext();
8
- const chat1 = new Chat({ chatId });
9
- const chat2 = new Chat({ chatId });
10
-
11
- export { chat1, chat2 };
12
- </script>