ai 2.1.7 → 2.1.9

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/dist/index.d.ts CHANGED
@@ -89,6 +89,8 @@ declare function streamToResponse(res: ReadableStream, response: ServerResponse,
89
89
 
90
90
  declare function HuggingFaceStream(res: AsyncGenerator<any>, callbacks?: AIStreamCallbacks): ReadableStream;
91
91
 
92
+ declare function CohereStream(res: AsyncGenerator<any>, callbacks?: AIStreamCallbacks): ReadableStream;
93
+
92
94
  declare function AnthropicStream(res: Response, cb?: AIStreamCallbacks): ReadableStream;
93
95
 
94
96
  declare function LangChainStream(callbacks?: AIStreamCallbacks): {
@@ -103,19 +105,23 @@ declare function LangChainStream(callbacks?: AIStreamCallbacks): {
103
105
  /**
104
106
  * Shared types between the API and UI packages.
105
107
  */
106
- declare type Message = {
108
+ type Message = {
107
109
  id: string;
108
110
  createdAt?: Date;
109
111
  content: string;
110
112
  role: 'system' | 'user' | 'assistant';
111
113
  };
112
- declare type CreateMessage = {
114
+ type CreateMessage = {
113
115
  id?: string;
114
116
  createdAt?: Date;
115
117
  content: string;
116
118
  role: 'system' | 'user' | 'assistant';
117
119
  };
118
- declare type UseChatOptions = {
120
+ type RequestOptions = {
121
+ headers?: Record<string, string> | Headers;
122
+ body?: object;
123
+ };
124
+ type UseChatOptions = {
119
125
  /**
120
126
  * The API endpoint that accepts a `{ messages: Message[] }` object and returns
121
127
  * a stream of tokens of the AI chat response. Defaults to `/api/chat`.
@@ -171,7 +177,7 @@ declare type UseChatOptions = {
171
177
  */
172
178
  sendExtraMessageFields?: boolean;
173
179
  };
174
- declare type UseCompletionOptions = {
180
+ type UseCompletionOptions = {
175
181
  /**
176
182
  * The API endpoint that accepts a `{ prompt: string }` object and returns
177
183
  * a stream of tokens of the AI completion response. Defaults to `/api/completion`.
@@ -222,4 +228,4 @@ declare type UseCompletionOptions = {
222
228
  body?: object;
223
229
  };
224
230
 
225
- export { AIStream, AIStreamCallbacks, AIStreamParser, AnthropicStream, CreateMessage, HuggingFaceStream, LangChainStream, Message, OpenAIStream, StreamingTextResponse, UseChatOptions, UseCompletionOptions, createCallbacksTransformer, createEventStreamTransformer, streamToResponse, trimStartOfStreamHelper };
231
+ export { AIStream, AIStreamCallbacks, AIStreamParser, AnthropicStream, CohereStream, CreateMessage, HuggingFaceStream, LangChainStream, Message, OpenAIStream, RequestOptions, StreamingTextResponse, UseChatOptions, UseCompletionOptions, createCallbacksTransformer, createEventStreamTransformer, streamToResponse, trimStartOfStreamHelper };
package/dist/index.js CHANGED
@@ -59,6 +59,7 @@ var streams_exports = {};
59
59
  __export(streams_exports, {
60
60
  AIStream: () => AIStream,
61
61
  AnthropicStream: () => AnthropicStream,
62
+ CohereStream: () => CohereStream,
62
63
  HuggingFaceStream: () => HuggingFaceStream,
63
64
  LangChainStream: () => LangChainStream,
64
65
  OpenAIStream: () => OpenAIStream,
@@ -231,6 +232,30 @@ function HuggingFaceStream(res, callbacks) {
231
232
  return createParser2(res).pipeThrough(createCallbacksTransformer(callbacks));
232
233
  }
233
234
 
235
+ // streams/cohere-stream.ts
236
+ function createParser3(res) {
237
+ return new ReadableStream({
238
+ pull(controller) {
239
+ return __async(this, null, function* () {
240
+ const { value, done } = yield res.next();
241
+ if (done) {
242
+ controller.close();
243
+ return;
244
+ }
245
+ const { text, is_finished } = JSON.parse(value);
246
+ if (is_finished === true) {
247
+ controller.close();
248
+ } else {
249
+ controller.enqueue(text);
250
+ }
251
+ });
252
+ }
253
+ });
254
+ }
255
+ function CohereStream(res, callbacks) {
256
+ return createParser3(res).pipeThrough(createCallbacksTransformer(callbacks));
257
+ }
258
+
234
259
  // streams/anthropic-stream.ts
235
260
  function parseAnthropicStream() {
236
261
  let previous = "";
@@ -272,6 +297,7 @@ function LangChainStream(callbacks) {
272
297
  0 && (module.exports = {
273
298
  AIStream,
274
299
  AnthropicStream,
300
+ CohereStream,
275
301
  HuggingFaceStream,
276
302
  LangChainStream,
277
303
  OpenAIStream,
package/dist/index.mjs CHANGED
@@ -201,6 +201,30 @@ function HuggingFaceStream(res, callbacks) {
201
201
  return createParser2(res).pipeThrough(createCallbacksTransformer(callbacks));
202
202
  }
203
203
 
204
+ // streams/cohere-stream.ts
205
+ function createParser3(res) {
206
+ return new ReadableStream({
207
+ pull(controller) {
208
+ return __async(this, null, function* () {
209
+ const { value, done } = yield res.next();
210
+ if (done) {
211
+ controller.close();
212
+ return;
213
+ }
214
+ const { text, is_finished } = JSON.parse(value);
215
+ if (is_finished === true) {
216
+ controller.close();
217
+ } else {
218
+ controller.enqueue(text);
219
+ }
220
+ });
221
+ }
222
+ });
223
+ }
224
+ function CohereStream(res, callbacks) {
225
+ return createParser3(res).pipeThrough(createCallbacksTransformer(callbacks));
226
+ }
227
+
204
228
  // streams/anthropic-stream.ts
205
229
  function parseAnthropicStream() {
206
230
  let previous = "";
@@ -241,6 +265,7 @@ function LangChainStream(callbacks) {
241
265
  export {
242
266
  AIStream,
243
267
  AnthropicStream,
268
+ CohereStream,
244
269
  HuggingFaceStream,
245
270
  LangChainStream,
246
271
  OpenAIStream,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ai",
3
- "version": "2.1.7",
3
+ "version": "2.1.9",
4
4
  "license": "Apache-2.0",
5
5
  "sideEffects": false,
6
6
  "main": "./dist/index.js",
@@ -54,18 +54,18 @@
54
54
  "@edge-runtime/jest-environment": "1.1.0-beta.31",
55
55
  "@types/jest": "29.2.0",
56
56
  "@types/node": "^17.0.12",
57
- "@types/react": "^18.2.0",
57
+ "@types/react": "^18.2.8",
58
58
  "@types/react-dom": "^18.2.0",
59
59
  "eslint": "^7.32.0",
60
60
  "jest": "29.2.1",
61
61
  "ts-jest": "29.0.3",
62
62
  "tsup": "^6.7.0",
63
- "typescript": "^4.5.3",
63
+ "typescript": "5.1.3",
64
64
  "@vercel/ai-tsconfig": "0.0.0",
65
65
  "eslint-config-vercel-ai": "0.0.0"
66
66
  },
67
67
  "peerDependencies": {
68
- "react": "^18.0.0",
68
+ "react": "^18.2.0",
69
69
  "svelte": "^3.29.0",
70
70
  "vue": "^3.3.4"
71
71
  },
@@ -1,19 +1,25 @@
1
+ import * as react_jsx_runtime from 'react/jsx-runtime';
2
+
1
3
  /**
2
4
  * Shared types between the API and UI packages.
3
5
  */
4
- declare type Message = {
6
+ type Message = {
5
7
  id: string;
6
8
  createdAt?: Date;
7
9
  content: string;
8
10
  role: 'system' | 'user' | 'assistant';
9
11
  };
10
- declare type CreateMessage = {
12
+ type CreateMessage = {
11
13
  id?: string;
12
14
  createdAt?: Date;
13
15
  content: string;
14
16
  role: 'system' | 'user' | 'assistant';
15
17
  };
16
- declare type UseChatOptions = {
18
+ type RequestOptions = {
19
+ headers?: Record<string, string> | Headers;
20
+ body?: object;
21
+ };
22
+ type UseChatOptions = {
17
23
  /**
18
24
  * The API endpoint that accepts a `{ messages: Message[] }` object and returns
19
25
  * a stream of tokens of the AI chat response. Defaults to `/api/chat`.
@@ -69,7 +75,7 @@ declare type UseChatOptions = {
69
75
  */
70
76
  sendExtraMessageFields?: boolean;
71
77
  };
72
- declare type UseCompletionOptions = {
78
+ type UseCompletionOptions = {
73
79
  /**
74
80
  * The API endpoint that accepts a `{ prompt: string }` object and returns
75
81
  * a stream of tokens of the AI completion response. Defaults to `/api/completion`.
@@ -120,7 +126,7 @@ declare type UseCompletionOptions = {
120
126
  body?: object;
121
127
  };
122
128
 
123
- declare type UseChatHelpers = {
129
+ type UseChatHelpers = {
124
130
  /** Current messages in the chat */
125
131
  messages: Message[];
126
132
  /** The error object of the API request */
@@ -128,14 +134,16 @@ declare type UseChatHelpers = {
128
134
  /**
129
135
  * Append a user message to the chat list. This triggers the API call to fetch
130
136
  * the assistant's response.
137
+ * @param message The message to append
138
+ * @param options Additional options to pass to the API call
131
139
  */
132
- append: (message: Message | CreateMessage) => Promise<string | null | undefined>;
140
+ append: (message: Message | CreateMessage, options?: RequestOptions) => Promise<string | null | undefined>;
133
141
  /**
134
142
  * Reload the last AI chat response for the given chat history. If the last
135
143
  * message isn't from the assistant, it will request the API to generate a
136
144
  * new response.
137
145
  */
138
- reload: () => Promise<string | null | undefined>;
146
+ reload: (options?: RequestOptions) => Promise<string | null | undefined>;
139
147
  /**
140
148
  * Abort the current request immediately, keep the generated tokens if any.
141
149
  */
@@ -159,13 +167,13 @@ declare type UseChatHelpers = {
159
167
  };
160
168
  declare function useChat({ api, id, initialMessages, initialInput, sendExtraMessageFields, onResponse, onFinish, onError, headers, body }?: UseChatOptions): UseChatHelpers;
161
169
 
162
- declare type UseCompletionHelpers = {
170
+ type UseCompletionHelpers = {
163
171
  /** The current completion result */
164
172
  completion: string;
165
173
  /**
166
174
  * Send a new prompt to the API endpoint and update the completion state.
167
175
  */
168
- complete: (prompt: string) => Promise<string | null | undefined>;
176
+ complete: (prompt: string, options?: RequestOptions) => Promise<string | null | undefined>;
169
177
  /** The error object of the API request */
170
178
  error: undefined | Error;
171
179
  /**
@@ -203,4 +211,15 @@ declare type UseCompletionHelpers = {
203
211
  };
204
212
  declare function useCompletion({ api, id, initialCompletion, initialInput, headers, body, onResponse, onFinish, onError }?: UseCompletionOptions): UseCompletionHelpers;
205
213
 
206
- export { CreateMessage, Message, UseChatHelpers, UseChatOptions, UseCompletionHelpers, useChat, useCompletion };
214
+ type Props = {
215
+ /**
216
+ * A ReadableStream produced by the AI SDK.
217
+ */
218
+ stream: ReadableStream;
219
+ };
220
+ /**
221
+ * A React Server Component that recursively renders a stream of tokens.
222
+ */
223
+ declare function Tokens(props: Props): Promise<react_jsx_runtime.JSX.Element>;
224
+
225
+ export { CreateMessage, Message, Tokens, UseChatHelpers, UseChatOptions, UseCompletionHelpers, useChat, useCompletion };
@@ -65,6 +65,7 @@ var __async = (__this, __arguments, generator) => {
65
65
  // react/index.ts
66
66
  var react_exports = {};
67
67
  __export(react_exports, {
68
+ Tokens: () => Tokens,
68
69
  useChat: () => useChat,
69
70
  useCompletion: () => useCompletion
70
71
  });
@@ -126,21 +127,22 @@ function useChat({
126
127
  }, [headers, body]);
127
128
  const { error, trigger, isMutating } = (0, import_mutation.default)(
128
129
  [api, chatId],
129
- (_0, _1) => __async(this, [_0, _1], function* (_, { arg: messagesSnapshot }) {
130
+ (_0, _1) => __async(this, [_0, _1], function* (_, { arg }) {
130
131
  try {
132
+ const { messages: messagesSnapshot, options } = arg;
131
133
  const abortController = new AbortController();
132
134
  abortControllerRef.current = abortController;
133
135
  const previousMessages = messagesRef.current;
134
136
  mutate(messagesSnapshot, false);
135
137
  const res = yield fetch(api, {
136
138
  method: "POST",
137
- body: JSON.stringify(__spreadValues({
139
+ body: JSON.stringify(__spreadValues(__spreadValues({
138
140
  messages: sendExtraMessageFields ? messagesSnapshot : messagesSnapshot.map(({ role, content }) => ({
139
141
  role,
140
142
  content
141
143
  }))
142
- }, extraMetadataRef.current.body)),
143
- headers: extraMetadataRef.current.headers || {},
144
+ }, extraMetadataRef.current.body), options == null ? void 0 : options.body)),
145
+ headers: __spreadValues(__spreadValues({}, extraMetadataRef.current.headers), options == null ? void 0 : options.headers),
144
146
  signal: abortController.signal
145
147
  }).catch((err) => {
146
148
  mutate(previousMessages, false);
@@ -217,23 +219,35 @@ function useChat({
217
219
  }
218
220
  );
219
221
  const append = (0, import_react.useCallback)(
220
- (message) => __async(this, null, function* () {
222
+ (message, options) => __async(this, null, function* () {
221
223
  if (!message.id) {
222
224
  message.id = nanoid();
223
225
  }
224
- return trigger(messagesRef.current.concat(message));
226
+ return trigger({
227
+ messages: messagesRef.current.concat(message),
228
+ options
229
+ });
230
+ }),
231
+ [trigger]
232
+ );
233
+ const reload = (0, import_react.useCallback)(
234
+ (options) => __async(this, null, function* () {
235
+ if (messagesRef.current.length === 0)
236
+ return null;
237
+ const lastMessage = messagesRef.current[messagesRef.current.length - 1];
238
+ if (lastMessage.role === "assistant") {
239
+ return trigger({
240
+ messages: messagesRef.current.slice(0, -1),
241
+ options
242
+ });
243
+ }
244
+ return trigger({
245
+ messages: messagesRef.current,
246
+ options
247
+ });
225
248
  }),
226
249
  [trigger]
227
250
  );
228
- const reload = (0, import_react.useCallback)(() => __async(this, null, function* () {
229
- if (messagesRef.current.length === 0)
230
- return null;
231
- const lastMessage = messagesRef.current[messagesRef.current.length - 1];
232
- if (lastMessage.role === "assistant") {
233
- return trigger(messagesRef.current.slice(0, -1));
234
- }
235
- return trigger(messagesRef.current);
236
- }), [trigger]);
237
251
  const stop = (0, import_react.useCallback)(() => {
238
252
  if (abortControllerRef.current) {
239
253
  abortControllerRef.current.abort();
@@ -249,7 +263,10 @@ function useChat({
249
263
  );
250
264
  const [input, setInput] = (0, import_react.useState)(initialInput);
251
265
  const handleSubmit = (0, import_react.useCallback)(
252
- (e) => {
266
+ (e, metadata) => {
267
+ if (metadata) {
268
+ extraMetadataRef.current = __spreadValues(__spreadValues({}, extraMetadataRef.current), metadata);
269
+ }
253
270
  e.preventDefault();
254
271
  if (!input)
255
272
  return;
@@ -314,17 +331,18 @@ function useCompletion({
314
331
  }, [headers, body]);
315
332
  const { error, trigger, isMutating } = (0, import_mutation2.default)(
316
333
  [api, completionId],
317
- (_0, _1) => __async(this, [_0, _1], function* (_, { arg: prompt }) {
334
+ (_0, _1) => __async(this, [_0, _1], function* (_, { arg }) {
318
335
  try {
336
+ const { prompt, options } = arg;
319
337
  const abortController2 = new AbortController();
320
338
  setAbortController(abortController2);
321
339
  mutate("", false);
322
340
  const res = yield fetch(api, {
323
341
  method: "POST",
324
- body: JSON.stringify(__spreadValues({
342
+ body: JSON.stringify(__spreadValues(__spreadValues({
325
343
  prompt
326
- }, extraMetadataRef.current.body)),
327
- headers: extraMetadataRef.current.headers || {},
344
+ }, extraMetadataRef.current.body), options == null ? void 0 : options.body)),
345
+ headers: __spreadValues(__spreadValues({}, extraMetadataRef.current.headers), options == null ? void 0 : options.headers),
328
346
  signal: abortController2.signal
329
347
  }).catch((err) => {
330
348
  throw err;
@@ -392,25 +410,28 @@ function useCompletion({
392
410
  },
393
411
  [mutate]
394
412
  );
413
+ const complete = (0, import_react2.useCallback)(
414
+ (prompt, options) => __async(this, null, function* () {
415
+ return trigger({
416
+ prompt,
417
+ options
418
+ });
419
+ }),
420
+ [trigger]
421
+ );
395
422
  const [input, setInput] = (0, import_react2.useState)(initialInput);
396
423
  const handleSubmit = (0, import_react2.useCallback)(
397
424
  (e) => {
398
425
  e.preventDefault();
399
426
  if (!input)
400
427
  return;
401
- return trigger(input);
428
+ return complete(input);
402
429
  },
403
- [input, trigger]
430
+ [input, complete]
404
431
  );
405
432
  const handleInputChange = (e) => {
406
433
  setInput(e.target.value);
407
434
  };
408
- const complete = (0, import_react2.useCallback)(
409
- (prompt) => __async(this, null, function* () {
410
- return trigger(prompt);
411
- }),
412
- [trigger]
413
- );
414
435
  return {
415
436
  completion,
416
437
  complete,
@@ -424,8 +445,33 @@ function useCompletion({
424
445
  isLoading: isMutating
425
446
  };
426
447
  }
448
+
449
+ // react/tokens.tsx
450
+ var import_react3 = require("react");
451
+ var import_jsx_runtime = require("react/jsx-runtime");
452
+ function Tokens(props) {
453
+ return __async(this, null, function* () {
454
+ const { stream } = props;
455
+ const reader = stream.getReader();
456
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react3.Suspense, { children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(RecursiveTokens, { reader }) });
457
+ });
458
+ }
459
+ function RecursiveTokens(_0) {
460
+ return __async(this, arguments, function* ({ reader }) {
461
+ const { done, value } = yield reader.read();
462
+ if (done) {
463
+ return null;
464
+ }
465
+ const text = new TextDecoder().decode(value);
466
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
467
+ text,
468
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react3.Suspense, { fallback: null, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(RecursiveTokens, { reader }) })
469
+ ] });
470
+ });
471
+ }
427
472
  // Annotate the CommonJS export names for ESM import in node:
428
473
  0 && (module.exports = {
474
+ Tokens,
429
475
  useChat,
430
476
  useCompletion
431
477
  });
@@ -92,21 +92,22 @@ function useChat({
92
92
  }, [headers, body]);
93
93
  const { error, trigger, isMutating } = useSWRMutation(
94
94
  [api, chatId],
95
- (_0, _1) => __async(this, [_0, _1], function* (_, { arg: messagesSnapshot }) {
95
+ (_0, _1) => __async(this, [_0, _1], function* (_, { arg }) {
96
96
  try {
97
+ const { messages: messagesSnapshot, options } = arg;
97
98
  const abortController = new AbortController();
98
99
  abortControllerRef.current = abortController;
99
100
  const previousMessages = messagesRef.current;
100
101
  mutate(messagesSnapshot, false);
101
102
  const res = yield fetch(api, {
102
103
  method: "POST",
103
- body: JSON.stringify(__spreadValues({
104
+ body: JSON.stringify(__spreadValues(__spreadValues({
104
105
  messages: sendExtraMessageFields ? messagesSnapshot : messagesSnapshot.map(({ role, content }) => ({
105
106
  role,
106
107
  content
107
108
  }))
108
- }, extraMetadataRef.current.body)),
109
- headers: extraMetadataRef.current.headers || {},
109
+ }, extraMetadataRef.current.body), options == null ? void 0 : options.body)),
110
+ headers: __spreadValues(__spreadValues({}, extraMetadataRef.current.headers), options == null ? void 0 : options.headers),
110
111
  signal: abortController.signal
111
112
  }).catch((err) => {
112
113
  mutate(previousMessages, false);
@@ -183,23 +184,35 @@ function useChat({
183
184
  }
184
185
  );
185
186
  const append = useCallback(
186
- (message) => __async(this, null, function* () {
187
+ (message, options) => __async(this, null, function* () {
187
188
  if (!message.id) {
188
189
  message.id = nanoid();
189
190
  }
190
- return trigger(messagesRef.current.concat(message));
191
+ return trigger({
192
+ messages: messagesRef.current.concat(message),
193
+ options
194
+ });
195
+ }),
196
+ [trigger]
197
+ );
198
+ const reload = useCallback(
199
+ (options) => __async(this, null, function* () {
200
+ if (messagesRef.current.length === 0)
201
+ return null;
202
+ const lastMessage = messagesRef.current[messagesRef.current.length - 1];
203
+ if (lastMessage.role === "assistant") {
204
+ return trigger({
205
+ messages: messagesRef.current.slice(0, -1),
206
+ options
207
+ });
208
+ }
209
+ return trigger({
210
+ messages: messagesRef.current,
211
+ options
212
+ });
191
213
  }),
192
214
  [trigger]
193
215
  );
194
- const reload = useCallback(() => __async(this, null, function* () {
195
- if (messagesRef.current.length === 0)
196
- return null;
197
- const lastMessage = messagesRef.current[messagesRef.current.length - 1];
198
- if (lastMessage.role === "assistant") {
199
- return trigger(messagesRef.current.slice(0, -1));
200
- }
201
- return trigger(messagesRef.current);
202
- }), [trigger]);
203
216
  const stop = useCallback(() => {
204
217
  if (abortControllerRef.current) {
205
218
  abortControllerRef.current.abort();
@@ -215,7 +228,10 @@ function useChat({
215
228
  );
216
229
  const [input, setInput] = useState(initialInput);
217
230
  const handleSubmit = useCallback(
218
- (e) => {
231
+ (e, metadata) => {
232
+ if (metadata) {
233
+ extraMetadataRef.current = __spreadValues(__spreadValues({}, extraMetadataRef.current), metadata);
234
+ }
219
235
  e.preventDefault();
220
236
  if (!input)
221
237
  return;
@@ -280,17 +296,18 @@ function useCompletion({
280
296
  }, [headers, body]);
281
297
  const { error, trigger, isMutating } = useSWRMutation2(
282
298
  [api, completionId],
283
- (_0, _1) => __async(this, [_0, _1], function* (_, { arg: prompt }) {
299
+ (_0, _1) => __async(this, [_0, _1], function* (_, { arg }) {
284
300
  try {
301
+ const { prompt, options } = arg;
285
302
  const abortController2 = new AbortController();
286
303
  setAbortController(abortController2);
287
304
  mutate("", false);
288
305
  const res = yield fetch(api, {
289
306
  method: "POST",
290
- body: JSON.stringify(__spreadValues({
307
+ body: JSON.stringify(__spreadValues(__spreadValues({
291
308
  prompt
292
- }, extraMetadataRef.current.body)),
293
- headers: extraMetadataRef.current.headers || {},
309
+ }, extraMetadataRef.current.body), options == null ? void 0 : options.body)),
310
+ headers: __spreadValues(__spreadValues({}, extraMetadataRef.current.headers), options == null ? void 0 : options.headers),
294
311
  signal: abortController2.signal
295
312
  }).catch((err) => {
296
313
  throw err;
@@ -358,25 +375,28 @@ function useCompletion({
358
375
  },
359
376
  [mutate]
360
377
  );
378
+ const complete = useCallback2(
379
+ (prompt, options) => __async(this, null, function* () {
380
+ return trigger({
381
+ prompt,
382
+ options
383
+ });
384
+ }),
385
+ [trigger]
386
+ );
361
387
  const [input, setInput] = useState2(initialInput);
362
388
  const handleSubmit = useCallback2(
363
389
  (e) => {
364
390
  e.preventDefault();
365
391
  if (!input)
366
392
  return;
367
- return trigger(input);
393
+ return complete(input);
368
394
  },
369
- [input, trigger]
395
+ [input, complete]
370
396
  );
371
397
  const handleInputChange = (e) => {
372
398
  setInput(e.target.value);
373
399
  };
374
- const complete = useCallback2(
375
- (prompt) => __async(this, null, function* () {
376
- return trigger(prompt);
377
- }),
378
- [trigger]
379
- );
380
400
  return {
381
401
  completion,
382
402
  complete,
@@ -390,7 +410,32 @@ function useCompletion({
390
410
  isLoading: isMutating
391
411
  };
392
412
  }
413
+
414
+ // react/tokens.tsx
415
+ import { Suspense } from "react";
416
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
417
+ function Tokens(props) {
418
+ return __async(this, null, function* () {
419
+ const { stream } = props;
420
+ const reader = stream.getReader();
421
+ return /* @__PURE__ */ jsx(Suspense, { children: /* @__PURE__ */ jsx(RecursiveTokens, { reader }) });
422
+ });
423
+ }
424
+ function RecursiveTokens(_0) {
425
+ return __async(this, arguments, function* ({ reader }) {
426
+ const { done, value } = yield reader.read();
427
+ if (done) {
428
+ return null;
429
+ }
430
+ const text = new TextDecoder().decode(value);
431
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
432
+ text,
433
+ /* @__PURE__ */ jsx(Suspense, { fallback: null, children: /* @__PURE__ */ jsx(RecursiveTokens, { reader }) })
434
+ ] });
435
+ });
436
+ }
393
437
  export {
438
+ Tokens,
394
439
  useChat,
395
440
  useCompletion
396
441
  };
@@ -3,19 +3,23 @@ import { Readable, Writable } from 'svelte/store';
3
3
  /**
4
4
  * Shared types between the API and UI packages.
5
5
  */
6
- declare type Message = {
6
+ type Message = {
7
7
  id: string;
8
8
  createdAt?: Date;
9
9
  content: string;
10
10
  role: 'system' | 'user' | 'assistant';
11
11
  };
12
- declare type CreateMessage = {
12
+ type CreateMessage = {
13
13
  id?: string;
14
14
  createdAt?: Date;
15
15
  content: string;
16
16
  role: 'system' | 'user' | 'assistant';
17
17
  };
18
- declare type UseChatOptions = {
18
+ type RequestOptions = {
19
+ headers?: Record<string, string> | Headers;
20
+ body?: object;
21
+ };
22
+ type UseChatOptions = {
19
23
  /**
20
24
  * The API endpoint that accepts a `{ messages: Message[] }` object and returns
21
25
  * a stream of tokens of the AI chat response. Defaults to `/api/chat`.
@@ -71,7 +75,7 @@ declare type UseChatOptions = {
71
75
  */
72
76
  sendExtraMessageFields?: boolean;
73
77
  };
74
- declare type UseCompletionOptions = {
78
+ type UseCompletionOptions = {
75
79
  /**
76
80
  * The API endpoint that accepts a `{ prompt: string }` object and returns
77
81
  * a stream of tokens of the AI completion response. Defaults to `/api/completion`.
@@ -122,7 +126,7 @@ declare type UseCompletionOptions = {
122
126
  body?: object;
123
127
  };
124
128
 
125
- declare type UseChatHelpers = {
129
+ type UseChatHelpers = {
126
130
  /** Current messages in the chat */
127
131
  messages: Readable<Message[]>;
128
132
  /** The error object of the API request */
@@ -131,13 +135,13 @@ declare type UseChatHelpers = {
131
135
  * Append a user message to the chat list. This triggers the API call to fetch
132
136
  * the assistant's response.
133
137
  */
134
- append: (message: Message | CreateMessage) => Promise<string | null | undefined>;
138
+ append: (message: Message | CreateMessage, options?: RequestOptions) => Promise<string | null | undefined>;
135
139
  /**
136
140
  * Reload the last AI chat response for the given chat history. If the last
137
141
  * message isn't from the assistant, it will request the API to generate a
138
142
  * new response.
139
143
  */
140
- reload: () => Promise<string | null | undefined>;
144
+ reload: (options?: RequestOptions) => Promise<string | null | undefined>;
141
145
  /**
142
146
  * Abort the current request immediately, keep the generated tokens if any.
143
147
  */
@@ -157,7 +161,7 @@ declare type UseChatHelpers = {
157
161
  };
158
162
  declare function useChat({ api, id, initialMessages, initialInput, sendExtraMessageFields, onResponse, onFinish, onError, headers, body }?: UseChatOptions): UseChatHelpers;
159
163
 
160
- declare type UseCompletionHelpers = {
164
+ type UseCompletionHelpers = {
161
165
  /** The current completion result */
162
166
  completion: Readable<string>;
163
167
  /** The error object of the API request */
@@ -165,7 +169,7 @@ declare type UseCompletionHelpers = {
165
169
  /**
166
170
  * Send a new prompt to the API endpoint and update the completion state.
167
171
  */
168
- complete: (prompt: string) => Promise<string | null | undefined>;
172
+ complete: (prompt: string, options?: RequestOptions) => Promise<string | null | undefined>;
169
173
  /**
170
174
  * Abort the current API request but keep the generated tokens.
171
175
  */
@@ -545,7 +545,7 @@ function useChat({
545
545
  const error = (0, import_store.writable)(void 0);
546
546
  const isLoading = (0, import_store.writable)(false);
547
547
  let abortController = null;
548
- function triggerRequest(messagesSnapshot) {
548
+ function triggerRequest(messagesSnapshot, options) {
549
549
  return __async(this, null, function* () {
550
550
  try {
551
551
  isLoading.set(true);
@@ -554,13 +554,13 @@ function useChat({
554
554
  mutate(messagesSnapshot);
555
555
  const res = yield fetch(api, {
556
556
  method: "POST",
557
- body: JSON.stringify(__spreadValues({
557
+ body: JSON.stringify(__spreadValues(__spreadValues({
558
558
  messages: sendExtraMessageFields ? messagesSnapshot : messagesSnapshot.map(({ role, content }) => ({
559
559
  role,
560
560
  content
561
561
  }))
562
- }, body)),
563
- headers: headers || {},
562
+ }, body), options == null ? void 0 : options.body)),
563
+ headers: __spreadValues(__spreadValues({}, headers), options == null ? void 0 : options.headers),
564
564
  signal: abortController.signal
565
565
  }).catch((err) => {
566
566
  mutate(previousMessages);
@@ -631,21 +631,21 @@ function useChat({
631
631
  }
632
632
  });
633
633
  }
634
- const append = (message) => __async(this, null, function* () {
634
+ const append = (message, options) => __async(this, null, function* () {
635
635
  if (!message.id) {
636
636
  message.id = nanoid();
637
637
  }
638
- return triggerRequest((0, import_store.get)(messages).concat(message));
638
+ return triggerRequest((0, import_store.get)(messages).concat(message), options);
639
639
  });
640
- const reload = () => __async(this, null, function* () {
640
+ const reload = (options) => __async(this, null, function* () {
641
641
  const messagesSnapshot = (0, import_store.get)(messages);
642
642
  if (messagesSnapshot.length === 0)
643
643
  return null;
644
644
  const lastMessage = messagesSnapshot[messagesSnapshot.length - 1];
645
645
  if (lastMessage.role === "assistant") {
646
- return triggerRequest(messagesSnapshot.slice(0, -1));
646
+ return triggerRequest(messagesSnapshot.slice(0, -1), options);
647
647
  }
648
- return triggerRequest(messagesSnapshot);
648
+ return triggerRequest(messagesSnapshot, options);
649
649
  });
650
650
  const stop = () => {
651
651
  if (abortController) {
@@ -712,7 +712,7 @@ function useCompletion({
712
712
  const error = (0, import_store2.writable)(void 0);
713
713
  const isLoading = (0, import_store2.writable)(false);
714
714
  let abortController = null;
715
- function triggerRequest(prompt) {
715
+ function triggerRequest(prompt, options) {
716
716
  return __async(this, null, function* () {
717
717
  try {
718
718
  isLoading.set(true);
@@ -720,10 +720,10 @@ function useCompletion({
720
720
  mutate("");
721
721
  const res = yield fetch(api, {
722
722
  method: "POST",
723
- body: JSON.stringify(__spreadValues({
723
+ body: JSON.stringify(__spreadValues(__spreadValues({
724
724
  prompt
725
- }, body)),
726
- headers: headers || {},
725
+ }, body), options == null ? void 0 : options.body)),
726
+ headers: __spreadValues(__spreadValues({}, headers), options == null ? void 0 : options.headers),
727
727
  signal: abortController.signal
728
728
  }).catch((err) => {
729
729
  throw err;
@@ -777,8 +777,8 @@ function useCompletion({
777
777
  }
778
778
  });
779
779
  }
780
- const complete = (prompt) => __async(this, null, function* () {
781
- return triggerRequest(prompt);
780
+ const complete = (prompt, options) => __async(this, null, function* () {
781
+ return triggerRequest(prompt, options);
782
782
  });
783
783
  const stop = () => {
784
784
  if (abortController) {
@@ -521,7 +521,7 @@ function useChat({
521
521
  const error = writable(void 0);
522
522
  const isLoading = writable(false);
523
523
  let abortController = null;
524
- function triggerRequest(messagesSnapshot) {
524
+ function triggerRequest(messagesSnapshot, options) {
525
525
  return __async(this, null, function* () {
526
526
  try {
527
527
  isLoading.set(true);
@@ -530,13 +530,13 @@ function useChat({
530
530
  mutate(messagesSnapshot);
531
531
  const res = yield fetch(api, {
532
532
  method: "POST",
533
- body: JSON.stringify(__spreadValues({
533
+ body: JSON.stringify(__spreadValues(__spreadValues({
534
534
  messages: sendExtraMessageFields ? messagesSnapshot : messagesSnapshot.map(({ role, content }) => ({
535
535
  role,
536
536
  content
537
537
  }))
538
- }, body)),
539
- headers: headers || {},
538
+ }, body), options == null ? void 0 : options.body)),
539
+ headers: __spreadValues(__spreadValues({}, headers), options == null ? void 0 : options.headers),
540
540
  signal: abortController.signal
541
541
  }).catch((err) => {
542
542
  mutate(previousMessages);
@@ -607,21 +607,21 @@ function useChat({
607
607
  }
608
608
  });
609
609
  }
610
- const append = (message) => __async(this, null, function* () {
610
+ const append = (message, options) => __async(this, null, function* () {
611
611
  if (!message.id) {
612
612
  message.id = nanoid();
613
613
  }
614
- return triggerRequest(get(messages).concat(message));
614
+ return triggerRequest(get(messages).concat(message), options);
615
615
  });
616
- const reload = () => __async(this, null, function* () {
616
+ const reload = (options) => __async(this, null, function* () {
617
617
  const messagesSnapshot = get(messages);
618
618
  if (messagesSnapshot.length === 0)
619
619
  return null;
620
620
  const lastMessage = messagesSnapshot[messagesSnapshot.length - 1];
621
621
  if (lastMessage.role === "assistant") {
622
- return triggerRequest(messagesSnapshot.slice(0, -1));
622
+ return triggerRequest(messagesSnapshot.slice(0, -1), options);
623
623
  }
624
- return triggerRequest(messagesSnapshot);
624
+ return triggerRequest(messagesSnapshot, options);
625
625
  });
626
626
  const stop = () => {
627
627
  if (abortController) {
@@ -688,7 +688,7 @@ function useCompletion({
688
688
  const error = writable2(void 0);
689
689
  const isLoading = writable2(false);
690
690
  let abortController = null;
691
- function triggerRequest(prompt) {
691
+ function triggerRequest(prompt, options) {
692
692
  return __async(this, null, function* () {
693
693
  try {
694
694
  isLoading.set(true);
@@ -696,10 +696,10 @@ function useCompletion({
696
696
  mutate("");
697
697
  const res = yield fetch(api, {
698
698
  method: "POST",
699
- body: JSON.stringify(__spreadValues({
699
+ body: JSON.stringify(__spreadValues(__spreadValues({
700
700
  prompt
701
- }, body)),
702
- headers: headers || {},
701
+ }, body), options == null ? void 0 : options.body)),
702
+ headers: __spreadValues(__spreadValues({}, headers), options == null ? void 0 : options.headers),
703
703
  signal: abortController.signal
704
704
  }).catch((err) => {
705
705
  throw err;
@@ -753,8 +753,8 @@ function useCompletion({
753
753
  }
754
754
  });
755
755
  }
756
- const complete = (prompt) => __async(this, null, function* () {
757
- return triggerRequest(prompt);
756
+ const complete = (prompt, options) => __async(this, null, function* () {
757
+ return triggerRequest(prompt, options);
758
758
  });
759
759
  const stop = () => {
760
760
  if (abortController) {
@@ -3,19 +3,23 @@ import { Ref } from 'vue';
3
3
  /**
4
4
  * Shared types between the API and UI packages.
5
5
  */
6
- declare type Message = {
6
+ type Message = {
7
7
  id: string;
8
8
  createdAt?: Date;
9
9
  content: string;
10
10
  role: 'system' | 'user' | 'assistant';
11
11
  };
12
- declare type CreateMessage = {
12
+ type CreateMessage = {
13
13
  id?: string;
14
14
  createdAt?: Date;
15
15
  content: string;
16
16
  role: 'system' | 'user' | 'assistant';
17
17
  };
18
- declare type UseChatOptions = {
18
+ type RequestOptions = {
19
+ headers?: Record<string, string> | Headers;
20
+ body?: object;
21
+ };
22
+ type UseChatOptions = {
19
23
  /**
20
24
  * The API endpoint that accepts a `{ messages: Message[] }` object and returns
21
25
  * a stream of tokens of the AI chat response. Defaults to `/api/chat`.
@@ -71,7 +75,7 @@ declare type UseChatOptions = {
71
75
  */
72
76
  sendExtraMessageFields?: boolean;
73
77
  };
74
- declare type UseCompletionOptions = {
78
+ type UseCompletionOptions = {
75
79
  /**
76
80
  * The API endpoint that accepts a `{ prompt: string }` object and returns
77
81
  * a stream of tokens of the AI completion response. Defaults to `/api/completion`.
@@ -122,7 +126,7 @@ declare type UseCompletionOptions = {
122
126
  body?: object;
123
127
  };
124
128
 
125
- declare type UseChatHelpers = {
129
+ type UseChatHelpers = {
126
130
  /** Current messages in the chat */
127
131
  messages: Ref<Message[]>;
128
132
  /** The error object of the API request */
@@ -131,13 +135,13 @@ declare type UseChatHelpers = {
131
135
  * Append a user message to the chat list. This triggers the API call to fetch
132
136
  * the assistant's response.
133
137
  */
134
- append: (message: Message | CreateMessage) => Promise<string | null | undefined>;
138
+ append: (message: Message | CreateMessage, options?: RequestOptions) => Promise<string | null | undefined>;
135
139
  /**
136
140
  * Reload the last AI chat response for the given chat history. If the last
137
141
  * message isn't from the assistant, it will request the API to generate a
138
142
  * new response.
139
143
  */
140
- reload: () => Promise<string | null | undefined>;
144
+ reload: (options?: RequestOptions) => Promise<string | null | undefined>;
141
145
  /**
142
146
  * Abort the current request immediately, keep the generated tokens if any.
143
147
  */
@@ -157,7 +161,7 @@ declare type UseChatHelpers = {
157
161
  };
158
162
  declare function useChat({ api, id, initialMessages, initialInput, sendExtraMessageFields, onResponse, onFinish, onError, headers, body }?: UseChatOptions): UseChatHelpers;
159
163
 
160
- declare type UseCompletionHelpers = {
164
+ type UseCompletionHelpers = {
161
165
  /** The current completion result */
162
166
  completion: Ref<string>;
163
167
  /** The error object of the API request */
@@ -165,7 +169,7 @@ declare type UseCompletionHelpers = {
165
169
  /**
166
170
  * Send a new prompt to the API endpoint and update the completion state.
167
171
  */
168
- complete: (prompt: string) => Promise<string | null | undefined>;
172
+ complete: (prompt: string, options?: RequestOptions) => Promise<string | null | undefined>;
169
173
  /**
170
174
  * Abort the current API request but keep the generated tokens.
171
175
  */
package/vue/dist/index.js CHANGED
@@ -119,7 +119,7 @@ function useChat({
119
119
  const error = (0, import_vue.ref)(void 0);
120
120
  const isLoading = (0, import_vue.ref)(false);
121
121
  let abortController = null;
122
- function triggerRequest(messagesSnapshot) {
122
+ function triggerRequest(messagesSnapshot, options) {
123
123
  return __async(this, null, function* () {
124
124
  try {
125
125
  isLoading.value = true;
@@ -128,13 +128,13 @@ function useChat({
128
128
  mutate(messagesSnapshot);
129
129
  const res = yield fetch(api, {
130
130
  method: "POST",
131
- body: JSON.stringify(__spreadValues({
131
+ body: JSON.stringify(__spreadValues(__spreadValues({
132
132
  messages: sendExtraMessageFields ? messagesSnapshot : messagesSnapshot.map(({ role, content }) => ({
133
133
  role,
134
134
  content
135
135
  }))
136
- }, body)),
137
- headers: headers || {},
136
+ }, body), options == null ? void 0 : options.body)),
137
+ headers: __spreadValues(__spreadValues({}, headers), options == null ? void 0 : options.headers),
138
138
  signal: abortController.signal
139
139
  }).catch((err) => {
140
140
  mutate(previousMessages);
@@ -205,21 +205,21 @@ function useChat({
205
205
  }
206
206
  });
207
207
  }
208
- const append = (message) => __async(this, null, function* () {
208
+ const append = (message, options) => __async(this, null, function* () {
209
209
  if (!message.id) {
210
210
  message.id = nanoid();
211
211
  }
212
- return triggerRequest(messages.value.concat(message));
212
+ return triggerRequest(messages.value.concat(message), options);
213
213
  });
214
- const reload = () => __async(this, null, function* () {
214
+ const reload = (options) => __async(this, null, function* () {
215
215
  const messagesSnapshot = messages.value;
216
216
  if (messagesSnapshot.length === 0)
217
217
  return null;
218
218
  const lastMessage = messagesSnapshot[messagesSnapshot.length - 1];
219
219
  if (lastMessage.role === "assistant") {
220
- return triggerRequest(messagesSnapshot.slice(0, -1));
220
+ return triggerRequest(messagesSnapshot.slice(0, -1), options);
221
221
  }
222
- return triggerRequest(messagesSnapshot);
222
+ return triggerRequest(messagesSnapshot, options);
223
223
  });
224
224
  const stop = () => {
225
225
  if (abortController) {
@@ -287,7 +287,7 @@ function useCompletion({
287
287
  const error = (0, import_vue2.ref)(void 0);
288
288
  const isLoading = (0, import_vue2.ref)(false);
289
289
  let abortController = null;
290
- function triggerRequest(prompt) {
290
+ function triggerRequest(prompt, options) {
291
291
  return __async(this, null, function* () {
292
292
  try {
293
293
  isLoading.value = true;
@@ -295,10 +295,10 @@ function useCompletion({
295
295
  mutate("");
296
296
  const res = yield fetch(api, {
297
297
  method: "POST",
298
- body: JSON.stringify(__spreadValues({
298
+ body: JSON.stringify(__spreadValues(__spreadValues({
299
299
  prompt
300
- }, body)),
301
- headers: headers || {},
300
+ }, body), options == null ? void 0 : options.body)),
301
+ headers: __spreadValues(__spreadValues({}, headers), options == null ? void 0 : options.headers),
302
302
  signal: abortController.signal
303
303
  }).catch((err) => {
304
304
  throw err;
@@ -352,8 +352,8 @@ function useCompletion({
352
352
  }
353
353
  });
354
354
  }
355
- const complete = (prompt) => __async(this, null, function* () {
356
- return triggerRequest(prompt);
355
+ const complete = (prompt, options) => __async(this, null, function* () {
356
+ return triggerRequest(prompt, options);
357
357
  });
358
358
  const stop = () => {
359
359
  if (abortController) {
@@ -85,7 +85,7 @@ function useChat({
85
85
  const error = ref(void 0);
86
86
  const isLoading = ref(false);
87
87
  let abortController = null;
88
- function triggerRequest(messagesSnapshot) {
88
+ function triggerRequest(messagesSnapshot, options) {
89
89
  return __async(this, null, function* () {
90
90
  try {
91
91
  isLoading.value = true;
@@ -94,13 +94,13 @@ function useChat({
94
94
  mutate(messagesSnapshot);
95
95
  const res = yield fetch(api, {
96
96
  method: "POST",
97
- body: JSON.stringify(__spreadValues({
97
+ body: JSON.stringify(__spreadValues(__spreadValues({
98
98
  messages: sendExtraMessageFields ? messagesSnapshot : messagesSnapshot.map(({ role, content }) => ({
99
99
  role,
100
100
  content
101
101
  }))
102
- }, body)),
103
- headers: headers || {},
102
+ }, body), options == null ? void 0 : options.body)),
103
+ headers: __spreadValues(__spreadValues({}, headers), options == null ? void 0 : options.headers),
104
104
  signal: abortController.signal
105
105
  }).catch((err) => {
106
106
  mutate(previousMessages);
@@ -171,21 +171,21 @@ function useChat({
171
171
  }
172
172
  });
173
173
  }
174
- const append = (message) => __async(this, null, function* () {
174
+ const append = (message, options) => __async(this, null, function* () {
175
175
  if (!message.id) {
176
176
  message.id = nanoid();
177
177
  }
178
- return triggerRequest(messages.value.concat(message));
178
+ return triggerRequest(messages.value.concat(message), options);
179
179
  });
180
- const reload = () => __async(this, null, function* () {
180
+ const reload = (options) => __async(this, null, function* () {
181
181
  const messagesSnapshot = messages.value;
182
182
  if (messagesSnapshot.length === 0)
183
183
  return null;
184
184
  const lastMessage = messagesSnapshot[messagesSnapshot.length - 1];
185
185
  if (lastMessage.role === "assistant") {
186
- return triggerRequest(messagesSnapshot.slice(0, -1));
186
+ return triggerRequest(messagesSnapshot.slice(0, -1), options);
187
187
  }
188
- return triggerRequest(messagesSnapshot);
188
+ return triggerRequest(messagesSnapshot, options);
189
189
  });
190
190
  const stop = () => {
191
191
  if (abortController) {
@@ -253,7 +253,7 @@ function useCompletion({
253
253
  const error = ref2(void 0);
254
254
  const isLoading = ref2(false);
255
255
  let abortController = null;
256
- function triggerRequest(prompt) {
256
+ function triggerRequest(prompt, options) {
257
257
  return __async(this, null, function* () {
258
258
  try {
259
259
  isLoading.value = true;
@@ -261,10 +261,10 @@ function useCompletion({
261
261
  mutate("");
262
262
  const res = yield fetch(api, {
263
263
  method: "POST",
264
- body: JSON.stringify(__spreadValues({
264
+ body: JSON.stringify(__spreadValues(__spreadValues({
265
265
  prompt
266
- }, body)),
267
- headers: headers || {},
266
+ }, body), options == null ? void 0 : options.body)),
267
+ headers: __spreadValues(__spreadValues({}, headers), options == null ? void 0 : options.headers),
268
268
  signal: abortController.signal
269
269
  }).catch((err) => {
270
270
  throw err;
@@ -318,8 +318,8 @@ function useCompletion({
318
318
  }
319
319
  });
320
320
  }
321
- const complete = (prompt) => __async(this, null, function* () {
322
- return triggerRequest(prompt);
321
+ const complete = (prompt, options) => __async(this, null, function* () {
322
+ return triggerRequest(prompt, options);
323
323
  });
324
324
  const stop = () => {
325
325
  if (abortController) {