@ai-sdk/vue 4.0.17 → 4.0.18
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 +9 -0
- package/dist/index.d.ts +54 -41
- package/dist/index.js +156 -152
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
- package/src/TestUseObjectComponent.vue +11 -12
- package/src/TestUseObjectCustomTransportComponent.vue +10 -11
- package/src/index.ts +32 -0
- package/src/use-object.ts +5 -11
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,14 @@
|
|
|
1
1
|
# @ai-sdk/vue
|
|
2
2
|
|
|
3
|
+
## 4.0.18
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- 0363440: Promote `useObject` (React, Vue) and `StructuredObject` (Svelte) to stable exports, with deprecated experimental aliases for backwards compatibility.
|
|
8
|
+
- Updated dependencies [ac306ed]
|
|
9
|
+
- @ai-sdk/provider-utils@5.0.6
|
|
10
|
+
- ai@7.0.18
|
|
11
|
+
|
|
3
12
|
## 4.0.17
|
|
4
13
|
|
|
5
14
|
### Patch Changes
|
package/dist/index.d.ts
CHANGED
|
@@ -1,7 +1,46 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { FetchFunction, FlexibleSchema as FlexibleSchema$1 } from '@ai-sdk/provider-utils';
|
|
2
|
+
import { FlexibleSchema, DeepPartial, InferSchema, CompletionRequestOptions, UseCompletionOptions, UIMessage, AbstractChat, ChatInit, ChatStatus } from 'ai';
|
|
2
3
|
export { UseCompletionOptions } from 'ai';
|
|
3
4
|
import { Ref, ComputedRef, ShallowRef, MaybeRefOrGetter } from 'vue';
|
|
4
|
-
|
|
5
|
+
|
|
6
|
+
type UseObjectOptions<SCHEMA extends FlexibleSchema, RESULT> = {
|
|
7
|
+
/** API endpoint that streams JSON chunks matching the schema */
|
|
8
|
+
api: string;
|
|
9
|
+
/** Schema that defines the final object shape */
|
|
10
|
+
schema: SCHEMA;
|
|
11
|
+
/** Shared state key. If omitted a random one is generated */
|
|
12
|
+
id?: string;
|
|
13
|
+
/** Initial partial value */
|
|
14
|
+
initialValue?: DeepPartial<RESULT>;
|
|
15
|
+
/** Optional custom fetch implementation */
|
|
16
|
+
fetch?: FetchFunction;
|
|
17
|
+
/** Called when stream ends */
|
|
18
|
+
onFinish?: (event: {
|
|
19
|
+
object: RESULT | undefined;
|
|
20
|
+
error: Error | undefined;
|
|
21
|
+
}) => Promise<void> | void;
|
|
22
|
+
/** Called on error */
|
|
23
|
+
onError?: (error: Error) => void;
|
|
24
|
+
/** Extra request headers */
|
|
25
|
+
headers?: Record<string, string> | Headers;
|
|
26
|
+
/** Request credentials mode. Defaults to 'same-origin' if omitted */
|
|
27
|
+
credentials?: RequestCredentials;
|
|
28
|
+
};
|
|
29
|
+
type UseObjectHelpers<RESULT, INPUT> = {
|
|
30
|
+
/** POST the input and start streaming */
|
|
31
|
+
submit: (input: INPUT) => void;
|
|
32
|
+
/** Current partial object, updated as chunks arrive */
|
|
33
|
+
object: Ref<DeepPartial<RESULT> | undefined>;
|
|
34
|
+
/** Latest error if any */
|
|
35
|
+
error: Ref<Error | undefined>;
|
|
36
|
+
/** Loading flag for the in-flight request */
|
|
37
|
+
isLoading: Ref<boolean | undefined>;
|
|
38
|
+
/** Abort the current request. Keeps current partial object. */
|
|
39
|
+
stop: () => void;
|
|
40
|
+
/** Abort and clear all state */
|
|
41
|
+
clear: () => void;
|
|
42
|
+
};
|
|
43
|
+
declare function useObject<SCHEMA extends FlexibleSchema, RESULT = InferSchema<SCHEMA>, INPUT = any>({ api, id, schema, initialValue, fetch, onError, onFinish, headers, credentials, }: UseObjectOptions<SCHEMA, RESULT>): UseObjectHelpers<RESULT, INPUT>;
|
|
5
44
|
|
|
6
45
|
type UseCompletionHelpers = {
|
|
7
46
|
/** The current completion result */
|
|
@@ -87,43 +126,17 @@ interface UseChatHelpers<UI_MESSAGE extends UIMessage> extends Pick<AbstractChat
|
|
|
87
126
|
*/
|
|
88
127
|
declare function useChat<UI_MESSAGE extends UIMessage = UIMessage>(init?: MaybeRefOrGetter<ChatInit<UI_MESSAGE>>): UseChatHelpers<UI_MESSAGE>;
|
|
89
128
|
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
onFinish?: (event: {
|
|
103
|
-
object: RESULT | undefined;
|
|
104
|
-
error: Error | undefined;
|
|
105
|
-
}) => Promise<void> | void;
|
|
106
|
-
/** Called on error */
|
|
107
|
-
onError?: (error: Error) => void;
|
|
108
|
-
/** Extra request headers */
|
|
109
|
-
headers?: Record<string, string> | Headers;
|
|
110
|
-
/** Request credentials mode. Defaults to 'same-origin' if omitted */
|
|
111
|
-
credentials?: RequestCredentials;
|
|
112
|
-
};
|
|
113
|
-
type Experimental_UseObjectHelpers<RESULT, INPUT> = {
|
|
114
|
-
/** POST the input and start streaming */
|
|
115
|
-
submit: (input: INPUT) => void;
|
|
116
|
-
/** Current partial object, updated as chunks arrive */
|
|
117
|
-
object: Ref<DeepPartial<RESULT> | undefined>;
|
|
118
|
-
/** Latest error if any */
|
|
119
|
-
error: Ref<Error | undefined>;
|
|
120
|
-
/** Loading flag for the in-flight request */
|
|
121
|
-
isLoading: Ref<boolean | undefined>;
|
|
122
|
-
/** Abort the current request. Keeps current partial object. */
|
|
123
|
-
stop: () => void;
|
|
124
|
-
/** Abort and clear all state */
|
|
125
|
-
clear: () => void;
|
|
126
|
-
};
|
|
127
|
-
declare const experimental_useObject: <SCHEMA extends FlexibleSchema, RESULT = InferSchema<SCHEMA>, INPUT = any>({ api, id, schema, initialValue, fetch, onError, onFinish, headers, credentials, }: Experimental_UseObjectOptions<SCHEMA, RESULT>) => Experimental_UseObjectHelpers<RESULT, INPUT>;
|
|
129
|
+
/**
|
|
130
|
+
* @deprecated Use `useObject` instead.
|
|
131
|
+
*/
|
|
132
|
+
declare const experimental_useObject: typeof useObject;
|
|
133
|
+
/**
|
|
134
|
+
* @deprecated Use `UseObjectOptions` instead.
|
|
135
|
+
*/
|
|
136
|
+
type Experimental_UseObjectOptions<SCHEMA extends FlexibleSchema$1, RESULT> = UseObjectOptions<SCHEMA, RESULT>;
|
|
137
|
+
/**
|
|
138
|
+
* @deprecated Use `UseObjectHelpers` instead.
|
|
139
|
+
*/
|
|
140
|
+
type Experimental_UseObjectHelpers<RESULT, INPUT> = UseObjectHelpers<RESULT, INPUT>;
|
|
128
141
|
|
|
129
|
-
export { Chat, Experimental_UseObjectHelpers, Experimental_UseObjectOptions, UseChatHelpers, UseCompletionHelpers, experimental_useObject, useChat, useCompletion };
|
|
142
|
+
export { Chat, Experimental_UseObjectHelpers, Experimental_UseObjectOptions, UseChatHelpers, UseCompletionHelpers, UseObjectHelpers, UseObjectOptions, experimental_useObject, useChat, useCompletion, useObject };
|
package/dist/index.js
CHANGED
|
@@ -1,12 +1,150 @@
|
|
|
1
|
-
// src/use-
|
|
1
|
+
// src/use-object.ts
|
|
2
2
|
import {
|
|
3
|
-
|
|
3
|
+
isAbortError,
|
|
4
|
+
safeValidateTypes
|
|
5
|
+
} from "@ai-sdk/provider-utils";
|
|
6
|
+
import {
|
|
7
|
+
asSchema,
|
|
8
|
+
isDeepEqualData,
|
|
9
|
+
parsePartialJson
|
|
4
10
|
} from "ai";
|
|
5
11
|
import swrv from "swrv";
|
|
6
|
-
import { ref
|
|
12
|
+
import { ref } from "vue";
|
|
13
|
+
var getOriginalFetch = () => fetch;
|
|
7
14
|
var uniqueId = 0;
|
|
8
15
|
var useSWRV = swrv.default || swrv;
|
|
9
16
|
var store = {};
|
|
17
|
+
function useObject({
|
|
18
|
+
api,
|
|
19
|
+
id,
|
|
20
|
+
schema,
|
|
21
|
+
initialValue,
|
|
22
|
+
fetch: fetch2,
|
|
23
|
+
onError,
|
|
24
|
+
onFinish,
|
|
25
|
+
headers,
|
|
26
|
+
credentials
|
|
27
|
+
}) {
|
|
28
|
+
var _a;
|
|
29
|
+
const completionId = id || `completion-${uniqueId++}`;
|
|
30
|
+
const key = `${api}|${completionId}`;
|
|
31
|
+
const { data, mutate: originalMutate } = useSWRV(key, () => key in store ? store[key] : initialValue);
|
|
32
|
+
const { data: isLoading, mutate: mutateLoading } = useSWRV(
|
|
33
|
+
`${completionId}-loading`,
|
|
34
|
+
null
|
|
35
|
+
);
|
|
36
|
+
(_a = isLoading.value) != null ? _a : isLoading.value = false;
|
|
37
|
+
data.value || (data.value = initialValue);
|
|
38
|
+
const mutateObject = (value) => {
|
|
39
|
+
store[key] = value;
|
|
40
|
+
return originalMutate();
|
|
41
|
+
};
|
|
42
|
+
const error = ref(void 0);
|
|
43
|
+
let abortController = null;
|
|
44
|
+
const stop = async () => {
|
|
45
|
+
if (abortController) {
|
|
46
|
+
try {
|
|
47
|
+
abortController.abort();
|
|
48
|
+
} catch (e) {
|
|
49
|
+
} finally {
|
|
50
|
+
abortController = null;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
await mutateLoading(() => false);
|
|
54
|
+
};
|
|
55
|
+
const clearObject = async () => {
|
|
56
|
+
error.value = void 0;
|
|
57
|
+
await mutateLoading(() => false);
|
|
58
|
+
await mutateObject(void 0);
|
|
59
|
+
data.value = void 0;
|
|
60
|
+
};
|
|
61
|
+
const clear = async () => {
|
|
62
|
+
await stop();
|
|
63
|
+
await clearObject();
|
|
64
|
+
};
|
|
65
|
+
const submit = async (input) => {
|
|
66
|
+
try {
|
|
67
|
+
await clearObject();
|
|
68
|
+
await mutateLoading(() => true);
|
|
69
|
+
abortController = new AbortController();
|
|
70
|
+
const actualFetch = fetch2 != null ? fetch2 : getOriginalFetch();
|
|
71
|
+
const response = await actualFetch(api, {
|
|
72
|
+
method: "POST",
|
|
73
|
+
headers: {
|
|
74
|
+
"Content-Type": "application/json",
|
|
75
|
+
...headers
|
|
76
|
+
},
|
|
77
|
+
credentials: credentials != null ? credentials : "same-origin",
|
|
78
|
+
signal: abortController.signal,
|
|
79
|
+
body: JSON.stringify(input)
|
|
80
|
+
});
|
|
81
|
+
if (!response.ok) {
|
|
82
|
+
throw new Error(
|
|
83
|
+
await response.text() || "Failed to fetch the response."
|
|
84
|
+
);
|
|
85
|
+
}
|
|
86
|
+
if (!response.body) {
|
|
87
|
+
throw new Error("The response body is empty.");
|
|
88
|
+
}
|
|
89
|
+
let accumulatedText = "";
|
|
90
|
+
let latestObject = void 0;
|
|
91
|
+
await response.body.pipeThrough(new TextDecoderStream()).pipeTo(
|
|
92
|
+
new WritableStream({
|
|
93
|
+
async write(chunk) {
|
|
94
|
+
accumulatedText += chunk;
|
|
95
|
+
const { value } = await parsePartialJson(accumulatedText);
|
|
96
|
+
const currentObject = value;
|
|
97
|
+
if (!isDeepEqualData(latestObject, currentObject)) {
|
|
98
|
+
latestObject = currentObject;
|
|
99
|
+
await mutateObject(currentObject);
|
|
100
|
+
}
|
|
101
|
+
},
|
|
102
|
+
async close() {
|
|
103
|
+
await mutateLoading(() => false);
|
|
104
|
+
abortController = null;
|
|
105
|
+
if (onFinish) {
|
|
106
|
+
const validationResult = await safeValidateTypes({
|
|
107
|
+
value: latestObject,
|
|
108
|
+
schema: asSchema(schema)
|
|
109
|
+
});
|
|
110
|
+
onFinish(
|
|
111
|
+
validationResult.success ? {
|
|
112
|
+
object: validationResult.value,
|
|
113
|
+
error: void 0
|
|
114
|
+
} : { object: void 0, error: validationResult.error }
|
|
115
|
+
);
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
})
|
|
119
|
+
);
|
|
120
|
+
} catch (err) {
|
|
121
|
+
if (isAbortError(err))
|
|
122
|
+
return;
|
|
123
|
+
if (onError && err instanceof Error)
|
|
124
|
+
onError(err);
|
|
125
|
+
await mutateLoading(() => false);
|
|
126
|
+
error.value = err instanceof Error ? err : new Error(String(err));
|
|
127
|
+
}
|
|
128
|
+
};
|
|
129
|
+
return {
|
|
130
|
+
submit,
|
|
131
|
+
object: data,
|
|
132
|
+
error,
|
|
133
|
+
isLoading,
|
|
134
|
+
stop,
|
|
135
|
+
clear
|
|
136
|
+
};
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
// src/use-completion.ts
|
|
140
|
+
import {
|
|
141
|
+
callCompletionApi
|
|
142
|
+
} from "ai";
|
|
143
|
+
import swrv2 from "swrv";
|
|
144
|
+
import { ref as ref2, unref } from "vue";
|
|
145
|
+
var uniqueId2 = 0;
|
|
146
|
+
var useSWRV2 = swrv2.default || swrv2;
|
|
147
|
+
var store2 = {};
|
|
10
148
|
function useCompletion({
|
|
11
149
|
api = "/api/completion",
|
|
12
150
|
id,
|
|
@@ -21,24 +159,24 @@ function useCompletion({
|
|
|
21
159
|
fetch: fetch2
|
|
22
160
|
} = {}) {
|
|
23
161
|
var _a;
|
|
24
|
-
const completionId = id || `completion-${
|
|
162
|
+
const completionId = id || `completion-${uniqueId2++}`;
|
|
25
163
|
const key = `${api}|${completionId}`;
|
|
26
|
-
const { data, mutate: originalMutate } =
|
|
164
|
+
const { data, mutate: originalMutate } = useSWRV2(
|
|
27
165
|
key,
|
|
28
|
-
() =>
|
|
166
|
+
() => store2[key] || initialCompletion
|
|
29
167
|
);
|
|
30
|
-
const { data: isLoading, mutate: mutateLoading } =
|
|
168
|
+
const { data: isLoading, mutate: mutateLoading } = useSWRV2(
|
|
31
169
|
`${completionId}-loading`,
|
|
32
170
|
null
|
|
33
171
|
);
|
|
34
172
|
(_a = isLoading.value) != null ? _a : isLoading.value = false;
|
|
35
173
|
data.value || (data.value = initialCompletion);
|
|
36
174
|
const mutate = (data2) => {
|
|
37
|
-
|
|
175
|
+
store2[key] = data2;
|
|
38
176
|
return originalMutate();
|
|
39
177
|
};
|
|
40
178
|
const completion = data;
|
|
41
|
-
const error =
|
|
179
|
+
const error = ref2(void 0);
|
|
42
180
|
let abortController = null;
|
|
43
181
|
async function triggerRequest(prompt, options) {
|
|
44
182
|
return callCompletionApi({
|
|
@@ -79,7 +217,7 @@ function useCompletion({
|
|
|
79
217
|
const setCompletion = (completion2) => {
|
|
80
218
|
mutate(completion2);
|
|
81
219
|
};
|
|
82
|
-
const input =
|
|
220
|
+
const input = ref2(initialInput);
|
|
83
221
|
const handleSubmit = (event) => {
|
|
84
222
|
var _a2;
|
|
85
223
|
(_a2 = event == null ? void 0 : event.preventDefault) == null ? void 0 : _a2.call(event);
|
|
@@ -102,11 +240,11 @@ function useCompletion({
|
|
|
102
240
|
import {
|
|
103
241
|
AbstractChat
|
|
104
242
|
} from "ai";
|
|
105
|
-
import { ref as
|
|
243
|
+
import { ref as ref3 } from "vue";
|
|
106
244
|
var VueChatState = class {
|
|
107
245
|
constructor(messages) {
|
|
108
|
-
this.statusRef =
|
|
109
|
-
this.errorRef =
|
|
246
|
+
this.statusRef = ref3("ready");
|
|
247
|
+
this.errorRef = ref3(void 0);
|
|
110
248
|
this.pushMessage = (message) => {
|
|
111
249
|
this.messagesRef.value = [...this.messagesRef.value, message];
|
|
112
250
|
};
|
|
@@ -117,7 +255,7 @@ var VueChatState = class {
|
|
|
117
255
|
this.messagesRef.value[index] = { ...message };
|
|
118
256
|
};
|
|
119
257
|
this.snapshot = (value) => value;
|
|
120
|
-
this.messagesRef =
|
|
258
|
+
this.messagesRef = ref3(messages != null ? messages : []);
|
|
121
259
|
}
|
|
122
260
|
get messages() {
|
|
123
261
|
return this.messagesRef.value;
|
|
@@ -236,147 +374,13 @@ function useChat(init) {
|
|
|
236
374
|
};
|
|
237
375
|
}
|
|
238
376
|
|
|
239
|
-
// src/
|
|
240
|
-
|
|
241
|
-
isAbortError,
|
|
242
|
-
safeValidateTypes
|
|
243
|
-
} from "@ai-sdk/provider-utils";
|
|
244
|
-
import {
|
|
245
|
-
asSchema,
|
|
246
|
-
isDeepEqualData,
|
|
247
|
-
parsePartialJson
|
|
248
|
-
} from "ai";
|
|
249
|
-
import swrv2 from "swrv";
|
|
250
|
-
import { ref as ref3 } from "vue";
|
|
251
|
-
var getOriginalFetch = () => fetch;
|
|
252
|
-
var uniqueId2 = 0;
|
|
253
|
-
var useSWRV2 = swrv2.default || swrv2;
|
|
254
|
-
var store2 = {};
|
|
255
|
-
var experimental_useObject = function useObject({
|
|
256
|
-
api,
|
|
257
|
-
id,
|
|
258
|
-
schema,
|
|
259
|
-
initialValue,
|
|
260
|
-
fetch: fetch2,
|
|
261
|
-
onError,
|
|
262
|
-
onFinish,
|
|
263
|
-
headers,
|
|
264
|
-
credentials
|
|
265
|
-
}) {
|
|
266
|
-
var _a;
|
|
267
|
-
const completionId = id || `completion-${uniqueId2++}`;
|
|
268
|
-
const key = `${api}|${completionId}`;
|
|
269
|
-
const { data, mutate: originalMutate } = useSWRV2(key, () => key in store2 ? store2[key] : initialValue);
|
|
270
|
-
const { data: isLoading, mutate: mutateLoading } = useSWRV2(
|
|
271
|
-
`${completionId}-loading`,
|
|
272
|
-
null
|
|
273
|
-
);
|
|
274
|
-
(_a = isLoading.value) != null ? _a : isLoading.value = false;
|
|
275
|
-
data.value || (data.value = initialValue);
|
|
276
|
-
const mutateObject = (value) => {
|
|
277
|
-
store2[key] = value;
|
|
278
|
-
return originalMutate();
|
|
279
|
-
};
|
|
280
|
-
const error = ref3(void 0);
|
|
281
|
-
let abortController = null;
|
|
282
|
-
const stop = async () => {
|
|
283
|
-
if (abortController) {
|
|
284
|
-
try {
|
|
285
|
-
abortController.abort();
|
|
286
|
-
} catch (e) {
|
|
287
|
-
} finally {
|
|
288
|
-
abortController = null;
|
|
289
|
-
}
|
|
290
|
-
}
|
|
291
|
-
await mutateLoading(() => false);
|
|
292
|
-
};
|
|
293
|
-
const clearObject = async () => {
|
|
294
|
-
error.value = void 0;
|
|
295
|
-
await mutateLoading(() => false);
|
|
296
|
-
await mutateObject(void 0);
|
|
297
|
-
data.value = void 0;
|
|
298
|
-
};
|
|
299
|
-
const clear = async () => {
|
|
300
|
-
await stop();
|
|
301
|
-
await clearObject();
|
|
302
|
-
};
|
|
303
|
-
const submit = async (input) => {
|
|
304
|
-
try {
|
|
305
|
-
await clearObject();
|
|
306
|
-
await mutateLoading(() => true);
|
|
307
|
-
abortController = new AbortController();
|
|
308
|
-
const actualFetch = fetch2 != null ? fetch2 : getOriginalFetch();
|
|
309
|
-
const response = await actualFetch(api, {
|
|
310
|
-
method: "POST",
|
|
311
|
-
headers: {
|
|
312
|
-
"Content-Type": "application/json",
|
|
313
|
-
...headers
|
|
314
|
-
},
|
|
315
|
-
credentials: credentials != null ? credentials : "same-origin",
|
|
316
|
-
signal: abortController.signal,
|
|
317
|
-
body: JSON.stringify(input)
|
|
318
|
-
});
|
|
319
|
-
if (!response.ok) {
|
|
320
|
-
throw new Error(
|
|
321
|
-
await response.text() || "Failed to fetch the response."
|
|
322
|
-
);
|
|
323
|
-
}
|
|
324
|
-
if (!response.body) {
|
|
325
|
-
throw new Error("The response body is empty.");
|
|
326
|
-
}
|
|
327
|
-
let accumulatedText = "";
|
|
328
|
-
let latestObject = void 0;
|
|
329
|
-
await response.body.pipeThrough(new TextDecoderStream()).pipeTo(
|
|
330
|
-
new WritableStream({
|
|
331
|
-
async write(chunk) {
|
|
332
|
-
accumulatedText += chunk;
|
|
333
|
-
const { value } = await parsePartialJson(accumulatedText);
|
|
334
|
-
const currentObject = value;
|
|
335
|
-
if (!isDeepEqualData(latestObject, currentObject)) {
|
|
336
|
-
latestObject = currentObject;
|
|
337
|
-
await mutateObject(currentObject);
|
|
338
|
-
}
|
|
339
|
-
},
|
|
340
|
-
async close() {
|
|
341
|
-
await mutateLoading(() => false);
|
|
342
|
-
abortController = null;
|
|
343
|
-
if (onFinish) {
|
|
344
|
-
const validationResult = await safeValidateTypes({
|
|
345
|
-
value: latestObject,
|
|
346
|
-
schema: asSchema(schema)
|
|
347
|
-
});
|
|
348
|
-
onFinish(
|
|
349
|
-
validationResult.success ? {
|
|
350
|
-
object: validationResult.value,
|
|
351
|
-
error: void 0
|
|
352
|
-
} : { object: void 0, error: validationResult.error }
|
|
353
|
-
);
|
|
354
|
-
}
|
|
355
|
-
}
|
|
356
|
-
})
|
|
357
|
-
);
|
|
358
|
-
} catch (err) {
|
|
359
|
-
if (isAbortError(err))
|
|
360
|
-
return;
|
|
361
|
-
if (onError && err instanceof Error)
|
|
362
|
-
onError(err);
|
|
363
|
-
await mutateLoading(() => false);
|
|
364
|
-
error.value = err instanceof Error ? err : new Error(String(err));
|
|
365
|
-
}
|
|
366
|
-
};
|
|
367
|
-
return {
|
|
368
|
-
submit,
|
|
369
|
-
object: data,
|
|
370
|
-
error,
|
|
371
|
-
isLoading,
|
|
372
|
-
stop,
|
|
373
|
-
clear
|
|
374
|
-
};
|
|
375
|
-
};
|
|
377
|
+
// src/index.ts
|
|
378
|
+
var experimental_useObject = useObject;
|
|
376
379
|
export {
|
|
377
380
|
Chat,
|
|
378
381
|
experimental_useObject,
|
|
379
382
|
useChat,
|
|
380
|
-
useCompletion
|
|
383
|
+
useCompletion,
|
|
384
|
+
useObject
|
|
381
385
|
};
|
|
382
386
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/use-completion.ts","../src/chat.vue.ts","../src/use-chat.ts","../src/use-object.ts"],"sourcesContent":["import {\n callCompletionApi,\n type CompletionRequestOptions,\n type UseCompletionOptions,\n} from 'ai';\nimport type * as SwrvModule from 'swrv';\nimport swrv from 'swrv';\nimport { ref, unref, type Ref } from 'vue';\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 SwrvModule)['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 type ChatInit,\n type ChatState,\n type ChatStatus,\n type UIMessage,\n} from 'ai';\nimport { ref, type Ref } from 'vue';\nclass VueChatState<\n UI_MESSAGE extends UIMessage,\n> implements ChatState<UI_MESSAGE> {\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\n/**\n * @deprecated Use the {@link useChat} composable instead. It exposes reactive\n * refs and automatically recreates the chat when its init object changes.\n */\nexport class Chat<\n UI_MESSAGE extends UIMessage,\n> extends AbstractChat<UI_MESSAGE> {\n constructor({ messages, ...init }: ChatInit<UI_MESSAGE>) {\n super({\n ...init,\n state: new VueChatState(messages),\n });\n }\n}\n","import {\n AbstractChat,\n type ChatInit as BaseChatInit,\n type ChatInit,\n type ChatState,\n type ChatStatus,\n type UIMessage,\n} from 'ai';\nimport {\n computed,\n shallowRef,\n toValue,\n triggerRef,\n watch,\n type ComputedRef,\n type MaybeRefOrGetter,\n type ShallowRef,\n} from 'vue';\n\n/**\n * @internal\n */\nexport class VueChat<\n UI_MESSAGE extends UIMessage,\n> extends AbstractChat<UI_MESSAGE> {\n constructor({\n state,\n ...init\n }: Omit<ChatInit<UI_MESSAGE>, 'messages'> & {\n state: ChatState<UI_MESSAGE>;\n }) {\n super({\n ...init,\n state,\n });\n }\n}\n\n/**\n * Return type of the {@link useChat} composable, which includes the chat\n * instance methods and reactive properties for messages, status, and error.\n */\nexport interface UseChatHelpers<UI_MESSAGE extends UIMessage> extends Pick<\n AbstractChat<UI_MESSAGE>,\n | 'sendMessage'\n | 'regenerate'\n | 'stop'\n | 'resumeStream'\n | 'addToolOutput'\n | 'addToolApprovalResponse'\n | 'clearError'\n> {\n /**\n * The id of the chat.\n */\n id: ComputedRef<string>;\n\n /**\n * The current error state of the chat, if any.\n */\n error: ShallowRef<Error | undefined>;\n\n /**\n * The current status of the chat, which can be 'ready', 'generating', 'streaming', or 'error'.\n */\n status: ShallowRef<ChatStatus>;\n\n /**\n * The list of messages in the chat, which can be updated by the chat instance methods or directly by setting this property.\n */\n messages: ShallowRef<UI_MESSAGE[]>;\n}\n\n/**\n * Composable to access messages, status, and other chat properties and\n * methods. Accepts an optional reactive initial configuration object\n *\n * @example\n *\n * ```ts\n * // passing a getter if any reactive properties are used within\n * // the init object\n * const { messages, sendMessage } = useChat(() => ({\n * // ...\n * })\n * ```\n *\n * @see BaseChatInit\n */\nexport function useChat<UI_MESSAGE extends UIMessage = UIMessage>(\n init?: MaybeRefOrGetter<BaseChatInit<UI_MESSAGE>>,\n): UseChatHelpers<UI_MESSAGE> {\n const messages = shallowRef<UI_MESSAGE[]>([]);\n const status = shallowRef<ChatStatus>('ready');\n const error = shallowRef<Error | undefined>();\n\n // this wrapper doesn't need to be reactive and can be reused across chat\n // instance changes, because the inner refs are reactive and the wrapper\n // methods trigger updates when needed\n const chatStateWrapper = {\n get messages(): UI_MESSAGE[] {\n return messages.value;\n },\n\n set messages(messageList: UI_MESSAGE[]) {\n messages.value = messageList;\n },\n\n get status(): ChatStatus {\n return status.value;\n },\n\n set status(statusValue: ChatStatus) {\n status.value = statusValue;\n },\n\n get error(): Error | undefined {\n return error.value;\n },\n\n set error(errorValue: Error | undefined) {\n error.value = errorValue;\n },\n\n pushMessage(message: UI_MESSAGE) {\n messages.value.push(message);\n // needed because messagesRef is a shallowRef\n triggerRef(messages);\n },\n\n popMessage() {\n messages.value.pop();\n triggerRef(messages);\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 messages.value[index] = { ...message };\n triggerRef(messages);\n },\n\n snapshot: <T>(value: T): T => value,\n } satisfies ChatState<UI_MESSAGE>;\n\n // the instance is created right away thanks to immediate: true. We do it this\n // way instead of a computed to ensure all changes to reactive state happen\n // in the same tick\n const chatInstance = shallowRef<VueChat<UI_MESSAGE>>() as ShallowRef<\n VueChat<UI_MESSAGE>\n >;\n\n watch(\n () => toValue(init),\n opts => {\n // reset the initial state\n messages.value = opts?.messages ?? [];\n status.value = 'ready';\n error.value = undefined;\n\n chatInstance.value = new VueChat<UI_MESSAGE>({\n ...opts,\n state: chatStateWrapper,\n });\n },\n { immediate: true },\n );\n\n return {\n id: computed(() => chatInstance.value.id),\n status,\n messages,\n error,\n addToolApprovalResponse: opts =>\n chatInstance.value.addToolApprovalResponse(opts),\n addToolOutput: opts => chatInstance.value.addToolOutput(opts),\n clearError: () => chatInstance.value.clearError(),\n regenerate: opts => chatInstance.value.regenerate(opts),\n sendMessage: (...args) => chatInstance.value.sendMessage(...args),\n stop: () => chatInstance.value.stop(),\n resumeStream: opts => chatInstance.value.resumeStream(opts),\n };\n}\n","import {\n isAbortError,\n safeValidateTypes,\n type FetchFunction,\n} from '@ai-sdk/provider-utils';\nimport {\n asSchema,\n isDeepEqualData,\n parsePartialJson,\n type DeepPartial,\n type FlexibleSchema,\n type InferSchema,\n} from 'ai';\nimport type * as SwrvModule from 'swrv';\nimport swrv from 'swrv';\nimport { ref, type Ref } from 'vue';\n// use function to allow for mocking in tests\nconst getOriginalFetch = () => fetch;\n\nexport type Experimental_UseObjectOptions<\n SCHEMA extends FlexibleSchema,\n RESULT,\n> = {\n /** API endpoint that streams JSON chunks matching the schema */\n api: string;\n\n /** 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 SwrvModule)['default']) || swrv;\nconst store: Record<string, any> = {};\n\nexport const experimental_useObject = function useObject<\n SCHEMA extends FlexibleSchema,\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","AbstractChat","swrv","ref","uniqueId","useSWRV","store","fetch"]}
|
|
1
|
+
{"version":3,"sources":["../src/use-object.ts","../src/use-completion.ts","../src/chat.vue.ts","../src/use-chat.ts","../src/index.ts"],"sourcesContent":["import {\n isAbortError,\n safeValidateTypes,\n type FetchFunction,\n} from '@ai-sdk/provider-utils';\nimport {\n asSchema,\n isDeepEqualData,\n parsePartialJson,\n type DeepPartial,\n type FlexibleSchema,\n type InferSchema,\n} from 'ai';\nimport type * as SwrvModule from 'swrv';\nimport swrv from 'swrv';\nimport { ref, type Ref } from 'vue';\n// use function to allow for mocking in tests\nconst getOriginalFetch = () => fetch;\n\nexport type UseObjectOptions<SCHEMA extends FlexibleSchema, RESULT> = {\n /** API endpoint that streams JSON chunks matching the schema */\n api: string;\n\n /** 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 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 SwrvModule)['default']) || swrv;\nconst store: Record<string, any> = {};\n\nexport function useObject<\n SCHEMA extends FlexibleSchema,\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}: UseObjectOptions<SCHEMA, RESULT>): 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","import {\n callCompletionApi,\n type CompletionRequestOptions,\n type UseCompletionOptions,\n} from 'ai';\nimport type * as SwrvModule from 'swrv';\nimport swrv from 'swrv';\nimport { ref, unref, type Ref } from 'vue';\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 SwrvModule)['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 type ChatInit,\n type ChatState,\n type ChatStatus,\n type UIMessage,\n} from 'ai';\nimport { ref, type Ref } from 'vue';\nclass VueChatState<\n UI_MESSAGE extends UIMessage,\n> implements ChatState<UI_MESSAGE> {\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\n/**\n * @deprecated Use the {@link useChat} composable instead. It exposes reactive\n * refs and automatically recreates the chat when its init object changes.\n */\nexport class Chat<\n UI_MESSAGE extends UIMessage,\n> extends AbstractChat<UI_MESSAGE> {\n constructor({ messages, ...init }: ChatInit<UI_MESSAGE>) {\n super({\n ...init,\n state: new VueChatState(messages),\n });\n }\n}\n","import {\n AbstractChat,\n type ChatInit as BaseChatInit,\n type ChatInit,\n type ChatState,\n type ChatStatus,\n type UIMessage,\n} from 'ai';\nimport {\n computed,\n shallowRef,\n toValue,\n triggerRef,\n watch,\n type ComputedRef,\n type MaybeRefOrGetter,\n type ShallowRef,\n} from 'vue';\n\n/**\n * @internal\n */\nexport class VueChat<\n UI_MESSAGE extends UIMessage,\n> extends AbstractChat<UI_MESSAGE> {\n constructor({\n state,\n ...init\n }: Omit<ChatInit<UI_MESSAGE>, 'messages'> & {\n state: ChatState<UI_MESSAGE>;\n }) {\n super({\n ...init,\n state,\n });\n }\n}\n\n/**\n * Return type of the {@link useChat} composable, which includes the chat\n * instance methods and reactive properties for messages, status, and error.\n */\nexport interface UseChatHelpers<UI_MESSAGE extends UIMessage> extends Pick<\n AbstractChat<UI_MESSAGE>,\n | 'sendMessage'\n | 'regenerate'\n | 'stop'\n | 'resumeStream'\n | 'addToolOutput'\n | 'addToolApprovalResponse'\n | 'clearError'\n> {\n /**\n * The id of the chat.\n */\n id: ComputedRef<string>;\n\n /**\n * The current error state of the chat, if any.\n */\n error: ShallowRef<Error | undefined>;\n\n /**\n * The current status of the chat, which can be 'ready', 'generating', 'streaming', or 'error'.\n */\n status: ShallowRef<ChatStatus>;\n\n /**\n * The list of messages in the chat, which can be updated by the chat instance methods or directly by setting this property.\n */\n messages: ShallowRef<UI_MESSAGE[]>;\n}\n\n/**\n * Composable to access messages, status, and other chat properties and\n * methods. Accepts an optional reactive initial configuration object\n *\n * @example\n *\n * ```ts\n * // passing a getter if any reactive properties are used within\n * // the init object\n * const { messages, sendMessage } = useChat(() => ({\n * // ...\n * })\n * ```\n *\n * @see BaseChatInit\n */\nexport function useChat<UI_MESSAGE extends UIMessage = UIMessage>(\n init?: MaybeRefOrGetter<BaseChatInit<UI_MESSAGE>>,\n): UseChatHelpers<UI_MESSAGE> {\n const messages = shallowRef<UI_MESSAGE[]>([]);\n const status = shallowRef<ChatStatus>('ready');\n const error = shallowRef<Error | undefined>();\n\n // this wrapper doesn't need to be reactive and can be reused across chat\n // instance changes, because the inner refs are reactive and the wrapper\n // methods trigger updates when needed\n const chatStateWrapper = {\n get messages(): UI_MESSAGE[] {\n return messages.value;\n },\n\n set messages(messageList: UI_MESSAGE[]) {\n messages.value = messageList;\n },\n\n get status(): ChatStatus {\n return status.value;\n },\n\n set status(statusValue: ChatStatus) {\n status.value = statusValue;\n },\n\n get error(): Error | undefined {\n return error.value;\n },\n\n set error(errorValue: Error | undefined) {\n error.value = errorValue;\n },\n\n pushMessage(message: UI_MESSAGE) {\n messages.value.push(message);\n // needed because messagesRef is a shallowRef\n triggerRef(messages);\n },\n\n popMessage() {\n messages.value.pop();\n triggerRef(messages);\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 messages.value[index] = { ...message };\n triggerRef(messages);\n },\n\n snapshot: <T>(value: T): T => value,\n } satisfies ChatState<UI_MESSAGE>;\n\n // the instance is created right away thanks to immediate: true. We do it this\n // way instead of a computed to ensure all changes to reactive state happen\n // in the same tick\n const chatInstance = shallowRef<VueChat<UI_MESSAGE>>() as ShallowRef<\n VueChat<UI_MESSAGE>\n >;\n\n watch(\n () => toValue(init),\n opts => {\n // reset the initial state\n messages.value = opts?.messages ?? [];\n status.value = 'ready';\n error.value = undefined;\n\n chatInstance.value = new VueChat<UI_MESSAGE>({\n ...opts,\n state: chatStateWrapper,\n });\n },\n { immediate: true },\n );\n\n return {\n id: computed(() => chatInstance.value.id),\n status,\n messages,\n error,\n addToolApprovalResponse: opts =>\n chatInstance.value.addToolApprovalResponse(opts),\n addToolOutput: opts => chatInstance.value.addToolOutput(opts),\n clearError: () => chatInstance.value.clearError(),\n regenerate: opts => chatInstance.value.regenerate(opts),\n sendMessage: (...args) => chatInstance.value.sendMessage(...args),\n stop: () => chatInstance.value.stop(),\n resumeStream: opts => chatInstance.value.resumeStream(opts),\n };\n}\n","import type { FlexibleSchema } from '@ai-sdk/provider-utils';\nimport {\n useObject,\n type UseObjectHelpers,\n type UseObjectOptions,\n} from './use-object';\n\nexport * from './use-completion';\nexport { Chat } from './chat.vue';\nexport { useChat, type UseChatHelpers } from './use-chat';\nexport * from './use-object';\n\n// deprecated aliases\n// note: declared here (instead of export aliases) so that the `@deprecated`\n// tags are preserved in the bundled type declarations\n\n/**\n * @deprecated Use `useObject` instead.\n */\nexport const experimental_useObject = useObject;\n\n/**\n * @deprecated Use `UseObjectOptions` instead.\n */\nexport type Experimental_UseObjectOptions<\n SCHEMA extends FlexibleSchema,\n RESULT,\n> = UseObjectOptions<SCHEMA, RESULT>;\n\n/**\n * @deprecated Use `UseObjectHelpers` instead.\n */\nexport type Experimental_UseObjectHelpers<RESULT, INPUT> = UseObjectHelpers<\n RESULT,\n INPUT\n>;\n"],"mappings":"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","names":["fetch","swrv","ref","uniqueId","useSWRV","store","fetch","data","completion","_a","ref","AbstractChat"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ai-sdk/vue",
|
|
3
|
-
"version": "4.0.
|
|
3
|
+
"version": "4.0.18",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"sideEffects": false,
|
|
@@ -27,8 +27,8 @@
|
|
|
27
27
|
],
|
|
28
28
|
"dependencies": {
|
|
29
29
|
"swrv": "^1.2.0",
|
|
30
|
-
"@ai-sdk/provider-utils": "5.0.
|
|
31
|
-
"ai": "7.0.
|
|
30
|
+
"@ai-sdk/provider-utils": "5.0.6",
|
|
31
|
+
"ai": "7.0.18"
|
|
32
32
|
},
|
|
33
33
|
"devDependencies": {
|
|
34
34
|
"@testing-library/jest-dom": "^6.9.1",
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
|
-
import {
|
|
2
|
+
import { useObject } from './use-object';
|
|
3
3
|
import { z } from 'zod/v4';
|
|
4
4
|
import { ref, reactive } from 'vue';
|
|
5
5
|
|
|
@@ -10,17 +10,16 @@ const onFinishCalls: Array<{
|
|
|
10
10
|
|
|
11
11
|
const onErrorResult: Error | undefined = ref(undefined);
|
|
12
12
|
|
|
13
|
-
const { object, error, submit, isLoading, stop, clear } =
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
});
|
|
13
|
+
const { object, error, submit, isLoading, stop, clear } = useObject({
|
|
14
|
+
api: '/api/use-object',
|
|
15
|
+
schema: z.object({ content: z.string() }),
|
|
16
|
+
onError(error) {
|
|
17
|
+
onErrorResult.value = error;
|
|
18
|
+
},
|
|
19
|
+
onFinish(event) {
|
|
20
|
+
onFinishCalls.push(event);
|
|
21
|
+
},
|
|
22
|
+
});
|
|
24
23
|
</script>
|
|
25
24
|
|
|
26
25
|
<template>
|
|
@@ -1,18 +1,17 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
|
-
import {
|
|
2
|
+
import { useObject } from './use-object';
|
|
3
3
|
import { z } from 'zod/v4';
|
|
4
4
|
import { ref, reactive } from 'vue';
|
|
5
5
|
|
|
6
|
-
const { object, error, submit, isLoading, stop, clear } =
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
});
|
|
6
|
+
const { object, error, submit, isLoading, stop, clear } = useObject({
|
|
7
|
+
api: '/api/use-object',
|
|
8
|
+
schema: z.object({ content: z.string() }),
|
|
9
|
+
headers: {
|
|
10
|
+
Authorization: 'Bearer TEST_TOKEN',
|
|
11
|
+
'X-Custom-Header': 'CustomValue',
|
|
12
|
+
},
|
|
13
|
+
credentials: 'include',
|
|
14
|
+
});
|
|
16
15
|
</script>
|
|
17
16
|
|
|
18
17
|
<template>
|
package/src/index.ts
CHANGED
|
@@ -1,4 +1,36 @@
|
|
|
1
|
+
import type { FlexibleSchema } from '@ai-sdk/provider-utils';
|
|
2
|
+
import {
|
|
3
|
+
useObject,
|
|
4
|
+
type UseObjectHelpers,
|
|
5
|
+
type UseObjectOptions,
|
|
6
|
+
} from './use-object';
|
|
7
|
+
|
|
1
8
|
export * from './use-completion';
|
|
2
9
|
export { Chat } from './chat.vue';
|
|
3
10
|
export { useChat, type UseChatHelpers } from './use-chat';
|
|
4
11
|
export * from './use-object';
|
|
12
|
+
|
|
13
|
+
// deprecated aliases
|
|
14
|
+
// note: declared here (instead of export aliases) so that the `@deprecated`
|
|
15
|
+
// tags are preserved in the bundled type declarations
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* @deprecated Use `useObject` instead.
|
|
19
|
+
*/
|
|
20
|
+
export const experimental_useObject = useObject;
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* @deprecated Use `UseObjectOptions` instead.
|
|
24
|
+
*/
|
|
25
|
+
export type Experimental_UseObjectOptions<
|
|
26
|
+
SCHEMA extends FlexibleSchema,
|
|
27
|
+
RESULT,
|
|
28
|
+
> = UseObjectOptions<SCHEMA, RESULT>;
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* @deprecated Use `UseObjectHelpers` instead.
|
|
32
|
+
*/
|
|
33
|
+
export type Experimental_UseObjectHelpers<RESULT, INPUT> = UseObjectHelpers<
|
|
34
|
+
RESULT,
|
|
35
|
+
INPUT
|
|
36
|
+
>;
|
package/src/use-object.ts
CHANGED
|
@@ -17,10 +17,7 @@ import { ref, type Ref } from 'vue';
|
|
|
17
17
|
// use function to allow for mocking in tests
|
|
18
18
|
const getOriginalFetch = () => fetch;
|
|
19
19
|
|
|
20
|
-
export type
|
|
21
|
-
SCHEMA extends FlexibleSchema,
|
|
22
|
-
RESULT,
|
|
23
|
-
> = {
|
|
20
|
+
export type UseObjectOptions<SCHEMA extends FlexibleSchema, RESULT> = {
|
|
24
21
|
/** API endpoint that streams JSON chunks matching the schema */
|
|
25
22
|
api: string;
|
|
26
23
|
|
|
@@ -52,7 +49,7 @@ export type Experimental_UseObjectOptions<
|
|
|
52
49
|
credentials?: RequestCredentials;
|
|
53
50
|
};
|
|
54
51
|
|
|
55
|
-
export type
|
|
52
|
+
export type UseObjectHelpers<RESULT, INPUT> = {
|
|
56
53
|
/** POST the input and start streaming */
|
|
57
54
|
submit: (input: INPUT) => void;
|
|
58
55
|
|
|
@@ -78,7 +75,7 @@ let uniqueId = 0;
|
|
|
78
75
|
const useSWRV = (swrv.default as (typeof SwrvModule)['default']) || swrv;
|
|
79
76
|
const store: Record<string, any> = {};
|
|
80
77
|
|
|
81
|
-
export
|
|
78
|
+
export function useObject<
|
|
82
79
|
SCHEMA extends FlexibleSchema,
|
|
83
80
|
RESULT = InferSchema<SCHEMA>,
|
|
84
81
|
INPUT = any,
|
|
@@ -92,10 +89,7 @@ export const experimental_useObject = function useObject<
|
|
|
92
89
|
onFinish,
|
|
93
90
|
headers,
|
|
94
91
|
credentials,
|
|
95
|
-
}:
|
|
96
|
-
SCHEMA,
|
|
97
|
-
RESULT
|
|
98
|
-
>): Experimental_UseObjectHelpers<RESULT, INPUT> {
|
|
92
|
+
}: UseObjectOptions<SCHEMA, RESULT>): UseObjectHelpers<RESULT, INPUT> {
|
|
99
93
|
// Generate an unique id for the object if not provided.
|
|
100
94
|
const completionId = id || `completion-${uniqueId++}`;
|
|
101
95
|
|
|
@@ -229,4 +223,4 @@ export const experimental_useObject = function useObject<
|
|
|
229
223
|
stop,
|
|
230
224
|
clear,
|
|
231
225
|
};
|
|
232
|
-
}
|
|
226
|
+
}
|