@ai-sdk/svelte 2.1.12 → 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.
Files changed (41) hide show
  1. package/CHANGELOG.md +354 -24
  2. package/dist/chat.svelte.d.ts +4 -73
  3. package/dist/chat.svelte.d.ts.map +1 -1
  4. package/dist/chat.svelte.js +23 -243
  5. package/dist/completion.svelte.d.ts +2 -9
  6. package/dist/completion.svelte.d.ts.map +1 -1
  7. package/dist/completion.svelte.js +4 -22
  8. package/dist/context-provider.d.ts.map +1 -1
  9. package/dist/context-provider.js +0 -3
  10. package/dist/index.d.ts +2 -2
  11. package/dist/index.d.ts.map +1 -1
  12. package/dist/index.js +2 -2
  13. package/dist/structured-object-context.svelte.d.ts +1 -1
  14. package/dist/structured-object-context.svelte.d.ts.map +1 -1
  15. package/dist/structured-object.svelte.d.ts +8 -7
  16. package/dist/structured-object.svelte.d.ts.map +1 -1
  17. package/dist/structured-object.svelte.js +5 -6
  18. package/dist/tests/structured-object-synchronization.svelte +1 -1
  19. package/dist/tests/structured-object-synchronization.svelte.d.ts +3 -3
  20. package/dist/tests/structured-object-synchronization.svelte.d.ts.map +1 -1
  21. package/dist/utils.svelte.js +1 -1
  22. package/package.json +12 -9
  23. package/src/chat.svelte.ts +40 -333
  24. package/src/completion-context.svelte.ts +1 -1
  25. package/src/completion.svelte.ts +11 -28
  26. package/src/context-provider.ts +0 -4
  27. package/src/index.ts +3 -12
  28. package/src/structured-object-context.svelte.ts +1 -1
  29. package/src/structured-object.svelte.ts +21 -12
  30. package/src/tests/structured-object-synchronization.svelte +1 -1
  31. package/src/utils.svelte.ts +1 -1
  32. package/dist/chat-context.svelte.d.ts +0 -14
  33. package/dist/chat-context.svelte.d.ts.map +0 -1
  34. package/dist/chat-context.svelte.js +0 -13
  35. package/dist/completion-context.svelte.d.ts +0 -15
  36. package/dist/completion-context.svelte.d.ts.map +0 -1
  37. package/dist/tests/chat-synchronization.svelte +0 -12
  38. package/dist/tests/chat-synchronization.svelte.d.ts +0 -11
  39. package/dist/tests/chat-synchronization.svelte.d.ts.map +0 -1
  40. package/src/chat-context.svelte.ts +0 -23
  41. package/src/tests/chat-synchronization.svelte +0 -12
@@ -1,250 +1,30 @@
1
- import { fillMessageParts, generateId, extractMaxToolInvocationStep, callChatApi, shouldResubmitMessages, prepareAttachmentsForRequest, getMessageParts, updateToolCallResult, isAssistantMessageWithCompletedToolCalls, } from '@ai-sdk/ui-utils';
2
- import { isAbortError } from '@ai-sdk/provider-utils';
3
- import { KeyedChatStore, getChatContext, hasChatContext, } from './chat-context.svelte.js';
4
- import { untrack } from 'svelte';
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 ?? 'data');
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
- id = $derived(this.#options.id ?? this.#generateId());
17
- #store = $derived(this.#keyedStore.get(this.id));
18
- #abortController;
19
- /**
20
- * Additional data added on the server via StreamData.
21
- *
22
- * This is writable, so you can use it to transform or clear the chat data.
23
- */
24
- get data() {
25
- return this.#store.data;
26
- }
27
- set data(value) {
28
- this.#store.data = value;
29
- }
30
- /**
31
- * Hook status:
32
- *
33
- * - `submitted`: The message has been sent to the API and we're awaiting the start of the response stream.
34
- * - `streaming`: The response is actively streaming in from the API, receiving chunks of data.
35
- * - `ready`: The full response has been received and processed; a new user message can be submitted.
36
- * - `error`: An error occurred during the API request, preventing successful completion.
37
- */
38
- get status() {
39
- return this.#store.status;
40
- }
41
- /** The error object of the API request */
42
- get error() {
43
- return this.#store.error;
44
- }
45
- /** The current value of the input. Writable, so it can be bound to form inputs. */
46
- input = $state();
47
- /**
48
- * Current messages in the chat.
49
- *
50
- * This is writable, which is useful when you want to edit the messages on the client, and then
51
- * trigger {@link reload} to regenerate the AI response.
52
- */
53
- get messages() {
54
- return this.#store.messages;
55
- }
56
- set messages(value) {
57
- untrack(() => (this.#store.messages = fillMessageParts(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
+ });
58
8
  }
59
- constructor(options = {}) {
60
- if (hasChatContext()) {
61
- this.#keyedStore = getChatContext();
62
- }
63
- else {
64
- this.#keyedStore = new KeyedChatStore();
65
- }
66
- this.#options = options;
67
- this.messages = options.initialMessages ?? [];
68
- 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);
69
16
  }
70
- /**
71
- * Append a user message to the chat list. This triggers the API call to fetch
72
- * the assistant's response.
73
- * @param message The message to append
74
- * @param options Additional options to pass to the API call
75
- */
76
- append = async (message, { data, headers, body, experimental_attachments } = {}) => {
77
- const attachmentsForRequest = await prepareAttachmentsForRequest(experimental_attachments);
78
- const messages = this.messages.concat({
79
- ...message,
80
- id: message.id ?? this.#generateId(),
81
- createdAt: message.createdAt ?? new Date(),
82
- experimental_attachments: attachmentsForRequest.length > 0 ? attachmentsForRequest : undefined,
83
- parts: getMessageParts(message),
84
- });
85
- return this.#triggerRequest({ messages, headers, body, data });
86
- };
87
- /**
88
- * Reload the last AI chat response for the given chat history. If the last
89
- * message isn't from the assistant, it will request the API to generate a
90
- * new response.
91
- */
92
- reload = async ({ data, headers, body } = {}) => {
93
- if (this.messages.length === 0) {
94
- return;
95
- }
96
- const lastMessage = this.messages[this.messages.length - 1];
97
- await this.#triggerRequest({
98
- messages: lastMessage.role === 'assistant'
99
- ? this.messages.slice(0, -1)
100
- : this.messages,
101
- headers,
102
- body,
103
- data,
104
- });
17
+ setMessages = (messages) => {
18
+ this.messages = messages;
105
19
  };
106
- /**
107
- * Abort the current request immediately, keep the generated tokens if any.
108
- */
109
- stop = () => {
110
- try {
111
- this.#abortController?.abort();
112
- }
113
- catch {
114
- // ignore
115
- }
116
- finally {
117
- this.#store.status = 'ready';
118
- this.#abortController = undefined;
119
- }
20
+ pushMessage = (message) => {
21
+ this.messages.push(message);
120
22
  };
121
- /** Form submission handler to automatically reset input and append a user message */
122
- handleSubmit = async (event, options = {}) => {
123
- event?.preventDefault?.();
124
- if (!this.input && !options.allowEmptySubmit)
125
- return;
126
- const attachmentsForRequest = await prepareAttachmentsForRequest(options.experimental_attachments);
127
- const messages = this.messages.concat({
128
- id: this.#generateId(),
129
- createdAt: new Date(),
130
- role: 'user',
131
- content: this.input,
132
- experimental_attachments: attachmentsForRequest.length > 0 ? attachmentsForRequest : undefined,
133
- parts: [{ type: 'text', text: this.input }],
134
- });
135
- const chatRequest = {
136
- messages,
137
- headers: options.headers,
138
- body: options.body,
139
- data: options.data,
140
- };
141
- const request = this.#triggerRequest(chatRequest);
142
- this.input = '';
143
- await request;
144
- };
145
- addToolResult = async ({ toolCallId, result, }) => {
146
- updateToolCallResult({
147
- messages: this.messages,
148
- toolCallId,
149
- toolResult: result,
150
- });
151
- // when the request is ongoing, the auto-submit will be triggered after the request is finished
152
- if (this.#store.status === 'submitted' ||
153
- this.#store.status === 'streaming') {
154
- return;
155
- }
156
- const lastMessage = this.messages[this.messages.length - 1];
157
- if (isAssistantMessageWithCompletedToolCalls(lastMessage)) {
158
- await this.#triggerRequest({ messages: this.messages });
159
- }
23
+ popMessage = () => {
24
+ this.messages.pop();
160
25
  };
161
- #triggerRequest = async (chatRequest) => {
162
- this.#store.status = 'submitted';
163
- this.#store.error = undefined;
164
- const messages = fillMessageParts(chatRequest.messages);
165
- const messageCount = messages.length;
166
- const maxStep = extractMaxToolInvocationStep(messages[messages.length - 1]?.toolInvocations);
167
- try {
168
- const abortController = new AbortController();
169
- this.#abortController = abortController;
170
- // Optimistically update messages
171
- this.messages = messages;
172
- const constructedMessagesPayload = this.#options.sendExtraMessageFields
173
- ? messages
174
- : messages.map(({ role, content, experimental_attachments, data, annotations, toolInvocations, parts, }) => ({
175
- role,
176
- content,
177
- ...(experimental_attachments !== undefined && {
178
- experimental_attachments,
179
- }),
180
- ...(data !== undefined && { data }),
181
- ...(annotations !== undefined && { annotations }),
182
- ...(toolInvocations !== undefined && { toolInvocations }),
183
- ...(parts !== undefined && { parts }),
184
- }));
185
- const existingData = this.data ?? [];
186
- await callChatApi({
187
- api: this.#api,
188
- body: {
189
- id: this.id,
190
- messages: constructedMessagesPayload,
191
- data: chatRequest.data,
192
- ...$state.snapshot(this.#options.body),
193
- ...chatRequest.body,
194
- },
195
- streamProtocol: this.#streamProtocol,
196
- credentials: this.#options.credentials,
197
- headers: {
198
- ...this.#options.headers,
199
- ...chatRequest.headers,
200
- },
201
- abortController: () => abortController,
202
- restoreMessagesOnFailure: () => { },
203
- onResponse: this.#options.onResponse,
204
- onUpdate: ({ message, data, replaceLastMessage }) => {
205
- this.#store.status = 'streaming';
206
- this.messages = messages;
207
- if (replaceLastMessage) {
208
- this.messages[this.messages.length - 1] = message;
209
- }
210
- else {
211
- this.messages.push(message);
212
- }
213
- if (data?.length) {
214
- this.data = existingData;
215
- this.data.push(...data);
216
- }
217
- },
218
- onToolCall: this.#options.onToolCall,
219
- onFinish: this.#options.onFinish,
220
- generateId: this.#generateId,
221
- fetch: this.#options.fetch,
222
- // callChatApi calls structuredClone on the message
223
- lastMessage: $state.snapshot(this.messages[this.messages.length - 1]),
224
- });
225
- this.#abortController = undefined;
226
- this.#store.status = 'ready';
227
- }
228
- catch (error) {
229
- if (isAbortError(error)) {
230
- return;
231
- }
232
- const coalescedError = error instanceof Error ? error : new Error(String(error));
233
- if (this.#options.onError) {
234
- this.#options.onError(coalescedError);
235
- }
236
- this.#store.status = 'error';
237
- this.#store.error = coalescedError;
238
- }
239
- // auto-submit when all tool calls in the last assistant message have results
240
- // and assistant has not answered yet
241
- if (shouldResubmitMessages({
242
- originalMaxToolInvocationStep: maxStep,
243
- originalMessageCount: messageCount,
244
- maxSteps: this.#maxSteps,
245
- messages: this.messages,
246
- })) {
247
- await this.#triggerRequest({ messages: this.messages });
248
- }
26
+ replaceMessage = (index, message) => {
27
+ this.messages[index] = message;
249
28
  };
29
+ snapshot = (thing) => $state.snapshot(thing);
250
30
  }
@@ -1,17 +1,10 @@
1
- import { type UseCompletionOptions, type JSONValue, type RequestOptions } from '@ai-sdk/ui-utils';
1
+ import { type CompletionRequestOptions, type UseCompletionOptions } from 'ai';
2
2
  export type CompletionOptions = Readonly<UseCompletionOptions>;
3
3
  export declare class Completion {
4
4
  #private;
5
5
  /** The current completion result */
6
6
  get completion(): string;
7
7
  set completion(value: string);
8
- /**
9
- * Additional data added on the server via StreamData.
10
- *
11
- * This is writable, so you can use it to transform or clear the chat data.
12
- */
13
- get data(): JSONValue[];
14
- set data(value: JSONValue[]);
15
8
  /** The error object of the API request */
16
9
  get error(): Error | undefined;
17
10
  /** The current value of the input. Writable, so it can be bound to form inputs. */
@@ -28,7 +21,7 @@ export declare class Completion {
28
21
  /**
29
22
  * Send a new prompt to the API endpoint and update the completion state.
30
23
  */
31
- complete: (prompt: string, options?: RequestOptions) => Promise<string | null | undefined>;
24
+ complete: (prompt: string, options?: CompletionRequestOptions) => Promise<string | null | undefined>;
32
25
  /** Form submission handler to automatically reset input and call the completion API */
33
26
  handleSubmit: (event?: {
34
27
  preventDefault?: () => void;
@@ -1 +1 @@
1
- {"version":3,"file":"completion.svelte.d.ts","sourceRoot":"","sources":["../src/completion.svelte.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,oBAAoB,EACzB,KAAK,SAAS,EACd,KAAK,cAAc,EAEpB,MAAM,kBAAkB,CAAC;AAO1B,MAAM,MAAM,iBAAiB,GAAG,QAAQ,CAAC,oBAAoB,CAAC,CAAC;AAE/D,qBAAa,UAAU;;IASrB,oCAAoC;IACpC,IAAI,UAAU,IAAI,MAAM,CAEvB;IACD,IAAI,UAAU,CAAC,KAAK,EAAE,MAAM,EAE3B;IAED;;;;OAIG;IACH,IAAI,IAAI,IAGQ,SAAS,EAAE,CAD1B;IACD,IAAI,IAAI,CAAC,KAAK,EAAE,SAAS,EAAE,EAE1B;IAED,0CAA0C;IAC1C,IAAI,KAAK,sBAER;IAED,mFAAmF;IACnF,KAAK,SAAqB;IAE1B;;OAEG;IACH,IAAI,OAAO,YAEV;gBAEW,OAAO,GAAE,iBAAsB;IAY3C;;OAEG;IACH,IAAI,aASF;IAEF;;OAEG;IACH,QAAQ,WAAkB,MAAM,YAAY,cAAc,wCAClB;IAExC,uFAAuF;IACvF,YAAY,WAAkB;QAAE,cAAc,CAAC,EAAE,MAAM,IAAI,CAAA;KAAE,mBAK3D;CAmCH"}
1
+ {"version":3,"file":"completion.svelte.d.ts","sourceRoot":"","sources":["../src/completion.svelte.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,KAAK,wBAAwB,EAC7B,KAAK,oBAAoB,EAC1B,MAAM,IAAI,CAAC;AAOZ,MAAM,MAAM,iBAAiB,GAAG,QAAQ,CAAC,oBAAoB,CAAC,CAAC;AAE/D,qBAAa,UAAU;;IASrB,oCAAoC;IACpC,IAAI,UAAU,IAAI,MAAM,CAEvB;IACD,IAAI,UAAU,CAAC,KAAK,EAAE,MAAM,EAE3B;IAED,0CAA0C;IAC1C,IAAI,KAAK,sBAER;IAED,mFAAmF;IACnF,KAAK,SAAqB;IAE1B;;OAEG;IACH,IAAI,OAAO,YAEV;gBAEW,OAAO,GAAE,iBAAsB;IAS3C;;OAEG;IACH,IAAI,aASF;IAEF;;OAEG;IACH,QAAQ,WAAkB,MAAM,YAAY,wBAAwB,wCAC5B;IAExC,uFAAuF;IACvF,YAAY,WAAkB;QAAE,cAAc,CAAC,EAAE,MAAM,IAAI,CAAA;KAAE,mBAK3D;CAkCH"}
@@ -1,4 +1,4 @@
1
- import { generateId, callCompletionApi, } from '@ai-sdk/ui-utils';
1
+ import { callCompletionApi, generateId, } from 'ai';
2
2
  import { KeyedCompletionStore, getCompletionContext, hasCompletionContext, } from './completion-context.svelte.js';
3
3
  export class Completion {
4
4
  #options = {};
@@ -15,17 +15,6 @@ export class Completion {
15
15
  set completion(value) {
16
16
  this.#store.completions.set(this.#id, value);
17
17
  }
18
- /**
19
- * Additional data added on the server via StreamData.
20
- *
21
- * This is writable, so you can use it to transform or clear the chat data.
22
- */
23
- get data() {
24
- return this.#store.data;
25
- }
26
- set data(value) {
27
- this.#store.data = value;
28
- }
29
18
  /** The error object of the API request */
30
19
  get error() {
31
20
  return this.#store.error;
@@ -39,12 +28,9 @@ export class Completion {
39
28
  return this.#store.loading;
40
29
  }
41
30
  constructor(options = {}) {
42
- if (hasCompletionContext()) {
43
- this.#keyedStore = getCompletionContext();
44
- }
45
- else {
46
- this.#keyedStore = new KeyedCompletionStore();
47
- }
31
+ this.#keyedStore = hasCompletionContext()
32
+ ? getCompletionContext()
33
+ : new KeyedCompletionStore();
48
34
  this.#options = options;
49
35
  this.completion = options.initialCompletion ?? '';
50
36
  this.input = options.initialInput ?? '';
@@ -91,9 +77,6 @@ export class Completion {
91
77
  setCompletion: completion => {
92
78
  this.completion = completion;
93
79
  },
94
- onData: data => {
95
- this.data.push(...data);
96
- },
97
80
  setLoading: loading => {
98
81
  this.#store.loading = loading;
99
82
  },
@@ -103,7 +86,6 @@ export class Completion {
103
86
  setAbortController: abortController => {
104
87
  this.#abortController = abortController ?? undefined;
105
88
  },
106
- onResponse: this.#options.onResponse,
107
89
  onFinish: this.#options.onFinish,
108
90
  onError: this.#options.onError,
109
91
  });
@@ -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 CreateMessage, type Message, 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,aAAa,EAClB,KAAK,OAAO,EACZ,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,4 +1,4 @@
1
- import type { DeepPartial } from '@ai-sdk/ui-utils';
1
+ import type { DeepPartial } from 'ai';
2
2
  import { KeyedStore } from './utils.svelte.js';
3
3
  export declare class StructuredObjectStore<RESULT> {
4
4
  object: DeepPartial<RESULT> | undefined;
@@ -1 +1 @@
1
- {"version":3,"file":"structured-object-context.svelte.d.ts","sourceRoot":"","sources":["../src/structured-object-context.svelte.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AACpD,OAAO,EAAiB,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAE9D,qBAAa,qBAAqB,CAAC,MAAM;IACvC,MAAM,kCAAiC;IACvC,OAAO,UAAiB;IACxB,KAAK,oBAAmB;CACzB;AAED,qBAAa,0BAA2B,SAAQ,UAAU,CACxD,qBAAqB,CAAC,OAAO,CAAC,CAC/B;gBAEG,KAAK,CAAC,EACF,QAAQ,CAAC,SAAS,CAAC,MAAM,EAAE,qBAAqB,CAAC,OAAO,CAAC,CAAC,CAAC,GAC3D,IAAI,GACJ,SAAS;CAIhB;AAED,eAAO,MACO,0BAA0B,iBAC1B,0BAA0B,oCAC1B,0BAA0B,mEACyB,CAAC"}
1
+ {"version":3,"file":"structured-object-context.svelte.d.ts","sourceRoot":"","sources":["../src/structured-object-context.svelte.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,IAAI,CAAC;AACtC,OAAO,EAAiB,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAE9D,qBAAa,qBAAqB,CAAC,MAAM;IACvC,MAAM,kCAAiC;IACvC,OAAO,UAAiB;IACxB,KAAK,oBAAmB;CACzB;AAED,qBAAa,0BAA2B,SAAQ,UAAU,CACxD,qBAAqB,CAAC,OAAO,CAAC,CAC/B;gBAEG,KAAK,CAAC,EACF,QAAQ,CAAC,SAAS,CAAC,MAAM,EAAE,qBAAqB,CAAC,OAAO,CAAC,CAAC,CAAC,GAC3D,IAAI,GACJ,SAAS;CAIhB;AAED,eAAO,MACO,0BAA0B,iBAC1B,0BAA0B,oCAC1B,0BAA0B,mEACyB,CAAC"}
@@ -1,7 +1,8 @@
1
- import { type FetchFunction } from '@ai-sdk/provider-utils';
2
- import { type DeepPartial, type Schema } from '@ai-sdk/ui-utils';
3
- import { type z } from 'zod';
4
- export type Experimental_StructuredObjectOptions<RESULT> = {
1
+ import { type FetchFunction, type InferSchema } from '@ai-sdk/provider-utils';
2
+ import { type DeepPartial, type Schema } from 'ai';
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,kBAAkB,CAAC;AAC1B,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
- import { asSchema, isDeepEqualData, parsePartialJson, } from '@ai-sdk/ui-utils';
3
- import {} from 'zod';
2
+ import { asSchema, isDeepEqualData, parsePartialJson, } from 'ai';
4
3
  import { getStructuredObjectContext, hasStructuredObjectContext, KeyedStructuredObjectStore, } from './structured-object-context.svelte.js';
5
4
  export class StructuredObject {
6
5
  #options = {};
@@ -82,23 +81,23 @@ export class StructuredObject {
82
81
  let accumulatedText = '';
83
82
  let latestObject = undefined;
84
83
  await response.body.pipeThrough(new TextDecoderStream()).pipeTo(new WritableStream({
85
- write: chunk => {
84
+ write: async (chunk) => {
86
85
  if (abortController?.signal.aborted) {
87
86
  throw new DOMException('Stream aborted', 'AbortError');
88
87
  }
89
88
  accumulatedText += chunk;
90
- const { value } = parsePartialJson(accumulatedText);
89
+ const { value } = await parsePartialJson(accumulatedText);
91
90
  const currentObject = value;
92
91
  if (!isDeepEqualData(latestObject, currentObject)) {
93
92
  latestObject = currentObject;
94
93
  this.#store.object = currentObject;
95
94
  }
96
95
  },
97
- close: () => {
96
+ close: async () => {
98
97
  this.#store.loading = false;
99
98
  this.#abortController = undefined;
100
99
  if (this.#options.onFinish != null) {
101
- const validationResult = safeValidateTypes({
100
+ const validationResult = await safeValidateTypes({
102
101
  value: latestObject,
103
102
  schema: asSchema(this.#options.schema),
104
103
  });
@@ -1,7 +1,7 @@
1
1
  <script lang="ts" generics="RESULT">
2
2
  import { createAIContext } from '../context-provider.js';
3
3
  import { StructuredObject } from '../structured-object.svelte.js';
4
- import type { Schema } from '@ai-sdk/ui-utils';
4
+ import type { Schema } from 'ai';
5
5
  import type { z } from 'zod';
6
6
 
7
7
  let {
@@ -1,5 +1,5 @@
1
1
  import { StructuredObject } from '../structured-object.svelte.js';
2
- import type { Schema } from '@ai-sdk/ui-utils';
2
+ import type { Schema } from 'ai';
3
3
  import type { z } from 'zod';
4
4
  declare class __sveltets_Render<RESULT> {
5
5
  props(): {
@@ -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 +1 @@
1
- {"version":3,"file":"structured-object-synchronization.svelte.d.ts","sourceRoot":"","sources":["../../src/tests/structured-object-synchronization.svelte.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,gBAAgB,EAAE,MAAM,gCAAgC,CAAC;AAClE,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAC/C,OAAO,KAAK,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AA2B7B,cAAM,iBAAiB,CAAC,MAAM;IAC1B,KAAK;aArBA,MAAM;aACN,MAAM;;;IAuBX,MAAM;IAGN,KAAK;IAGL,QAAQ;IACR,OAAO;;;;CACV;AAED,UAAU,qBAAqB;IAC3B,KAAK,MAAM,EAAE,OAAO,EAAE,OAAO,QAAQ,EAAE,2BAA2B,CAAC,UAAU,CAAC,iBAAiB,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,QAAQ,EAAE,eAAe,CAAC,UAAU,CAAC,iBAAiB,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,CAAC,EAAE,UAAU,CAAC,iBAAiB,CAAC,MAAM,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,UAAU,CAAC,iBAAiB,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG;QAAE,UAAU,CAAC,EAAE,UAAU,CAAC,iBAAiB,CAAC,MAAM,CAAC,CAAC,UAAU,CAAC,CAAC,CAAA;KAAE,GAAG,UAAU,CAAC,iBAAiB,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC;IAC/Z,CAAC,MAAM,EAAE,QAAQ,EAAE,OAAO,EAAE,KAAK,EAAE,UAAU,CAAC,iBAAiB,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,CAAC,GAAG,EAAE,GAAG,UAAU,CAAC,iBAAiB,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC;IAC1I,YAAY,CAAC,EAAE,UAAU,CAAC,iBAAiB,CAAC,GAAG,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC;CACjE;AACD,QAAA,MAAM,+BAA+B,EAAE,qBAAmC,CAAC;AACzD,KAAK,+BAA+B,CAAC,MAAM,IAAI,YAAY,CAAC,OAAO,+BAA+B,CAAC,MAAM,CAAC,CAAC,CAAC;AAC9G,eAAe,+BAA+B,CAAC"}
1
+ {"version":3,"file":"structured-object-synchronization.svelte.d.ts","sourceRoot":"","sources":["../../src/tests/structured-object-synchronization.svelte.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,gBAAgB,EAAE,MAAM,gCAAgC,CAAC;AAClE,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,IAAI,CAAC;AACjC,OAAO,KAAK,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AA2B7B,cAAM,iBAAiB,CAAC,MAAM;IAC1B,KAAK;aArBA,MAAM;aACN,MAAM;;;IAuBX,MAAM;IAGN,KAAK;IAGL,QAAQ;IACR,OAAO;;;;CACV;AAED,UAAU,qBAAqB;IAC3B,KAAK,MAAM,EAAE,OAAO,EAAE,OAAO,QAAQ,EAAE,2BAA2B,CAAC,UAAU,CAAC,iBAAiB,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,QAAQ,EAAE,eAAe,CAAC,UAAU,CAAC,iBAAiB,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,CAAC,EAAE,UAAU,CAAC,iBAAiB,CAAC,MAAM,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,UAAU,CAAC,iBAAiB,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG;QAAE,UAAU,CAAC,EAAE,UAAU,CAAC,iBAAiB,CAAC,MAAM,CAAC,CAAC,UAAU,CAAC,CAAC,CAAA;KAAE,GAAG,UAAU,CAAC,iBAAiB,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC;IAC/Z,CAAC,MAAM,EAAE,QAAQ,EAAE,OAAO,EAAE,KAAK,EAAE,UAAU,CAAC,iBAAiB,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,CAAC,GAAG,EAAE,GAAG,UAAU,CAAC,iBAAiB,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC;IAC1I,YAAY,CAAC,EAAE,UAAU,CAAC,iBAAiB,CAAC,GAAG,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC;CACjE;AACD,QAAA,MAAM,+BAA+B,EAAE,qBAAmC,CAAC;AACzD,KAAK,+BAA+B,CAAC,MAAM,IAAI,YAAY,CAAC,OAAO,+BAA+B,CAAC,MAAM,CAAC,CAAC,CAAC;AAC9G,eAAe,+BAA+B,CAAC"}
@@ -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": "2.1.12",
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,10 +36,11 @@
36
36
  }
37
37
  },
38
38
  "dependencies": {
39
- "@ai-sdk/provider-utils": "2.2.8",
40
- "@ai-sdk/ui-utils": "1.2.11"
39
+ "ai": "5.0.0-alpha.10",
40
+ "@ai-sdk/provider-utils": "3.0.0-alpha.10"
41
41
  },
42
42
  "devDependencies": {
43
+ "@types/node": "20.17.24",
43
44
  "@eslint/compat": "^1.2.5",
44
45
  "@eslint/js": "^9.18.0",
45
46
  "@sveltejs/package": "^2.0.0",
@@ -51,13 +52,14 @@
51
52
  "globals": "^16.0.0",
52
53
  "jsdom": "^26.0.0",
53
54
  "publint": "^0.3.2",
54
- "svelte": "^5.0.0",
55
+ "svelte": "^5.31.0",
55
56
  "svelte-check": "^4.0.0",
56
57
  "typescript": "^5.0.0",
57
58
  "typescript-eslint": "^8.20.0",
58
59
  "vite": "^6.0.0",
59
60
  "vitest": "^3.0.0",
60
- "zod": "3.23.8"
61
+ "zod": "3.25.49",
62
+ "@vercel/ai-tsconfig": "0.0.0"
61
63
  },
62
64
  "homepage": "https://ai-sdk.dev/docs",
63
65
  "repository": {
@@ -74,7 +76,7 @@
74
76
  ],
75
77
  "scripts": {
76
78
  "build": "pnpm prepack",
77
- "build:watch": "svelte-package --input=src --watch",
79
+ "build:watch": "pnpm clean && pnpm --filter svelte build && svelte-package --input=src --watch",
78
80
  "preview": "vite preview",
79
81
  "type-check": "svelte-check --tsconfig ./tsconfig.json",
80
82
  "type-check:watch": "svelte-check --tsconfig ./tsconfig.json --watch",
@@ -82,7 +84,8 @@
82
84
  "prettier-check": "prettier --check .",
83
85
  "lint": "eslint .",
84
86
  "test": "vitest --run",
87
+ "test:update": "vitest --run -u",
85
88
  "test:watch": "vitest",
86
- "clean": "rm -rf dist"
89
+ "clean": "rm -rf dist *.tsbuildinfo"
87
90
  }
88
91
  }