@ai-sdk/vue 2.0.39 → 2.0.41
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +14 -0
- package/dist/index.d.mts +44 -2
- package/dist/index.d.ts +44 -2
- package/dist/index.js +135 -2
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +141 -2
- package/dist/index.mjs.map +1 -1
- package/package.json +7 -3
package/CHANGELOG.md
CHANGED
package/dist/index.d.mts
CHANGED
|
@@ -1,6 +1,9 @@
|
|
|
1
|
-
import { CompletionRequestOptions, UseCompletionOptions, UIMessage, AbstractChat, ChatInit } from 'ai';
|
|
1
|
+
import { CompletionRequestOptions, UseCompletionOptions, UIMessage, AbstractChat, ChatInit, Schema, DeepPartial } from 'ai';
|
|
2
2
|
export { UseCompletionOptions } from 'ai';
|
|
3
3
|
import { Ref } from 'vue';
|
|
4
|
+
import { FetchFunction, InferSchema } from '@ai-sdk/provider-utils';
|
|
5
|
+
import * as z3 from 'zod/v3';
|
|
6
|
+
import * as z4 from 'zod/v4';
|
|
4
7
|
|
|
5
8
|
type UseCompletionHelpers = {
|
|
6
9
|
/** The current completion result */
|
|
@@ -42,4 +45,43 @@ declare class Chat<UI_MESSAGE extends UIMessage> extends AbstractChat<UI_MESSAGE
|
|
|
42
45
|
constructor({ messages, ...init }: ChatInit<UI_MESSAGE>);
|
|
43
46
|
}
|
|
44
47
|
|
|
45
|
-
|
|
48
|
+
type Experimental_UseObjectOptions<SCHEMA extends z4.core.$ZodType | z3.Schema | Schema, RESULT> = {
|
|
49
|
+
/** API endpoint that streams JSON chunks matching the schema */
|
|
50
|
+
api: string;
|
|
51
|
+
/** Zod or AI schema that defines the final object shape */
|
|
52
|
+
schema: SCHEMA;
|
|
53
|
+
/** Shared state key. If omitted a random one is generated */
|
|
54
|
+
id?: string;
|
|
55
|
+
/** Initial partial value */
|
|
56
|
+
initialValue?: DeepPartial<RESULT>;
|
|
57
|
+
/** Optional custom fetch implementation */
|
|
58
|
+
fetch?: FetchFunction;
|
|
59
|
+
/** Called when stream ends */
|
|
60
|
+
onFinish?: (event: {
|
|
61
|
+
object: RESULT | undefined;
|
|
62
|
+
error: Error | undefined;
|
|
63
|
+
}) => Promise<void> | void;
|
|
64
|
+
/** Called on error */
|
|
65
|
+
onError?: (error: Error) => void;
|
|
66
|
+
/** Extra request headers */
|
|
67
|
+
headers?: Record<string, string> | Headers;
|
|
68
|
+
/** Request credentials mode. Defaults to 'same-origin' if omitted */
|
|
69
|
+
credentials?: RequestCredentials;
|
|
70
|
+
};
|
|
71
|
+
type Experimental_UseObjectHelpers<RESULT, INPUT> = {
|
|
72
|
+
/** POST the input and start streaming */
|
|
73
|
+
submit: (input: INPUT) => void;
|
|
74
|
+
/** Current partial object, updated as chunks arrive */
|
|
75
|
+
object: Ref<DeepPartial<RESULT> | undefined>;
|
|
76
|
+
/** Latest error if any */
|
|
77
|
+
error: Ref<Error | undefined>;
|
|
78
|
+
/** Loading flag for the in-flight request */
|
|
79
|
+
isLoading: Ref<boolean | undefined>;
|
|
80
|
+
/** Abort the current request. Keeps current partial object. */
|
|
81
|
+
stop: () => void;
|
|
82
|
+
/** Abort and clear all state */
|
|
83
|
+
clear: () => void;
|
|
84
|
+
};
|
|
85
|
+
declare const experimental_useObject: <SCHEMA extends z4.core.$ZodType | z3.Schema | Schema, RESULT = InferSchema<SCHEMA>, INPUT = any>({ api, id, schema, initialValue, fetch, onError, onFinish, headers, credentials, }: Experimental_UseObjectOptions<SCHEMA, RESULT>) => Experimental_UseObjectHelpers<RESULT, INPUT>;
|
|
86
|
+
|
|
87
|
+
export { Chat, Experimental_UseObjectHelpers, Experimental_UseObjectOptions, UseCompletionHelpers, experimental_useObject, useCompletion };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,9 @@
|
|
|
1
|
-
import { CompletionRequestOptions, UseCompletionOptions, UIMessage, AbstractChat, ChatInit } from 'ai';
|
|
1
|
+
import { CompletionRequestOptions, UseCompletionOptions, UIMessage, AbstractChat, ChatInit, Schema, DeepPartial } from 'ai';
|
|
2
2
|
export { UseCompletionOptions } from 'ai';
|
|
3
3
|
import { Ref } from 'vue';
|
|
4
|
+
import { FetchFunction, InferSchema } from '@ai-sdk/provider-utils';
|
|
5
|
+
import * as z3 from 'zod/v3';
|
|
6
|
+
import * as z4 from 'zod/v4';
|
|
4
7
|
|
|
5
8
|
type UseCompletionHelpers = {
|
|
6
9
|
/** The current completion result */
|
|
@@ -42,4 +45,43 @@ declare class Chat<UI_MESSAGE extends UIMessage> extends AbstractChat<UI_MESSAGE
|
|
|
42
45
|
constructor({ messages, ...init }: ChatInit<UI_MESSAGE>);
|
|
43
46
|
}
|
|
44
47
|
|
|
45
|
-
|
|
48
|
+
type Experimental_UseObjectOptions<SCHEMA extends z4.core.$ZodType | z3.Schema | Schema, RESULT> = {
|
|
49
|
+
/** API endpoint that streams JSON chunks matching the schema */
|
|
50
|
+
api: string;
|
|
51
|
+
/** Zod or AI schema that defines the final object shape */
|
|
52
|
+
schema: SCHEMA;
|
|
53
|
+
/** Shared state key. If omitted a random one is generated */
|
|
54
|
+
id?: string;
|
|
55
|
+
/** Initial partial value */
|
|
56
|
+
initialValue?: DeepPartial<RESULT>;
|
|
57
|
+
/** Optional custom fetch implementation */
|
|
58
|
+
fetch?: FetchFunction;
|
|
59
|
+
/** Called when stream ends */
|
|
60
|
+
onFinish?: (event: {
|
|
61
|
+
object: RESULT | undefined;
|
|
62
|
+
error: Error | undefined;
|
|
63
|
+
}) => Promise<void> | void;
|
|
64
|
+
/** Called on error */
|
|
65
|
+
onError?: (error: Error) => void;
|
|
66
|
+
/** Extra request headers */
|
|
67
|
+
headers?: Record<string, string> | Headers;
|
|
68
|
+
/** Request credentials mode. Defaults to 'same-origin' if omitted */
|
|
69
|
+
credentials?: RequestCredentials;
|
|
70
|
+
};
|
|
71
|
+
type Experimental_UseObjectHelpers<RESULT, INPUT> = {
|
|
72
|
+
/** POST the input and start streaming */
|
|
73
|
+
submit: (input: INPUT) => void;
|
|
74
|
+
/** Current partial object, updated as chunks arrive */
|
|
75
|
+
object: Ref<DeepPartial<RESULT> | undefined>;
|
|
76
|
+
/** Latest error if any */
|
|
77
|
+
error: Ref<Error | undefined>;
|
|
78
|
+
/** Loading flag for the in-flight request */
|
|
79
|
+
isLoading: Ref<boolean | undefined>;
|
|
80
|
+
/** Abort the current request. Keeps current partial object. */
|
|
81
|
+
stop: () => void;
|
|
82
|
+
/** Abort and clear all state */
|
|
83
|
+
clear: () => void;
|
|
84
|
+
};
|
|
85
|
+
declare const experimental_useObject: <SCHEMA extends z4.core.$ZodType | z3.Schema | Schema, RESULT = InferSchema<SCHEMA>, INPUT = any>({ api, id, schema, initialValue, fetch, onError, onFinish, headers, credentials, }: Experimental_UseObjectOptions<SCHEMA, RESULT>) => Experimental_UseObjectHelpers<RESULT, INPUT>;
|
|
86
|
+
|
|
87
|
+
export { Chat, Experimental_UseObjectHelpers, Experimental_UseObjectOptions, UseCompletionHelpers, experimental_useObject, useCompletion };
|
package/dist/index.js
CHANGED
|
@@ -31,6 +31,7 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
31
31
|
var src_exports = {};
|
|
32
32
|
__export(src_exports, {
|
|
33
33
|
Chat: () => Chat,
|
|
34
|
+
experimental_useObject: () => experimental_useObject,
|
|
34
35
|
useCompletion: () => useCompletion
|
|
35
36
|
});
|
|
36
37
|
module.exports = __toCommonJS(src_exports);
|
|
@@ -53,7 +54,7 @@ function useCompletion({
|
|
|
53
54
|
streamProtocol,
|
|
54
55
|
onFinish,
|
|
55
56
|
onError,
|
|
56
|
-
fetch
|
|
57
|
+
fetch: fetch2
|
|
57
58
|
} = {}) {
|
|
58
59
|
var _a;
|
|
59
60
|
const completionId = id || `completion-${uniqueId++}`;
|
|
@@ -99,7 +100,7 @@ function useCompletion({
|
|
|
99
100
|
},
|
|
100
101
|
onFinish,
|
|
101
102
|
onError,
|
|
102
|
-
fetch
|
|
103
|
+
fetch: fetch2
|
|
103
104
|
});
|
|
104
105
|
}
|
|
105
106
|
const complete = async (prompt, options) => {
|
|
@@ -179,9 +180,141 @@ var Chat = class extends import_ai2.AbstractChat {
|
|
|
179
180
|
});
|
|
180
181
|
}
|
|
181
182
|
};
|
|
183
|
+
|
|
184
|
+
// src/use-object.ts
|
|
185
|
+
var import_vue3 = require("vue");
|
|
186
|
+
var import_swrv2 = __toESM(require("swrv"));
|
|
187
|
+
var import_provider_utils = require("@ai-sdk/provider-utils");
|
|
188
|
+
var import_ai3 = require("ai");
|
|
189
|
+
var getOriginalFetch = () => fetch;
|
|
190
|
+
var uniqueId2 = 0;
|
|
191
|
+
var useSWRV2 = import_swrv2.default.default || import_swrv2.default;
|
|
192
|
+
var store2 = {};
|
|
193
|
+
var experimental_useObject = function useObject({
|
|
194
|
+
api,
|
|
195
|
+
id,
|
|
196
|
+
schema,
|
|
197
|
+
initialValue,
|
|
198
|
+
fetch: fetch2,
|
|
199
|
+
onError,
|
|
200
|
+
onFinish,
|
|
201
|
+
headers,
|
|
202
|
+
credentials
|
|
203
|
+
}) {
|
|
204
|
+
var _a;
|
|
205
|
+
const completionId = id || `completion-${uniqueId2++}`;
|
|
206
|
+
const key = `${api}|${completionId}`;
|
|
207
|
+
const { data, mutate: originalMutate } = useSWRV2(key, () => key in store2 ? store2[key] : initialValue);
|
|
208
|
+
const { data: isLoading, mutate: mutateLoading } = useSWRV2(
|
|
209
|
+
`${completionId}-loading`,
|
|
210
|
+
null
|
|
211
|
+
);
|
|
212
|
+
(_a = isLoading.value) != null ? _a : isLoading.value = false;
|
|
213
|
+
data.value || (data.value = initialValue);
|
|
214
|
+
const mutateObject = (value) => {
|
|
215
|
+
store2[key] = value;
|
|
216
|
+
return originalMutate();
|
|
217
|
+
};
|
|
218
|
+
const error = (0, import_vue3.ref)(void 0);
|
|
219
|
+
let abortController = null;
|
|
220
|
+
const stop = async () => {
|
|
221
|
+
if (abortController) {
|
|
222
|
+
try {
|
|
223
|
+
abortController.abort();
|
|
224
|
+
} catch (e) {
|
|
225
|
+
} finally {
|
|
226
|
+
abortController = null;
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
await mutateLoading(() => false);
|
|
230
|
+
};
|
|
231
|
+
const clearObject = async () => {
|
|
232
|
+
error.value = void 0;
|
|
233
|
+
await mutateLoading(() => false);
|
|
234
|
+
await mutateObject(void 0);
|
|
235
|
+
data.value = void 0;
|
|
236
|
+
};
|
|
237
|
+
const clear = async () => {
|
|
238
|
+
await stop();
|
|
239
|
+
await clearObject();
|
|
240
|
+
};
|
|
241
|
+
const submit = async (input) => {
|
|
242
|
+
try {
|
|
243
|
+
await clearObject();
|
|
244
|
+
await mutateLoading(() => true);
|
|
245
|
+
abortController = new AbortController();
|
|
246
|
+
const actualFetch = fetch2 != null ? fetch2 : getOriginalFetch();
|
|
247
|
+
const response = await actualFetch(api, {
|
|
248
|
+
method: "POST",
|
|
249
|
+
headers: {
|
|
250
|
+
"Content-Type": "application/json",
|
|
251
|
+
...headers
|
|
252
|
+
},
|
|
253
|
+
credentials: credentials != null ? credentials : "same-origin",
|
|
254
|
+
signal: abortController.signal,
|
|
255
|
+
body: JSON.stringify(input)
|
|
256
|
+
});
|
|
257
|
+
if (!response.ok) {
|
|
258
|
+
throw new Error(
|
|
259
|
+
await response.text() || "Failed to fetch the response."
|
|
260
|
+
);
|
|
261
|
+
}
|
|
262
|
+
if (!response.body) {
|
|
263
|
+
throw new Error("The response body is empty.");
|
|
264
|
+
}
|
|
265
|
+
let accumulatedText = "";
|
|
266
|
+
let latestObject = void 0;
|
|
267
|
+
await response.body.pipeThrough(new TextDecoderStream()).pipeTo(
|
|
268
|
+
new WritableStream({
|
|
269
|
+
async write(chunk) {
|
|
270
|
+
accumulatedText += chunk;
|
|
271
|
+
const { value } = await (0, import_ai3.parsePartialJson)(accumulatedText);
|
|
272
|
+
const currentObject = value;
|
|
273
|
+
if (!(0, import_ai3.isDeepEqualData)(latestObject, currentObject)) {
|
|
274
|
+
latestObject = currentObject;
|
|
275
|
+
await mutateObject(currentObject);
|
|
276
|
+
}
|
|
277
|
+
},
|
|
278
|
+
async close() {
|
|
279
|
+
await mutateLoading(() => false);
|
|
280
|
+
abortController = null;
|
|
281
|
+
if (onFinish) {
|
|
282
|
+
const validationResult = await (0, import_provider_utils.safeValidateTypes)({
|
|
283
|
+
value: latestObject,
|
|
284
|
+
schema: (0, import_ai3.asSchema)(schema)
|
|
285
|
+
});
|
|
286
|
+
onFinish(
|
|
287
|
+
validationResult.success ? {
|
|
288
|
+
object: validationResult.value,
|
|
289
|
+
error: void 0
|
|
290
|
+
} : { object: void 0, error: validationResult.error }
|
|
291
|
+
);
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
})
|
|
295
|
+
);
|
|
296
|
+
} catch (err) {
|
|
297
|
+
if ((0, import_provider_utils.isAbortError)(err))
|
|
298
|
+
return;
|
|
299
|
+
if (onError && err instanceof Error)
|
|
300
|
+
onError(err);
|
|
301
|
+
await mutateLoading(() => false);
|
|
302
|
+
error.value = err instanceof Error ? err : new Error(String(err));
|
|
303
|
+
}
|
|
304
|
+
};
|
|
305
|
+
return {
|
|
306
|
+
submit,
|
|
307
|
+
object: data,
|
|
308
|
+
error,
|
|
309
|
+
isLoading,
|
|
310
|
+
stop,
|
|
311
|
+
clear
|
|
312
|
+
};
|
|
313
|
+
};
|
|
182
314
|
// Annotate the CommonJS export names for ESM import in node:
|
|
183
315
|
0 && (module.exports = {
|
|
184
316
|
Chat,
|
|
317
|
+
experimental_useObject,
|
|
185
318
|
useCompletion
|
|
186
319
|
});
|
|
187
320
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/use-completion.ts","../src/chat.vue.ts"],"sourcesContent":["export * from './use-completion';\nexport { Chat } from './chat.vue';\n","import type { CompletionRequestOptions, UseCompletionOptions } from 'ai';\nimport { callCompletionApi } from 'ai';\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?: CompletionRequestOptions,\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: (event?: { preventDefault?: () => void }) => void;\n /** Whether the API request is in progress */\n isLoading: Ref<boolean | 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 streamProtocol,\n onFinish,\n onError,\n fetch,\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 // 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(\n prompt: string,\n options?: CompletionRequestOptions,\n ) {\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 streamProtocol,\n setCompletion: mutate,\n setLoading: loading => mutateLoading(() => loading),\n setError: err => {\n error.value = err;\n },\n setAbortController: controller => {\n abortController = controller;\n },\n onFinish,\n onError,\n fetch,\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 = (event?: { preventDefault?: () => void }) => {\n event?.preventDefault?.();\n const inputValue = input.value;\n return inputValue ? complete(inputValue) : undefined;\n };\n\n return {\n completion,\n complete,\n error,\n stop,\n setCompletion,\n input,\n handleSubmit,\n isLoading,\n };\n}\n","import {\n AbstractChat,\n ChatInit as BaseChatInit,\n ChatState,\n ChatStatus,\n UIMessage,\n} from 'ai';\nimport { Ref, ref } from 'vue';\n\nclass VueChatState<UI_MESSAGE extends UIMessage>\n implements ChatState<UI_MESSAGE>\n{\n private messagesRef: Ref<UI_MESSAGE[]>;\n private statusRef = ref<ChatStatus>('ready');\n private errorRef = ref<Error | undefined>(undefined);\n\n constructor(messages?: UI_MESSAGE[]) {\n this.messagesRef = ref(messages ?? []) as Ref<UI_MESSAGE[]>;\n }\n\n get messages(): UI_MESSAGE[] {\n return this.messagesRef.value;\n }\n\n set messages(messages: UI_MESSAGE[]) {\n this.messagesRef.value = messages;\n }\n\n get status(): ChatStatus {\n return this.statusRef.value;\n }\n\n set status(status: ChatStatus) {\n this.statusRef.value = status;\n }\n\n get error(): Error | undefined {\n return this.errorRef.value;\n }\n\n set error(error: Error | undefined) {\n this.errorRef.value = error;\n }\n\n pushMessage = (message: UI_MESSAGE) => {\n this.messagesRef.value = [...this.messagesRef.value, message];\n };\n\n popMessage = () => {\n this.messagesRef.value = this.messagesRef.value.slice(0, -1);\n };\n\n replaceMessage = (index: number, message: UI_MESSAGE) => {\n // message is cloned here because vue's deep reactivity shows unexpected behavior, particularly when updating tool invocation parts\n this.messagesRef.value[index] = { ...message };\n };\n\n snapshot = <T>(value: T): T => value;\n}\n\nexport class Chat<\n UI_MESSAGE extends UIMessage,\n> extends AbstractChat<UI_MESSAGE> {\n constructor({ messages, ...init }: BaseChatInit<UI_MESSAGE>) {\n super({\n ...init,\n state: new VueChatState(messages),\n });\n }\n}\n"],"mappings":"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","names":["swrv","data","completion","_a","import_ai","import_vue"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/use-completion.ts","../src/chat.vue.ts","../src/use-object.ts"],"sourcesContent":["export * from './use-completion';\nexport { Chat } from './chat.vue';\nexport * from './use-object';\n","import type { CompletionRequestOptions, UseCompletionOptions } from 'ai';\nimport { callCompletionApi } from 'ai';\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?: CompletionRequestOptions,\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: (event?: { preventDefault?: () => void }) => void;\n /** Whether the API request is in progress */\n isLoading: Ref<boolean | 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 streamProtocol,\n onFinish,\n onError,\n fetch,\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 // 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(\n prompt: string,\n options?: CompletionRequestOptions,\n ) {\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 streamProtocol,\n setCompletion: mutate,\n setLoading: loading => mutateLoading(() => loading),\n setError: err => {\n error.value = err;\n },\n setAbortController: controller => {\n abortController = controller;\n },\n onFinish,\n onError,\n fetch,\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 = (event?: { preventDefault?: () => void }) => {\n event?.preventDefault?.();\n const inputValue = input.value;\n return inputValue ? complete(inputValue) : undefined;\n };\n\n return {\n completion,\n complete,\n error,\n stop,\n setCompletion,\n input,\n handleSubmit,\n isLoading,\n };\n}\n","import {\n AbstractChat,\n ChatInit as BaseChatInit,\n ChatState,\n ChatStatus,\n UIMessage,\n} from 'ai';\nimport { Ref, ref } from 'vue';\n\nclass VueChatState<UI_MESSAGE extends UIMessage>\n implements ChatState<UI_MESSAGE>\n{\n private messagesRef: Ref<UI_MESSAGE[]>;\n private statusRef = ref<ChatStatus>('ready');\n private errorRef = ref<Error | undefined>(undefined);\n\n constructor(messages?: UI_MESSAGE[]) {\n this.messagesRef = ref(messages ?? []) as Ref<UI_MESSAGE[]>;\n }\n\n get messages(): UI_MESSAGE[] {\n return this.messagesRef.value;\n }\n\n set messages(messages: UI_MESSAGE[]) {\n this.messagesRef.value = messages;\n }\n\n get status(): ChatStatus {\n return this.statusRef.value;\n }\n\n set status(status: ChatStatus) {\n this.statusRef.value = status;\n }\n\n get error(): Error | undefined {\n return this.errorRef.value;\n }\n\n set error(error: Error | undefined) {\n this.errorRef.value = error;\n }\n\n pushMessage = (message: UI_MESSAGE) => {\n this.messagesRef.value = [...this.messagesRef.value, message];\n };\n\n popMessage = () => {\n this.messagesRef.value = this.messagesRef.value.slice(0, -1);\n };\n\n replaceMessage = (index: number, message: UI_MESSAGE) => {\n // message is cloned here because vue's deep reactivity shows unexpected behavior, particularly when updating tool invocation parts\n this.messagesRef.value[index] = { ...message };\n };\n\n snapshot = <T>(value: T): T => value;\n}\n\nexport class Chat<\n UI_MESSAGE extends UIMessage,\n> extends AbstractChat<UI_MESSAGE> {\n constructor({ messages, ...init }: BaseChatInit<UI_MESSAGE>) {\n super({\n ...init,\n state: new VueChatState(messages),\n });\n }\n}\n","import { ref, type Ref } from 'vue';\nimport swrv from 'swrv';\nimport {\n isAbortError,\n safeValidateTypes,\n type FetchFunction,\n type InferSchema,\n} from '@ai-sdk/provider-utils';\nimport {\n asSchema,\n type DeepPartial,\n isDeepEqualData,\n parsePartialJson,\n type Schema,\n} from 'ai';\nimport * as z3 from 'zod/v3';\nimport * as z4 from 'zod/v4';\n\n// use function to allow for mocking in tests\nconst getOriginalFetch = () => fetch;\n\nexport type Experimental_UseObjectOptions<\n SCHEMA extends z4.core.$ZodType | z3.Schema | Schema,\n RESULT,\n> = {\n /** API endpoint that streams JSON chunks matching the schema */\n api: string;\n\n /** Zod or AI schema that defines the final object shape */\n schema: SCHEMA;\n\n /** Shared state key. If omitted a random one is generated */\n id?: string;\n\n /** Initial partial value */\n initialValue?: DeepPartial<RESULT>;\n\n /** Optional custom fetch implementation */\n fetch?: FetchFunction;\n\n /** Called when stream ends */\n onFinish?: (event: {\n object: RESULT | undefined;\n error: Error | undefined;\n }) => Promise<void> | void;\n\n /** Called on error */\n onError?: (error: Error) => void;\n\n /** Extra request headers */\n headers?: Record<string, string> | Headers;\n\n /** Request credentials mode. Defaults to 'same-origin' if omitted */\n credentials?: RequestCredentials;\n};\n\nexport type Experimental_UseObjectHelpers<RESULT, INPUT> = {\n /** POST the input and start streaming */\n submit: (input: INPUT) => void;\n\n /** Current partial object, updated as chunks arrive */\n object: Ref<DeepPartial<RESULT> | undefined>;\n\n /** Latest error if any */\n error: Ref<Error | undefined>;\n\n /** Loading flag for the in-flight request */\n isLoading: Ref<boolean | undefined>;\n\n /** Abort the current request. Keeps current partial object. */\n stop: () => void;\n\n /** Abort and clear all state */\n clear: () => void;\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 const experimental_useObject = function useObject<\n SCHEMA extends z4.core.$ZodType | z3.Schema | Schema,\n RESULT = InferSchema<SCHEMA>,\n INPUT = any,\n>({\n api,\n id,\n schema,\n initialValue,\n fetch,\n onError,\n onFinish,\n headers,\n credentials,\n}: Experimental_UseObjectOptions<\n SCHEMA,\n RESULT\n>): Experimental_UseObjectHelpers<RESULT, INPUT> {\n // Generate an unique id for the object if not provided.\n const completionId = id || `completion-${uniqueId++}`;\n\n const key = `${api}|${completionId}`;\n const { data, mutate: originalMutate } = useSWRV<\n DeepPartial<RESULT> | undefined\n >(key, () => (key in store ? store[key] : initialValue));\n\n const { data: isLoading, mutate: mutateLoading } = useSWRV<boolean>(\n `${completionId}-loading`,\n null,\n );\n\n isLoading.value ??= false;\n data.value ||= initialValue as DeepPartial<RESULT> | undefined;\n\n const mutateObject = (value: DeepPartial<RESULT> | undefined) => {\n store[key] = value;\n return originalMutate();\n };\n\n const error = ref<Error | undefined>(undefined);\n let abortController: AbortController | null = null;\n\n const stop = async () => {\n if (abortController) {\n try {\n abortController.abort();\n } catch {\n // ignore\n } finally {\n abortController = null;\n }\n }\n await mutateLoading(() => false);\n };\n\n const clearObject = async () => {\n error.value = undefined;\n await mutateLoading(() => false);\n await mutateObject(undefined);\n // Need to explicitly set the value to undefined to trigger a re-render\n data.value = undefined;\n };\n\n const clear = async () => {\n await stop();\n await clearObject();\n };\n\n const submit = async (input: INPUT) => {\n try {\n await clearObject();\n await mutateLoading(() => true);\n\n abortController = new AbortController();\n\n const actualFetch = fetch ?? getOriginalFetch();\n const response = await actualFetch(api, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n ...(headers as any),\n },\n credentials: credentials ?? 'same-origin',\n signal: abortController.signal,\n body: JSON.stringify(input),\n });\n\n if (!response.ok) {\n throw new Error(\n (await response.text()) || 'Failed to fetch the response.',\n );\n }\n\n if (!response.body) {\n throw new Error('The response body is empty.');\n }\n\n let accumulatedText = '';\n let latestObject: DeepPartial<RESULT> | undefined = undefined;\n\n await response.body.pipeThrough(new TextDecoderStream()).pipeTo(\n new WritableStream<string>({\n async write(chunk) {\n accumulatedText += chunk;\n const { value } = await parsePartialJson(accumulatedText);\n const currentObject = value as DeepPartial<RESULT>;\n if (!isDeepEqualData(latestObject, currentObject)) {\n latestObject = currentObject;\n await mutateObject(currentObject);\n }\n },\n async close() {\n await mutateLoading(() => false);\n abortController = null;\n\n if (onFinish) {\n const validationResult = await safeValidateTypes({\n value: latestObject,\n schema: asSchema(schema),\n });\n\n onFinish(\n validationResult.success\n ? {\n object: validationResult.value as RESULT,\n error: undefined,\n }\n : { object: undefined, error: validationResult.error },\n );\n }\n },\n }),\n );\n } catch (err: unknown) {\n if (isAbortError(err)) return;\n\n if (onError && err instanceof Error) onError(err);\n\n await mutateLoading(() => false);\n error.value = err instanceof Error ? err : new Error(String(err));\n }\n };\n\n return {\n submit,\n object: data,\n error,\n isLoading,\n stop,\n clear,\n };\n};\n"],"mappings":"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","names":["swrv","fetch","data","completion","_a","import_ai","import_vue","import_vue","import_swrv","import_ai","uniqueId","useSWRV","swrv","store","fetch"]}
|
package/dist/index.mjs
CHANGED
|
@@ -16,7 +16,7 @@ function useCompletion({
|
|
|
16
16
|
streamProtocol,
|
|
17
17
|
onFinish,
|
|
18
18
|
onError,
|
|
19
|
-
fetch
|
|
19
|
+
fetch: fetch2
|
|
20
20
|
} = {}) {
|
|
21
21
|
var _a;
|
|
22
22
|
const completionId = id || `completion-${uniqueId++}`;
|
|
@@ -62,7 +62,7 @@ function useCompletion({
|
|
|
62
62
|
},
|
|
63
63
|
onFinish,
|
|
64
64
|
onError,
|
|
65
|
-
fetch
|
|
65
|
+
fetch: fetch2
|
|
66
66
|
});
|
|
67
67
|
}
|
|
68
68
|
const complete = async (prompt, options) => {
|
|
@@ -144,8 +144,147 @@ var Chat = class extends AbstractChat {
|
|
|
144
144
|
});
|
|
145
145
|
}
|
|
146
146
|
};
|
|
147
|
+
|
|
148
|
+
// src/use-object.ts
|
|
149
|
+
import { ref as ref3 } from "vue";
|
|
150
|
+
import swrv2 from "swrv";
|
|
151
|
+
import {
|
|
152
|
+
isAbortError,
|
|
153
|
+
safeValidateTypes
|
|
154
|
+
} from "@ai-sdk/provider-utils";
|
|
155
|
+
import {
|
|
156
|
+
asSchema,
|
|
157
|
+
isDeepEqualData,
|
|
158
|
+
parsePartialJson
|
|
159
|
+
} from "ai";
|
|
160
|
+
var getOriginalFetch = () => fetch;
|
|
161
|
+
var uniqueId2 = 0;
|
|
162
|
+
var useSWRV2 = swrv2.default || swrv2;
|
|
163
|
+
var store2 = {};
|
|
164
|
+
var experimental_useObject = function useObject({
|
|
165
|
+
api,
|
|
166
|
+
id,
|
|
167
|
+
schema,
|
|
168
|
+
initialValue,
|
|
169
|
+
fetch: fetch2,
|
|
170
|
+
onError,
|
|
171
|
+
onFinish,
|
|
172
|
+
headers,
|
|
173
|
+
credentials
|
|
174
|
+
}) {
|
|
175
|
+
var _a;
|
|
176
|
+
const completionId = id || `completion-${uniqueId2++}`;
|
|
177
|
+
const key = `${api}|${completionId}`;
|
|
178
|
+
const { data, mutate: originalMutate } = useSWRV2(key, () => key in store2 ? store2[key] : initialValue);
|
|
179
|
+
const { data: isLoading, mutate: mutateLoading } = useSWRV2(
|
|
180
|
+
`${completionId}-loading`,
|
|
181
|
+
null
|
|
182
|
+
);
|
|
183
|
+
(_a = isLoading.value) != null ? _a : isLoading.value = false;
|
|
184
|
+
data.value || (data.value = initialValue);
|
|
185
|
+
const mutateObject = (value) => {
|
|
186
|
+
store2[key] = value;
|
|
187
|
+
return originalMutate();
|
|
188
|
+
};
|
|
189
|
+
const error = ref3(void 0);
|
|
190
|
+
let abortController = null;
|
|
191
|
+
const stop = async () => {
|
|
192
|
+
if (abortController) {
|
|
193
|
+
try {
|
|
194
|
+
abortController.abort();
|
|
195
|
+
} catch (e) {
|
|
196
|
+
} finally {
|
|
197
|
+
abortController = null;
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
await mutateLoading(() => false);
|
|
201
|
+
};
|
|
202
|
+
const clearObject = async () => {
|
|
203
|
+
error.value = void 0;
|
|
204
|
+
await mutateLoading(() => false);
|
|
205
|
+
await mutateObject(void 0);
|
|
206
|
+
data.value = void 0;
|
|
207
|
+
};
|
|
208
|
+
const clear = async () => {
|
|
209
|
+
await stop();
|
|
210
|
+
await clearObject();
|
|
211
|
+
};
|
|
212
|
+
const submit = async (input) => {
|
|
213
|
+
try {
|
|
214
|
+
await clearObject();
|
|
215
|
+
await mutateLoading(() => true);
|
|
216
|
+
abortController = new AbortController();
|
|
217
|
+
const actualFetch = fetch2 != null ? fetch2 : getOriginalFetch();
|
|
218
|
+
const response = await actualFetch(api, {
|
|
219
|
+
method: "POST",
|
|
220
|
+
headers: {
|
|
221
|
+
"Content-Type": "application/json",
|
|
222
|
+
...headers
|
|
223
|
+
},
|
|
224
|
+
credentials: credentials != null ? credentials : "same-origin",
|
|
225
|
+
signal: abortController.signal,
|
|
226
|
+
body: JSON.stringify(input)
|
|
227
|
+
});
|
|
228
|
+
if (!response.ok) {
|
|
229
|
+
throw new Error(
|
|
230
|
+
await response.text() || "Failed to fetch the response."
|
|
231
|
+
);
|
|
232
|
+
}
|
|
233
|
+
if (!response.body) {
|
|
234
|
+
throw new Error("The response body is empty.");
|
|
235
|
+
}
|
|
236
|
+
let accumulatedText = "";
|
|
237
|
+
let latestObject = void 0;
|
|
238
|
+
await response.body.pipeThrough(new TextDecoderStream()).pipeTo(
|
|
239
|
+
new WritableStream({
|
|
240
|
+
async write(chunk) {
|
|
241
|
+
accumulatedText += chunk;
|
|
242
|
+
const { value } = await parsePartialJson(accumulatedText);
|
|
243
|
+
const currentObject = value;
|
|
244
|
+
if (!isDeepEqualData(latestObject, currentObject)) {
|
|
245
|
+
latestObject = currentObject;
|
|
246
|
+
await mutateObject(currentObject);
|
|
247
|
+
}
|
|
248
|
+
},
|
|
249
|
+
async close() {
|
|
250
|
+
await mutateLoading(() => false);
|
|
251
|
+
abortController = null;
|
|
252
|
+
if (onFinish) {
|
|
253
|
+
const validationResult = await safeValidateTypes({
|
|
254
|
+
value: latestObject,
|
|
255
|
+
schema: asSchema(schema)
|
|
256
|
+
});
|
|
257
|
+
onFinish(
|
|
258
|
+
validationResult.success ? {
|
|
259
|
+
object: validationResult.value,
|
|
260
|
+
error: void 0
|
|
261
|
+
} : { object: void 0, error: validationResult.error }
|
|
262
|
+
);
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
})
|
|
266
|
+
);
|
|
267
|
+
} catch (err) {
|
|
268
|
+
if (isAbortError(err))
|
|
269
|
+
return;
|
|
270
|
+
if (onError && err instanceof Error)
|
|
271
|
+
onError(err);
|
|
272
|
+
await mutateLoading(() => false);
|
|
273
|
+
error.value = err instanceof Error ? err : new Error(String(err));
|
|
274
|
+
}
|
|
275
|
+
};
|
|
276
|
+
return {
|
|
277
|
+
submit,
|
|
278
|
+
object: data,
|
|
279
|
+
error,
|
|
280
|
+
isLoading,
|
|
281
|
+
stop,
|
|
282
|
+
clear
|
|
283
|
+
};
|
|
284
|
+
};
|
|
147
285
|
export {
|
|
148
286
|
Chat,
|
|
287
|
+
experimental_useObject,
|
|
149
288
|
useCompletion
|
|
150
289
|
};
|
|
151
290
|
//# sourceMappingURL=index.mjs.map
|
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/use-completion.ts","../src/chat.vue.ts"],"sourcesContent":["import type { CompletionRequestOptions, UseCompletionOptions } from 'ai';\nimport { callCompletionApi } from 'ai';\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?: CompletionRequestOptions,\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: (event?: { preventDefault?: () => void }) => void;\n /** Whether the API request is in progress */\n isLoading: Ref<boolean | 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 streamProtocol,\n onFinish,\n onError,\n fetch,\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 // 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(\n prompt: string,\n options?: CompletionRequestOptions,\n ) {\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 streamProtocol,\n setCompletion: mutate,\n setLoading: loading => mutateLoading(() => loading),\n setError: err => {\n error.value = err;\n },\n setAbortController: controller => {\n abortController = controller;\n },\n onFinish,\n onError,\n fetch,\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 = (event?: { preventDefault?: () => void }) => {\n event?.preventDefault?.();\n const inputValue = input.value;\n return inputValue ? complete(inputValue) : undefined;\n };\n\n return {\n completion,\n complete,\n error,\n stop,\n setCompletion,\n input,\n handleSubmit,\n isLoading,\n };\n}\n","import {\n AbstractChat,\n ChatInit as BaseChatInit,\n ChatState,\n ChatStatus,\n UIMessage,\n} from 'ai';\nimport { Ref, ref } from 'vue';\n\nclass VueChatState<UI_MESSAGE extends UIMessage>\n implements ChatState<UI_MESSAGE>\n{\n private messagesRef: Ref<UI_MESSAGE[]>;\n private statusRef = ref<ChatStatus>('ready');\n private errorRef = ref<Error | undefined>(undefined);\n\n constructor(messages?: UI_MESSAGE[]) {\n this.messagesRef = ref(messages ?? []) as Ref<UI_MESSAGE[]>;\n }\n\n get messages(): UI_MESSAGE[] {\n return this.messagesRef.value;\n }\n\n set messages(messages: UI_MESSAGE[]) {\n this.messagesRef.value = messages;\n }\n\n get status(): ChatStatus {\n return this.statusRef.value;\n }\n\n set status(status: ChatStatus) {\n this.statusRef.value = status;\n }\n\n get error(): Error | undefined {\n return this.errorRef.value;\n }\n\n set error(error: Error | undefined) {\n this.errorRef.value = error;\n }\n\n pushMessage = (message: UI_MESSAGE) => {\n this.messagesRef.value = [...this.messagesRef.value, message];\n };\n\n popMessage = () => {\n this.messagesRef.value = this.messagesRef.value.slice(0, -1);\n };\n\n replaceMessage = (index: number, message: UI_MESSAGE) => {\n // message is cloned here because vue's deep reactivity shows unexpected behavior, particularly when updating tool invocation parts\n this.messagesRef.value[index] = { ...message };\n };\n\n snapshot = <T>(value: T): T => value;\n}\n\nexport class Chat<\n UI_MESSAGE extends UIMessage,\n> extends AbstractChat<UI_MESSAGE> {\n constructor({ messages, ...init }: BaseChatInit<UI_MESSAGE>) {\n super({\n ...init,\n state: new VueChatState(messages),\n });\n }\n}\n"],"mappings":"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","names":["data","completion","_a","ref"]}
|
|
1
|
+
{"version":3,"sources":["../src/use-completion.ts","../src/chat.vue.ts","../src/use-object.ts"],"sourcesContent":["import type { CompletionRequestOptions, UseCompletionOptions } from 'ai';\nimport { callCompletionApi } from 'ai';\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?: CompletionRequestOptions,\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: (event?: { preventDefault?: () => void }) => void;\n /** Whether the API request is in progress */\n isLoading: Ref<boolean | 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 streamProtocol,\n onFinish,\n onError,\n fetch,\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 // 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(\n prompt: string,\n options?: CompletionRequestOptions,\n ) {\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 streamProtocol,\n setCompletion: mutate,\n setLoading: loading => mutateLoading(() => loading),\n setError: err => {\n error.value = err;\n },\n setAbortController: controller => {\n abortController = controller;\n },\n onFinish,\n onError,\n fetch,\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 = (event?: { preventDefault?: () => void }) => {\n event?.preventDefault?.();\n const inputValue = input.value;\n return inputValue ? complete(inputValue) : undefined;\n };\n\n return {\n completion,\n complete,\n error,\n stop,\n setCompletion,\n input,\n handleSubmit,\n isLoading,\n };\n}\n","import {\n AbstractChat,\n ChatInit as BaseChatInit,\n ChatState,\n ChatStatus,\n UIMessage,\n} from 'ai';\nimport { Ref, ref } from 'vue';\n\nclass VueChatState<UI_MESSAGE extends UIMessage>\n implements ChatState<UI_MESSAGE>\n{\n private messagesRef: Ref<UI_MESSAGE[]>;\n private statusRef = ref<ChatStatus>('ready');\n private errorRef = ref<Error | undefined>(undefined);\n\n constructor(messages?: UI_MESSAGE[]) {\n this.messagesRef = ref(messages ?? []) as Ref<UI_MESSAGE[]>;\n }\n\n get messages(): UI_MESSAGE[] {\n return this.messagesRef.value;\n }\n\n set messages(messages: UI_MESSAGE[]) {\n this.messagesRef.value = messages;\n }\n\n get status(): ChatStatus {\n return this.statusRef.value;\n }\n\n set status(status: ChatStatus) {\n this.statusRef.value = status;\n }\n\n get error(): Error | undefined {\n return this.errorRef.value;\n }\n\n set error(error: Error | undefined) {\n this.errorRef.value = error;\n }\n\n pushMessage = (message: UI_MESSAGE) => {\n this.messagesRef.value = [...this.messagesRef.value, message];\n };\n\n popMessage = () => {\n this.messagesRef.value = this.messagesRef.value.slice(0, -1);\n };\n\n replaceMessage = (index: number, message: UI_MESSAGE) => {\n // message is cloned here because vue's deep reactivity shows unexpected behavior, particularly when updating tool invocation parts\n this.messagesRef.value[index] = { ...message };\n };\n\n snapshot = <T>(value: T): T => value;\n}\n\nexport class Chat<\n UI_MESSAGE extends UIMessage,\n> extends AbstractChat<UI_MESSAGE> {\n constructor({ messages, ...init }: BaseChatInit<UI_MESSAGE>) {\n super({\n ...init,\n state: new VueChatState(messages),\n });\n }\n}\n","import { ref, type Ref } from 'vue';\nimport swrv from 'swrv';\nimport {\n isAbortError,\n safeValidateTypes,\n type FetchFunction,\n type InferSchema,\n} from '@ai-sdk/provider-utils';\nimport {\n asSchema,\n type DeepPartial,\n isDeepEqualData,\n parsePartialJson,\n type Schema,\n} from 'ai';\nimport * as z3 from 'zod/v3';\nimport * as z4 from 'zod/v4';\n\n// use function to allow for mocking in tests\nconst getOriginalFetch = () => fetch;\n\nexport type Experimental_UseObjectOptions<\n SCHEMA extends z4.core.$ZodType | z3.Schema | Schema,\n RESULT,\n> = {\n /** API endpoint that streams JSON chunks matching the schema */\n api: string;\n\n /** Zod or AI schema that defines the final object shape */\n schema: SCHEMA;\n\n /** Shared state key. If omitted a random one is generated */\n id?: string;\n\n /** Initial partial value */\n initialValue?: DeepPartial<RESULT>;\n\n /** Optional custom fetch implementation */\n fetch?: FetchFunction;\n\n /** Called when stream ends */\n onFinish?: (event: {\n object: RESULT | undefined;\n error: Error | undefined;\n }) => Promise<void> | void;\n\n /** Called on error */\n onError?: (error: Error) => void;\n\n /** Extra request headers */\n headers?: Record<string, string> | Headers;\n\n /** Request credentials mode. Defaults to 'same-origin' if omitted */\n credentials?: RequestCredentials;\n};\n\nexport type Experimental_UseObjectHelpers<RESULT, INPUT> = {\n /** POST the input and start streaming */\n submit: (input: INPUT) => void;\n\n /** Current partial object, updated as chunks arrive */\n object: Ref<DeepPartial<RESULT> | undefined>;\n\n /** Latest error if any */\n error: Ref<Error | undefined>;\n\n /** Loading flag for the in-flight request */\n isLoading: Ref<boolean | undefined>;\n\n /** Abort the current request. Keeps current partial object. */\n stop: () => void;\n\n /** Abort and clear all state */\n clear: () => void;\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 const experimental_useObject = function useObject<\n SCHEMA extends z4.core.$ZodType | z3.Schema | Schema,\n RESULT = InferSchema<SCHEMA>,\n INPUT = any,\n>({\n api,\n id,\n schema,\n initialValue,\n fetch,\n onError,\n onFinish,\n headers,\n credentials,\n}: Experimental_UseObjectOptions<\n SCHEMA,\n RESULT\n>): Experimental_UseObjectHelpers<RESULT, INPUT> {\n // Generate an unique id for the object if not provided.\n const completionId = id || `completion-${uniqueId++}`;\n\n const key = `${api}|${completionId}`;\n const { data, mutate: originalMutate } = useSWRV<\n DeepPartial<RESULT> | undefined\n >(key, () => (key in store ? store[key] : initialValue));\n\n const { data: isLoading, mutate: mutateLoading } = useSWRV<boolean>(\n `${completionId}-loading`,\n null,\n );\n\n isLoading.value ??= false;\n data.value ||= initialValue as DeepPartial<RESULT> | undefined;\n\n const mutateObject = (value: DeepPartial<RESULT> | undefined) => {\n store[key] = value;\n return originalMutate();\n };\n\n const error = ref<Error | undefined>(undefined);\n let abortController: AbortController | null = null;\n\n const stop = async () => {\n if (abortController) {\n try {\n abortController.abort();\n } catch {\n // ignore\n } finally {\n abortController = null;\n }\n }\n await mutateLoading(() => false);\n };\n\n const clearObject = async () => {\n error.value = undefined;\n await mutateLoading(() => false);\n await mutateObject(undefined);\n // Need to explicitly set the value to undefined to trigger a re-render\n data.value = undefined;\n };\n\n const clear = async () => {\n await stop();\n await clearObject();\n };\n\n const submit = async (input: INPUT) => {\n try {\n await clearObject();\n await mutateLoading(() => true);\n\n abortController = new AbortController();\n\n const actualFetch = fetch ?? getOriginalFetch();\n const response = await actualFetch(api, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n ...(headers as any),\n },\n credentials: credentials ?? 'same-origin',\n signal: abortController.signal,\n body: JSON.stringify(input),\n });\n\n if (!response.ok) {\n throw new Error(\n (await response.text()) || 'Failed to fetch the response.',\n );\n }\n\n if (!response.body) {\n throw new Error('The response body is empty.');\n }\n\n let accumulatedText = '';\n let latestObject: DeepPartial<RESULT> | undefined = undefined;\n\n await response.body.pipeThrough(new TextDecoderStream()).pipeTo(\n new WritableStream<string>({\n async write(chunk) {\n accumulatedText += chunk;\n const { value } = await parsePartialJson(accumulatedText);\n const currentObject = value as DeepPartial<RESULT>;\n if (!isDeepEqualData(latestObject, currentObject)) {\n latestObject = currentObject;\n await mutateObject(currentObject);\n }\n },\n async close() {\n await mutateLoading(() => false);\n abortController = null;\n\n if (onFinish) {\n const validationResult = await safeValidateTypes({\n value: latestObject,\n schema: asSchema(schema),\n });\n\n onFinish(\n validationResult.success\n ? {\n object: validationResult.value as RESULT,\n error: undefined,\n }\n : { object: undefined, error: validationResult.error },\n );\n }\n },\n }),\n );\n } catch (err: unknown) {\n if (isAbortError(err)) return;\n\n if (onError && err instanceof Error) onError(err);\n\n await mutateLoading(() => false);\n error.value = err instanceof Error ? err : new Error(String(err));\n }\n };\n\n return {\n submit,\n object: data,\n error,\n isLoading,\n stop,\n clear,\n };\n};\n"],"mappings":"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","names":["fetch","data","completion","_a","ref","ref","swrv","uniqueId","useSWRV","store","fetch"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ai-sdk/vue",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.41",
|
|
4
4
|
"license": "Apache-2.0",
|
|
5
5
|
"sideEffects": false,
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
],
|
|
21
21
|
"dependencies": {
|
|
22
22
|
"swrv": "^1.0.4",
|
|
23
|
-
"ai": "5.0.
|
|
23
|
+
"ai": "5.0.41",
|
|
24
24
|
"@ai-sdk/provider-utils": "3.0.8"
|
|
25
25
|
},
|
|
26
26
|
"devDependencies": {
|
|
@@ -39,11 +39,15 @@
|
|
|
39
39
|
"eslint-config-vercel-ai": "0.0.0"
|
|
40
40
|
},
|
|
41
41
|
"peerDependencies": {
|
|
42
|
-
"vue": "^3.3.4"
|
|
42
|
+
"vue": "^3.3.4",
|
|
43
|
+
"zod": "^3.25.76 || ^4"
|
|
43
44
|
},
|
|
44
45
|
"peerDependenciesMeta": {
|
|
45
46
|
"vue": {
|
|
46
47
|
"optional": true
|
|
48
|
+
},
|
|
49
|
+
"zod": {
|
|
50
|
+
"optional": true
|
|
47
51
|
}
|
|
48
52
|
},
|
|
49
53
|
"engines": {
|