@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/dist/index.mjs ADDED
@@ -0,0 +1,296 @@
1
+ // src/use-chat.ts
2
+ import {
3
+ callChatApi,
4
+ generateId as generateIdFunc,
5
+ processChatStream
6
+ } from "@ai-sdk/ui-utils";
7
+ import swrv from "swrv";
8
+ import { ref, unref } from "vue";
9
+ var uniqueId = 0;
10
+ var useSWRV = swrv.default || swrv;
11
+ var store = {};
12
+ function useChat({
13
+ api = "/api/chat",
14
+ id,
15
+ initialMessages = [],
16
+ initialInput = "",
17
+ sendExtraMessageFields,
18
+ experimental_onFunctionCall,
19
+ streamMode,
20
+ onResponse,
21
+ onFinish,
22
+ onError,
23
+ credentials,
24
+ headers,
25
+ body,
26
+ generateId = generateIdFunc
27
+ } = {}) {
28
+ var _a, _b;
29
+ const chatId = id || `chat-${uniqueId++}`;
30
+ const key = `${api}|${chatId}`;
31
+ const { data: messagesData, mutate: originalMutate } = useSWRV(
32
+ key,
33
+ () => store[key] || initialMessages
34
+ );
35
+ const { data: isLoading, mutate: mutateLoading } = useSWRV(
36
+ `${chatId}-loading`,
37
+ null
38
+ );
39
+ (_a = isLoading.value) != null ? _a : isLoading.value = false;
40
+ (_b = messagesData.value) != null ? _b : messagesData.value = initialMessages;
41
+ const mutate = (data) => {
42
+ store[key] = data;
43
+ return originalMutate();
44
+ };
45
+ const messages = messagesData;
46
+ const error = ref(void 0);
47
+ const streamData = ref(void 0);
48
+ let abortController = null;
49
+ async function triggerRequest(messagesSnapshot, { options, data } = {}) {
50
+ try {
51
+ error.value = void 0;
52
+ mutateLoading(() => true);
53
+ abortController = new AbortController();
54
+ const previousMessages = messagesData.value;
55
+ mutate(messagesSnapshot);
56
+ let chatRequest = {
57
+ messages: messagesSnapshot,
58
+ options,
59
+ data
60
+ };
61
+ await processChatStream({
62
+ getStreamedResponse: async () => {
63
+ var _a2;
64
+ const existingData = (_a2 = streamData.value) != null ? _a2 : [];
65
+ return await callChatApi({
66
+ api,
67
+ messages: sendExtraMessageFields ? chatRequest.messages : chatRequest.messages.map(
68
+ ({
69
+ role,
70
+ content,
71
+ name,
72
+ data: data2,
73
+ annotations,
74
+ function_call
75
+ }) => ({
76
+ role,
77
+ content,
78
+ ...name !== void 0 && { name },
79
+ ...data2 !== void 0 && { data: data2 },
80
+ ...annotations !== void 0 && { annotations },
81
+ // outdated function/tool call handling (TODO deprecate):
82
+ ...function_call !== void 0 && { function_call }
83
+ })
84
+ ),
85
+ body: {
86
+ data: chatRequest.data,
87
+ ...unref(body),
88
+ // Use unref to unwrap the ref value
89
+ ...options == null ? void 0 : options.body
90
+ },
91
+ streamMode,
92
+ headers: {
93
+ ...headers,
94
+ ...options == null ? void 0 : options.headers
95
+ },
96
+ abortController: () => abortController,
97
+ credentials,
98
+ onResponse,
99
+ onUpdate(merged, data2) {
100
+ mutate([...chatRequest.messages, ...merged]);
101
+ streamData.value = [...existingData, ...data2 != null ? data2 : []];
102
+ },
103
+ onFinish(message) {
104
+ mutate([...chatRequest.messages, message]);
105
+ onFinish == null ? void 0 : onFinish(message);
106
+ },
107
+ restoreMessagesOnFailure() {
108
+ mutate(previousMessages);
109
+ },
110
+ generateId
111
+ });
112
+ },
113
+ experimental_onFunctionCall,
114
+ updateChatRequest(newChatRequest) {
115
+ chatRequest = newChatRequest;
116
+ },
117
+ getCurrentMessages: () => messages.value
118
+ });
119
+ abortController = null;
120
+ } catch (err) {
121
+ if (err.name === "AbortError") {
122
+ abortController = null;
123
+ return null;
124
+ }
125
+ if (onError && err instanceof Error) {
126
+ onError(err);
127
+ }
128
+ error.value = err;
129
+ } finally {
130
+ mutateLoading(() => false);
131
+ }
132
+ }
133
+ const append = async (message, options) => {
134
+ if (!message.id) {
135
+ message.id = generateId();
136
+ }
137
+ return triggerRequest(messages.value.concat(message), options);
138
+ };
139
+ const reload = async (options) => {
140
+ const messagesSnapshot = messages.value;
141
+ if (messagesSnapshot.length === 0)
142
+ return null;
143
+ const lastMessage = messagesSnapshot[messagesSnapshot.length - 1];
144
+ if (lastMessage.role === "assistant") {
145
+ return triggerRequest(messagesSnapshot.slice(0, -1), options);
146
+ }
147
+ return triggerRequest(messagesSnapshot, options);
148
+ };
149
+ const stop = () => {
150
+ if (abortController) {
151
+ abortController.abort();
152
+ abortController = null;
153
+ }
154
+ };
155
+ const setMessages = (messages2) => {
156
+ mutate(messages2);
157
+ };
158
+ const input = ref(initialInput);
159
+ const handleSubmit = (e, options = {}) => {
160
+ e.preventDefault();
161
+ const inputValue = input.value;
162
+ if (!inputValue)
163
+ return;
164
+ append(
165
+ {
166
+ content: inputValue,
167
+ role: "user"
168
+ },
169
+ options
170
+ );
171
+ input.value = "";
172
+ };
173
+ return {
174
+ messages,
175
+ append,
176
+ error,
177
+ reload,
178
+ stop,
179
+ setMessages,
180
+ input,
181
+ handleSubmit,
182
+ isLoading,
183
+ data: streamData
184
+ };
185
+ }
186
+
187
+ // src/use-completion.ts
188
+ import { callCompletionApi } from "@ai-sdk/ui-utils";
189
+ import swrv2 from "swrv";
190
+ import { ref as ref2, unref as unref2 } from "vue";
191
+ var uniqueId2 = 0;
192
+ var useSWRV2 = swrv2.default || swrv2;
193
+ var store2 = {};
194
+ function useCompletion({
195
+ api = "/api/completion",
196
+ id,
197
+ initialCompletion = "",
198
+ initialInput = "",
199
+ credentials,
200
+ headers,
201
+ body,
202
+ streamMode,
203
+ onResponse,
204
+ onFinish,
205
+ onError
206
+ } = {}) {
207
+ var _a;
208
+ const completionId = id || `completion-${uniqueId2++}`;
209
+ const key = `${api}|${completionId}`;
210
+ const { data, mutate: originalMutate } = useSWRV2(
211
+ key,
212
+ () => store2[key] || initialCompletion
213
+ );
214
+ const { data: isLoading, mutate: mutateLoading } = useSWRV2(
215
+ `${completionId}-loading`,
216
+ null
217
+ );
218
+ (_a = isLoading.value) != null ? _a : isLoading.value = false;
219
+ const { data: streamData, mutate: mutateStreamData } = useSWRV2(`${completionId}-data`, null);
220
+ data.value || (data.value = initialCompletion);
221
+ const mutate = (data2) => {
222
+ store2[key] = data2;
223
+ return originalMutate();
224
+ };
225
+ const completion = data;
226
+ const error = ref2(void 0);
227
+ let abortController = null;
228
+ async function triggerRequest(prompt, options) {
229
+ var _a2;
230
+ const existingData = (_a2 = streamData.value) != null ? _a2 : [];
231
+ return callCompletionApi({
232
+ api,
233
+ prompt,
234
+ credentials,
235
+ headers: {
236
+ ...headers,
237
+ ...options == null ? void 0 : options.headers
238
+ },
239
+ body: {
240
+ ...unref2(body),
241
+ ...options == null ? void 0 : options.body
242
+ },
243
+ streamMode,
244
+ setCompletion: mutate,
245
+ setLoading: (loading) => mutateLoading(() => loading),
246
+ setError: (err) => {
247
+ error.value = err;
248
+ },
249
+ setAbortController: (controller) => {
250
+ abortController = controller;
251
+ },
252
+ onResponse,
253
+ onFinish,
254
+ onError,
255
+ onData: (data2) => {
256
+ mutateStreamData(() => [...existingData, ...data2 != null ? data2 : []]);
257
+ }
258
+ });
259
+ }
260
+ const complete = async (prompt, options) => {
261
+ return triggerRequest(prompt, options);
262
+ };
263
+ const stop = () => {
264
+ if (abortController) {
265
+ abortController.abort();
266
+ abortController = null;
267
+ }
268
+ };
269
+ const setCompletion = (completion2) => {
270
+ mutate(completion2);
271
+ };
272
+ const input = ref2(initialInput);
273
+ const handleSubmit = (e) => {
274
+ e.preventDefault();
275
+ const inputValue = input.value;
276
+ if (!inputValue)
277
+ return;
278
+ return complete(inputValue);
279
+ };
280
+ return {
281
+ completion,
282
+ complete,
283
+ error,
284
+ stop,
285
+ setCompletion,
286
+ input,
287
+ handleSubmit,
288
+ isLoading,
289
+ data: streamData
290
+ };
291
+ }
292
+ export {
293
+ useChat,
294
+ useCompletion
295
+ };
296
+ //# sourceMappingURL=index.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/use-chat.ts","../src/use-completion.ts"],"sourcesContent":["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":["_a","data","messages","swrv","ref","unref","uniqueId","useSWRV","store","data","_a","completion"]}
package/package.json ADDED
@@ -0,0 +1,71 @@
1
+ {
2
+ "name": "@ai-sdk/vue",
3
+ "version": "0.0.1",
4
+ "license": "Apache-2.0",
5
+ "sideEffects": false,
6
+ "main": "./dist/index.js",
7
+ "module": "./dist/index.mjs",
8
+ "types": "./dist/index.d.ts",
9
+ "exports": {
10
+ "./package.json": "./package.json",
11
+ ".": {
12
+ "types": "./dist/index.d.ts",
13
+ "import": "./dist/index.mjs",
14
+ "require": "./dist/index.js"
15
+ }
16
+ },
17
+ "dependencies": {
18
+ "@ai-sdk/ui-utils": "0.0.1",
19
+ "swrv": "1.0.4"
20
+ },
21
+ "devDependencies": {
22
+ "@testing-library/jest-dom": "^6.4.5",
23
+ "@testing-library/user-event": "^14.5.1",
24
+ "@testing-library/vue": "^8.0.1",
25
+ "@types/node": "^18",
26
+ "@vitejs/plugin-vue": "4.5.0",
27
+ "eslint": "^7.32.0",
28
+ "jsdom": "^24.0.0",
29
+ "msw": "2.0.9",
30
+ "tsup": "^7.2.0",
31
+ "typescript": "5.1.3",
32
+ "@vercel/ai-tsconfig": "0.0.0",
33
+ "eslint-config-vercel-ai": "0.0.0"
34
+ },
35
+ "peerDependencies": {
36
+ "vue": "^3.3.4"
37
+ },
38
+ "peerDependenciesMeta": {
39
+ "vue": {
40
+ "optional": true
41
+ }
42
+ },
43
+ "engines": {
44
+ "node": ">=18"
45
+ },
46
+ "publishConfig": {
47
+ "access": "public"
48
+ },
49
+ "homepage": "https://sdk.vercel.ai/docs",
50
+ "repository": {
51
+ "type": "git",
52
+ "url": "git+https://github.com/vercel/ai.git"
53
+ },
54
+ "bugs": {
55
+ "url": "https://github.com/vercel/ai/issues"
56
+ },
57
+ "keywords": [
58
+ "ai",
59
+ "vue"
60
+ ],
61
+ "scripts": {
62
+ "build": "tsup",
63
+ "clean": "rm -rf dist",
64
+ "dev": "tsup --watch",
65
+ "lint": "eslint \"./**/*.ts*\"",
66
+ "type-check": "tsc --noEmit",
67
+ "prettier-check": "prettier --check \"./**/*.ts*\"",
68
+ "test": "vitest --config vitest.config.js --run",
69
+ "test:watch": "vitest --config vitest.config.js"
70
+ }
71
+ }
@@ -0,0 +1,26 @@
1
+ <script setup lang="ts">
2
+ import { useChat } from './use-chat';
3
+
4
+ const { messages, append, data, error, isLoading } = useChat();
5
+ </script>
6
+
7
+ <template>
8
+ <div class="flex flex-col w-full max-w-md py-24 mx-auto stretch">
9
+ <div data-testid="loading">{{ isLoading?.toString() }}</div>
10
+ <div data-testid="error">{{ error?.toString() }}</div>
11
+ <div data-testid="data">{{ JSON.stringify(data) }}</div>
12
+ <div
13
+ v-for="(m, idx) in messages"
14
+ key="m.id"
15
+ :data-testid="`message-${idx}`"
16
+ >
17
+ {{ m.role === 'user' ? 'User: ' : 'AI: ' }}
18
+ {{ m.content }}
19
+ </div>
20
+
21
+ <button
22
+ data-testid="button"
23
+ @click="append({ role: 'user', content: 'hi' })"
24
+ />
25
+ </div>
26
+ </template>
@@ -0,0 +1,28 @@
1
+ <script setup lang="ts">
2
+ import { useChat } from './use-chat';
3
+
4
+ const { messages, append, data, error, isLoading } = useChat({
5
+ streamMode: 'text',
6
+ });
7
+ </script>
8
+
9
+ <template>
10
+ <div class="flex flex-col w-full max-w-md py-24 mx-auto stretch">
11
+ <div data-testid="loading">{{ isLoading?.toString() }}</div>
12
+ <div data-testid="error">{{ error?.toString() }}</div>
13
+ <div data-testid="data">{{ JSON.stringify(data) }}</div>
14
+ <div
15
+ v-for="(m, idx) in messages"
16
+ key="m.id"
17
+ :data-testid="`message-${idx}`"
18
+ >
19
+ {{ m.role === 'user' ? 'User: ' : 'AI: ' }}
20
+ {{ m.content }}
21
+ </div>
22
+
23
+ <button
24
+ data-testid="button"
25
+ @click="append({ role: 'user', content: 'hi' })"
26
+ />
27
+ </div>
28
+ </template>
@@ -0,0 +1,17 @@
1
+ <script setup lang="ts">
2
+ import { useCompletion } from './use-completion';
3
+
4
+ const { completion, handleSubmit, input, isLoading, error } = useCompletion();
5
+ </script>
6
+
7
+ <template>
8
+ <div class="flex flex-col w-full max-w-md py-24 mx-auto stretch">
9
+ <div data-testid="loading">{{ isLoading?.toString() }}</div>
10
+ <div data-testid="error">{{ error?.toString() }}</div>
11
+ <div data-testid="completion">{{ completion }}</div>
12
+
13
+ <form @submit="handleSubmit">
14
+ <input data-testid="input" v-model="input" />
15
+ </form>
16
+ </div>
17
+ </template>
@@ -0,0 +1,19 @@
1
+ <script setup lang="ts">
2
+ import { useCompletion } from './use-completion';
3
+
4
+ const { completion, handleSubmit, input, isLoading, error } = useCompletion({
5
+ streamMode: 'text',
6
+ });
7
+ </script>
8
+
9
+ <template>
10
+ <div class="flex flex-col w-full max-w-md py-24 mx-auto stretch">
11
+ <div data-testid="loading">{{ isLoading?.toString() }}</div>
12
+ <div data-testid="error">{{ error?.toString() }}</div>
13
+ <div data-testid="completion">{{ completion }}</div>
14
+
15
+ <form @submit="handleSubmit">
16
+ <input data-testid="input" v-model="input" />
17
+ </form>
18
+ </div>
19
+ </template>
package/src/index.ts ADDED
@@ -0,0 +1,2 @@
1
+ export * from './use-chat';
2
+ export * from './use-completion';
@@ -0,0 +1,10 @@
1
+ {
2
+ "main": "./dist/index.js",
3
+ "module": "./dist/index.mjs",
4
+ "types": "./dist/index.d.ts",
5
+ "exports": "./dist/index.mjs",
6
+ "private": true,
7
+ "peerDependencies": {
8
+ "vue": "*"
9
+ }
10
+ }
@@ -0,0 +1,5 @@
1
+ // required for vue testing library
2
+ declare module '*.vue' {
3
+ import Vue from 'vue';
4
+ export default Vue;
5
+ }