@ai-sdk/svelte 3.0.0-canary.15 → 3.0.0-canary.17

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,32 @@
1
1
  # @ai-sdk/svelte
2
2
 
3
+ ## 3.0.0-canary.17
4
+
5
+ ### Patch Changes
6
+
7
+ - Updated dependencies [a571d6e]
8
+ - Updated dependencies [c60f895]
9
+ - Updated dependencies [332167b]
10
+ - Updated dependencies [a8c8bd5]
11
+ - Updated dependencies [a662dea]
12
+ - Updated dependencies [41fa418]
13
+ - @ai-sdk/provider-utils@3.0.0-canary.15
14
+ - ai@5.0.0-canary.18
15
+
16
+ ## 3.0.0-canary.16
17
+
18
+ ### Patch Changes
19
+
20
+ - Updated dependencies [f04fb4a]
21
+ - Updated dependencies [fd1924b]
22
+ - Updated dependencies [957b739]
23
+ - Updated dependencies [fafc3f2]
24
+ - Updated dependencies [c9ad635]
25
+ - Updated dependencies [9bd5ab5]
26
+ - Updated dependencies [92cb0a2]
27
+ - ai@5.0.0-canary.17
28
+ - @ai-sdk/provider-utils@3.0.0-canary.14
29
+
3
30
  ## 3.0.0-canary.15
4
31
 
5
32
  ### Patch Changes
package/README.md CHANGED
@@ -1,9 +1,9 @@
1
1
  # AI SDK: Svelte provider
2
2
 
3
- [Svelte](https://svelte.dev/) UI components for the [AI SDK](https://sdk.vercel.ai/docs):
3
+ [Svelte](https://svelte.dev/) UI components for the [AI SDK](https://ai-sdk.dev/docs):
4
4
 
5
- - [`Chat`](https://sdk.vercel.ai/docs/reference/ai-sdk-ui/use-chat)
6
- - [`Completion`](https://sdk.vercel.ai/docs/reference/ai-sdk-ui/use-completion)
7
- - [`StructuredObject`](https://sdk.vercel.ai/docs/reference/ai-sdk-ui/use-object)
5
+ - [`Chat`](https://ai-sdk.dev/docs/reference/ai-sdk-ui/use-chat)
6
+ - [`Completion`](https://ai-sdk.dev/docs/reference/ai-sdk-ui/use-completion)
7
+ - [`StructuredObject`](https://ai-sdk.dev/docs/reference/ai-sdk-ui/use-object)
8
8
 
9
- For information on the few ways the Svelte APIs differ from the React ones, see [the docs](https://sdk.vercel.ai/docs/getting-started/svelte#how-does-ai-sdksvelte-differ-from-ai-sdkreact)
9
+ For information on the few ways the Svelte APIs differ from the React ones, see [the docs](https://ai-sdk.dev/docs/getting-started/svelte#how-does-ai-sdksvelte-differ-from-ai-sdkreact)
@@ -1,13 +1,8 @@
1
1
  import { type ChatRequestOptions, type CreateUIMessage, type JSONValue, type UIMessage, type UseChatOptions } from 'ai';
2
- export type ChatOptions = Readonly<Omit<UseChatOptions, 'keepLastMessageOnError'> & {
3
- /**
4
- * Maximum number of sequential LLM calls (steps), e.g. when you use tool calls.
5
- * Must be at least 1.
6
- * A maximum number is required to prevent infinite loops in the case of misconfigured tools.
7
- * By default, it's set to 1, which means that only a single LLM call is made.
8
- * @default 1
9
- */
10
- maxSteps?: number;
2
+ export type ChatOptions = Readonly<UseChatOptions & {
3
+ '~internal'?: {
4
+ currentDate?: () => Date;
5
+ };
11
6
  }>;
12
7
  export type { CreateUIMessage, UIMessage };
13
8
  export declare class Chat {
@@ -45,6 +40,7 @@ export declare class Chat {
45
40
  */
46
41
  get messages(): UIMessage[];
47
42
  set messages(value: UIMessage[]);
43
+ private currentDate;
48
44
  constructor(options?: ChatOptions);
49
45
  /**
50
46
  * Append a user message to the chat list. This triggers the API call to fetch
@@ -52,7 +48,7 @@ export declare class Chat {
52
48
  * @param message The message to append
53
49
  * @param options Additional options to pass to the API call
54
50
  */
55
- append: (message: UIMessage | CreateUIMessage, { data, headers, body, experimental_attachments }?: ChatRequestOptions) => Promise<void>;
51
+ append: (message: UIMessage | CreateUIMessage, { data, headers, body }?: ChatRequestOptions) => Promise<void>;
56
52
  /**
57
53
  * Reload the last AI chat response for the given chat history. If the last
58
54
  * message isn't from the assistant, it will request the API to generate a
@@ -66,7 +62,9 @@ export declare class Chat {
66
62
  /** Form submission handler to automatically reset input and append a user message */
67
63
  handleSubmit: (event?: {
68
64
  preventDefault?: () => void;
69
- }, options?: ChatRequestOptions) => Promise<void>;
65
+ }, options?: ChatRequestOptions & {
66
+ files?: FileList;
67
+ }) => Promise<void>;
70
68
  addToolResult: ({ toolCallId, result, }: {
71
69
  toolCallId: string;
72
70
  result: unknown;
@@ -1 +1 @@
1
- {"version":3,"file":"chat.svelte.d.ts","sourceRoot":"","sources":["../src/chat.svelte.ts"],"names":[],"mappings":"AACA,OAAO,EAUL,KAAK,kBAAkB,EACvB,KAAK,eAAe,EACpB,KAAK,SAAS,EACd,KAAK,SAAS,EACd,KAAK,cAAc,EACpB,MAAM,IAAI,CAAC;AAQZ,MAAM,MAAM,WAAW,GAAG,QAAQ,CAChC,IAAI,CAAC,cAAc,EAAE,wBAAwB,CAAC,GAAG;IAC/C;;;;;;OAMG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB,CACF,CAAC;AAEF,YAAY,EAAE,eAAe,EAAE,SAAS,EAAE,CAAC;AAE3C,qBAAa,IAAI;;IAOf;;;OAGG;IACH,QAAQ,CAAC,EAAE,SAAoD;IAI/D;;;;OAIG;IACH,IAAI,IAAI,IAGQ,SAAS,EAAE,GAAG,SAAS,CADtC;IACD,IAAI,IAAI,CAAC,KAAK,EAAE,SAAS,EAAE,GAAG,SAAS,EAEtC;IAED;;;;;;;OAOG;IACH,IAAI,MAAM,kDAET;IAED,0CAA0C;IAC1C,IAAI,KAAK,sBAER;IAED,mFAAmF;IACnF,KAAK,SAAqB;IAE1B;;;;;OAKG;IACH,IAAI,QAAQ,IAAI,SAAS,EAAE,CAE1B;IACD,IAAI,QAAQ,CAAC,KAAK,EAAE,SAAS,EAAE,EAE9B;gBAEW,OAAO,GAAE,WAAgB;IAYrC;;;;;OAKG;IACH,MAAM,YACK,SAAS,GAAG,eAAe,sDACe,kBAAkB,mBAgBrE;IAEF;;;;OAIG;IACH,MAAM,6BAAmC,kBAAkB,mBAezD;IAEF;;OAEG;IACH,IAAI,aASF;IAEF,qFAAqF;IACrF,YAAY,WACF;QAAE,cAAc,CAAC,EAAE,MAAM,IAAI,CAAA;KAAE,YAC9B,kBAAkB,mBA6B3B;IAEF,aAAa,4BAGV;QACD,UAAU,EAAE,MAAM,CAAC;QACnB,MAAM,EAAE,OAAO,CAAC;KACjB,mBAmBC;CA+GH"}
1
+ {"version":3,"file":"chat.svelte.d.ts","sourceRoot":"","sources":["../src/chat.svelte.ts"],"names":[],"mappings":"AACA,OAAO,EAUL,KAAK,kBAAkB,EACvB,KAAK,eAAe,EACpB,KAAK,SAAS,EACd,KAAK,SAAS,EACd,KAAK,cAAc,EACpB,MAAM,IAAI,CAAC;AAQZ,MAAM,MAAM,WAAW,GAAG,QAAQ,CAChC,cAAc,GAAG;IACf,WAAW,CAAC,EAAE;QACZ,WAAW,CAAC,EAAE,MAAM,IAAI,CAAC;KAC1B,CAAC;CACH,CACF,CAAC;AAEF,YAAY,EAAE,eAAe,EAAE,SAAS,EAAE,CAAC;AAE3C,qBAAa,IAAI;;IAOf;;;OAGG;IACH,QAAQ,CAAC,EAAE,SAAoD;IAI/D;;;;OAIG;IACH,IAAI,IAAI,IAGQ,SAAS,EAAE,GAAG,SAAS,CADtC;IACD,IAAI,IAAI,CAAC,KAAK,EAAE,SAAS,EAAE,GAAG,SAAS,EAEtC;IAED;;;;;;;OAOG;IACH,IAAI,MAAM,kDAET;IAED,0CAA0C;IAC1C,IAAI,KAAK,sBAER;IAED,mFAAmF;IACnF,KAAK,SAAqB;IAE1B;;;;;OAKG;IACH,IAAI,QAAQ,IAAI,SAAS,EAAE,CAE1B;IACD,IAAI,QAAQ,CAAC,KAAK,EAAE,SAAS,EAAE,EAE9B;IAED,OAAO,CAAC,WAAW,CAEjB;gBAEU,OAAO,GAAE,WAAgB;IAYrC;;;;;OAKG;IACH,MAAM,YACK,SAAS,GAAG,eAAe,4BACX,kBAAkB,mBAU3C;IAEF;;;;OAIG;IACH,MAAM,6BAAmC,kBAAkB,mBAezD;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,mBA2BlD;IAEF,aAAa,4BAGV;QACD,UAAU,EAAE,MAAM,CAAC;QACnB,MAAM,EAAE,OAAO,CAAC;KACjB,mBAmBC;CA2FH"}
@@ -1,5 +1,5 @@
1
1
  import { isAbortError } from '@ai-sdk/provider-utils';
2
- import { callChatApi, extractMaxToolInvocationStep, generateId, getToolInvocations, isAssistantMessageWithCompletedToolCalls, prepareAttachmentsForRequest, shouldResubmitMessages, updateToolCallResult, } from 'ai';
2
+ import { callChatApi, convertFileListToFileUIParts, extractMaxToolInvocationStep, generateId, getToolInvocations, isAssistantMessageWithCompletedToolCalls, shouldResubmitMessages, updateToolCallResult, } from 'ai';
3
3
  import { untrack } from 'svelte';
4
4
  import { KeyedChatStore, getChatContext, hasChatContext, } from './chat-context.svelte.js';
5
5
  export class Chat {
@@ -56,6 +56,7 @@ export class Chat {
56
56
  set messages(value) {
57
57
  untrack(() => (this.#store.messages = value));
58
58
  }
59
+ currentDate = $derived(this.#options['~internal']?.currentDate ?? (() => new Date()));
59
60
  constructor(options = {}) {
60
61
  if (hasChatContext()) {
61
62
  this.#keyedStore = getChatContext();
@@ -73,13 +74,11 @@ export class Chat {
73
74
  * @param message The message to append
74
75
  * @param options Additional options to pass to the API call
75
76
  */
76
- append = async (message, { data, headers, body, experimental_attachments } = {}) => {
77
- const attachmentsForRequest = await prepareAttachmentsForRequest(experimental_attachments);
77
+ append = async (message, { data, headers, body } = {}) => {
78
78
  const messages = this.messages.concat({
79
79
  ...message,
80
80
  id: message.id ?? this.#generateId(),
81
- createdAt: message.createdAt ?? new Date(),
82
- experimental_attachments: attachmentsForRequest.length > 0 ? attachmentsForRequest : undefined,
81
+ createdAt: message.createdAt ?? this.currentDate(),
83
82
  parts: message.parts,
84
83
  });
85
84
  return this.#triggerRequest({ messages, headers, body, data });
@@ -123,14 +122,15 @@ export class Chat {
123
122
  event?.preventDefault?.();
124
123
  if (!this.input && !options.allowEmptySubmit)
125
124
  return;
126
- const attachmentsForRequest = await prepareAttachmentsForRequest(options.experimental_attachments);
125
+ const fileParts = Array.isArray(options?.files)
126
+ ? options.files
127
+ : await convertFileListToFileUIParts(options?.files);
127
128
  const messages = this.messages.concat({
128
129
  id: this.#generateId(),
129
- createdAt: new Date(),
130
+ createdAt: this.currentDate(),
130
131
  role: 'user',
131
132
  content: this.input,
132
- experimental_attachments: attachmentsForRequest.length > 0 ? attachmentsForRequest : undefined,
133
- parts: [{ type: 'text', text: this.input }],
133
+ parts: [...fileParts, { type: 'text', text: this.input }],
134
134
  });
135
135
  const chatRequest = {
136
136
  messages,
@@ -169,23 +169,12 @@ export class Chat {
169
169
  this.#abortController = abortController;
170
170
  // Optimistically update messages
171
171
  this.messages = messages;
172
- const constructedMessagesPayload = this.#options.sendExtraMessageFields
173
- ? messages
174
- : messages.map(({ role, content, experimental_attachments, annotations, parts, }) => ({
175
- role,
176
- content,
177
- ...(experimental_attachments !== undefined && {
178
- experimental_attachments,
179
- }),
180
- ...(annotations !== undefined && { annotations }),
181
- ...(parts !== undefined && { parts }),
182
- }));
183
172
  const existingData = this.data ?? [];
184
173
  await callChatApi({
185
174
  api: this.#api,
186
175
  body: {
187
176
  id: this.id,
188
- messages: constructedMessagesPayload,
177
+ messages,
189
178
  data: chatRequest.data,
190
179
  ...$state.snapshot(this.#options.body),
191
180
  ...chatRequest.body,
@@ -197,7 +186,6 @@ export class Chat {
197
186
  ...chatRequest.headers,
198
187
  },
199
188
  abortController: () => abortController,
200
- restoreMessagesOnFailure: () => { },
201
189
  onResponse: this.#options.onResponse,
202
190
  onUpdate: ({ message, data, replaceLastMessage }) => {
203
191
  this.#store.status = 'streaming';
@@ -216,6 +204,7 @@ export class Chat {
216
204
  onToolCall: this.#options.onToolCall,
217
205
  onFinish: this.#options.onFinish,
218
206
  generateId: this.#generateId,
207
+ getCurrentDate: this.currentDate,
219
208
  fetch: this.#options.fetch,
220
209
  // callChatApi calls structuredClone on the message
221
210
  lastMessage: $state.snapshot(this.messages[this.messages.length - 1]),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ai-sdk/svelte",
3
- "version": "3.0.0-canary.15",
3
+ "version": "3.0.0-canary.17",
4
4
  "license": "Apache-2.0",
5
5
  "files": [
6
6
  "dist",
@@ -36,8 +36,8 @@
36
36
  }
37
37
  },
38
38
  "dependencies": {
39
- "@ai-sdk/provider-utils": "3.0.0-canary.13",
40
- "ai": "5.0.0-canary.16"
39
+ "ai": "5.0.0-canary.18",
40
+ "@ai-sdk/provider-utils": "3.0.0-canary.15"
41
41
  },
42
42
  "devDependencies": {
43
43
  "@types/node": "20.17.24",
@@ -61,7 +61,7 @@
61
61
  "zod": "3.23.8",
62
62
  "@vercel/ai-tsconfig": "0.0.0"
63
63
  },
64
- "homepage": "https://sdk.vercel.ai/docs",
64
+ "homepage": "https://ai-sdk.dev/docs",
65
65
  "repository": {
66
66
  "type": "git",
67
67
  "url": "git+https://github.com/vercel/ai.git",
@@ -1,11 +1,11 @@
1
1
  import { isAbortError } from '@ai-sdk/provider-utils';
2
2
  import {
3
3
  callChatApi,
4
+ convertFileListToFileUIParts,
4
5
  extractMaxToolInvocationStep,
5
6
  generateId,
6
7
  getToolInvocations,
7
8
  isAssistantMessageWithCompletedToolCalls,
8
- prepareAttachmentsForRequest,
9
9
  shouldResubmitMessages,
10
10
  updateToolCallResult,
11
11
  type ChatRequest,
@@ -23,15 +23,10 @@ import {
23
23
  } from './chat-context.svelte.js';
24
24
 
25
25
  export type ChatOptions = Readonly<
26
- Omit<UseChatOptions, 'keepLastMessageOnError'> & {
27
- /**
28
- * Maximum number of sequential LLM calls (steps), e.g. when you use tool calls.
29
- * Must be at least 1.
30
- * A maximum number is required to prevent infinite loops in the case of misconfigured tools.
31
- * By default, it's set to 1, which means that only a single LLM call is made.
32
- * @default 1
33
- */
34
- maxSteps?: number;
26
+ UseChatOptions & {
27
+ '~internal'?: {
28
+ currentDate?: () => Date;
29
+ };
35
30
  }
36
31
  >;
37
32
 
@@ -97,6 +92,10 @@ export class Chat {
97
92
  untrack(() => (this.#store.messages = value));
98
93
  }
99
94
 
95
+ private currentDate = $derived(
96
+ this.#options['~internal']?.currentDate ?? (() => new Date()),
97
+ );
98
+
100
99
  constructor(options: ChatOptions = {}) {
101
100
  if (hasChatContext()) {
102
101
  this.#keyedStore = getChatContext();
@@ -117,18 +116,12 @@ export class Chat {
117
116
  */
118
117
  append = async (
119
118
  message: UIMessage | CreateUIMessage,
120
- { data, headers, body, experimental_attachments }: ChatRequestOptions = {},
119
+ { data, headers, body }: ChatRequestOptions = {},
121
120
  ) => {
122
- const attachmentsForRequest = await prepareAttachmentsForRequest(
123
- experimental_attachments,
124
- );
125
-
126
121
  const messages = this.messages.concat({
127
122
  ...message,
128
123
  id: message.id ?? this.#generateId(),
129
- createdAt: message.createdAt ?? new Date(),
130
- experimental_attachments:
131
- attachmentsForRequest.length > 0 ? attachmentsForRequest : undefined,
124
+ createdAt: message.createdAt ?? this.currentDate(),
132
125
  parts: message.parts,
133
126
  });
134
127
 
@@ -174,23 +167,21 @@ export class Chat {
174
167
  /** Form submission handler to automatically reset input and append a user message */
175
168
  handleSubmit = async (
176
169
  event?: { preventDefault?: () => void },
177
- options: ChatRequestOptions = {},
170
+ options: ChatRequestOptions & { files?: FileList } = {},
178
171
  ) => {
179
172
  event?.preventDefault?.();
180
173
  if (!this.input && !options.allowEmptySubmit) return;
181
174
 
182
- const attachmentsForRequest = await prepareAttachmentsForRequest(
183
- options.experimental_attachments,
184
- );
175
+ const fileParts = Array.isArray(options?.files)
176
+ ? options.files
177
+ : await convertFileListToFileUIParts(options?.files);
185
178
 
186
179
  const messages = this.messages.concat({
187
180
  id: this.#generateId(),
188
- createdAt: new Date(),
181
+ createdAt: this.currentDate(),
189
182
  role: 'user',
190
183
  content: this.input,
191
- experimental_attachments:
192
- attachmentsForRequest.length > 0 ? attachmentsForRequest : undefined,
193
- parts: [{ type: 'text', text: this.input }],
184
+ parts: [...fileParts, { type: 'text', text: this.input }],
194
185
  });
195
186
 
196
187
  const chatRequest: ChatRequest = {
@@ -249,32 +240,12 @@ export class Chat {
249
240
  // Optimistically update messages
250
241
  this.messages = messages;
251
242
 
252
- const constructedMessagesPayload = this.#options.sendExtraMessageFields
253
- ? messages
254
- : messages.map(
255
- ({
256
- role,
257
- content,
258
- experimental_attachments,
259
- annotations,
260
- parts,
261
- }) => ({
262
- role,
263
- content,
264
- ...(experimental_attachments !== undefined && {
265
- experimental_attachments,
266
- }),
267
- ...(annotations !== undefined && { annotations }),
268
- ...(parts !== undefined && { parts }),
269
- }),
270
- );
271
-
272
243
  const existingData = this.data ?? [];
273
244
  await callChatApi({
274
245
  api: this.#api,
275
246
  body: {
276
247
  id: this.id,
277
- messages: constructedMessagesPayload,
248
+ messages,
278
249
  data: chatRequest.data,
279
250
  ...$state.snapshot(this.#options.body),
280
251
  ...chatRequest.body,
@@ -286,7 +257,6 @@ export class Chat {
286
257
  ...chatRequest.headers,
287
258
  },
288
259
  abortController: () => abortController,
289
- restoreMessagesOnFailure: () => {},
290
260
  onResponse: this.#options.onResponse,
291
261
  onUpdate: ({ message, data, replaceLastMessage }) => {
292
262
  this.#store.status = 'streaming';
@@ -306,6 +276,7 @@ export class Chat {
306
276
  onToolCall: this.#options.onToolCall,
307
277
  onFinish: this.#options.onFinish,
308
278
  generateId: this.#generateId,
279
+ getCurrentDate: this.currentDate,
309
280
  fetch: this.#options.fetch,
310
281
  // callChatApi calls structuredClone on the message
311
282
  lastMessage: $state.snapshot(this.messages[this.messages.length - 1]),