@ai-sdk/svelte 1.1.24 → 2.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +13 -0
- package/README.md +5 -3
- package/dist/chat-context.svelte.d.ts +14 -0
- package/dist/chat-context.svelte.d.ts.map +1 -0
- package/dist/chat-context.svelte.js +13 -0
- package/dist/chat.svelte.d.ts +75 -0
- package/dist/chat.svelte.d.ts.map +1 -0
- package/dist/chat.svelte.js +244 -0
- package/dist/completion-context.svelte.d.ts +15 -0
- package/dist/completion-context.svelte.d.ts.map +1 -0
- package/dist/completion-context.svelte.js +14 -0
- package/dist/completion.svelte.d.ts +37 -0
- package/dist/completion.svelte.d.ts.map +1 -0
- package/dist/completion.svelte.js +111 -0
- package/dist/context-provider.d.ts +2 -0
- package/dist/context-provider.d.ts.map +1 -0
- package/dist/context-provider.js +11 -0
- package/dist/index.d.ts +5 -166
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +4 -551
- package/dist/structured-object-context.svelte.d.ts +12 -0
- package/dist/structured-object-context.svelte.d.ts.map +1 -0
- package/dist/structured-object-context.svelte.js +12 -0
- package/dist/structured-object.svelte.d.ts +73 -0
- package/dist/structured-object.svelte.d.ts.map +1 -0
- package/dist/structured-object.svelte.js +123 -0
- package/dist/tests/chat-synchronization.svelte +12 -0
- package/dist/tests/chat-synchronization.svelte.d.ts +11 -0
- package/dist/tests/chat-synchronization.svelte.d.ts.map +1 -0
- package/dist/tests/completion-synchronization.svelte +12 -0
- package/dist/tests/completion-synchronization.svelte.d.ts +11 -0
- package/dist/tests/completion-synchronization.svelte.d.ts.map +1 -0
- package/dist/tests/structured-object-synchronization.svelte +22 -0
- package/dist/tests/structured-object-synchronization.svelte.d.ts +28 -0
- package/dist/tests/structured-object-synchronization.svelte.d.ts.map +1 -0
- package/dist/utils.svelte.d.ts +17 -0
- package/dist/utils.svelte.d.ts.map +1 -0
- package/dist/utils.svelte.js +50 -0
- package/package.json +56 -35
- package/src/chat-context.svelte.ts +23 -0
- package/src/chat.svelte.ts +341 -0
- package/src/completion-context.svelte.ts +24 -0
- package/src/completion.svelte.ts +133 -0
- package/src/context-provider.ts +20 -0
- package/src/index.ts +16 -0
- package/src/structured-object-context.svelte.ts +27 -0
- package/src/structured-object.svelte.ts +222 -0
- package/src/tests/chat-synchronization.svelte +12 -0
- package/src/tests/completion-synchronization.svelte +12 -0
- package/src/tests/structured-object-synchronization.svelte +22 -0
- package/src/utils.svelte.ts +66 -0
- package/dist/index.d.mts +0 -166
- package/dist/index.js.map +0 -1
- package/dist/index.mjs +0 -532
- package/dist/index.mjs.map +0 -1
|
@@ -0,0 +1,222 @@
|
|
|
1
|
+
import {
|
|
2
|
+
generateId,
|
|
3
|
+
isAbortError,
|
|
4
|
+
safeValidateTypes,
|
|
5
|
+
type FetchFunction,
|
|
6
|
+
} from '@ai-sdk/provider-utils';
|
|
7
|
+
import {
|
|
8
|
+
asSchema,
|
|
9
|
+
isDeepEqualData,
|
|
10
|
+
parsePartialJson,
|
|
11
|
+
type DeepPartial,
|
|
12
|
+
type Schema,
|
|
13
|
+
} from '@ai-sdk/ui-utils';
|
|
14
|
+
import { type z } from 'zod';
|
|
15
|
+
import {
|
|
16
|
+
getStructuredObjectContext,
|
|
17
|
+
hasStructuredObjectContext,
|
|
18
|
+
KeyedStructuredObjectStore,
|
|
19
|
+
type StructuredObjectStore,
|
|
20
|
+
} from './structured-object-context.svelte.js';
|
|
21
|
+
|
|
22
|
+
export type Experimental_StructuredObjectOptions<RESULT> = {
|
|
23
|
+
/**
|
|
24
|
+
* The API endpoint. It should stream JSON that matches the schema as chunked text.
|
|
25
|
+
*/
|
|
26
|
+
api: string;
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* A Zod schema that defines the shape of the complete object.
|
|
30
|
+
*/
|
|
31
|
+
schema: z.Schema<RESULT, z.ZodTypeDef, unknown> | Schema<RESULT>;
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* An unique identifier. If not provided, a random one will be
|
|
35
|
+
* generated. When provided, the `useObject` hook with the same `id` will
|
|
36
|
+
* have shared states across components.
|
|
37
|
+
*/
|
|
38
|
+
id?: string;
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* An optional value for the initial object.
|
|
42
|
+
*/
|
|
43
|
+
initialValue?: DeepPartial<RESULT>;
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Custom fetch implementation. You can use it as a middleware to intercept requests,
|
|
47
|
+
* or to provide a custom fetch implementation for e.g. testing.
|
|
48
|
+
*/
|
|
49
|
+
fetch?: FetchFunction;
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Callback that is called when the stream has finished.
|
|
53
|
+
*/
|
|
54
|
+
onFinish?: (event: {
|
|
55
|
+
/**
|
|
56
|
+
* The generated object (typed according to the schema).
|
|
57
|
+
* Can be undefined if the final object does not match the schema.
|
|
58
|
+
*/
|
|
59
|
+
object: RESULT | undefined;
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* Optional error object. This is e.g. a TypeValidationError when the final object does not match the schema.
|
|
63
|
+
*/
|
|
64
|
+
error: Error | undefined;
|
|
65
|
+
}) => Promise<void> | void;
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* Callback function to be called when an error is encountered.
|
|
69
|
+
*/
|
|
70
|
+
onError?: (error: Error) => void;
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Additional HTTP headers to be included in the request.
|
|
74
|
+
*/
|
|
75
|
+
headers?: Record<string, string> | Headers;
|
|
76
|
+
};
|
|
77
|
+
|
|
78
|
+
export class StructuredObject<RESULT, INPUT = unknown> {
|
|
79
|
+
#options: Experimental_StructuredObjectOptions<RESULT> =
|
|
80
|
+
{} as Experimental_StructuredObjectOptions<RESULT>;
|
|
81
|
+
readonly #id = $derived(this.#options.id ?? generateId());
|
|
82
|
+
readonly #keyedStore = $state<KeyedStructuredObjectStore>()!;
|
|
83
|
+
readonly #store = $derived(
|
|
84
|
+
this.#keyedStore.get(this.#id),
|
|
85
|
+
) as StructuredObjectStore<RESULT>;
|
|
86
|
+
#abortController: AbortController | undefined;
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* The current value for the generated object. Updated as the API streams JSON chunks.
|
|
90
|
+
*/
|
|
91
|
+
get object(): DeepPartial<RESULT> | undefined {
|
|
92
|
+
return this.#store.object;
|
|
93
|
+
}
|
|
94
|
+
set #object(value: DeepPartial<RESULT> | undefined) {
|
|
95
|
+
this.#store.object = value;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/** The error object of the API request */
|
|
99
|
+
get error() {
|
|
100
|
+
return this.#store.error;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
/**
|
|
104
|
+
* Flag that indicates whether an API request is in progress.
|
|
105
|
+
*/
|
|
106
|
+
get loading() {
|
|
107
|
+
return this.#store.loading;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
constructor(options: Experimental_StructuredObjectOptions<RESULT>) {
|
|
111
|
+
if (hasStructuredObjectContext()) {
|
|
112
|
+
this.#keyedStore = getStructuredObjectContext();
|
|
113
|
+
} else {
|
|
114
|
+
this.#keyedStore = new KeyedStructuredObjectStore();
|
|
115
|
+
}
|
|
116
|
+
this.#options = options;
|
|
117
|
+
this.#object = options.initialValue;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
/**
|
|
121
|
+
* Abort the current request immediately, keep the current partial object if any.
|
|
122
|
+
*/
|
|
123
|
+
stop = () => {
|
|
124
|
+
try {
|
|
125
|
+
this.#abortController?.abort();
|
|
126
|
+
} catch {
|
|
127
|
+
// ignore
|
|
128
|
+
} finally {
|
|
129
|
+
this.#store.loading = false;
|
|
130
|
+
this.#abortController = undefined;
|
|
131
|
+
}
|
|
132
|
+
};
|
|
133
|
+
|
|
134
|
+
/**
|
|
135
|
+
* Calls the API with the provided input as JSON body.
|
|
136
|
+
*/
|
|
137
|
+
submit = async (input: INPUT) => {
|
|
138
|
+
try {
|
|
139
|
+
this.#store.object = undefined; // reset the data
|
|
140
|
+
this.#store.loading = true;
|
|
141
|
+
this.#store.error = undefined;
|
|
142
|
+
|
|
143
|
+
const abortController = new AbortController();
|
|
144
|
+
this.#abortController = abortController;
|
|
145
|
+
|
|
146
|
+
const actualFetch = this.#options.fetch ?? fetch;
|
|
147
|
+
const response = await actualFetch(this.#options.api, {
|
|
148
|
+
method: 'POST',
|
|
149
|
+
headers: {
|
|
150
|
+
'Content-Type': 'application/json',
|
|
151
|
+
...this.#options.headers,
|
|
152
|
+
},
|
|
153
|
+
signal: abortController.signal,
|
|
154
|
+
body: JSON.stringify(input),
|
|
155
|
+
});
|
|
156
|
+
|
|
157
|
+
if (!response.ok) {
|
|
158
|
+
throw new Error(
|
|
159
|
+
(await response.text()) ?? 'Failed to fetch the response.',
|
|
160
|
+
);
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
if (response.body == null) {
|
|
164
|
+
throw new Error('The response body is empty.');
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
let accumulatedText = '';
|
|
168
|
+
let latestObject: DeepPartial<RESULT> | undefined = undefined;
|
|
169
|
+
|
|
170
|
+
await response.body.pipeThrough(new TextDecoderStream()).pipeTo(
|
|
171
|
+
new WritableStream<string>({
|
|
172
|
+
write: chunk => {
|
|
173
|
+
if (abortController?.signal.aborted) {
|
|
174
|
+
throw new DOMException('Stream aborted', 'AbortError');
|
|
175
|
+
}
|
|
176
|
+
accumulatedText += chunk;
|
|
177
|
+
|
|
178
|
+
const { value } = parsePartialJson(accumulatedText);
|
|
179
|
+
const currentObject = value as DeepPartial<RESULT>;
|
|
180
|
+
|
|
181
|
+
if (!isDeepEqualData(latestObject, currentObject)) {
|
|
182
|
+
latestObject = currentObject;
|
|
183
|
+
|
|
184
|
+
this.#store.object = currentObject;
|
|
185
|
+
}
|
|
186
|
+
},
|
|
187
|
+
|
|
188
|
+
close: () => {
|
|
189
|
+
this.#store.loading = false;
|
|
190
|
+
this.#abortController = undefined;
|
|
191
|
+
|
|
192
|
+
if (this.#options.onFinish != null) {
|
|
193
|
+
const validationResult = safeValidateTypes({
|
|
194
|
+
value: latestObject,
|
|
195
|
+
schema: asSchema(this.#options.schema),
|
|
196
|
+
});
|
|
197
|
+
|
|
198
|
+
this.#options.onFinish(
|
|
199
|
+
validationResult.success
|
|
200
|
+
? { object: validationResult.value, error: undefined }
|
|
201
|
+
: { object: undefined, error: validationResult.error },
|
|
202
|
+
);
|
|
203
|
+
}
|
|
204
|
+
},
|
|
205
|
+
}),
|
|
206
|
+
);
|
|
207
|
+
} catch (error) {
|
|
208
|
+
if (isAbortError(error)) {
|
|
209
|
+
return;
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
const coalescedError =
|
|
213
|
+
error instanceof Error ? error : new Error(String(error));
|
|
214
|
+
if (this.#options.onError) {
|
|
215
|
+
this.#options.onError(coalescedError);
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
this.#store.loading = false;
|
|
219
|
+
this.#store.error = coalescedError;
|
|
220
|
+
}
|
|
221
|
+
};
|
|
222
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import { Chat } from '../chat.svelte.js';
|
|
3
|
+
import { createAIContext } from '../context-provider.js';
|
|
4
|
+
|
|
5
|
+
let { id }: { id?: string } = $props();
|
|
6
|
+
|
|
7
|
+
createAIContext();
|
|
8
|
+
const chat1 = new Chat({ id });
|
|
9
|
+
const chat2 = new Chat({ id });
|
|
10
|
+
|
|
11
|
+
export { chat1, chat2 };
|
|
12
|
+
</script>
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import { Completion } from '../completion.svelte.js';
|
|
3
|
+
import { createAIContext } from '../context-provider.js';
|
|
4
|
+
|
|
5
|
+
let { id }: { id?: string } = $props();
|
|
6
|
+
|
|
7
|
+
createAIContext();
|
|
8
|
+
const completion1 = new Completion({ id });
|
|
9
|
+
const completion2 = new Completion({ id });
|
|
10
|
+
|
|
11
|
+
export { completion1, completion2 };
|
|
12
|
+
</script>
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
<script lang="ts" generics="RESULT">
|
|
2
|
+
import { createAIContext } from '../context-provider.js';
|
|
3
|
+
import { StructuredObject } from '../structured-object.svelte.js';
|
|
4
|
+
import type { Schema } from '@ai-sdk/ui-utils';
|
|
5
|
+
import type { z } from 'zod';
|
|
6
|
+
|
|
7
|
+
let {
|
|
8
|
+
id,
|
|
9
|
+
api,
|
|
10
|
+
schema,
|
|
11
|
+
}: {
|
|
12
|
+
id?: string;
|
|
13
|
+
api: string;
|
|
14
|
+
schema: z.Schema<RESULT, z.ZodTypeDef, unknown> | Schema<RESULT>;
|
|
15
|
+
} = $props();
|
|
16
|
+
|
|
17
|
+
createAIContext();
|
|
18
|
+
const object1 = new StructuredObject({ id, api, schema });
|
|
19
|
+
const object2 = new StructuredObject({ id, api, schema });
|
|
20
|
+
|
|
21
|
+
export { object1, object2 };
|
|
22
|
+
</script>
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import { hasContext, getContext, setContext, untrack } from 'svelte';
|
|
2
|
+
import { SvelteMap } from 'svelte/reactivity';
|
|
3
|
+
|
|
4
|
+
export function createContext<T>(name: string) {
|
|
5
|
+
const key = Symbol(name);
|
|
6
|
+
return {
|
|
7
|
+
hasContext: () => {
|
|
8
|
+
// At the time of writing there's no way to determine if we're
|
|
9
|
+
// currently initializing a component without a try-catch
|
|
10
|
+
try {
|
|
11
|
+
return hasContext(key);
|
|
12
|
+
} catch (e) {
|
|
13
|
+
if (
|
|
14
|
+
typeof e === 'object' &&
|
|
15
|
+
e !== null &&
|
|
16
|
+
'message' in e &&
|
|
17
|
+
typeof e.message === 'string' &&
|
|
18
|
+
e.message?.includes('lifecycle_outside_component')
|
|
19
|
+
) {
|
|
20
|
+
return false;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
throw e;
|
|
24
|
+
}
|
|
25
|
+
},
|
|
26
|
+
getContext: () => getContext<T>(key),
|
|
27
|
+
setContext: (value: T) => setContext(key, value),
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export function promiseWithResolvers<T>(): {
|
|
32
|
+
promise: Promise<T>;
|
|
33
|
+
resolve: (value: T) => void;
|
|
34
|
+
reject: (reason?: unknown) => void;
|
|
35
|
+
} {
|
|
36
|
+
let resolve: (value: T) => void;
|
|
37
|
+
let reject: (reason?: unknown) => void;
|
|
38
|
+
const promise = new Promise<T>((res, rej) => {
|
|
39
|
+
resolve = res;
|
|
40
|
+
reject = rej;
|
|
41
|
+
});
|
|
42
|
+
return { promise, resolve: resolve!, reject: reject! };
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
export class KeyedStore<T> extends SvelteMap<string, T> {
|
|
46
|
+
#itemConstructor: new () => T;
|
|
47
|
+
|
|
48
|
+
constructor(
|
|
49
|
+
itemConstructor: new () => T,
|
|
50
|
+
value?: Iterable<readonly [string, T]> | null | undefined,
|
|
51
|
+
) {
|
|
52
|
+
super(value);
|
|
53
|
+
this.#itemConstructor = itemConstructor;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
get(key: string): T {
|
|
57
|
+
const test =
|
|
58
|
+
super.get(key) ??
|
|
59
|
+
// Untrack here because this is technically a state mutation, meaning
|
|
60
|
+
// deriveds downstream would fail. Because this is idempotent (even
|
|
61
|
+
// though it's not pure), it's safe.
|
|
62
|
+
untrack(() => this.set(key, new this.#itemConstructor())).get(key)!;
|
|
63
|
+
|
|
64
|
+
return test;
|
|
65
|
+
}
|
|
66
|
+
}
|
package/dist/index.d.mts
DELETED
|
@@ -1,166 +0,0 @@
|
|
|
1
|
-
import { UseChatOptions as UseChatOptions$1, UIMessage, Message, CreateMessage, ChatRequestOptions, JSONValue, RequestOptions, UseCompletionOptions, AssistantStatus, UseAssistantOptions } from '@ai-sdk/ui-utils';
|
|
2
|
-
export { CreateMessage, Message, UseCompletionOptions } from '@ai-sdk/ui-utils';
|
|
3
|
-
import { Readable, Writable } from 'svelte/store';
|
|
4
|
-
|
|
5
|
-
type UseChatOptions = UseChatOptions$1 & {
|
|
6
|
-
/**
|
|
7
|
-
Maximum number of sequential LLM calls (steps), e.g. when you use tool calls. Must be at least 1.
|
|
8
|
-
|
|
9
|
-
A maximum number is required to prevent infinite loops in the case of misconfigured tools.
|
|
10
|
-
|
|
11
|
-
By default, it's set to 1, which means that only a single LLM call is made.
|
|
12
|
-
*/
|
|
13
|
-
maxSteps?: number;
|
|
14
|
-
};
|
|
15
|
-
type UseChatHelpers = {
|
|
16
|
-
/** Current messages in the chat */
|
|
17
|
-
messages: Readable<UIMessage[]>;
|
|
18
|
-
/** The error object of the API request */
|
|
19
|
-
error: Readable<undefined | Error>;
|
|
20
|
-
/**
|
|
21
|
-
* Append a user message to the chat list. This triggers the API call to fetch
|
|
22
|
-
* the assistant's response.
|
|
23
|
-
* @param message The message to append
|
|
24
|
-
* @param chatRequestOptions Additional options to pass to the API call
|
|
25
|
-
*/
|
|
26
|
-
append: (message: Message | CreateMessage, chatRequestOptions?: ChatRequestOptions) => Promise<string | null | undefined>;
|
|
27
|
-
/**
|
|
28
|
-
* Reload the last AI chat response for the given chat history. If the last
|
|
29
|
-
* message isn't from the assistant, it will request the API to generate a
|
|
30
|
-
* new response.
|
|
31
|
-
*/
|
|
32
|
-
reload: (chatRequestOptions?: ChatRequestOptions) => Promise<string | null | undefined>;
|
|
33
|
-
/**
|
|
34
|
-
* Abort the current request immediately, keep the generated tokens if any.
|
|
35
|
-
*/
|
|
36
|
-
stop: () => void;
|
|
37
|
-
/**
|
|
38
|
-
* Update the `messages` state locally. This is useful when you want to
|
|
39
|
-
* edit the messages on the client, and then trigger the `reload` method
|
|
40
|
-
* manually to regenerate the AI response.
|
|
41
|
-
*/
|
|
42
|
-
setMessages: (messages: Message[] | ((messages: Message[]) => Message[])) => void;
|
|
43
|
-
/** The current value of the input */
|
|
44
|
-
input: Writable<string>;
|
|
45
|
-
/** Form submission handler to automatically reset input and append a user message */
|
|
46
|
-
handleSubmit: (event?: {
|
|
47
|
-
preventDefault?: () => void;
|
|
48
|
-
}, chatRequestOptions?: ChatRequestOptions) => void;
|
|
49
|
-
metadata?: Object;
|
|
50
|
-
/**
|
|
51
|
-
* Whether the API request is in progress
|
|
52
|
-
*
|
|
53
|
-
* @deprecated use `status` instead
|
|
54
|
-
*/
|
|
55
|
-
isLoading: Readable<boolean | undefined>;
|
|
56
|
-
/**
|
|
57
|
-
* Hook status:
|
|
58
|
-
*
|
|
59
|
-
* - `submitted`: The message has been sent to the API and we're awaiting the start of the response stream.
|
|
60
|
-
* - `streaming`: The response is actively streaming in from the API, receiving chunks of data.
|
|
61
|
-
* - `ready`: The full response has been received and processed; a new user message can be submitted.
|
|
62
|
-
* - `error`: An error occurred during the API request, preventing successful completion.
|
|
63
|
-
*/
|
|
64
|
-
status: Readable<'submitted' | 'streaming' | 'ready' | 'error'>;
|
|
65
|
-
/** Additional data added on the server via StreamData */
|
|
66
|
-
data: Readable<JSONValue[] | undefined>;
|
|
67
|
-
/** Set the data of the chat. You can use this to transform or clear the chat data. */
|
|
68
|
-
setData: (data: JSONValue[] | undefined | ((data: JSONValue[] | undefined) => JSONValue[] | undefined)) => void;
|
|
69
|
-
/** The id of the chat */
|
|
70
|
-
id: string;
|
|
71
|
-
};
|
|
72
|
-
declare function useChat({ api, id, initialMessages, initialInput, sendExtraMessageFields, streamProtocol, onResponse, onFinish, onError, onToolCall, credentials, headers, body, generateId, fetch, keepLastMessageOnError, maxSteps, }?: UseChatOptions): UseChatHelpers & {
|
|
73
|
-
addToolResult: ({ toolCallId, result, }: {
|
|
74
|
-
toolCallId: string;
|
|
75
|
-
result: any;
|
|
76
|
-
}) => void;
|
|
77
|
-
};
|
|
78
|
-
|
|
79
|
-
type UseCompletionHelpers = {
|
|
80
|
-
/** The current completion result */
|
|
81
|
-
completion: Readable<string>;
|
|
82
|
-
/** The error object of the API request */
|
|
83
|
-
error: Readable<undefined | Error>;
|
|
84
|
-
/**
|
|
85
|
-
* Send a new prompt to the API endpoint and update the completion state.
|
|
86
|
-
*/
|
|
87
|
-
complete: (prompt: string, options?: RequestOptions) => Promise<string | null | undefined>;
|
|
88
|
-
/**
|
|
89
|
-
* Abort the current API request but keep the generated tokens.
|
|
90
|
-
*/
|
|
91
|
-
stop: () => void;
|
|
92
|
-
/**
|
|
93
|
-
* Update the `completion` state locally.
|
|
94
|
-
*/
|
|
95
|
-
setCompletion: (completion: string) => void;
|
|
96
|
-
/** The current value of the input */
|
|
97
|
-
input: Writable<string>;
|
|
98
|
-
/**
|
|
99
|
-
* Form submission handler to automatically reset input and append a user message
|
|
100
|
-
* @example
|
|
101
|
-
* ```jsx
|
|
102
|
-
* <form onSubmit={handleSubmit}>
|
|
103
|
-
* <input onChange={handleInputChange} value={input} />
|
|
104
|
-
* </form>
|
|
105
|
-
* ```
|
|
106
|
-
*/
|
|
107
|
-
handleSubmit: (event?: {
|
|
108
|
-
preventDefault?: () => void;
|
|
109
|
-
}) => void;
|
|
110
|
-
/** Whether the API request is in progress */
|
|
111
|
-
isLoading: Readable<boolean | undefined>;
|
|
112
|
-
/** Additional data added on the server via StreamData */
|
|
113
|
-
data: Readable<JSONValue[] | undefined>;
|
|
114
|
-
};
|
|
115
|
-
declare function useCompletion({ api, id, initialCompletion, initialInput, credentials, headers, body, streamProtocol, onResponse, onFinish, onError, fetch, }?: UseCompletionOptions): UseCompletionHelpers;
|
|
116
|
-
|
|
117
|
-
type UseAssistantHelpers = {
|
|
118
|
-
/**
|
|
119
|
-
* The current array of chat messages.
|
|
120
|
-
*/
|
|
121
|
-
messages: Readable<Message[]>;
|
|
122
|
-
/**
|
|
123
|
-
* Update the message store with a new array of messages.
|
|
124
|
-
*/
|
|
125
|
-
setMessages: (messages: Message[]) => void;
|
|
126
|
-
/**
|
|
127
|
-
* The current thread ID.
|
|
128
|
-
*/
|
|
129
|
-
threadId: Readable<string | undefined>;
|
|
130
|
-
/**
|
|
131
|
-
* The current value of the input field.
|
|
132
|
-
*/
|
|
133
|
-
input: Writable<string>;
|
|
134
|
-
/**
|
|
135
|
-
* Append a user message to the chat list. This triggers the API call to fetch
|
|
136
|
-
* the assistant's response.
|
|
137
|
-
* @param message The message to append
|
|
138
|
-
* @param requestOptions Additional options to pass to the API call
|
|
139
|
-
*/
|
|
140
|
-
append: (message: Message | CreateMessage, requestOptions?: {
|
|
141
|
-
data?: Record<string, string>;
|
|
142
|
-
}) => Promise<void>;
|
|
143
|
-
/**
|
|
144
|
-
Abort the current request immediately, keep the generated tokens if any.
|
|
145
|
-
*/
|
|
146
|
-
stop: () => void;
|
|
147
|
-
/**
|
|
148
|
-
* Form submission handler that automatically resets the input field and appends a user message.
|
|
149
|
-
*/
|
|
150
|
-
submitMessage: (event?: {
|
|
151
|
-
preventDefault?: () => void;
|
|
152
|
-
}, requestOptions?: {
|
|
153
|
-
data?: Record<string, string>;
|
|
154
|
-
}) => Promise<void>;
|
|
155
|
-
/**
|
|
156
|
-
* The current status of the assistant. This can be used to show a loading indicator.
|
|
157
|
-
*/
|
|
158
|
-
status: Readable<AssistantStatus>;
|
|
159
|
-
/**
|
|
160
|
-
* The error thrown during the assistant message processing, if any.
|
|
161
|
-
*/
|
|
162
|
-
error: Readable<undefined | Error>;
|
|
163
|
-
};
|
|
164
|
-
declare function useAssistant({ api, threadId: threadIdParam, credentials, headers, body, onError, fetch, }: UseAssistantOptions): UseAssistantHelpers;
|
|
165
|
-
|
|
166
|
-
export { UseAssistantHelpers, UseChatHelpers, UseChatOptions, UseCompletionHelpers, useAssistant, useChat, useCompletion };
|
package/dist/index.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/use-chat.ts","../src/use-completion.ts","../src/use-assistant.ts"],"sourcesContent":["export * from './use-chat';\nexport * from './use-completion';\nexport * from './use-assistant';\n","import type {\n ChatRequest,\n ChatRequestOptions,\n CreateMessage,\n JSONValue,\n Message,\n UseChatOptions as SharedUseChatOptions,\n UIMessage,\n} from '@ai-sdk/ui-utils';\nimport {\n callChatApi,\n extractMaxToolInvocationStep,\n fillMessageParts,\n generateId as generateIdFunc,\n getMessageParts,\n isAssistantMessageWithCompletedToolCalls,\n prepareAttachmentsForRequest,\n shouldResubmitMessages,\n updateToolCallResult,\n} from '@ai-sdk/ui-utils';\nimport { Readable, Writable, derived, get, writable } from 'svelte/store';\nexport type { CreateMessage, Message };\n\nexport type UseChatOptions = SharedUseChatOptions & {\n /**\nMaximum number of sequential LLM calls (steps), e.g. when you use tool calls. Must be at least 1.\n\nA maximum number is required to prevent infinite loops in the case of misconfigured tools.\n\nBy default, it's set to 1, which means that only a single LLM call is made.\n */\n maxSteps?: number;\n};\n\nexport type UseChatHelpers = {\n /** Current messages in the chat */\n messages: Readable<UIMessage[]>;\n /** The error object of the API request */\n error: Readable<undefined | Error>;\n /**\n * Append a user message to the chat list. This triggers the API call to fetch\n * the assistant's response.\n * @param message The message to append\n * @param chatRequestOptions Additional options to pass to the API call\n */\n append: (\n message: Message | CreateMessage,\n chatRequestOptions?: ChatRequestOptions,\n ) => Promise<string | null | undefined>;\n /**\n * Reload the last AI chat response for the given chat history. If the last\n * message isn't from the assistant, it will request the API to generate a\n * new response.\n */\n reload: (\n chatRequestOptions?: ChatRequestOptions,\n ) => Promise<string | null | undefined>;\n /**\n * Abort the current request immediately, keep the generated tokens if any.\n */\n stop: () => void;\n /**\n * Update the `messages` state locally. This is useful when you want to\n * edit the messages on the client, and then trigger the `reload` method\n * manually to regenerate the AI response.\n */\n setMessages: (\n messages: Message[] | ((messages: Message[]) => Message[]),\n ) => void;\n\n /** The current value of the input */\n input: Writable<string>;\n /** Form submission handler to automatically reset input and append a user message */\n handleSubmit: (\n event?: { preventDefault?: () => void },\n chatRequestOptions?: ChatRequestOptions,\n ) => void;\n metadata?: Object;\n\n /**\n * Whether the API request is in progress\n *\n * @deprecated use `status` instead\n */\n isLoading: Readable<boolean | undefined>;\n\n /**\n * Hook status:\n *\n * - `submitted`: The message has been sent to the API and we're awaiting the start of the response stream.\n * - `streaming`: The response is actively streaming in from the API, receiving chunks of data.\n * - `ready`: The full response has been received and processed; a new user message can be submitted.\n * - `error`: An error occurred during the API request, preventing successful completion.\n */\n status: Readable<'submitted' | 'streaming' | 'ready' | 'error'>;\n\n /** Additional data added on the server via StreamData */\n data: Readable<JSONValue[] | undefined>;\n /** Set the data of the chat. You can use this to transform or clear the chat data. */\n setData: (\n data:\n | JSONValue[]\n | undefined\n | ((data: JSONValue[] | undefined) => JSONValue[] | undefined),\n ) => void;\n\n /** The id of the chat */\n id: string;\n};\n\nconst store = writable<Record<string, UIMessage[] | undefined>>({});\n\nexport function useChat({\n api = '/api/chat',\n id,\n initialMessages = [],\n initialInput = '',\n sendExtraMessageFields,\n streamProtocol = 'data',\n onResponse,\n onFinish,\n onError,\n onToolCall,\n credentials,\n headers,\n body,\n generateId = generateIdFunc,\n fetch,\n keepLastMessageOnError = true,\n maxSteps = 1,\n}: UseChatOptions = {}): UseChatHelpers & {\n addToolResult: ({\n toolCallId,\n result,\n }: {\n toolCallId: string;\n result: any;\n }) => void;\n} {\n // Generate a unique id for the chat if not provided.\n const chatId = id ?? generateId();\n\n const key = `${api}|${chatId}`;\n const messages = derived(\n [store],\n ([$store]) => $store[key] ?? fillMessageParts(initialMessages),\n );\n\n const streamData = writable<JSONValue[] | undefined>(undefined);\n\n const status = writable<'submitted' | 'streaming' | 'ready' | 'error'>(\n 'ready',\n );\n\n const mutate = (data: UIMessage[]) => {\n store.update(value => {\n value[key] = data;\n return value;\n });\n };\n\n // Abort controller to cancel the current API call.\n let abortController: AbortController | null = null;\n\n const extraMetadata = {\n credentials,\n headers,\n body,\n };\n\n const error = writable<undefined | Error>(undefined);\n\n // Actual mutation hook to send messages to the API endpoint and update the\n // chat state.\n async function triggerRequest(chatRequest: ChatRequest) {\n status.set('submitted');\n error.set(undefined);\n\n const messagesSnapshot = get(messages);\n const messageCount = messagesSnapshot.length;\n const maxStep = extractMaxToolInvocationStep(\n chatRequest.messages[chatRequest.messages.length - 1]?.toolInvocations,\n );\n\n try {\n abortController = new AbortController();\n\n // Do an optimistic update to the chat state to show the updated messages\n // immediately.\n const chatMessages = fillMessageParts(chatRequest.messages);\n\n mutate(chatMessages);\n\n const existingData = get(streamData);\n const previousMessages = get(messages);\n\n const constructedMessagesPayload = sendExtraMessageFields\n ? chatMessages\n : chatMessages.map(\n ({\n role,\n content,\n experimental_attachments,\n data,\n annotations,\n toolInvocations,\n parts,\n }) => ({\n role,\n content,\n ...(experimental_attachments !== undefined && {\n experimental_attachments,\n }),\n ...(data !== undefined && { data }),\n ...(annotations !== undefined && { annotations }),\n ...(toolInvocations !== undefined && { toolInvocations }),\n ...(parts !== undefined && { parts }),\n }),\n );\n\n await callChatApi({\n api,\n body: {\n id: chatId,\n messages: constructedMessagesPayload,\n data: chatRequest.data,\n ...extraMetadata.body,\n ...chatRequest.body,\n },\n streamProtocol,\n credentials: extraMetadata.credentials,\n headers: {\n ...extraMetadata.headers,\n ...chatRequest.headers,\n },\n abortController: () => abortController,\n restoreMessagesOnFailure() {\n if (!keepLastMessageOnError) {\n mutate(previousMessages);\n }\n },\n onResponse,\n onUpdate({ message, data, replaceLastMessage }) {\n status.set('streaming');\n\n mutate([\n ...(replaceLastMessage\n ? chatMessages.slice(0, chatMessages.length - 1)\n : chatMessages),\n message,\n ]);\n if (data?.length) {\n streamData.set([...(existingData ?? []), ...data]);\n }\n },\n onFinish,\n generateId,\n onToolCall,\n fetch,\n lastMessage: chatMessages[chatMessages.length - 1],\n });\n\n status.set('ready');\n } catch (err) {\n // Ignore abort errors as they are expected.\n if ((err as any).name === 'AbortError') {\n abortController = null;\n status.set('ready');\n return null;\n }\n\n if (onError && err instanceof Error) {\n onError(err);\n }\n\n error.set(err as Error);\n status.set('error');\n } finally {\n abortController = null;\n }\n\n // auto-submit when all tool calls in the last assistant message have results:\n const newMessagesSnapshot = get(messages);\n if (\n shouldResubmitMessages({\n originalMaxToolInvocationStep: maxStep,\n originalMessageCount: messageCount,\n maxSteps,\n messages: newMessagesSnapshot,\n })\n ) {\n await triggerRequest({ messages: newMessagesSnapshot });\n }\n }\n\n const append: UseChatHelpers['append'] = async (\n message: Message | CreateMessage,\n { data, headers, body, experimental_attachments }: ChatRequestOptions = {},\n ) => {\n const attachmentsForRequest = await prepareAttachmentsForRequest(\n experimental_attachments,\n );\n\n return triggerRequest({\n messages: get(messages).concat({\n ...message,\n id: message.id ?? generateId(),\n createdAt: message.createdAt ?? new Date(),\n experimental_attachments:\n attachmentsForRequest.length > 0 ? attachmentsForRequest : undefined,\n parts: getMessageParts(message),\n }),\n headers,\n body,\n data,\n });\n };\n\n const reload: UseChatHelpers['reload'] = async ({\n data,\n headers,\n body,\n }: ChatRequestOptions = {}) => {\n const messagesSnapshot = get(messages);\n if (messagesSnapshot.length === 0) {\n return null;\n }\n\n // Remove last assistant message and retry last user message.\n const lastMessage = messagesSnapshot.at(-1);\n return triggerRequest({\n messages:\n lastMessage?.role === 'assistant'\n ? messagesSnapshot.slice(0, -1)\n : messagesSnapshot,\n headers,\n body,\n data,\n });\n };\n\n const stop = () => {\n if (abortController) {\n abortController.abort();\n abortController = null;\n }\n };\n\n const setMessages = (\n messagesArg: Message[] | ((messages: Message[]) => Message[]),\n ) => {\n if (typeof messagesArg === 'function') {\n messagesArg = messagesArg(get(messages));\n }\n\n mutate(fillMessageParts(messagesArg));\n };\n\n const setData = (\n dataArg:\n | JSONValue[]\n | undefined\n | ((data: JSONValue[] | undefined) => JSONValue[] | undefined),\n ) => {\n if (typeof dataArg === 'function') {\n dataArg = dataArg(get(streamData));\n }\n\n streamData.set(dataArg);\n };\n\n const input = writable(initialInput);\n\n const handleSubmit = async (\n event?: { preventDefault?: () => void },\n options: ChatRequestOptions = {},\n ) => {\n event?.preventDefault?.();\n const inputValue = get(input);\n\n if (!inputValue && !options.allowEmptySubmit) return;\n\n const attachmentsForRequest = await prepareAttachmentsForRequest(\n options.experimental_attachments,\n );\n\n triggerRequest({\n messages: get(messages).concat({\n id: generateId(),\n content: inputValue,\n role: 'user',\n createdAt: new Date(),\n experimental_attachments:\n attachmentsForRequest.length > 0 ? attachmentsForRequest : undefined,\n parts: [{ type: 'text', text: inputValue }],\n }),\n body: options.body,\n headers: options.headers,\n data: options.data,\n });\n\n input.set('');\n };\n\n const addToolResult = ({\n toolCallId,\n result,\n }: {\n toolCallId: string;\n result: any;\n }) => {\n const messagesSnapshot = get(messages) ?? [];\n\n updateToolCallResult({\n messages: messagesSnapshot,\n toolCallId,\n toolResult: result,\n });\n\n mutate(messagesSnapshot);\n\n // auto-submit when all tool calls in the last assistant message have results:\n const lastMessage = messagesSnapshot[messagesSnapshot.length - 1];\n\n if (isAssistantMessageWithCompletedToolCalls(lastMessage)) {\n triggerRequest({ messages: messagesSnapshot });\n }\n };\n\n return {\n id: chatId,\n messages,\n error,\n append,\n reload,\n stop,\n setMessages,\n input,\n handleSubmit,\n isLoading: derived(\n status,\n $status => $status === 'submitted' || $status === 'streaming',\n ),\n status,\n data: streamData,\n setData,\n addToolResult,\n };\n}\n","import type {\n JSONValue,\n RequestOptions,\n UseCompletionOptions,\n} from '@ai-sdk/ui-utils';\nimport { callCompletionApi } from '@ai-sdk/ui-utils';\nimport { Readable, Writable, derived, get, writable } from 'svelte/store';\n\nexport type { UseCompletionOptions };\n\nexport type UseCompletionHelpers = {\n /** The current completion result */\n completion: Readable<string>;\n /** The error object of the API request */\n error: Readable<undefined | Error>;\n /**\n * Send a new prompt to the API endpoint and update the completion state.\n */\n complete: (\n prompt: string,\n options?: RequestOptions,\n ) => Promise<string | null | undefined>;\n /**\n * Abort the current API request but keep the generated tokens.\n */\n stop: () => void;\n /**\n * Update the `completion` state locally.\n */\n setCompletion: (completion: string) => void;\n /** The current value of the input */\n input: Writable<string>;\n /**\n * Form submission handler to automatically reset input and append a user message\n * @example\n * ```jsx\n * <form onSubmit={handleSubmit}>\n * <input onChange={handleInputChange} value={input} />\n * </form>\n * ```\n */\n handleSubmit: (event?: { preventDefault?: () => void }) => void;\n /** Whether the API request is in progress */\n isLoading: Readable<boolean | undefined>;\n\n /** Additional data added on the server via StreamData */\n data: Readable<JSONValue[] | undefined>;\n};\n\nlet uniqueId = 0;\n\nconst store = writable<Record<string, string>>({});\n\nexport function useCompletion({\n api = '/api/completion',\n id,\n initialCompletion = '',\n initialInput = '',\n credentials,\n headers,\n body,\n streamProtocol = 'data',\n onResponse,\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 = derived([store], ([$store]) => $store[key] ?? initialCompletion);\n\n const streamData = writable<JSONValue[] | undefined>(undefined);\n\n const loading = writable<boolean>(false);\n\n const mutate = (data: string) => {\n store.update(value => {\n value[key] = data;\n return value;\n });\n };\n\n // Because of the `fallbackData` option, the `data` will never be `undefined`.\n const completion = data;\n\n const error = writable<undefined | Error>(undefined);\n\n let abortController: AbortController | null = null;\n\n const complete: UseCompletionHelpers['complete'] = async (\n prompt: string,\n options?: RequestOptions,\n ) => {\n const existingData = get(streamData);\n return callCompletionApi({\n api,\n prompt,\n credentials,\n headers: {\n ...headers,\n ...options?.headers,\n },\n body: {\n ...body,\n ...options?.body,\n },\n streamProtocol,\n setCompletion: mutate,\n setLoading: loadingState => loading.set(loadingState),\n setError: err => error.set(err),\n setAbortController: controller => {\n abortController = controller;\n },\n onResponse,\n onFinish,\n onError,\n onData(data) {\n streamData.set([...(existingData || []), ...(data || [])]);\n },\n fetch,\n });\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 = writable(initialInput);\n\n const handleSubmit = (event?: { preventDefault?: () => void }) => {\n event?.preventDefault?.();\n\n const inputValue = get(input);\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: loading,\n data: streamData,\n };\n}\n","import { isAbortError } from '@ai-sdk/provider-utils';\nimport type {\n AssistantStatus,\n CreateMessage,\n Message,\n UseAssistantOptions,\n} from '@ai-sdk/ui-utils';\nimport { generateId, processAssistantStream } from '@ai-sdk/ui-utils';\nimport { Readable, Writable, get, writable } from 'svelte/store';\n\n// use function to allow for mocking in tests:\nconst getOriginalFetch = () => fetch;\n\nlet uniqueId = 0;\n\nconst store: Record<string, any> = {};\n\nexport type UseAssistantHelpers = {\n /**\n * The current array of chat messages.\n */\n messages: Readable<Message[]>;\n\n /**\n * Update the message store with a new array of messages.\n */\n setMessages: (messages: Message[]) => void;\n\n /**\n * The current thread ID.\n */\n threadId: Readable<string | undefined>;\n\n /**\n * The current value of the input field.\n */\n input: Writable<string>;\n\n /**\n * Append a user message to the chat list. This triggers the API call to fetch\n * the assistant's response.\n * @param message The message to append\n * @param requestOptions Additional options to pass to the API call\n */\n append: (\n message: Message | CreateMessage,\n requestOptions?: { data?: Record<string, string> },\n ) => Promise<void>;\n\n /**\nAbort the current request immediately, keep the generated tokens if any.\n */\n stop: () => void;\n\n /**\n * Form submission handler that automatically resets the input field and appends a user message.\n */\n submitMessage: (\n event?: { preventDefault?: () => void },\n requestOptions?: { data?: Record<string, string> },\n ) => Promise<void>;\n\n /**\n * The current status of the assistant. This can be used to show a loading indicator.\n */\n status: Readable<AssistantStatus>;\n\n /**\n * The error thrown during the assistant message processing, if any.\n */\n error: Readable<undefined | Error>;\n};\n\nexport function useAssistant({\n api,\n threadId: threadIdParam,\n credentials,\n headers,\n body,\n onError,\n fetch,\n}: UseAssistantOptions): UseAssistantHelpers {\n // Generate a unique thread ID\n const threadIdStore = writable<string | undefined>(threadIdParam);\n\n // Initialize message, input, status, and error stores\n const key = `${api}|${threadIdParam ?? `completion-${uniqueId++}`}`;\n const messages = writable<Message[]>(store[key] || []);\n const input = writable('');\n const status = writable<AssistantStatus>('awaiting_message');\n const error = writable<undefined | Error>(undefined);\n\n // To manage aborting the current fetch request\n let abortController: AbortController | null = null;\n\n // Update the message store\n const mutateMessages = (newMessages: Message[]) => {\n store[key] = newMessages;\n messages.set(newMessages);\n };\n\n // Function to handle API calls and state management\n async function append(\n message: Message | CreateMessage,\n requestOptions?: { data?: Record<string, string> },\n ) {\n status.set('in_progress');\n abortController = new AbortController(); // Initialize a new AbortController\n\n // Add the new message to the existing array\n mutateMessages([\n ...get(messages),\n { ...message, id: message.id ?? generateId() },\n ]);\n\n input.set('');\n\n try {\n const actualFetch = fetch ?? getOriginalFetch();\n const response = await actualFetch(api, {\n method: 'POST',\n credentials,\n signal: abortController.signal,\n headers: { 'Content-Type': 'application/json', ...headers },\n body: JSON.stringify({\n ...body,\n // always use user-provided threadId when available:\n threadId: threadIdParam ?? get(threadIdStore) ?? null,\n message: message.content,\n\n // optional request data:\n data: requestOptions?.data,\n }),\n });\n\n if (!response.ok) {\n throw new Error(\n (await response.text()) ?? 'Failed to fetch the assistant response.',\n );\n }\n\n if (response.body == null) {\n throw new Error('The response body is empty.');\n }\n\n await processAssistantStream({\n stream: response.body,\n onAssistantMessagePart(value) {\n mutateMessages([\n ...get(messages),\n {\n id: value.id,\n role: value.role,\n content: value.content[0].text.value,\n parts: [],\n },\n ]);\n },\n onTextPart(value) {\n // text delta - add to last message:\n mutateMessages(\n get(messages).map((msg, index, array) => {\n if (index === array.length - 1) {\n return { ...msg, content: msg.content + value };\n }\n return msg;\n }),\n );\n },\n onAssistantControlDataPart(value) {\n threadIdStore.set(value.threadId);\n\n mutateMessages(\n get(messages).map((msg, index, array) => {\n if (index === array.length - 1) {\n return { ...msg, id: value.messageId };\n }\n return msg;\n }),\n );\n },\n onDataMessagePart(value) {\n mutateMessages([\n ...get(messages),\n {\n id: value.id ?? generateId(),\n role: 'data',\n content: '',\n data: value.data,\n parts: [],\n },\n ]);\n },\n onErrorPart(value) {\n error.set(new Error(value));\n },\n });\n } catch (err) {\n // Ignore abort errors as they are expected when the user cancels the request:\n if (isAbortError(error) && abortController?.signal?.aborted) {\n abortController = null;\n return;\n }\n\n if (onError && err instanceof Error) {\n onError(err);\n }\n\n error.set(err as Error);\n } finally {\n abortController = null;\n status.set('awaiting_message');\n }\n }\n\n function setMessages(messages: Message[]) {\n mutateMessages(messages);\n }\n\n function stop() {\n if (abortController) {\n abortController.abort();\n abortController = null;\n }\n }\n\n // Function to handle form submission\n async function submitMessage(\n event?: { preventDefault?: () => void },\n requestOptions?: { data?: Record<string, string> },\n ) {\n event?.preventDefault?.();\n const inputValue = get(input);\n if (!inputValue) return;\n\n await append(\n { role: 'user', content: inputValue, parts: [] },\n requestOptions,\n );\n }\n\n return {\n messages,\n error,\n threadId: threadIdStore,\n input,\n append,\n submitMessage,\n status,\n setMessages,\n stop,\n };\n}\n"],"mappings":"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","names":["generateId","generateIdFunc","fetch","headers","body","import_ui_utils","import_store","store","fetch","data","completion","import_ui_utils","import_store","uniqueId","store","fetch","_a","messages"]}
|