@ai-sdk/vue 4.0.120 → 4.0.123
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 +33 -0
- package/dist/index.d.ts +113 -109
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +423 -523
- package/dist/index.js.map +1 -1
- package/package.json +8 -8
package/dist/index.js
CHANGED
|
@@ -1,539 +1,439 @@
|
|
|
1
|
-
|
|
2
|
-
import {
|
|
3
|
-
isAbortError,
|
|
4
|
-
safeValidateTypes
|
|
5
|
-
} from "@ai-sdk/provider-utils";
|
|
6
|
-
import {
|
|
7
|
-
asSchema,
|
|
8
|
-
isDeepEqualData,
|
|
9
|
-
parsePartialJson
|
|
10
|
-
} from "ai";
|
|
1
|
+
import { isAbortError, safeValidateTypes } from "@ai-sdk/provider-utils";
|
|
2
|
+
import { AbstractChat, asSchema, callCompletionApi, isDeepEqualData, parsePartialJson } from "ai";
|
|
11
3
|
import swrv from "swrv";
|
|
12
|
-
import { ref } from "vue";
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
object: validationResult.value,
|
|
112
|
-
error: void 0
|
|
113
|
-
} : { object: void 0, error: validationResult.error }
|
|
114
|
-
);
|
|
115
|
-
}
|
|
116
|
-
}
|
|
117
|
-
})
|
|
118
|
-
);
|
|
119
|
-
} catch (err) {
|
|
120
|
-
if (isAbortError(err))
|
|
121
|
-
return;
|
|
122
|
-
if (onError && err instanceof Error)
|
|
123
|
-
onError(err);
|
|
124
|
-
await mutateLoading(() => false);
|
|
125
|
-
error.value = err instanceof Error ? err : new Error(String(err));
|
|
126
|
-
}
|
|
127
|
-
};
|
|
128
|
-
return {
|
|
129
|
-
submit,
|
|
130
|
-
object: data,
|
|
131
|
-
error,
|
|
132
|
-
isLoading,
|
|
133
|
-
stop,
|
|
134
|
-
clear
|
|
135
|
-
};
|
|
4
|
+
import { computed, getCurrentScope, onScopeDispose, ref, shallowRef, toValue, unref, watch } from "vue";
|
|
5
|
+
//#region src/use-object.ts
|
|
6
|
+
const getOriginalFetch = () => fetch;
|
|
7
|
+
let uniqueId$1 = 0;
|
|
8
|
+
const useSWRV$1 = swrv.default || swrv;
|
|
9
|
+
const store$1 = {};
|
|
10
|
+
function useObject({ api, id, schema, initialValue, fetch, onError, onFinish, headers, credentials }) {
|
|
11
|
+
const completionId = id || `completion-${uniqueId$1++}`;
|
|
12
|
+
const key = `${api}|${completionId}`;
|
|
13
|
+
const { data, mutate: originalMutate } = useSWRV$1(key, () => key in store$1 ? store$1[key] : initialValue);
|
|
14
|
+
const { data: isLoading, mutate: mutateLoading } = useSWRV$1(`${completionId}-loading`, null);
|
|
15
|
+
isLoading.value ??= false;
|
|
16
|
+
data.value ||= initialValue;
|
|
17
|
+
const mutateObject = (value) => {
|
|
18
|
+
store$1[key] = value;
|
|
19
|
+
return originalMutate();
|
|
20
|
+
};
|
|
21
|
+
const error = ref(void 0);
|
|
22
|
+
let abortController = null;
|
|
23
|
+
const stop = async () => {
|
|
24
|
+
if (abortController) try {
|
|
25
|
+
abortController.abort();
|
|
26
|
+
} catch {} finally {
|
|
27
|
+
abortController = null;
|
|
28
|
+
}
|
|
29
|
+
await mutateLoading(() => false);
|
|
30
|
+
};
|
|
31
|
+
const clearObject = async () => {
|
|
32
|
+
error.value = void 0;
|
|
33
|
+
await mutateLoading(() => false);
|
|
34
|
+
await mutateObject(void 0);
|
|
35
|
+
data.value = void 0;
|
|
36
|
+
};
|
|
37
|
+
const clear = async () => {
|
|
38
|
+
await stop();
|
|
39
|
+
await clearObject();
|
|
40
|
+
};
|
|
41
|
+
const submit = async (input) => {
|
|
42
|
+
try {
|
|
43
|
+
await clearObject();
|
|
44
|
+
await mutateLoading(() => true);
|
|
45
|
+
abortController = new AbortController();
|
|
46
|
+
const response = await (fetch ?? getOriginalFetch())(api, {
|
|
47
|
+
method: "POST",
|
|
48
|
+
headers: {
|
|
49
|
+
"Content-Type": "application/json",
|
|
50
|
+
...headers
|
|
51
|
+
},
|
|
52
|
+
credentials: credentials ?? "same-origin",
|
|
53
|
+
signal: abortController.signal,
|
|
54
|
+
body: JSON.stringify(input)
|
|
55
|
+
});
|
|
56
|
+
if (!response.ok) throw new Error(await response.text() || "Failed to fetch the response.");
|
|
57
|
+
if (!response.body) throw new Error("The response body is empty.");
|
|
58
|
+
let accumulatedText = "";
|
|
59
|
+
let latestObject = void 0;
|
|
60
|
+
await response.body.pipeThrough(new TextDecoderStream()).pipeTo(new WritableStream({
|
|
61
|
+
async write(chunk) {
|
|
62
|
+
accumulatedText += chunk;
|
|
63
|
+
const { value } = await parsePartialJson(accumulatedText);
|
|
64
|
+
const currentObject = value;
|
|
65
|
+
if (!isDeepEqualData(latestObject, currentObject)) {
|
|
66
|
+
latestObject = currentObject;
|
|
67
|
+
await mutateObject(currentObject);
|
|
68
|
+
}
|
|
69
|
+
},
|
|
70
|
+
async close() {
|
|
71
|
+
await mutateLoading(() => false);
|
|
72
|
+
abortController = null;
|
|
73
|
+
if (onFinish) {
|
|
74
|
+
const validationResult = await safeValidateTypes({
|
|
75
|
+
value: latestObject,
|
|
76
|
+
schema: asSchema(schema)
|
|
77
|
+
});
|
|
78
|
+
onFinish(validationResult.success ? {
|
|
79
|
+
object: validationResult.value,
|
|
80
|
+
error: void 0
|
|
81
|
+
} : {
|
|
82
|
+
object: void 0,
|
|
83
|
+
error: validationResult.error
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
}));
|
|
88
|
+
} catch (err) {
|
|
89
|
+
if (isAbortError(err)) return;
|
|
90
|
+
if (onError && err instanceof Error) onError(err);
|
|
91
|
+
await mutateLoading(() => false);
|
|
92
|
+
error.value = err instanceof Error ? err : new Error(String(err));
|
|
93
|
+
}
|
|
94
|
+
};
|
|
95
|
+
return {
|
|
96
|
+
submit,
|
|
97
|
+
object: data,
|
|
98
|
+
error,
|
|
99
|
+
isLoading,
|
|
100
|
+
stop,
|
|
101
|
+
clear
|
|
102
|
+
};
|
|
136
103
|
}
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
};
|
|
210
|
-
const stop = () => {
|
|
211
|
-
if (abortController) {
|
|
212
|
-
abortController.abort();
|
|
213
|
-
}
|
|
214
|
-
};
|
|
215
|
-
const setCompletion = (completion2) => {
|
|
216
|
-
mutate(completion2);
|
|
217
|
-
};
|
|
218
|
-
const input = ref2(initialInput);
|
|
219
|
-
const handleSubmit = (event) => {
|
|
220
|
-
event?.preventDefault?.();
|
|
221
|
-
const inputValue = input.value;
|
|
222
|
-
return inputValue ? complete(inputValue) : void 0;
|
|
223
|
-
};
|
|
224
|
-
return {
|
|
225
|
-
completion,
|
|
226
|
-
complete,
|
|
227
|
-
error,
|
|
228
|
-
stop,
|
|
229
|
-
setCompletion,
|
|
230
|
-
input,
|
|
231
|
-
handleSubmit,
|
|
232
|
-
isLoading
|
|
233
|
-
};
|
|
104
|
+
//#endregion
|
|
105
|
+
//#region src/use-completion.ts
|
|
106
|
+
let uniqueId = 0;
|
|
107
|
+
const useSWRV = swrv.default || swrv;
|
|
108
|
+
const store = {};
|
|
109
|
+
function useCompletion({ api = "/api/completion", id, initialCompletion = "", initialInput = "", credentials, headers, body, streamProtocol, onFinish, onError, fetch } = {}) {
|
|
110
|
+
const completionId = id || `completion-${uniqueId++}`;
|
|
111
|
+
const key = `${api}|${completionId}`;
|
|
112
|
+
const { data, mutate: originalMutate } = useSWRV(key, () => store[key] ?? initialCompletion);
|
|
113
|
+
const { data: isLoading, mutate: mutateLoading } = useSWRV(`${completionId}-loading`, null);
|
|
114
|
+
isLoading.value ??= false;
|
|
115
|
+
data.value ??= initialCompletion;
|
|
116
|
+
const mutate = (data) => {
|
|
117
|
+
store[key] = data;
|
|
118
|
+
return originalMutate();
|
|
119
|
+
};
|
|
120
|
+
const completion = data;
|
|
121
|
+
const error = ref(void 0);
|
|
122
|
+
let abortController = null;
|
|
123
|
+
async function triggerRequest(prompt, options) {
|
|
124
|
+
return callCompletionApi({
|
|
125
|
+
api,
|
|
126
|
+
prompt,
|
|
127
|
+
credentials,
|
|
128
|
+
headers: {
|
|
129
|
+
...headers,
|
|
130
|
+
...options?.headers
|
|
131
|
+
},
|
|
132
|
+
body: {
|
|
133
|
+
...unref(body),
|
|
134
|
+
...options?.body
|
|
135
|
+
},
|
|
136
|
+
streamProtocol,
|
|
137
|
+
setCompletion: mutate,
|
|
138
|
+
setLoading: (loading) => mutateLoading(() => loading),
|
|
139
|
+
setError: (err) => {
|
|
140
|
+
error.value = err;
|
|
141
|
+
},
|
|
142
|
+
setAbortController: (controller) => {
|
|
143
|
+
abortController = controller;
|
|
144
|
+
},
|
|
145
|
+
getAbortController: () => abortController,
|
|
146
|
+
onFinish,
|
|
147
|
+
onError,
|
|
148
|
+
fetch
|
|
149
|
+
});
|
|
150
|
+
}
|
|
151
|
+
const complete = async (prompt, options) => {
|
|
152
|
+
return triggerRequest(prompt, options);
|
|
153
|
+
};
|
|
154
|
+
const stop = () => {
|
|
155
|
+
if (abortController) abortController.abort();
|
|
156
|
+
};
|
|
157
|
+
const setCompletion = (completion) => {
|
|
158
|
+
mutate(completion);
|
|
159
|
+
};
|
|
160
|
+
const input = ref(initialInput);
|
|
161
|
+
const handleSubmit = (event) => {
|
|
162
|
+
event?.preventDefault?.();
|
|
163
|
+
const inputValue = input.value;
|
|
164
|
+
return inputValue ? complete(inputValue) : void 0;
|
|
165
|
+
};
|
|
166
|
+
return {
|
|
167
|
+
completion,
|
|
168
|
+
complete,
|
|
169
|
+
error,
|
|
170
|
+
stop,
|
|
171
|
+
setCompletion,
|
|
172
|
+
input,
|
|
173
|
+
handleSubmit,
|
|
174
|
+
isLoading
|
|
175
|
+
};
|
|
234
176
|
}
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
}
|
|
272
|
-
set error(error) {
|
|
273
|
-
this.errorRef.value = error;
|
|
274
|
-
}
|
|
177
|
+
//#endregion
|
|
178
|
+
//#region src/chat.vue.ts
|
|
179
|
+
var VueChatState$1 = class {
|
|
180
|
+
constructor(messages) {
|
|
181
|
+
this.statusRef = ref("ready");
|
|
182
|
+
this.errorRef = ref(void 0);
|
|
183
|
+
this.pushMessage = (message) => {
|
|
184
|
+
this.messagesRef.value = [...this.messagesRef.value, message];
|
|
185
|
+
};
|
|
186
|
+
this.popMessage = () => {
|
|
187
|
+
this.messagesRef.value = this.messagesRef.value.slice(0, -1);
|
|
188
|
+
};
|
|
189
|
+
this.replaceMessage = (index, message) => {
|
|
190
|
+
this.messagesRef.value[index] = { ...message };
|
|
191
|
+
};
|
|
192
|
+
this.snapshot = (value) => value;
|
|
193
|
+
this.messagesRef = ref(messages ?? []);
|
|
194
|
+
}
|
|
195
|
+
get messages() {
|
|
196
|
+
return this.messagesRef.value;
|
|
197
|
+
}
|
|
198
|
+
set messages(messages) {
|
|
199
|
+
this.messagesRef.value = messages;
|
|
200
|
+
}
|
|
201
|
+
get status() {
|
|
202
|
+
return this.statusRef.value;
|
|
203
|
+
}
|
|
204
|
+
set status(status) {
|
|
205
|
+
this.statusRef.value = status;
|
|
206
|
+
}
|
|
207
|
+
get error() {
|
|
208
|
+
return this.errorRef.value;
|
|
209
|
+
}
|
|
210
|
+
set error(error) {
|
|
211
|
+
this.errorRef.value = error;
|
|
212
|
+
}
|
|
275
213
|
};
|
|
214
|
+
/**
|
|
215
|
+
* @deprecated Use the {@link useChat} composable instead. It exposes reactive
|
|
216
|
+
* refs and automatically recreates the chat when its init object changes.
|
|
217
|
+
*/
|
|
276
218
|
var Chat = class extends AbstractChat {
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
219
|
+
constructor({ messages, ...init }) {
|
|
220
|
+
super({
|
|
221
|
+
...init,
|
|
222
|
+
state: new VueChatState$1(messages)
|
|
223
|
+
});
|
|
224
|
+
}
|
|
283
225
|
};
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
import {
|
|
287
|
-
AbstractChat as AbstractChat2
|
|
288
|
-
} from "ai";
|
|
289
|
-
import {
|
|
290
|
-
computed,
|
|
291
|
-
getCurrentScope,
|
|
292
|
-
onScopeDispose,
|
|
293
|
-
shallowRef,
|
|
294
|
-
toValue,
|
|
295
|
-
watch
|
|
296
|
-
} from "vue";
|
|
226
|
+
//#endregion
|
|
227
|
+
//#region src/use-chat.ts
|
|
297
228
|
function cloneMetadata(metadata) {
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
if (metadata != null && typeof metadata === "object" && (Object.getPrototypeOf(metadata) === Object.prototype || Object.getPrototypeOf(metadata) === null)) {
|
|
302
|
-
return { ...metadata };
|
|
303
|
-
}
|
|
304
|
-
return metadata;
|
|
229
|
+
if (Array.isArray(metadata)) return [...metadata];
|
|
230
|
+
if (metadata != null && typeof metadata === "object" && (Object.getPrototypeOf(metadata) === Object.prototype || Object.getPrototypeOf(metadata) === null)) return { ...metadata };
|
|
231
|
+
return metadata;
|
|
305
232
|
}
|
|
306
233
|
function snapshotValue(value) {
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
if ("metadata" in message) {
|
|
316
|
-
snapshot.metadata = cloneMetadata(message.metadata);
|
|
317
|
-
}
|
|
318
|
-
return snapshot;
|
|
234
|
+
if (value == null || typeof value !== "object" || !("parts" in value) || !Array.isArray(value.parts)) return value;
|
|
235
|
+
const message = value;
|
|
236
|
+
const snapshot = {
|
|
237
|
+
...message,
|
|
238
|
+
parts: message.parts.map((part) => ({ ...part }))
|
|
239
|
+
};
|
|
240
|
+
if ("metadata" in message) snapshot.metadata = cloneMetadata(message.metadata);
|
|
241
|
+
return snapshot;
|
|
319
242
|
}
|
|
320
|
-
var
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
}
|
|
437
|
-
flushPublication() {
|
|
438
|
-
if (this.timeout != null) {
|
|
439
|
-
clearTimeout(this.timeout);
|
|
440
|
-
this.timeout = void 0;
|
|
441
|
-
}
|
|
442
|
-
this.hasPendingPublication = false;
|
|
443
|
-
this.publishMessages();
|
|
444
|
-
}
|
|
445
|
-
publishMessages() {
|
|
446
|
-
if (!this.isActive) {
|
|
447
|
-
return;
|
|
448
|
-
}
|
|
449
|
-
const publishedMessages = this.messagesValue.map(
|
|
450
|
-
(message, index) => this.dirtyMessageIndices.has(index) || this.publishedMessageSources[index] !== message ? snapshotValue(message) : this.publishedMessages[index]
|
|
451
|
-
);
|
|
452
|
-
this.publishedMessages = publishedMessages;
|
|
453
|
-
this.publishedMessageSources = [...this.messagesValue];
|
|
454
|
-
this.dirtyMessageIndices.clear();
|
|
455
|
-
this.isPublishing = true;
|
|
456
|
-
try {
|
|
457
|
-
this.messagesRef.value = publishedMessages;
|
|
458
|
-
} finally {
|
|
459
|
-
this.isPublishing = false;
|
|
460
|
-
}
|
|
461
|
-
}
|
|
243
|
+
var VueChatState = class {
|
|
244
|
+
constructor({ initialMessages, messagesRef, statusRef, errorRef, throttleWaitMs }) {
|
|
245
|
+
this.publishedMessages = [];
|
|
246
|
+
this.publishedMessageSources = [];
|
|
247
|
+
this.dirtyMessageIndices = /* @__PURE__ */ new Set();
|
|
248
|
+
this.statusValue = "ready";
|
|
249
|
+
this.hasPendingPublication = false;
|
|
250
|
+
this.isActive = true;
|
|
251
|
+
this.isPublishing = false;
|
|
252
|
+
this.pushMessage = (message) => {
|
|
253
|
+
this.messagesValue.push(message);
|
|
254
|
+
this.dirtyMessageIndices.add(this.messagesValue.length - 1);
|
|
255
|
+
this.schedulePublication();
|
|
256
|
+
};
|
|
257
|
+
this.popMessage = () => {
|
|
258
|
+
this.messagesValue.pop();
|
|
259
|
+
this.schedulePublication();
|
|
260
|
+
};
|
|
261
|
+
this.replaceMessage = (index, message) => {
|
|
262
|
+
this.messagesValue[index] = message;
|
|
263
|
+
this.dirtyMessageIndices.add(index);
|
|
264
|
+
this.schedulePublication();
|
|
265
|
+
};
|
|
266
|
+
this.snapshot = snapshotValue;
|
|
267
|
+
this.handleIntervalEnd = () => {
|
|
268
|
+
this.timeout = void 0;
|
|
269
|
+
if (!this.isActive || !this.hasPendingPublication) return;
|
|
270
|
+
this.hasPendingPublication = false;
|
|
271
|
+
this.publishMessages();
|
|
272
|
+
this.timeout = setTimeout(this.handleIntervalEnd, this.throttleWaitMs);
|
|
273
|
+
};
|
|
274
|
+
this.messagesValue = initialMessages;
|
|
275
|
+
this.messagesRef = messagesRef;
|
|
276
|
+
this.statusRef = statusRef;
|
|
277
|
+
this.errorRef = errorRef;
|
|
278
|
+
this.throttleWaitMs = throttleWaitMs != null && Number.isFinite(throttleWaitMs) && throttleWaitMs > 0 ? throttleWaitMs : void 0;
|
|
279
|
+
}
|
|
280
|
+
get messages() {
|
|
281
|
+
return this.messagesValue;
|
|
282
|
+
}
|
|
283
|
+
set messages(messages) {
|
|
284
|
+
const previousMessages = this.messagesValue;
|
|
285
|
+
this.messagesValue = messages;
|
|
286
|
+
for (let index = 0; index < messages.length; index++) if (messages[index] !== previousMessages[index]) this.dirtyMessageIndices.add(index);
|
|
287
|
+
this.schedulePublication();
|
|
288
|
+
}
|
|
289
|
+
get status() {
|
|
290
|
+
return this.statusValue;
|
|
291
|
+
}
|
|
292
|
+
set status(status) {
|
|
293
|
+
this.statusValue = status;
|
|
294
|
+
if (!this.isActive) return;
|
|
295
|
+
if (status === "ready" || status === "error") this.flushPublication();
|
|
296
|
+
this.statusRef.value = status;
|
|
297
|
+
}
|
|
298
|
+
get error() {
|
|
299
|
+
return this.errorValue;
|
|
300
|
+
}
|
|
301
|
+
set error(error) {
|
|
302
|
+
this.errorValue = error;
|
|
303
|
+
if (this.isActive) this.errorRef.value = error;
|
|
304
|
+
}
|
|
305
|
+
publishInitialState() {
|
|
306
|
+
this.publishMessages();
|
|
307
|
+
this.statusRef.value = this.statusValue;
|
|
308
|
+
this.errorRef.value = this.errorValue;
|
|
309
|
+
}
|
|
310
|
+
setMessagesFromConsumer(messages) {
|
|
311
|
+
this.messagesValue = messages;
|
|
312
|
+
this.publishedMessages = messages;
|
|
313
|
+
this.publishedMessageSources = messages;
|
|
314
|
+
this.dirtyMessageIndices.clear();
|
|
315
|
+
}
|
|
316
|
+
dispose() {
|
|
317
|
+
this.isActive = false;
|
|
318
|
+
this.hasPendingPublication = false;
|
|
319
|
+
this.dirtyMessageIndices.clear();
|
|
320
|
+
this.publishedMessages = [];
|
|
321
|
+
this.publishedMessageSources = [];
|
|
322
|
+
if (this.timeout != null) {
|
|
323
|
+
clearTimeout(this.timeout);
|
|
324
|
+
this.timeout = void 0;
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
schedulePublication() {
|
|
328
|
+
if (!this.isActive) return;
|
|
329
|
+
if (this.throttleWaitMs == null) {
|
|
330
|
+
this.publishMessages();
|
|
331
|
+
return;
|
|
332
|
+
}
|
|
333
|
+
if (this.timeout == null) {
|
|
334
|
+
this.publishMessages();
|
|
335
|
+
this.timeout = setTimeout(this.handleIntervalEnd, this.throttleWaitMs);
|
|
336
|
+
} else this.hasPendingPublication = true;
|
|
337
|
+
}
|
|
338
|
+
flushPublication() {
|
|
339
|
+
if (this.timeout != null) {
|
|
340
|
+
clearTimeout(this.timeout);
|
|
341
|
+
this.timeout = void 0;
|
|
342
|
+
}
|
|
343
|
+
this.hasPendingPublication = false;
|
|
344
|
+
this.publishMessages();
|
|
345
|
+
}
|
|
346
|
+
publishMessages() {
|
|
347
|
+
if (!this.isActive) return;
|
|
348
|
+
const publishedMessages = this.messagesValue.map((message, index) => this.dirtyMessageIndices.has(index) || this.publishedMessageSources[index] !== message ? snapshotValue(message) : this.publishedMessages[index]);
|
|
349
|
+
this.publishedMessages = publishedMessages;
|
|
350
|
+
this.publishedMessageSources = [...this.messagesValue];
|
|
351
|
+
this.dirtyMessageIndices.clear();
|
|
352
|
+
this.isPublishing = true;
|
|
353
|
+
try {
|
|
354
|
+
this.messagesRef.value = publishedMessages;
|
|
355
|
+
} finally {
|
|
356
|
+
this.isPublishing = false;
|
|
357
|
+
}
|
|
358
|
+
}
|
|
462
359
|
};
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
360
|
+
/**
|
|
361
|
+
* @internal
|
|
362
|
+
*/
|
|
363
|
+
var VueChat = class extends AbstractChat {
|
|
364
|
+
constructor({ state, ...init }) {
|
|
365
|
+
super({
|
|
366
|
+
...init,
|
|
367
|
+
state
|
|
368
|
+
});
|
|
369
|
+
}
|
|
473
370
|
};
|
|
371
|
+
/**
|
|
372
|
+
* Composable to access messages, status, and other chat properties and
|
|
373
|
+
* methods. Accepts an optional reactive initial configuration object
|
|
374
|
+
*
|
|
375
|
+
* @example
|
|
376
|
+
*
|
|
377
|
+
* ```ts
|
|
378
|
+
* // passing a getter if any reactive properties are used within
|
|
379
|
+
* // the init object
|
|
380
|
+
* const { messages, sendMessage } = useChat(() => ({
|
|
381
|
+
* // ...
|
|
382
|
+
* })
|
|
383
|
+
* ```
|
|
384
|
+
*
|
|
385
|
+
* @see BaseChatInit
|
|
386
|
+
*/
|
|
474
387
|
function useChat(init) {
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
id: computed(() => chatInstance.value.id),
|
|
517
|
-
status,
|
|
518
|
-
messages,
|
|
519
|
-
error,
|
|
520
|
-
addToolApprovalResponse: (opts) => chatInstance.value.addToolApprovalResponse(opts),
|
|
521
|
-
addToolOutput: (opts) => chatInstance.value.addToolOutput(opts),
|
|
522
|
-
clearError: () => chatInstance.value.clearError(),
|
|
523
|
-
regenerate: (opts) => chatInstance.value.regenerate(opts),
|
|
524
|
-
sendMessage: (...args) => chatInstance.value.sendMessage(...args),
|
|
525
|
-
stop: () => chatInstance.value.stop(),
|
|
526
|
-
resumeStream: (opts) => chatInstance.value.resumeStream(opts)
|
|
527
|
-
};
|
|
388
|
+
const messages = shallowRef([]);
|
|
389
|
+
const status = shallowRef("ready");
|
|
390
|
+
const error = shallowRef();
|
|
391
|
+
const chatInstance = shallowRef();
|
|
392
|
+
let chatState;
|
|
393
|
+
watch(messages, (messageList) => {
|
|
394
|
+
if (chatState != null && !chatState.isPublishing) chatState.setMessagesFromConsumer(messageList);
|
|
395
|
+
}, { flush: "sync" });
|
|
396
|
+
watch(() => toValue(init), (opts) => {
|
|
397
|
+
chatState?.dispose();
|
|
398
|
+
const { throttle, ...chatInit } = opts ?? {};
|
|
399
|
+
const nextChatState = new VueChatState({
|
|
400
|
+
initialMessages: chatInit.messages ?? [],
|
|
401
|
+
messagesRef: messages,
|
|
402
|
+
statusRef: status,
|
|
403
|
+
errorRef: error,
|
|
404
|
+
throttleWaitMs: throttle
|
|
405
|
+
});
|
|
406
|
+
chatState = nextChatState;
|
|
407
|
+
nextChatState.publishInitialState();
|
|
408
|
+
chatInstance.value = new VueChat({
|
|
409
|
+
...chatInit,
|
|
410
|
+
state: nextChatState
|
|
411
|
+
});
|
|
412
|
+
}, { immediate: true });
|
|
413
|
+
if (getCurrentScope() != null) onScopeDispose(() => {
|
|
414
|
+
chatState?.dispose();
|
|
415
|
+
});
|
|
416
|
+
return {
|
|
417
|
+
id: computed(() => chatInstance.value.id),
|
|
418
|
+
status,
|
|
419
|
+
messages,
|
|
420
|
+
error,
|
|
421
|
+
addToolApprovalResponse: (opts) => chatInstance.value.addToolApprovalResponse(opts),
|
|
422
|
+
addToolOutput: (opts) => chatInstance.value.addToolOutput(opts),
|
|
423
|
+
clearError: () => chatInstance.value.clearError(),
|
|
424
|
+
regenerate: (opts) => chatInstance.value.regenerate(opts),
|
|
425
|
+
sendMessage: (...args) => chatInstance.value.sendMessage(...args),
|
|
426
|
+
stop: () => chatInstance.value.stop(),
|
|
427
|
+
resumeStream: (opts) => chatInstance.value.resumeStream(opts)
|
|
428
|
+
};
|
|
528
429
|
}
|
|
430
|
+
//#endregion
|
|
431
|
+
//#region src/index.ts
|
|
432
|
+
/**
|
|
433
|
+
* @deprecated Use `useObject` instead.
|
|
434
|
+
*/
|
|
435
|
+
const experimental_useObject = useObject;
|
|
436
|
+
//#endregion
|
|
437
|
+
export { Chat, experimental_useObject, useChat, useCompletion, useObject };
|
|
529
438
|
|
|
530
|
-
// src/index.ts
|
|
531
|
-
var experimental_useObject = useObject;
|
|
532
|
-
export {
|
|
533
|
-
Chat,
|
|
534
|
-
experimental_useObject,
|
|
535
|
-
useChat,
|
|
536
|
-
useCompletion,
|
|
537
|
-
useObject
|
|
538
|
-
};
|
|
539
439
|
//# sourceMappingURL=index.js.map
|