@ai-sdk/vue 0.0.1

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/.eslintrc.js ADDED
@@ -0,0 +1,4 @@
1
+ module.exports = {
2
+ root: true,
3
+ extends: ['vercel-ai'],
4
+ };
@@ -0,0 +1,21 @@
1
+
2
+ > @ai-sdk/vue@0.0.1 build /home/runner/work/ai/ai/packages/vue
3
+ > tsup
4
+
5
+ CLI Building entry: src/index.ts
6
+ CLI Using tsconfig: tsconfig.json
7
+ CLI tsup v7.2.0
8
+ CLI Using tsup config: /home/runner/work/ai/ai/packages/vue/tsup.config.ts
9
+ CLI Target: es2018
10
+ CJS Build start
11
+ ESM Build start
12
+ CJS dist/index.js 9.51 KB
13
+ CJS dist/index.js.map 17.84 KB
14
+ CJS ⚡️ Build success in 67ms
15
+ ESM dist/index.mjs 7.69 KB
16
+ ESM dist/index.mjs.map 17.67 KB
17
+ ESM ⚡️ Build success in 67ms
18
+ DTS Build start
19
+ DTS ⚡️ Build success in 3836ms
20
+ DTS dist/index.d.ts 3.38 KB
21
+ DTS dist/index.d.mts 3.38 KB
@@ -0,0 +1,4 @@
1
+
2
+ > @ai-sdk/vue@0.0.1 clean /home/runner/work/ai/ai/packages/vue
3
+ > rm -rf dist
4
+
package/CHANGELOG.md ADDED
@@ -0,0 +1,9 @@
1
+ # @ai-sdk/vue
2
+
3
+ ## 0.0.1
4
+
5
+ ### Patch Changes
6
+
7
+ - 85f209a4: chore: extracted ui library support into separate modules
8
+ - Updated dependencies [85f209a4]
9
+ - @ai-sdk/ui-utils@0.0.1
package/LICENSE ADDED
@@ -0,0 +1,13 @@
1
+ Copyright 2023 Vercel, Inc.
2
+
3
+ Licensed under the Apache License, Version 2.0 (the "License");
4
+ you may not use this file except in compliance with the License.
5
+ You may obtain a copy of the License at
6
+
7
+ http://www.apache.org/licenses/LICENSE-2.0
8
+
9
+ Unless required by applicable law or agreed to in writing, software
10
+ distributed under the License is distributed on an "AS IS" BASIS,
11
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ See the License for the specific language governing permissions and
13
+ limitations under the License.
package/README.md ADDED
@@ -0,0 +1,6 @@
1
+ # Vercel AI SDK: Vue.js provider
2
+
3
+ [Vue.js](https://vuejs.org/) UI components for the [Vercel AI SDK](https://sdk.vercel.ai/docs):
4
+
5
+ - [`useChat`](https://sdk.vercel.ai/docs/reference/ai-sdk-ui/use-chat) hook
6
+ - [`useCompletion`](https://sdk.vercel.ai/docs/reference/ai-sdk-ui/use-completion) hook
@@ -0,0 +1,78 @@
1
+ import { Message, CreateMessage, ChatRequestOptions, JSONValue, UseChatOptions, RequestOptions, UseCompletionOptions } from '@ai-sdk/ui-utils';
2
+ export { CreateMessage, Message, UseChatOptions, UseCompletionOptions } from '@ai-sdk/ui-utils';
3
+ import { Ref } from 'vue';
4
+
5
+ type UseChatHelpers = {
6
+ /** Current messages in the chat */
7
+ messages: Ref<Message[]>;
8
+ /** The error object of the API request */
9
+ error: Ref<undefined | Error>;
10
+ /**
11
+ * Append a user message to the chat list. This triggers the API call to fetch
12
+ * the assistant's response.
13
+ */
14
+ append: (message: Message | CreateMessage, chatRequestOptions?: ChatRequestOptions) => Promise<string | null | undefined>;
15
+ /**
16
+ * Reload the last AI chat response for the given chat history. If the last
17
+ * message isn't from the assistant, it will request the API to generate a
18
+ * new response.
19
+ */
20
+ reload: (chatRequestOptions?: ChatRequestOptions) => Promise<string | null | undefined>;
21
+ /**
22
+ * Abort the current request immediately, keep the generated tokens if any.
23
+ */
24
+ stop: () => void;
25
+ /**
26
+ * Update the `messages` state locally. This is useful when you want to
27
+ * edit the messages on the client, and then trigger the `reload` method
28
+ * manually to regenerate the AI response.
29
+ */
30
+ setMessages: (messages: Message[]) => void;
31
+ /** The current value of the input */
32
+ input: Ref<string>;
33
+ /** Form submission handler to automatically reset input and append a user message */
34
+ handleSubmit: (e: any, chatRequestOptions?: ChatRequestOptions) => void;
35
+ /** Whether the API request is in progress */
36
+ isLoading: Ref<boolean | undefined>;
37
+ /** Additional data added on the server via StreamData */
38
+ data: Ref<JSONValue[] | undefined>;
39
+ };
40
+ declare function useChat({ api, id, initialMessages, initialInput, sendExtraMessageFields, experimental_onFunctionCall, streamMode, onResponse, onFinish, onError, credentials, headers, body, generateId, }?: UseChatOptions): UseChatHelpers;
41
+
42
+ type UseCompletionHelpers = {
43
+ /** The current completion result */
44
+ completion: Ref<string>;
45
+ /** The error object of the API request */
46
+ error: Ref<undefined | Error>;
47
+ /**
48
+ * Send a new prompt to the API endpoint and update the completion state.
49
+ */
50
+ complete: (prompt: string, options?: RequestOptions) => Promise<string | null | undefined>;
51
+ /**
52
+ * Abort the current API request but keep the generated tokens.
53
+ */
54
+ stop: () => void;
55
+ /**
56
+ * Update the `completion` state locally.
57
+ */
58
+ setCompletion: (completion: string) => void;
59
+ /** The current value of the input */
60
+ input: Ref<string>;
61
+ /**
62
+ * Form submission handler to automatically reset input and append a user message
63
+ * @example
64
+ * ```jsx
65
+ * <form @submit="handleSubmit">
66
+ * <input @change="handleInputChange" v-model="input" />
67
+ * </form>
68
+ * ```
69
+ */
70
+ handleSubmit: (e: any) => void;
71
+ /** Whether the API request is in progress */
72
+ isLoading: Ref<boolean | undefined>;
73
+ /** Additional data added on the server via StreamData */
74
+ data: Ref<JSONValue[] | undefined>;
75
+ };
76
+ declare function useCompletion({ api, id, initialCompletion, initialInput, credentials, headers, body, streamMode, onResponse, onFinish, onError, }?: UseCompletionOptions): UseCompletionHelpers;
77
+
78
+ export { UseChatHelpers, UseCompletionHelpers, useChat, useCompletion };
@@ -0,0 +1,78 @@
1
+ import { Message, CreateMessage, ChatRequestOptions, JSONValue, UseChatOptions, RequestOptions, UseCompletionOptions } from '@ai-sdk/ui-utils';
2
+ export { CreateMessage, Message, UseChatOptions, UseCompletionOptions } from '@ai-sdk/ui-utils';
3
+ import { Ref } from 'vue';
4
+
5
+ type UseChatHelpers = {
6
+ /** Current messages in the chat */
7
+ messages: Ref<Message[]>;
8
+ /** The error object of the API request */
9
+ error: Ref<undefined | Error>;
10
+ /**
11
+ * Append a user message to the chat list. This triggers the API call to fetch
12
+ * the assistant's response.
13
+ */
14
+ append: (message: Message | CreateMessage, chatRequestOptions?: ChatRequestOptions) => Promise<string | null | undefined>;
15
+ /**
16
+ * Reload the last AI chat response for the given chat history. If the last
17
+ * message isn't from the assistant, it will request the API to generate a
18
+ * new response.
19
+ */
20
+ reload: (chatRequestOptions?: ChatRequestOptions) => Promise<string | null | undefined>;
21
+ /**
22
+ * Abort the current request immediately, keep the generated tokens if any.
23
+ */
24
+ stop: () => void;
25
+ /**
26
+ * Update the `messages` state locally. This is useful when you want to
27
+ * edit the messages on the client, and then trigger the `reload` method
28
+ * manually to regenerate the AI response.
29
+ */
30
+ setMessages: (messages: Message[]) => void;
31
+ /** The current value of the input */
32
+ input: Ref<string>;
33
+ /** Form submission handler to automatically reset input and append a user message */
34
+ handleSubmit: (e: any, chatRequestOptions?: ChatRequestOptions) => void;
35
+ /** Whether the API request is in progress */
36
+ isLoading: Ref<boolean | undefined>;
37
+ /** Additional data added on the server via StreamData */
38
+ data: Ref<JSONValue[] | undefined>;
39
+ };
40
+ declare function useChat({ api, id, initialMessages, initialInput, sendExtraMessageFields, experimental_onFunctionCall, streamMode, onResponse, onFinish, onError, credentials, headers, body, generateId, }?: UseChatOptions): UseChatHelpers;
41
+
42
+ type UseCompletionHelpers = {
43
+ /** The current completion result */
44
+ completion: Ref<string>;
45
+ /** The error object of the API request */
46
+ error: Ref<undefined | Error>;
47
+ /**
48
+ * Send a new prompt to the API endpoint and update the completion state.
49
+ */
50
+ complete: (prompt: string, options?: RequestOptions) => Promise<string | null | undefined>;
51
+ /**
52
+ * Abort the current API request but keep the generated tokens.
53
+ */
54
+ stop: () => void;
55
+ /**
56
+ * Update the `completion` state locally.
57
+ */
58
+ setCompletion: (completion: string) => void;
59
+ /** The current value of the input */
60
+ input: Ref<string>;
61
+ /**
62
+ * Form submission handler to automatically reset input and append a user message
63
+ * @example
64
+ * ```jsx
65
+ * <form @submit="handleSubmit">
66
+ * <input @change="handleInputChange" v-model="input" />
67
+ * </form>
68
+ * ```
69
+ */
70
+ handleSubmit: (e: any) => void;
71
+ /** Whether the API request is in progress */
72
+ isLoading: Ref<boolean | undefined>;
73
+ /** Additional data added on the server via StreamData */
74
+ data: Ref<JSONValue[] | undefined>;
75
+ };
76
+ declare function useCompletion({ api, id, initialCompletion, initialInput, credentials, headers, body, streamMode, onResponse, onFinish, onError, }?: UseCompletionOptions): UseCompletionHelpers;
77
+
78
+ export { UseChatHelpers, UseCompletionHelpers, useChat, useCompletion };
package/dist/index.js ADDED
@@ -0,0 +1,330 @@
1
+ "use strict";
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __export = (target, all) => {
9
+ for (var name in all)
10
+ __defProp(target, name, { get: all[name], enumerable: true });
11
+ };
12
+ var __copyProps = (to, from, except, desc) => {
13
+ if (from && typeof from === "object" || typeof from === "function") {
14
+ for (let key of __getOwnPropNames(from))
15
+ if (!__hasOwnProp.call(to, key) && key !== except)
16
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
+ }
18
+ return to;
19
+ };
20
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
+ // If the importer is in node compatibility mode or this is not an ESM
22
+ // file that has been converted to a CommonJS file using a Babel-
23
+ // compatible transform (i.e. "__esModule" has not been set), then set
24
+ // "default" to the CommonJS "module.exports" for node compatibility.
25
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
+ mod
27
+ ));
28
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
+
30
+ // src/index.ts
31
+ var src_exports = {};
32
+ __export(src_exports, {
33
+ useChat: () => useChat,
34
+ useCompletion: () => useCompletion
35
+ });
36
+ module.exports = __toCommonJS(src_exports);
37
+
38
+ // src/use-chat.ts
39
+ var import_ui_utils = require("@ai-sdk/ui-utils");
40
+ var import_swrv = __toESM(require("swrv"));
41
+ var import_vue = require("vue");
42
+ var uniqueId = 0;
43
+ var useSWRV = import_swrv.default.default || import_swrv.default;
44
+ var store = {};
45
+ function useChat({
46
+ api = "/api/chat",
47
+ id,
48
+ initialMessages = [],
49
+ initialInput = "",
50
+ sendExtraMessageFields,
51
+ experimental_onFunctionCall,
52
+ streamMode,
53
+ onResponse,
54
+ onFinish,
55
+ onError,
56
+ credentials,
57
+ headers,
58
+ body,
59
+ generateId = import_ui_utils.generateId
60
+ } = {}) {
61
+ var _a, _b;
62
+ const chatId = id || `chat-${uniqueId++}`;
63
+ const key = `${api}|${chatId}`;
64
+ const { data: messagesData, mutate: originalMutate } = useSWRV(
65
+ key,
66
+ () => store[key] || initialMessages
67
+ );
68
+ const { data: isLoading, mutate: mutateLoading } = useSWRV(
69
+ `${chatId}-loading`,
70
+ null
71
+ );
72
+ (_a = isLoading.value) != null ? _a : isLoading.value = false;
73
+ (_b = messagesData.value) != null ? _b : messagesData.value = initialMessages;
74
+ const mutate = (data) => {
75
+ store[key] = data;
76
+ return originalMutate();
77
+ };
78
+ const messages = messagesData;
79
+ const error = (0, import_vue.ref)(void 0);
80
+ const streamData = (0, import_vue.ref)(void 0);
81
+ let abortController = null;
82
+ async function triggerRequest(messagesSnapshot, { options, data } = {}) {
83
+ try {
84
+ error.value = void 0;
85
+ mutateLoading(() => true);
86
+ abortController = new AbortController();
87
+ const previousMessages = messagesData.value;
88
+ mutate(messagesSnapshot);
89
+ let chatRequest = {
90
+ messages: messagesSnapshot,
91
+ options,
92
+ data
93
+ };
94
+ await (0, import_ui_utils.processChatStream)({
95
+ getStreamedResponse: async () => {
96
+ var _a2;
97
+ const existingData = (_a2 = streamData.value) != null ? _a2 : [];
98
+ return await (0, import_ui_utils.callChatApi)({
99
+ api,
100
+ messages: sendExtraMessageFields ? chatRequest.messages : chatRequest.messages.map(
101
+ ({
102
+ role,
103
+ content,
104
+ name,
105
+ data: data2,
106
+ annotations,
107
+ function_call
108
+ }) => ({
109
+ role,
110
+ content,
111
+ ...name !== void 0 && { name },
112
+ ...data2 !== void 0 && { data: data2 },
113
+ ...annotations !== void 0 && { annotations },
114
+ // outdated function/tool call handling (TODO deprecate):
115
+ ...function_call !== void 0 && { function_call }
116
+ })
117
+ ),
118
+ body: {
119
+ data: chatRequest.data,
120
+ ...(0, import_vue.unref)(body),
121
+ // Use unref to unwrap the ref value
122
+ ...options == null ? void 0 : options.body
123
+ },
124
+ streamMode,
125
+ headers: {
126
+ ...headers,
127
+ ...options == null ? void 0 : options.headers
128
+ },
129
+ abortController: () => abortController,
130
+ credentials,
131
+ onResponse,
132
+ onUpdate(merged, data2) {
133
+ mutate([...chatRequest.messages, ...merged]);
134
+ streamData.value = [...existingData, ...data2 != null ? data2 : []];
135
+ },
136
+ onFinish(message) {
137
+ mutate([...chatRequest.messages, message]);
138
+ onFinish == null ? void 0 : onFinish(message);
139
+ },
140
+ restoreMessagesOnFailure() {
141
+ mutate(previousMessages);
142
+ },
143
+ generateId
144
+ });
145
+ },
146
+ experimental_onFunctionCall,
147
+ updateChatRequest(newChatRequest) {
148
+ chatRequest = newChatRequest;
149
+ },
150
+ getCurrentMessages: () => messages.value
151
+ });
152
+ abortController = null;
153
+ } catch (err) {
154
+ if (err.name === "AbortError") {
155
+ abortController = null;
156
+ return null;
157
+ }
158
+ if (onError && err instanceof Error) {
159
+ onError(err);
160
+ }
161
+ error.value = err;
162
+ } finally {
163
+ mutateLoading(() => false);
164
+ }
165
+ }
166
+ const append = async (message, options) => {
167
+ if (!message.id) {
168
+ message.id = generateId();
169
+ }
170
+ return triggerRequest(messages.value.concat(message), options);
171
+ };
172
+ const reload = async (options) => {
173
+ const messagesSnapshot = messages.value;
174
+ if (messagesSnapshot.length === 0)
175
+ return null;
176
+ const lastMessage = messagesSnapshot[messagesSnapshot.length - 1];
177
+ if (lastMessage.role === "assistant") {
178
+ return triggerRequest(messagesSnapshot.slice(0, -1), options);
179
+ }
180
+ return triggerRequest(messagesSnapshot, options);
181
+ };
182
+ const stop = () => {
183
+ if (abortController) {
184
+ abortController.abort();
185
+ abortController = null;
186
+ }
187
+ };
188
+ const setMessages = (messages2) => {
189
+ mutate(messages2);
190
+ };
191
+ const input = (0, import_vue.ref)(initialInput);
192
+ const handleSubmit = (e, options = {}) => {
193
+ e.preventDefault();
194
+ const inputValue = input.value;
195
+ if (!inputValue)
196
+ return;
197
+ append(
198
+ {
199
+ content: inputValue,
200
+ role: "user"
201
+ },
202
+ options
203
+ );
204
+ input.value = "";
205
+ };
206
+ return {
207
+ messages,
208
+ append,
209
+ error,
210
+ reload,
211
+ stop,
212
+ setMessages,
213
+ input,
214
+ handleSubmit,
215
+ isLoading,
216
+ data: streamData
217
+ };
218
+ }
219
+
220
+ // src/use-completion.ts
221
+ var import_ui_utils2 = require("@ai-sdk/ui-utils");
222
+ var import_swrv2 = __toESM(require("swrv"));
223
+ var import_vue2 = require("vue");
224
+ var uniqueId2 = 0;
225
+ var useSWRV2 = import_swrv2.default.default || import_swrv2.default;
226
+ var store2 = {};
227
+ function useCompletion({
228
+ api = "/api/completion",
229
+ id,
230
+ initialCompletion = "",
231
+ initialInput = "",
232
+ credentials,
233
+ headers,
234
+ body,
235
+ streamMode,
236
+ onResponse,
237
+ onFinish,
238
+ onError
239
+ } = {}) {
240
+ var _a;
241
+ const completionId = id || `completion-${uniqueId2++}`;
242
+ const key = `${api}|${completionId}`;
243
+ const { data, mutate: originalMutate } = useSWRV2(
244
+ key,
245
+ () => store2[key] || initialCompletion
246
+ );
247
+ const { data: isLoading, mutate: mutateLoading } = useSWRV2(
248
+ `${completionId}-loading`,
249
+ null
250
+ );
251
+ (_a = isLoading.value) != null ? _a : isLoading.value = false;
252
+ const { data: streamData, mutate: mutateStreamData } = useSWRV2(`${completionId}-data`, null);
253
+ data.value || (data.value = initialCompletion);
254
+ const mutate = (data2) => {
255
+ store2[key] = data2;
256
+ return originalMutate();
257
+ };
258
+ const completion = data;
259
+ const error = (0, import_vue2.ref)(void 0);
260
+ let abortController = null;
261
+ async function triggerRequest(prompt, options) {
262
+ var _a2;
263
+ const existingData = (_a2 = streamData.value) != null ? _a2 : [];
264
+ return (0, import_ui_utils2.callCompletionApi)({
265
+ api,
266
+ prompt,
267
+ credentials,
268
+ headers: {
269
+ ...headers,
270
+ ...options == null ? void 0 : options.headers
271
+ },
272
+ body: {
273
+ ...(0, import_vue2.unref)(body),
274
+ ...options == null ? void 0 : options.body
275
+ },
276
+ streamMode,
277
+ setCompletion: mutate,
278
+ setLoading: (loading) => mutateLoading(() => loading),
279
+ setError: (err) => {
280
+ error.value = err;
281
+ },
282
+ setAbortController: (controller) => {
283
+ abortController = controller;
284
+ },
285
+ onResponse,
286
+ onFinish,
287
+ onError,
288
+ onData: (data2) => {
289
+ mutateStreamData(() => [...existingData, ...data2 != null ? data2 : []]);
290
+ }
291
+ });
292
+ }
293
+ const complete = async (prompt, options) => {
294
+ return triggerRequest(prompt, options);
295
+ };
296
+ const stop = () => {
297
+ if (abortController) {
298
+ abortController.abort();
299
+ abortController = null;
300
+ }
301
+ };
302
+ const setCompletion = (completion2) => {
303
+ mutate(completion2);
304
+ };
305
+ const input = (0, import_vue2.ref)(initialInput);
306
+ const handleSubmit = (e) => {
307
+ e.preventDefault();
308
+ const inputValue = input.value;
309
+ if (!inputValue)
310
+ return;
311
+ return complete(inputValue);
312
+ };
313
+ return {
314
+ completion,
315
+ complete,
316
+ error,
317
+ stop,
318
+ setCompletion,
319
+ input,
320
+ handleSubmit,
321
+ isLoading,
322
+ data: streamData
323
+ };
324
+ }
325
+ // Annotate the CommonJS export names for ESM import in node:
326
+ 0 && (module.exports = {
327
+ useChat,
328
+ useCompletion
329
+ });
330
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/index.ts","../src/use-chat.ts","../src/use-completion.ts"],"sourcesContent":["export * from './use-chat';\nexport * from './use-completion';\n","import type {\n ChatRequest,\n ChatRequestOptions,\n CreateMessage,\n JSONValue,\n Message,\n UseChatOptions,\n} from '@ai-sdk/ui-utils';\nimport {\n callChatApi,\n generateId as generateIdFunc,\n processChatStream,\n} from '@ai-sdk/ui-utils';\nimport swrv from 'swrv';\nimport type { Ref } from 'vue';\nimport { ref, unref } from 'vue';\n\nexport type { CreateMessage, Message, UseChatOptions };\n\nexport type UseChatHelpers = {\n /** Current messages in the chat */\n messages: Ref<Message[]>;\n /** The error object of the API request */\n error: Ref<undefined | Error>;\n /**\n * Append a user message to the chat list. This triggers the API call to fetch\n * the assistant's response.\n */\n append: (\n message: Message | CreateMessage,\n chatRequestOptions?: ChatRequestOptions,\n ) => Promise<string | null | undefined>;\n /**\n * Reload the last AI chat response for the given chat history. If the last\n * message isn't from the assistant, it will request the API to generate a\n * new response.\n */\n reload: (\n chatRequestOptions?: ChatRequestOptions,\n ) => Promise<string | null | undefined>;\n /**\n * Abort the current request immediately, keep the generated tokens if any.\n */\n stop: () => void;\n /**\n * Update the `messages` state locally. This is useful when you want to\n * edit the messages on the client, and then trigger the `reload` method\n * manually to regenerate the AI response.\n */\n setMessages: (messages: Message[]) => void;\n /** The current value of the input */\n input: Ref<string>;\n /** Form submission handler to automatically reset input and append a user message */\n handleSubmit: (e: any, chatRequestOptions?: ChatRequestOptions) => void;\n /** Whether the API request is in progress */\n isLoading: Ref<boolean | undefined>;\n\n /** Additional data added on the server via StreamData */\n data: Ref<JSONValue[] | undefined>;\n};\n\nlet uniqueId = 0;\n\n// @ts-expect-error - some issues with the default export of useSWRV\nconst useSWRV = (swrv.default as typeof import('swrv')['default']) || swrv;\nconst store: Record<string, Message[] | undefined> = {};\n\nexport function useChat({\n api = '/api/chat',\n id,\n initialMessages = [],\n initialInput = '',\n sendExtraMessageFields,\n experimental_onFunctionCall,\n streamMode,\n onResponse,\n onFinish,\n onError,\n credentials,\n headers,\n body,\n generateId = generateIdFunc,\n}: UseChatOptions = {}): UseChatHelpers {\n // Generate a unique ID for the chat if not provided.\n const chatId = id || `chat-${uniqueId++}`;\n\n const key = `${api}|${chatId}`;\n const { data: messagesData, mutate: originalMutate } = useSWRV<Message[]>(\n key,\n () => store[key] || initialMessages,\n );\n\n const { data: isLoading, mutate: mutateLoading } = useSWRV<boolean>(\n `${chatId}-loading`,\n null,\n );\n\n isLoading.value ??= false;\n\n // Force the `data` to be `initialMessages` if it's `undefined`.\n messagesData.value ??= initialMessages;\n\n const mutate = (data?: Message[]) => {\n store[key] = data;\n return originalMutate();\n };\n\n // Because of the `initialData` option, the `data` will never be `undefined`.\n const messages = messagesData as Ref<Message[]>;\n\n const error = ref<undefined | Error>(undefined);\n // cannot use JSONValue[] in ref because of infinite Typescript recursion:\n const streamData = ref<undefined | unknown[]>(undefined);\n\n let abortController: AbortController | null = null;\n async function triggerRequest(\n messagesSnapshot: Message[],\n { options, data }: ChatRequestOptions = {},\n ) {\n try {\n error.value = undefined;\n mutateLoading(() => true);\n\n abortController = new AbortController();\n\n // Do an optimistic update to the chat state to show the updated messages\n // immediately.\n const previousMessages = messagesData.value;\n mutate(messagesSnapshot);\n\n let chatRequest: ChatRequest = {\n messages: messagesSnapshot,\n options,\n data,\n };\n\n await processChatStream({\n getStreamedResponse: async () => {\n const existingData = (streamData.value ?? []) as JSONValue[];\n\n return await callChatApi({\n api,\n messages: sendExtraMessageFields\n ? chatRequest.messages\n : chatRequest.messages.map(\n ({\n role,\n content,\n name,\n data,\n annotations,\n function_call,\n }) => ({\n role,\n content,\n ...(name !== undefined && { name }),\n ...(data !== undefined && { data }),\n ...(annotations !== undefined && { annotations }),\n // outdated function/tool call handling (TODO deprecate):\n ...(function_call !== undefined && { function_call }),\n }),\n ),\n body: {\n data: chatRequest.data,\n ...unref(body), // Use unref to unwrap the ref value\n ...options?.body,\n },\n streamMode,\n headers: {\n ...headers,\n ...options?.headers,\n },\n abortController: () => abortController,\n credentials,\n onResponse,\n onUpdate(merged, data) {\n mutate([...chatRequest.messages, ...merged]);\n streamData.value = [...existingData, ...(data ?? [])];\n },\n onFinish(message) {\n // workaround: sometimes the last chunk is not shown in the UI.\n // push it twice to make sure it's displayed.\n mutate([...chatRequest.messages, message]);\n onFinish?.(message);\n },\n restoreMessagesOnFailure() {\n // Restore the previous messages if the request fails.\n mutate(previousMessages);\n },\n generateId,\n });\n },\n experimental_onFunctionCall,\n updateChatRequest(newChatRequest) {\n chatRequest = newChatRequest;\n },\n getCurrentMessages: () => messages.value,\n });\n\n abortController = null;\n } catch (err) {\n // Ignore abort errors as they are expected.\n if ((err as any).name === 'AbortError') {\n abortController = null;\n return null;\n }\n\n if (onError && err instanceof Error) {\n onError(err);\n }\n\n error.value = err as Error;\n } finally {\n mutateLoading(() => false);\n }\n }\n\n const append: UseChatHelpers['append'] = async (message, options) => {\n if (!message.id) {\n message.id = generateId();\n }\n return triggerRequest(messages.value.concat(message as Message), options);\n };\n\n const reload: UseChatHelpers['reload'] = async options => {\n const messagesSnapshot = messages.value;\n if (messagesSnapshot.length === 0) return null;\n\n const lastMessage = messagesSnapshot[messagesSnapshot.length - 1];\n if (lastMessage.role === 'assistant') {\n return triggerRequest(messagesSnapshot.slice(0, -1), options);\n }\n return triggerRequest(messagesSnapshot, options);\n };\n\n const stop = () => {\n if (abortController) {\n abortController.abort();\n abortController = null;\n }\n };\n\n const setMessages = (messages: Message[]) => {\n mutate(messages);\n };\n\n const input = ref(initialInput);\n\n const handleSubmit = (e: any, options: ChatRequestOptions = {}) => {\n e.preventDefault();\n const inputValue = input.value;\n if (!inputValue) return;\n append(\n {\n content: inputValue,\n role: 'user',\n },\n options,\n );\n input.value = '';\n };\n\n return {\n messages,\n append,\n error,\n reload,\n stop,\n setMessages,\n input,\n handleSubmit,\n isLoading,\n data: streamData as Ref<undefined | JSONValue[]>,\n };\n}\n","import type {\n JSONValue,\n RequestOptions,\n UseCompletionOptions,\n} from '@ai-sdk/ui-utils';\nimport { callCompletionApi } from '@ai-sdk/ui-utils';\nimport swrv from 'swrv';\nimport type { Ref } from 'vue';\nimport { ref, unref } from 'vue';\n\nexport type { UseCompletionOptions };\n\nexport type UseCompletionHelpers = {\n /** The current completion result */\n completion: Ref<string>;\n /** The error object of the API request */\n error: Ref<undefined | Error>;\n /**\n * Send a new prompt to the API endpoint and update the completion state.\n */\n complete: (\n prompt: string,\n options?: RequestOptions,\n ) => Promise<string | null | undefined>;\n /**\n * Abort the current API request but keep the generated tokens.\n */\n stop: () => void;\n /**\n * Update the `completion` state locally.\n */\n setCompletion: (completion: string) => void;\n /** The current value of the input */\n input: Ref<string>;\n /**\n * Form submission handler to automatically reset input and append a user message\n * @example\n * ```jsx\n * <form @submit=\"handleSubmit\">\n * <input @change=\"handleInputChange\" v-model=\"input\" />\n * </form>\n * ```\n */\n handleSubmit: (e: any) => void;\n /** Whether the API request is in progress */\n isLoading: Ref<boolean | undefined>;\n\n /** Additional data added on the server via StreamData */\n data: Ref<JSONValue[] | undefined>;\n};\n\nlet uniqueId = 0;\n\n// @ts-expect-error - some issues with the default export of useSWRV\nconst useSWRV = (swrv.default as typeof import('swrv')['default']) || swrv;\nconst store: Record<string, any> = {};\n\nexport function useCompletion({\n api = '/api/completion',\n id,\n initialCompletion = '',\n initialInput = '',\n credentials,\n headers,\n body,\n streamMode,\n onResponse,\n onFinish,\n onError,\n}: UseCompletionOptions = {}): UseCompletionHelpers {\n // Generate an unique id for the completion if not provided.\n const completionId = id || `completion-${uniqueId++}`;\n\n const key = `${api}|${completionId}`;\n const { data, mutate: originalMutate } = useSWRV<string>(\n key,\n () => store[key] || initialCompletion,\n );\n\n const { data: isLoading, mutate: mutateLoading } = useSWRV<boolean>(\n `${completionId}-loading`,\n null,\n );\n\n isLoading.value ??= false;\n\n const { data: streamData, mutate: mutateStreamData } = useSWRV<\n JSONValue[] | undefined\n >(`${completionId}-data`, null);\n\n // Force the `data` to be `initialCompletion` if it's `undefined`.\n data.value ||= initialCompletion;\n\n const mutate = (data: string) => {\n store[key] = data;\n return originalMutate();\n };\n\n // Because of the `initialData` option, the `data` will never be `undefined`.\n const completion = data as Ref<string>;\n\n const error = ref<undefined | Error>(undefined);\n\n let abortController: AbortController | null = null;\n\n async function triggerRequest(prompt: string, options?: RequestOptions) {\n const existingData = (streamData.value ?? []) as JSONValue[];\n return callCompletionApi({\n api,\n prompt,\n credentials,\n headers: {\n ...headers,\n ...options?.headers,\n },\n body: {\n ...unref(body),\n ...options?.body,\n },\n streamMode,\n setCompletion: mutate,\n setLoading: loading => mutateLoading(() => loading),\n setError: err => {\n error.value = err;\n },\n setAbortController: controller => {\n abortController = controller;\n },\n onResponse,\n onFinish,\n onError,\n onData: data => {\n mutateStreamData(() => [...existingData, ...(data ?? [])]);\n },\n });\n }\n\n const complete: UseCompletionHelpers['complete'] = async (\n prompt,\n options,\n ) => {\n return triggerRequest(prompt, options);\n };\n\n const stop = () => {\n if (abortController) {\n abortController.abort();\n abortController = null;\n }\n };\n\n const setCompletion = (completion: string) => {\n mutate(completion);\n };\n\n const input = ref(initialInput);\n\n const handleSubmit = (e: any) => {\n e.preventDefault();\n const inputValue = input.value;\n if (!inputValue) return;\n return complete(inputValue);\n };\n\n return {\n completion,\n complete,\n error,\n stop,\n setCompletion,\n input,\n handleSubmit,\n isLoading,\n data: streamData,\n };\n}\n"],"mappings":"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","names":["swrv","generateIdFunc","_a","data","messages","import_ui_utils","import_swrv","import_vue","uniqueId","useSWRV","swrv","store","data","_a","completion"]}