@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/dist/index.js CHANGED
@@ -1,539 +1,439 @@
1
- // src/use-object.ts
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
- var getOriginalFetch = () => fetch;
14
- var uniqueId = 0;
15
- var useSWRV = swrv.default || swrv;
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
- const completionId = id || `completion-${uniqueId++}`;
29
- const key = `${api}|${completionId}`;
30
- const { data, mutate: originalMutate } = useSWRV(key, () => key in store ? store[key] : initialValue);
31
- const { data: isLoading, mutate: mutateLoading } = useSWRV(
32
- `${completionId}-loading`,
33
- null
34
- );
35
- isLoading.value ??= false;
36
- data.value ||= initialValue;
37
- const mutateObject = (value) => {
38
- store[key] = value;
39
- return originalMutate();
40
- };
41
- const error = ref(void 0);
42
- let abortController = null;
43
- const stop = async () => {
44
- if (abortController) {
45
- try {
46
- abortController.abort();
47
- } catch {
48
- } finally {
49
- abortController = null;
50
- }
51
- }
52
- await mutateLoading(() => false);
53
- };
54
- const clearObject = async () => {
55
- error.value = void 0;
56
- await mutateLoading(() => false);
57
- await mutateObject(void 0);
58
- data.value = void 0;
59
- };
60
- const clear = async () => {
61
- await stop();
62
- await clearObject();
63
- };
64
- const submit = async (input) => {
65
- try {
66
- await clearObject();
67
- await mutateLoading(() => true);
68
- abortController = new AbortController();
69
- const actualFetch = fetch2 ?? getOriginalFetch();
70
- const response = await actualFetch(api, {
71
- method: "POST",
72
- headers: {
73
- "Content-Type": "application/json",
74
- ...headers
75
- },
76
- credentials: credentials ?? "same-origin",
77
- signal: abortController.signal,
78
- body: JSON.stringify(input)
79
- });
80
- if (!response.ok) {
81
- throw new Error(
82
- await response.text() || "Failed to fetch the response."
83
- );
84
- }
85
- if (!response.body) {
86
- throw new Error("The response body is empty.");
87
- }
88
- let accumulatedText = "";
89
- let latestObject = void 0;
90
- await response.body.pipeThrough(new TextDecoderStream()).pipeTo(
91
- new WritableStream({
92
- async write(chunk) {
93
- accumulatedText += chunk;
94
- const { value } = await parsePartialJson(accumulatedText);
95
- const currentObject = value;
96
- if (!isDeepEqualData(latestObject, currentObject)) {
97
- latestObject = currentObject;
98
- await mutateObject(currentObject);
99
- }
100
- },
101
- async close() {
102
- await mutateLoading(() => false);
103
- abortController = null;
104
- if (onFinish) {
105
- const validationResult = await safeValidateTypes({
106
- value: latestObject,
107
- schema: asSchema(schema)
108
- });
109
- onFinish(
110
- validationResult.success ? {
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
- // src/use-completion.ts
139
- import {
140
- callCompletionApi
141
- } from "ai";
142
- import swrv2 from "swrv";
143
- import { ref as ref2, unref } from "vue";
144
- var uniqueId2 = 0;
145
- var useSWRV2 = swrv2.default || swrv2;
146
- var store2 = {};
147
- function useCompletion({
148
- api = "/api/completion",
149
- id,
150
- initialCompletion = "",
151
- initialInput = "",
152
- credentials,
153
- headers,
154
- body,
155
- streamProtocol,
156
- onFinish,
157
- onError,
158
- fetch: fetch2
159
- } = {}) {
160
- const completionId = id || `completion-${uniqueId2++}`;
161
- const key = `${api}|${completionId}`;
162
- const { data, mutate: originalMutate } = useSWRV2(
163
- key,
164
- () => store2[key] ?? initialCompletion
165
- );
166
- const { data: isLoading, mutate: mutateLoading } = useSWRV2(
167
- `${completionId}-loading`,
168
- null
169
- );
170
- isLoading.value ??= false;
171
- data.value ??= initialCompletion;
172
- const mutate = (data2) => {
173
- store2[key] = data2;
174
- return originalMutate();
175
- };
176
- const completion = data;
177
- const error = ref2(void 0);
178
- let abortController = null;
179
- async function triggerRequest(prompt, options) {
180
- return callCompletionApi({
181
- api,
182
- prompt,
183
- credentials,
184
- headers: {
185
- ...headers,
186
- ...options?.headers
187
- },
188
- body: {
189
- ...unref(body),
190
- ...options?.body
191
- },
192
- streamProtocol,
193
- setCompletion: mutate,
194
- setLoading: (loading) => mutateLoading(() => loading),
195
- setError: (err) => {
196
- error.value = err;
197
- },
198
- setAbortController: (controller) => {
199
- abortController = controller;
200
- },
201
- getAbortController: () => abortController,
202
- onFinish,
203
- onError,
204
- fetch: fetch2
205
- });
206
- }
207
- const complete = async (prompt, options) => {
208
- return triggerRequest(prompt, options);
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
- // src/chat.vue.ts
237
- import {
238
- AbstractChat
239
- } from "ai";
240
- import { ref as ref3 } from "vue";
241
- var VueChatState = class {
242
- constructor(messages) {
243
- this.statusRef = ref3("ready");
244
- this.errorRef = ref3(void 0);
245
- this.pushMessage = (message) => {
246
- this.messagesRef.value = [...this.messagesRef.value, message];
247
- };
248
- this.popMessage = () => {
249
- this.messagesRef.value = this.messagesRef.value.slice(0, -1);
250
- };
251
- this.replaceMessage = (index, message) => {
252
- this.messagesRef.value[index] = { ...message };
253
- };
254
- this.snapshot = (value) => value;
255
- this.messagesRef = ref3(messages ?? []);
256
- }
257
- get messages() {
258
- return this.messagesRef.value;
259
- }
260
- set messages(messages) {
261
- this.messagesRef.value = messages;
262
- }
263
- get status() {
264
- return this.statusRef.value;
265
- }
266
- set status(status) {
267
- this.statusRef.value = status;
268
- }
269
- get error() {
270
- return this.errorRef.value;
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
- constructor({ messages, ...init }) {
278
- super({
279
- ...init,
280
- state: new VueChatState(messages)
281
- });
282
- }
219
+ constructor({ messages, ...init }) {
220
+ super({
221
+ ...init,
222
+ state: new VueChatState$1(messages)
223
+ });
224
+ }
283
225
  };
284
-
285
- // src/use-chat.ts
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
- if (Array.isArray(metadata)) {
299
- return [...metadata];
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
- if (value == null || typeof value !== "object" || !("parts" in value) || !Array.isArray(value.parts)) {
308
- return value;
309
- }
310
- const message = value;
311
- const snapshot = {
312
- ...message,
313
- parts: message.parts.map((part) => ({ ...part }))
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 VueChatState2 = class {
321
- constructor({
322
- initialMessages,
323
- messagesRef,
324
- statusRef,
325
- errorRef,
326
- throttleWaitMs
327
- }) {
328
- this.publishedMessages = [];
329
- this.publishedMessageSources = [];
330
- this.dirtyMessageIndices = /* @__PURE__ */ new Set();
331
- this.statusValue = "ready";
332
- this.hasPendingPublication = false;
333
- this.isActive = true;
334
- this.isPublishing = false;
335
- this.pushMessage = (message) => {
336
- this.messagesValue.push(message);
337
- this.dirtyMessageIndices.add(this.messagesValue.length - 1);
338
- this.schedulePublication();
339
- };
340
- this.popMessage = () => {
341
- this.messagesValue.pop();
342
- this.schedulePublication();
343
- };
344
- this.replaceMessage = (index, message) => {
345
- this.messagesValue[index] = message;
346
- this.dirtyMessageIndices.add(index);
347
- this.schedulePublication();
348
- };
349
- this.snapshot = snapshotValue;
350
- this.handleIntervalEnd = () => {
351
- this.timeout = void 0;
352
- if (!this.isActive || !this.hasPendingPublication) {
353
- return;
354
- }
355
- this.hasPendingPublication = false;
356
- this.publishMessages();
357
- this.timeout = setTimeout(this.handleIntervalEnd, this.throttleWaitMs);
358
- };
359
- this.messagesValue = initialMessages;
360
- this.messagesRef = messagesRef;
361
- this.statusRef = statusRef;
362
- this.errorRef = errorRef;
363
- this.throttleWaitMs = throttleWaitMs != null && Number.isFinite(throttleWaitMs) && throttleWaitMs > 0 ? throttleWaitMs : void 0;
364
- }
365
- get messages() {
366
- return this.messagesValue;
367
- }
368
- set messages(messages) {
369
- const previousMessages = this.messagesValue;
370
- this.messagesValue = messages;
371
- for (let index = 0; index < messages.length; index++) {
372
- if (messages[index] !== previousMessages[index]) {
373
- this.dirtyMessageIndices.add(index);
374
- }
375
- }
376
- this.schedulePublication();
377
- }
378
- get status() {
379
- return this.statusValue;
380
- }
381
- set status(status) {
382
- this.statusValue = status;
383
- if (!this.isActive) {
384
- return;
385
- }
386
- if (status === "ready" || status === "error") {
387
- this.flushPublication();
388
- }
389
- this.statusRef.value = status;
390
- }
391
- get error() {
392
- return this.errorValue;
393
- }
394
- set error(error) {
395
- this.errorValue = error;
396
- if (this.isActive) {
397
- this.errorRef.value = error;
398
- }
399
- }
400
- publishInitialState() {
401
- this.publishMessages();
402
- this.statusRef.value = this.statusValue;
403
- this.errorRef.value = this.errorValue;
404
- }
405
- setMessagesFromConsumer(messages) {
406
- this.messagesValue = messages;
407
- this.publishedMessages = messages;
408
- this.publishedMessageSources = messages;
409
- this.dirtyMessageIndices.clear();
410
- }
411
- dispose() {
412
- this.isActive = false;
413
- this.hasPendingPublication = false;
414
- this.dirtyMessageIndices.clear();
415
- this.publishedMessages = [];
416
- this.publishedMessageSources = [];
417
- if (this.timeout != null) {
418
- clearTimeout(this.timeout);
419
- this.timeout = void 0;
420
- }
421
- }
422
- schedulePublication() {
423
- if (!this.isActive) {
424
- return;
425
- }
426
- if (this.throttleWaitMs == null) {
427
- this.publishMessages();
428
- return;
429
- }
430
- if (this.timeout == null) {
431
- this.publishMessages();
432
- this.timeout = setTimeout(this.handleIntervalEnd, this.throttleWaitMs);
433
- } else {
434
- this.hasPendingPublication = true;
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
- var VueChat = class extends AbstractChat2 {
464
- constructor({
465
- state,
466
- ...init
467
- }) {
468
- super({
469
- ...init,
470
- state
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
- const messages = shallowRef([]);
476
- const status = shallowRef("ready");
477
- const error = shallowRef();
478
- const chatInstance = shallowRef();
479
- let chatState;
480
- watch(
481
- messages,
482
- (messageList) => {
483
- if (chatState != null && !chatState.isPublishing) {
484
- chatState.setMessagesFromConsumer(messageList);
485
- }
486
- },
487
- { flush: "sync" }
488
- );
489
- watch(
490
- () => toValue(init),
491
- (opts) => {
492
- chatState?.dispose();
493
- const { throttle, ...chatInit } = opts ?? {};
494
- const nextChatState = new VueChatState2({
495
- initialMessages: chatInit.messages ?? [],
496
- messagesRef: messages,
497
- statusRef: status,
498
- errorRef: error,
499
- throttleWaitMs: throttle
500
- });
501
- chatState = nextChatState;
502
- nextChatState.publishInitialState();
503
- chatInstance.value = new VueChat({
504
- ...chatInit,
505
- state: nextChatState
506
- });
507
- },
508
- { immediate: true }
509
- );
510
- if (getCurrentScope() != null) {
511
- onScopeDispose(() => {
512
- chatState?.dispose();
513
- });
514
- }
515
- return {
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