@anvia/react 0.3.0 → 0.4.0
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.d.ts +51 -18
- package/dist/index.js +262 -90
- package/dist/index.js.map +1 -1
- package/package.json +7 -1
package/dist/index.d.ts
CHANGED
|
@@ -6,21 +6,6 @@ type TransportOptions = {
|
|
|
6
6
|
type EventTransport<TRequest, TEvent> = {
|
|
7
7
|
send(request: TRequest, options?: TransportOptions): AsyncIterable<TEvent>;
|
|
8
8
|
};
|
|
9
|
-
type FetchEventStreamOptions = Omit<RequestInit, "headers"> & {
|
|
10
|
-
format?: EventStreamFormat;
|
|
11
|
-
fetch?: typeof fetch;
|
|
12
|
-
headers?: HeadersInit;
|
|
13
|
-
};
|
|
14
|
-
type CreateFetchTransportOptions<TRequest, TEvent> = {
|
|
15
|
-
endpoint: string | URL | ((request: TRequest) => string | URL);
|
|
16
|
-
method?: string;
|
|
17
|
-
format?: EventStreamFormat;
|
|
18
|
-
fetch?: typeof fetch;
|
|
19
|
-
headers?: HeadersInit | ((request: TRequest) => HeadersInit | Promise<HeadersInit>);
|
|
20
|
-
body?: (request: TRequest) => BodyInit | null | undefined | Promise<BodyInit | null | undefined>;
|
|
21
|
-
init?: Omit<RequestInit, "body" | "headers" | "method" | "signal">;
|
|
22
|
-
mapEvent?: (event: unknown) => TEvent;
|
|
23
|
-
};
|
|
24
9
|
type ChatRole = "system" | "user" | "assistant" | "tool";
|
|
25
10
|
type ChatMessage = {
|
|
26
11
|
id: string;
|
|
@@ -57,16 +42,64 @@ type UseChatResult<TEvent = unknown, TMessage extends ChatMessage = ChatMessage>
|
|
|
57
42
|
error: unknown;
|
|
58
43
|
text: string;
|
|
59
44
|
};
|
|
45
|
+
|
|
46
|
+
declare function createDirectTransport<TRequest, TEvent>(handler: (request: TRequest) => AsyncIterable<TEvent>): EventTransport<TRequest, TEvent>;
|
|
47
|
+
|
|
48
|
+
type FetchEventStreamOptions = Omit<RequestInit, "headers"> & {
|
|
49
|
+
format?: EventStreamFormat;
|
|
50
|
+
fetch?: typeof fetch;
|
|
51
|
+
headers?: HeadersInit;
|
|
52
|
+
};
|
|
60
53
|
declare class EventStreamHttpError extends Error {
|
|
61
54
|
readonly response: Response;
|
|
62
55
|
readonly body: string;
|
|
63
56
|
constructor(response: Response, body: string);
|
|
64
57
|
}
|
|
58
|
+
declare function fetchEventStream<TEvent>(input: string | URL | Request, options?: FetchEventStreamOptions): AsyncIterable<TEvent>;
|
|
59
|
+
|
|
65
60
|
declare function readJsonlStream<TEvent>(stream: ReadableStream<Uint8Array>): AsyncIterable<TEvent>;
|
|
66
61
|
declare function readSseStream<TEvent>(stream: ReadableStream<Uint8Array>): AsyncIterable<TEvent>;
|
|
67
|
-
|
|
62
|
+
|
|
63
|
+
type CreateFetchTransportOptions<TRequest, TEvent> = {
|
|
64
|
+
endpoint: string | URL | ((request: TRequest) => string | URL);
|
|
65
|
+
method?: string;
|
|
66
|
+
format?: EventStreamFormat;
|
|
67
|
+
fetch?: typeof fetch;
|
|
68
|
+
headers?: HeadersInit | ((request: TRequest) => HeadersInit | Promise<HeadersInit>);
|
|
69
|
+
body?: (request: TRequest) => BodyInit | null | undefined | Promise<BodyInit | null | undefined>;
|
|
70
|
+
init?: Omit<RequestInit, "body" | "headers" | "method" | "signal">;
|
|
71
|
+
mapEvent?: (event: unknown) => TEvent;
|
|
72
|
+
};
|
|
68
73
|
declare function createFetchTransport<TRequest, TEvent = unknown>(options: CreateFetchTransportOptions<TRequest, TEvent>): EventTransport<TRequest, TEvent>;
|
|
69
|
-
declare function createChatTransport<TRequest
|
|
74
|
+
declare function createChatTransport<TRequest, TEvent = unknown>(options: CreateFetchTransportOptions<TRequest, TEvent>): EventTransport<TRequest, TEvent>;
|
|
75
|
+
|
|
70
76
|
declare function useChat<TRequest = DefaultChatRequest, TEvent = unknown, TMessage extends ChatMessage = ChatMessage>(options?: UseChatOptions<TRequest, TEvent, TMessage>): UseChatResult<TEvent, TMessage>;
|
|
71
77
|
|
|
72
|
-
|
|
78
|
+
type UseCompletionRequest = {
|
|
79
|
+
prompt: string;
|
|
80
|
+
stream: true;
|
|
81
|
+
};
|
|
82
|
+
type UseCompletionStatus = "idle" | "streaming" | "error";
|
|
83
|
+
type UseCompletionOptions<TEvent = unknown> = {
|
|
84
|
+
transport?: EventTransport<UseCompletionRequest, TEvent>;
|
|
85
|
+
endpoint?: string | URL;
|
|
86
|
+
format?: EventStreamFormat;
|
|
87
|
+
initialCompletion?: string;
|
|
88
|
+
eventToDelta?: (event: TEvent) => string | undefined;
|
|
89
|
+
eventToFinal?: (event: TEvent) => string | undefined;
|
|
90
|
+
onEvent?: (event: TEvent) => void;
|
|
91
|
+
onError?: (error: unknown) => void;
|
|
92
|
+
};
|
|
93
|
+
type UseCompletionResult = {
|
|
94
|
+
completion: string;
|
|
95
|
+
input: string;
|
|
96
|
+
setInput(input: string): void;
|
|
97
|
+
complete(prompt?: string): Promise<void>;
|
|
98
|
+
stop(): void;
|
|
99
|
+
reset(completion?: string): void;
|
|
100
|
+
status: UseCompletionStatus;
|
|
101
|
+
error: unknown;
|
|
102
|
+
};
|
|
103
|
+
declare function useCompletion<TEvent = unknown>(options?: UseCompletionOptions<TEvent>): UseCompletionResult;
|
|
104
|
+
|
|
105
|
+
export { type ChatMessage, type ChatRole, type CreateFetchTransportOptions, type DefaultChatRequest, type EventStreamFormat, EventStreamHttpError, type EventTransport, type FetchEventStreamOptions, type TransportOptions, type UseChatOptions, type UseChatResult, type UseChatStatus, type UseCompletionOptions, type UseCompletionRequest, type UseCompletionResult, type UseCompletionStatus, createChatTransport, createDirectTransport, createFetchTransport, fetchEventStream, readJsonlStream, readSseStream, useChat, useCompletion };
|
package/dist/index.js
CHANGED
|
@@ -1,15 +1,28 @@
|
|
|
1
|
-
// src/
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
1
|
+
// src/direct.ts
|
|
2
|
+
function createDirectTransport(handler) {
|
|
3
|
+
return {
|
|
4
|
+
async *send(request, options) {
|
|
5
|
+
const iterable = handler(request);
|
|
6
|
+
const iterator = iterable[Symbol.asyncIterator]();
|
|
7
|
+
try {
|
|
8
|
+
while (true) {
|
|
9
|
+
if (options?.signal?.aborted) {
|
|
10
|
+
break;
|
|
11
|
+
}
|
|
12
|
+
const next = await iterator.next();
|
|
13
|
+
if (next.done) {
|
|
14
|
+
break;
|
|
15
|
+
}
|
|
16
|
+
yield next.value;
|
|
17
|
+
}
|
|
18
|
+
} finally {
|
|
19
|
+
await iterator.return?.();
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
// src/streams.ts
|
|
13
26
|
async function* readJsonlStream(stream) {
|
|
14
27
|
const reader = stream.getReader();
|
|
15
28
|
const decoder = new TextDecoder();
|
|
@@ -21,7 +34,7 @@ async function* readJsonlStream(stream) {
|
|
|
21
34
|
break;
|
|
22
35
|
}
|
|
23
36
|
buffer += decoder.decode(next.value, { stream: true });
|
|
24
|
-
const lines = buffer.split(
|
|
37
|
+
const lines = buffer.split(/\r?\n/);
|
|
25
38
|
buffer = lines.pop() ?? "";
|
|
26
39
|
for (const line of lines) {
|
|
27
40
|
const trimmed2 = line.trim();
|
|
@@ -77,6 +90,43 @@ async function* readSseStream(stream) {
|
|
|
77
90
|
reader.releaseLock();
|
|
78
91
|
}
|
|
79
92
|
}
|
|
93
|
+
function createEmptySseEvent() {
|
|
94
|
+
return { data: [] };
|
|
95
|
+
}
|
|
96
|
+
function parseSseLine(line, event) {
|
|
97
|
+
if (line === "") {
|
|
98
|
+
const data = flushSseEvent(event);
|
|
99
|
+
return data === void 0 ? { event: createEmptySseEvent(), complete: true } : { event: createEmptySseEvent(), complete: true, data };
|
|
100
|
+
}
|
|
101
|
+
if (line.startsWith(":")) {
|
|
102
|
+
return { event };
|
|
103
|
+
}
|
|
104
|
+
const separator = line.indexOf(":");
|
|
105
|
+
const field = separator === -1 ? line : line.slice(0, separator);
|
|
106
|
+
const value = separator === -1 ? "" : line.slice(separator + 1).replace(/^ /, "");
|
|
107
|
+
if (field === "data") {
|
|
108
|
+
event.data.push(value);
|
|
109
|
+
}
|
|
110
|
+
return { event };
|
|
111
|
+
}
|
|
112
|
+
function flushSseEvent(event) {
|
|
113
|
+
if (event.data.length === 0) {
|
|
114
|
+
return void 0;
|
|
115
|
+
}
|
|
116
|
+
return event.data.join("\n");
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
// src/fetch.ts
|
|
120
|
+
var EventStreamHttpError = class extends Error {
|
|
121
|
+
constructor(response, body) {
|
|
122
|
+
super(`Event stream request failed with status ${response.status}`);
|
|
123
|
+
this.response = response;
|
|
124
|
+
this.body = body;
|
|
125
|
+
this.name = "EventStreamHttpError";
|
|
126
|
+
}
|
|
127
|
+
response;
|
|
128
|
+
body;
|
|
129
|
+
};
|
|
80
130
|
async function* fetchEventStream(input, options = {}) {
|
|
81
131
|
const fetchImpl = options.fetch ?? globalThis.fetch;
|
|
82
132
|
if (fetchImpl === void 0) {
|
|
@@ -96,6 +146,15 @@ async function* fetchEventStream(input, options = {}) {
|
|
|
96
146
|
}
|
|
97
147
|
yield* readJsonlStream(response.body);
|
|
98
148
|
}
|
|
149
|
+
function fetchOptions(options) {
|
|
150
|
+
const { format: _format, fetch: _fetch, ...init } = options;
|
|
151
|
+
return init;
|
|
152
|
+
}
|
|
153
|
+
function inferEventStreamFormat(contentType) {
|
|
154
|
+
return contentType?.toLowerCase().includes("text/event-stream") ? "sse" : "jsonl";
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
// src/transport.ts
|
|
99
158
|
function createFetchTransport(options) {
|
|
100
159
|
return {
|
|
101
160
|
async *send(request, transportOptions = {}) {
|
|
@@ -128,6 +187,69 @@ function createFetchTransport(options) {
|
|
|
128
187
|
function createChatTransport(options) {
|
|
129
188
|
return createFetchTransport(options);
|
|
130
189
|
}
|
|
190
|
+
async function resolveHeaders(headers, request) {
|
|
191
|
+
return typeof headers === "function" ? headers(request) : headers;
|
|
192
|
+
}
|
|
193
|
+
async function resolveBody(body, request, headers) {
|
|
194
|
+
if (body !== void 0) {
|
|
195
|
+
return body(request);
|
|
196
|
+
}
|
|
197
|
+
if (!headers.has("content-type")) {
|
|
198
|
+
headers.set("content-type", "application/json");
|
|
199
|
+
}
|
|
200
|
+
return JSON.stringify(request);
|
|
201
|
+
}
|
|
202
|
+
function mergeHeaders(...values) {
|
|
203
|
+
const headers = new Headers();
|
|
204
|
+
for (const value of values) {
|
|
205
|
+
if (value === void 0) {
|
|
206
|
+
continue;
|
|
207
|
+
}
|
|
208
|
+
new Headers(value).forEach((headerValue, key) => {
|
|
209
|
+
headers.set(key, headerValue);
|
|
210
|
+
});
|
|
211
|
+
}
|
|
212
|
+
return headers;
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
// src/use-chat.ts
|
|
216
|
+
import { useCallback, useEffect, useMemo, useRef, useState } from "react";
|
|
217
|
+
|
|
218
|
+
// src/chat-defaults.ts
|
|
219
|
+
function defaultCreateRequest(input, messages) {
|
|
220
|
+
return {
|
|
221
|
+
message: input,
|
|
222
|
+
history: messages.slice(0, -1),
|
|
223
|
+
stream: true
|
|
224
|
+
};
|
|
225
|
+
}
|
|
226
|
+
function createMessage(role, content) {
|
|
227
|
+
return {
|
|
228
|
+
id: createId(),
|
|
229
|
+
role,
|
|
230
|
+
content
|
|
231
|
+
};
|
|
232
|
+
}
|
|
233
|
+
function defaultEventToDelta(event) {
|
|
234
|
+
if (!isRecord(event)) {
|
|
235
|
+
return void 0;
|
|
236
|
+
}
|
|
237
|
+
return event.type === "text_delta" && typeof event.delta === "string" ? event.delta : void 0;
|
|
238
|
+
}
|
|
239
|
+
function defaultEventToFinal(event) {
|
|
240
|
+
if (!isRecord(event)) {
|
|
241
|
+
return void 0;
|
|
242
|
+
}
|
|
243
|
+
return event.type === "final" && typeof event.output === "string" ? event.output : void 0;
|
|
244
|
+
}
|
|
245
|
+
function createId() {
|
|
246
|
+
return globalThis.crypto?.randomUUID?.() ?? Math.random().toString(36).slice(2);
|
|
247
|
+
}
|
|
248
|
+
function isRecord(value) {
|
|
249
|
+
return typeof value === "object" && value !== null;
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
// src/use-chat.ts
|
|
131
253
|
function useChat(options = {}) {
|
|
132
254
|
const [messages, setMessages] = useState(() => [...options.initialMessages ?? []]);
|
|
133
255
|
const [events, setEvents] = useState([]);
|
|
@@ -265,104 +387,154 @@ function useChat(options = {}) {
|
|
|
265
387
|
text
|
|
266
388
|
};
|
|
267
389
|
}
|
|
268
|
-
function
|
|
269
|
-
|
|
270
|
-
return init;
|
|
271
|
-
}
|
|
272
|
-
function inferEventStreamFormat(contentType) {
|
|
273
|
-
return contentType?.toLowerCase().includes("text/event-stream") ? "sse" : "jsonl";
|
|
274
|
-
}
|
|
275
|
-
function createEmptySseEvent() {
|
|
276
|
-
return { data: [] };
|
|
277
|
-
}
|
|
278
|
-
function parseSseLine(line, event) {
|
|
279
|
-
if (line === "") {
|
|
280
|
-
const data = flushSseEvent(event);
|
|
281
|
-
return data === void 0 ? { event: createEmptySseEvent(), complete: true } : { event: createEmptySseEvent(), complete: true, data };
|
|
282
|
-
}
|
|
283
|
-
if (line.startsWith(":")) {
|
|
284
|
-
return { event };
|
|
285
|
-
}
|
|
286
|
-
const separator = line.indexOf(":");
|
|
287
|
-
const field = separator === -1 ? line : line.slice(0, separator);
|
|
288
|
-
const value = separator === -1 ? "" : line.slice(separator + 1).replace(/^ /, "");
|
|
289
|
-
if (field === "data") {
|
|
290
|
-
event.data.push(value);
|
|
291
|
-
}
|
|
292
|
-
return { event };
|
|
390
|
+
function isAbortError(error) {
|
|
391
|
+
return error instanceof DOMException && error.name === "AbortError";
|
|
293
392
|
}
|
|
294
|
-
|
|
295
|
-
|
|
393
|
+
|
|
394
|
+
// src/use-completion.ts
|
|
395
|
+
import { useCallback as useCallback2, useEffect as useEffect2, useMemo as useMemo2, useRef as useRef2, useState as useState2 } from "react";
|
|
396
|
+
|
|
397
|
+
// src/completion-defaults.ts
|
|
398
|
+
function defaultCompletionEventToDelta(event) {
|
|
399
|
+
if (!isRecord2(event)) {
|
|
296
400
|
return void 0;
|
|
297
401
|
}
|
|
298
|
-
return event.
|
|
299
|
-
}
|
|
300
|
-
async function resolveHeaders(headers, request) {
|
|
301
|
-
return typeof headers === "function" ? headers(request) : headers;
|
|
402
|
+
return event.type === "text_delta" && typeof event.delta === "string" ? event.delta : void 0;
|
|
302
403
|
}
|
|
303
|
-
|
|
304
|
-
if (
|
|
305
|
-
return
|
|
404
|
+
function defaultCompletionEventToFinal(event) {
|
|
405
|
+
if (!isRecord2(event) || event.type !== "final") {
|
|
406
|
+
return void 0;
|
|
306
407
|
}
|
|
307
|
-
|
|
308
|
-
|
|
408
|
+
const response = event.response;
|
|
409
|
+
if (!isRecord2(response) || !Array.isArray(response.choice)) {
|
|
410
|
+
return void 0;
|
|
309
411
|
}
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
for (const value of values) {
|
|
315
|
-
if (value === void 0) {
|
|
316
|
-
continue;
|
|
412
|
+
const parts = [];
|
|
413
|
+
for (const item of response.choice) {
|
|
414
|
+
if (isRecord2(item) && item.type === "text" && typeof item.text === "string") {
|
|
415
|
+
parts.push(item.text);
|
|
317
416
|
}
|
|
318
|
-
new Headers(value).forEach((headerValue, key) => {
|
|
319
|
-
headers.set(key, headerValue);
|
|
320
|
-
});
|
|
321
417
|
}
|
|
322
|
-
return
|
|
418
|
+
return parts.length > 0 ? parts.join("") : void 0;
|
|
323
419
|
}
|
|
324
|
-
function
|
|
325
|
-
return
|
|
326
|
-
message: input,
|
|
327
|
-
history: messages.slice(0, -1),
|
|
328
|
-
stream: true
|
|
329
|
-
};
|
|
420
|
+
function isRecord2(value) {
|
|
421
|
+
return typeof value === "object" && value !== null;
|
|
330
422
|
}
|
|
331
|
-
|
|
423
|
+
|
|
424
|
+
// src/use-completion.ts
|
|
425
|
+
function useCompletion(options = {}) {
|
|
426
|
+
const [completion, setCompletion] = useState2(options.initialCompletion ?? "");
|
|
427
|
+
const [input, setInput] = useState2("");
|
|
428
|
+
const [status, setStatus] = useState2("idle");
|
|
429
|
+
const [error, setError] = useState2();
|
|
430
|
+
const abortRef = useRef2(void 0);
|
|
431
|
+
const completionRef = useRef2(completion);
|
|
432
|
+
useEffect2(() => {
|
|
433
|
+
completionRef.current = completion;
|
|
434
|
+
}, [completion]);
|
|
435
|
+
useEffect2(() => {
|
|
436
|
+
return () => {
|
|
437
|
+
abortRef.current?.abort();
|
|
438
|
+
};
|
|
439
|
+
}, []);
|
|
440
|
+
const transport = useMemo2(() => {
|
|
441
|
+
if (options.transport !== void 0) {
|
|
442
|
+
return options.transport;
|
|
443
|
+
}
|
|
444
|
+
if (options.endpoint === void 0) {
|
|
445
|
+
return void 0;
|
|
446
|
+
}
|
|
447
|
+
return createFetchTransport({
|
|
448
|
+
endpoint: options.endpoint,
|
|
449
|
+
format: options.format ?? "jsonl"
|
|
450
|
+
});
|
|
451
|
+
}, [options.transport, options.endpoint, options.format]);
|
|
452
|
+
const eventToDelta = options.eventToDelta ?? defaultCompletionEventToDelta;
|
|
453
|
+
const eventToFinal = options.eventToFinal ?? defaultCompletionEventToFinal;
|
|
454
|
+
const complete = useCallback2(
|
|
455
|
+
async (nextInput) => {
|
|
456
|
+
if (transport === void 0) {
|
|
457
|
+
throw new Error("useCompletion requires either transport or endpoint");
|
|
458
|
+
}
|
|
459
|
+
const prompt = nextInput ?? input;
|
|
460
|
+
if (prompt.trim().length === 0) {
|
|
461
|
+
return;
|
|
462
|
+
}
|
|
463
|
+
abortRef.current?.abort();
|
|
464
|
+
const abortController = new AbortController();
|
|
465
|
+
abortRef.current = abortController;
|
|
466
|
+
const request = { prompt, stream: true };
|
|
467
|
+
setInput("");
|
|
468
|
+
setError(void 0);
|
|
469
|
+
setStatus("streaming");
|
|
470
|
+
setCompletion("");
|
|
471
|
+
try {
|
|
472
|
+
for await (const event of transport.send(request, { signal: abortController.signal })) {
|
|
473
|
+
options.onEvent?.(event);
|
|
474
|
+
const delta = eventToDelta(event);
|
|
475
|
+
if (delta !== void 0 && delta.length > 0) {
|
|
476
|
+
setCompletion((current) => `${current}${delta}`);
|
|
477
|
+
}
|
|
478
|
+
const final = eventToFinal(event);
|
|
479
|
+
if (final !== void 0) {
|
|
480
|
+
setCompletion(final);
|
|
481
|
+
}
|
|
482
|
+
}
|
|
483
|
+
if (!abortController.signal.aborted) {
|
|
484
|
+
setStatus("idle");
|
|
485
|
+
}
|
|
486
|
+
} catch (caught) {
|
|
487
|
+
if (isAbortError2(caught)) {
|
|
488
|
+
setStatus("idle");
|
|
489
|
+
return;
|
|
490
|
+
}
|
|
491
|
+
setError(caught);
|
|
492
|
+
setStatus("error");
|
|
493
|
+
options.onError?.(caught);
|
|
494
|
+
} finally {
|
|
495
|
+
if (abortRef.current === abortController) {
|
|
496
|
+
abortRef.current = void 0;
|
|
497
|
+
}
|
|
498
|
+
}
|
|
499
|
+
},
|
|
500
|
+
[eventToDelta, eventToFinal, input, options, transport]
|
|
501
|
+
);
|
|
502
|
+
const stop = useCallback2(() => {
|
|
503
|
+
abortRef.current?.abort();
|
|
504
|
+
abortRef.current = void 0;
|
|
505
|
+
setStatus("idle");
|
|
506
|
+
}, []);
|
|
507
|
+
const reset = useCallback2((nextCompletion) => {
|
|
508
|
+
abortRef.current?.abort();
|
|
509
|
+
abortRef.current = void 0;
|
|
510
|
+
setCompletion(nextCompletion ?? "");
|
|
511
|
+
setError(void 0);
|
|
512
|
+
setInput("");
|
|
513
|
+
setStatus("idle");
|
|
514
|
+
}, []);
|
|
332
515
|
return {
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
516
|
+
completion,
|
|
517
|
+
input,
|
|
518
|
+
setInput,
|
|
519
|
+
complete,
|
|
520
|
+
stop,
|
|
521
|
+
reset,
|
|
522
|
+
status,
|
|
523
|
+
error
|
|
336
524
|
};
|
|
337
525
|
}
|
|
338
|
-
function
|
|
339
|
-
return globalThis.crypto?.randomUUID?.() ?? Math.random().toString(36).slice(2);
|
|
340
|
-
}
|
|
341
|
-
function defaultEventToDelta(event) {
|
|
342
|
-
if (!isRecord(event)) {
|
|
343
|
-
return void 0;
|
|
344
|
-
}
|
|
345
|
-
return event.type === "text_delta" && typeof event.delta === "string" ? event.delta : void 0;
|
|
346
|
-
}
|
|
347
|
-
function defaultEventToFinal(event) {
|
|
348
|
-
if (!isRecord(event)) {
|
|
349
|
-
return void 0;
|
|
350
|
-
}
|
|
351
|
-
return event.type === "final" && typeof event.output === "string" ? event.output : void 0;
|
|
352
|
-
}
|
|
353
|
-
function isRecord(value) {
|
|
354
|
-
return typeof value === "object" && value !== null;
|
|
355
|
-
}
|
|
356
|
-
function isAbortError(error) {
|
|
526
|
+
function isAbortError2(error) {
|
|
357
527
|
return error instanceof DOMException && error.name === "AbortError";
|
|
358
528
|
}
|
|
359
529
|
export {
|
|
360
530
|
EventStreamHttpError,
|
|
361
531
|
createChatTransport,
|
|
532
|
+
createDirectTransport,
|
|
362
533
|
createFetchTransport,
|
|
363
534
|
fetchEventStream,
|
|
364
535
|
readJsonlStream,
|
|
365
536
|
readSseStream,
|
|
366
|
-
useChat
|
|
537
|
+
useChat,
|
|
538
|
+
useCompletion
|
|
367
539
|
};
|
|
368
540
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["import { useCallback, useEffect, useMemo, useRef, useState } from \"react\";\n\nexport type EventStreamFormat = \"jsonl\" | \"sse\";\n\nexport type TransportOptions = {\n signal?: AbortSignal;\n headers?: HeadersInit;\n};\n\nexport type EventTransport<TRequest, TEvent> = {\n send(request: TRequest, options?: TransportOptions): AsyncIterable<TEvent>;\n};\n\nexport type FetchEventStreamOptions = Omit<RequestInit, \"headers\"> & {\n format?: EventStreamFormat;\n fetch?: typeof fetch;\n headers?: HeadersInit;\n};\n\nexport type CreateFetchTransportOptions<TRequest, TEvent> = {\n endpoint: string | URL | ((request: TRequest) => string | URL);\n method?: string;\n format?: EventStreamFormat;\n fetch?: typeof fetch;\n headers?: HeadersInit | ((request: TRequest) => HeadersInit | Promise<HeadersInit>);\n body?: (request: TRequest) => BodyInit | null | undefined | Promise<BodyInit | null | undefined>;\n init?: Omit<RequestInit, \"body\" | \"headers\" | \"method\" | \"signal\">;\n mapEvent?: (event: unknown) => TEvent;\n};\n\nexport type ChatRole = \"system\" | \"user\" | \"assistant\" | \"tool\";\n\nexport type ChatMessage = {\n id: string;\n role: ChatRole;\n content: string;\n metadata?: unknown;\n};\n\nexport type DefaultChatRequest = {\n message: string;\n history: ChatMessage[];\n stream: true;\n};\n\nexport type UseChatStatus = \"idle\" | \"streaming\" | \"error\";\n\nexport type UseChatOptions<\n TRequest = DefaultChatRequest,\n TEvent = unknown,\n TMessage extends ChatMessage = ChatMessage,\n> = {\n transport?: EventTransport<TRequest, TEvent>;\n endpoint?: string | URL;\n format?: EventStreamFormat;\n initialMessages?: TMessage[];\n createRequest?: (input: string, messages: TMessage[]) => TRequest;\n eventToDelta?: (event: TEvent) => string | undefined;\n eventToFinal?: (event: TEvent) => string | undefined;\n onEvent?: (event: TEvent) => void;\n onError?: (error: unknown) => void;\n};\n\nexport type UseChatResult<TEvent = unknown, TMessage extends ChatMessage = ChatMessage> = {\n messages: TMessage[];\n events: TEvent[];\n input: string;\n setInput(input: string): void;\n send(input?: string): Promise<void>;\n stop(): void;\n reset(messages?: TMessage[]): void;\n status: UseChatStatus;\n error: unknown;\n text: string;\n};\n\nexport class EventStreamHttpError extends Error {\n constructor(\n readonly response: Response,\n readonly body: string,\n ) {\n super(`Event stream request failed with status ${response.status}`);\n this.name = \"EventStreamHttpError\";\n }\n}\n\nexport async function* readJsonlStream<TEvent>(\n stream: ReadableStream<Uint8Array>,\n): AsyncIterable<TEvent> {\n const reader = stream.getReader();\n const decoder = new TextDecoder();\n let buffer = \"\";\n\n try {\n while (true) {\n const next = await reader.read();\n if (next.done === true) {\n break;\n }\n\n buffer += decoder.decode(next.value, { stream: true });\n const lines = buffer.split(\"\\n\");\n buffer = lines.pop() ?? \"\";\n\n for (const line of lines) {\n const trimmed = line.trim();\n if (trimmed.length > 0) {\n yield JSON.parse(trimmed) as TEvent;\n }\n }\n }\n\n buffer += decoder.decode();\n const trimmed = buffer.trim();\n if (trimmed.length > 0) {\n yield JSON.parse(trimmed) as TEvent;\n }\n } finally {\n reader.releaseLock();\n }\n}\n\nexport async function* readSseStream<TEvent>(\n stream: ReadableStream<Uint8Array>,\n): AsyncIterable<TEvent> {\n const reader = stream.getReader();\n const decoder = new TextDecoder();\n let buffer = \"\";\n let event = createEmptySseEvent();\n\n try {\n while (true) {\n const next = await reader.read();\n if (next.done === true) {\n break;\n }\n\n buffer += decoder.decode(next.value, { stream: true });\n const lines = buffer.split(/\\r?\\n/);\n buffer = lines.pop() ?? \"\";\n\n for (const line of lines) {\n const parsed = parseSseLine(line, event);\n event = parsed.event;\n if (parsed.complete === true && parsed.data !== undefined) {\n yield JSON.parse(parsed.data) as TEvent;\n }\n }\n }\n\n buffer += decoder.decode();\n if (buffer.length > 0) {\n const parsed = parseSseLine(buffer, event);\n event = parsed.event;\n if (parsed.complete === true && parsed.data !== undefined) {\n yield JSON.parse(parsed.data) as TEvent;\n }\n }\n const data = flushSseEvent(event);\n if (data !== undefined) {\n yield JSON.parse(data) as TEvent;\n }\n } finally {\n reader.releaseLock();\n }\n}\n\nexport async function* fetchEventStream<TEvent>(\n input: string | URL | Request,\n options: FetchEventStreamOptions = {},\n): AsyncIterable<TEvent> {\n const fetchImpl = options.fetch ?? globalThis.fetch;\n if (fetchImpl === undefined) {\n throw new Error(\"fetchEventStream requires a fetch implementation\");\n }\n\n const response = await fetchImpl(input, fetchOptions(options));\n if (!response.ok) {\n throw new EventStreamHttpError(response, await response.text());\n }\n if (response.body === null) {\n throw new Error(\"Event stream response does not include a body\");\n }\n\n const format = options.format ?? inferEventStreamFormat(response.headers.get(\"content-type\"));\n if (format === \"sse\") {\n yield* readSseStream<TEvent>(response.body);\n return;\n }\n\n yield* readJsonlStream<TEvent>(response.body);\n}\n\nexport function createFetchTransport<TRequest, TEvent = unknown>(\n options: CreateFetchTransportOptions<TRequest, TEvent>,\n): EventTransport<TRequest, TEvent> {\n return {\n async *send(request, transportOptions = {}) {\n const endpoint =\n typeof options.endpoint === \"function\" ? options.endpoint(request) : options.endpoint;\n const requestHeaders = await resolveHeaders(options.headers, request);\n const headers = mergeHeaders(requestHeaders, transportOptions.headers);\n const method = options.method ?? \"POST\";\n const body = await resolveBody(options.body, request, headers);\n const init: FetchEventStreamOptions = {\n ...(options.init ?? {}),\n method,\n headers,\n format: options.format ?? \"jsonl\",\n };\n\n if (body !== undefined) {\n init.body = body;\n }\n if (transportOptions.signal !== undefined) {\n init.signal = transportOptions.signal;\n }\n if (options.fetch !== undefined) {\n init.fetch = options.fetch;\n }\n\n for await (const event of fetchEventStream<unknown>(endpoint, init)) {\n yield options.mapEvent === undefined ? (event as TEvent) : options.mapEvent(event);\n }\n },\n };\n}\n\nexport function createChatTransport<TRequest = DefaultChatRequest, TEvent = unknown>(\n options: CreateFetchTransportOptions<TRequest, TEvent>,\n): EventTransport<TRequest, TEvent> {\n return createFetchTransport(options);\n}\n\nexport function useChat<\n TRequest = DefaultChatRequest,\n TEvent = unknown,\n TMessage extends ChatMessage = ChatMessage,\n>(options: UseChatOptions<TRequest, TEvent, TMessage> = {}): UseChatResult<TEvent, TMessage> {\n const [messages, setMessages] = useState<TMessage[]>(() => [...(options.initialMessages ?? [])]);\n const [events, setEvents] = useState<TEvent[]>([]);\n const [input, setInput] = useState(\"\");\n const [status, setStatus] = useState<UseChatStatus>(\"idle\");\n const [error, setError] = useState<unknown>();\n const abortRef = useRef<AbortController | undefined>(undefined);\n const messagesRef = useRef(messages);\n\n useEffect(() => {\n messagesRef.current = messages;\n }, [messages]);\n\n useEffect(() => {\n return () => {\n abortRef.current?.abort();\n };\n }, []);\n\n const transport = useMemo(() => {\n if (options.transport !== undefined) {\n return options.transport;\n }\n if (options.endpoint === undefined) {\n return undefined;\n }\n\n return createChatTransport<TRequest, TEvent>({\n endpoint: options.endpoint,\n format: options.format ?? \"jsonl\",\n });\n }, [options.transport, options.endpoint, options.format]);\n\n const createRequest = options.createRequest ?? defaultCreateRequest<TRequest, TMessage>;\n const eventToDelta = options.eventToDelta ?? defaultEventToDelta<TEvent>;\n const eventToFinal = options.eventToFinal ?? defaultEventToFinal<TEvent>;\n\n const appendAssistantText = useCallback((assistantId: string, text: string) => {\n setMessages((current) =>\n current.map((message) =>\n message.id === assistantId\n ? ({ ...message, content: `${message.content}${text}` } as TMessage)\n : message,\n ),\n );\n }, []);\n\n const replaceAssistantText = useCallback((assistantId: string, text: string) => {\n setMessages((current) =>\n current.map((message) =>\n message.id === assistantId ? ({ ...message, content: text } as TMessage) : message,\n ),\n );\n }, []);\n\n const send = useCallback(\n async (nextInput?: string) => {\n if (transport === undefined) {\n throw new Error(\"useChat requires either transport or endpoint\");\n }\n\n const content = nextInput ?? input;\n if (content.trim().length === 0) {\n return;\n }\n\n abortRef.current?.abort();\n const abortController = new AbortController();\n abortRef.current = abortController;\n\n const userMessage = createMessage<TMessage>(\"user\", content);\n const assistantMessage = createMessage<TMessage>(\"assistant\", \"\");\n const requestMessages = [...messagesRef.current, userMessage];\n const request = createRequest(content, requestMessages);\n\n setInput(\"\");\n setError(undefined);\n setStatus(\"streaming\");\n setEvents([]);\n setMessages([...requestMessages, assistantMessage]);\n\n try {\n for await (const event of transport.send(request, { signal: abortController.signal })) {\n setEvents((current) => [...current, event]);\n options.onEvent?.(event);\n\n const delta = eventToDelta(event);\n if (delta !== undefined && delta.length > 0) {\n appendAssistantText(assistantMessage.id, delta);\n }\n\n const final = eventToFinal(event);\n if (final !== undefined) {\n replaceAssistantText(assistantMessage.id, final);\n }\n }\n\n if (!abortController.signal.aborted) {\n setStatus(\"idle\");\n }\n } catch (caught) {\n if (isAbortError(caught)) {\n setStatus(\"idle\");\n return;\n }\n\n setError(caught);\n setStatus(\"error\");\n options.onError?.(caught);\n } finally {\n if (abortRef.current === abortController) {\n abortRef.current = undefined;\n }\n }\n },\n [\n appendAssistantText,\n createRequest,\n eventToDelta,\n eventToFinal,\n input,\n options,\n replaceAssistantText,\n transport,\n ],\n );\n\n const stop = useCallback(() => {\n abortRef.current?.abort();\n abortRef.current = undefined;\n setStatus(\"idle\");\n }, []);\n\n const reset = useCallback((nextMessages?: TMessage[]) => {\n const resetMessages = nextMessages ?? [];\n messagesRef.current = resetMessages;\n abortRef.current?.abort();\n abortRef.current = undefined;\n setMessages(resetMessages);\n setEvents([]);\n setError(undefined);\n setInput(\"\");\n setStatus(\"idle\");\n }, []);\n\n const text = messages\n .filter((message) => message.role === \"assistant\")\n .map((message) => message.content)\n .join(\"\");\n\n return {\n messages,\n events,\n input,\n setInput,\n send,\n stop,\n reset,\n status,\n error,\n text,\n };\n}\n\nfunction fetchOptions(options: FetchEventStreamOptions): RequestInit {\n const { format: _format, fetch: _fetch, ...init } = options;\n return init;\n}\n\nfunction inferEventStreamFormat(contentType: string | null): EventStreamFormat {\n return contentType?.toLowerCase().includes(\"text/event-stream\") ? \"sse\" : \"jsonl\";\n}\n\nfunction createEmptySseEvent(): { data: string[] } {\n return { data: [] };\n}\n\nfunction parseSseLine(\n line: string,\n event: { data: string[] },\n): { event: { data: string[] }; complete?: true; data?: string } {\n if (line === \"\") {\n const data = flushSseEvent(event);\n return data === undefined\n ? { event: createEmptySseEvent(), complete: true }\n : { event: createEmptySseEvent(), complete: true, data };\n }\n\n if (line.startsWith(\":\")) {\n return { event };\n }\n\n const separator = line.indexOf(\":\");\n const field = separator === -1 ? line : line.slice(0, separator);\n const value = separator === -1 ? \"\" : line.slice(separator + 1).replace(/^ /, \"\");\n\n if (field === \"data\") {\n event.data.push(value);\n }\n\n return { event };\n}\n\nfunction flushSseEvent(event: { data: string[] }): string | undefined {\n if (event.data.length === 0) {\n return undefined;\n }\n\n return event.data.join(\"\\n\");\n}\n\nasync function resolveHeaders<TRequest>(\n headers: CreateFetchTransportOptions<TRequest, unknown>[\"headers\"],\n request: TRequest,\n): Promise<HeadersInit | undefined> {\n return typeof headers === \"function\" ? headers(request) : headers;\n}\n\nasync function resolveBody<TRequest>(\n body: CreateFetchTransportOptions<TRequest, unknown>[\"body\"],\n request: TRequest,\n headers: Headers,\n): Promise<BodyInit | null | undefined> {\n if (body !== undefined) {\n return body(request);\n }\n\n if (!headers.has(\"content-type\")) {\n headers.set(\"content-type\", \"application/json\");\n }\n\n return JSON.stringify(request);\n}\n\nfunction mergeHeaders(...values: (HeadersInit | undefined)[]): Headers {\n const headers = new Headers();\n\n for (const value of values) {\n if (value === undefined) {\n continue;\n }\n new Headers(value).forEach((headerValue, key) => {\n headers.set(key, headerValue);\n });\n }\n\n return headers;\n}\n\nfunction defaultCreateRequest<TRequest, TMessage extends ChatMessage>(\n input: string,\n messages: TMessage[],\n): TRequest {\n return {\n message: input,\n history: messages.slice(0, -1),\n stream: true,\n } as TRequest;\n}\n\nfunction createMessage<TMessage extends ChatMessage>(role: ChatRole, content: string): TMessage {\n return {\n id: createId(),\n role,\n content,\n } as TMessage;\n}\n\nfunction createId(): string {\n return globalThis.crypto?.randomUUID?.() ?? Math.random().toString(36).slice(2);\n}\n\nfunction defaultEventToDelta<TEvent>(event: TEvent): string | undefined {\n if (!isRecord(event)) {\n return undefined;\n }\n\n return event.type === \"text_delta\" && typeof event.delta === \"string\" ? event.delta : undefined;\n}\n\nfunction defaultEventToFinal<TEvent>(event: TEvent): string | undefined {\n if (!isRecord(event)) {\n return undefined;\n }\n\n return event.type === \"final\" && typeof event.output === \"string\" ? event.output : undefined;\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null;\n}\n\nfunction isAbortError(error: unknown): boolean {\n return error instanceof DOMException && error.name === \"AbortError\";\n}\n"],"mappings":"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","names":["trimmed","text"]}
|
|
1
|
+
{"version":3,"sources":["../src/direct.ts","../src/streams.ts","../src/fetch.ts","../src/transport.ts","../src/use-chat.ts","../src/chat-defaults.ts","../src/use-completion.ts","../src/completion-defaults.ts"],"sourcesContent":["import type { EventTransport } from \"./types\";\n\nexport function createDirectTransport<TRequest, TEvent>(\n handler: (request: TRequest) => AsyncIterable<TEvent>,\n): EventTransport<TRequest, TEvent> {\n return {\n async *send(request, options) {\n const iterable = handler(request);\n const iterator = iterable[Symbol.asyncIterator]();\n try {\n while (true) {\n if (options?.signal?.aborted) {\n break;\n }\n\n const next = await iterator.next();\n if (next.done) {\n break;\n }\n\n yield next.value;\n }\n } finally {\n await iterator.return?.();\n }\n },\n };\n}\n","export async function* readJsonlStream<TEvent>(\n stream: ReadableStream<Uint8Array>,\n): AsyncIterable<TEvent> {\n const reader = stream.getReader();\n const decoder = new TextDecoder();\n let buffer = \"\";\n\n try {\n while (true) {\n const next = await reader.read();\n if (next.done === true) {\n break;\n }\n\n buffer += decoder.decode(next.value, { stream: true });\n const lines = buffer.split(/\\r?\\n/);\n buffer = lines.pop() ?? \"\";\n\n for (const line of lines) {\n const trimmed = line.trim();\n if (trimmed.length > 0) {\n yield JSON.parse(trimmed) as TEvent;\n }\n }\n }\n\n buffer += decoder.decode();\n const trimmed = buffer.trim();\n if (trimmed.length > 0) {\n yield JSON.parse(trimmed) as TEvent;\n }\n } finally {\n reader.releaseLock();\n }\n}\n\nexport async function* readSseStream<TEvent>(\n stream: ReadableStream<Uint8Array>,\n): AsyncIterable<TEvent> {\n const reader = stream.getReader();\n const decoder = new TextDecoder();\n let buffer = \"\";\n let event = createEmptySseEvent();\n\n try {\n while (true) {\n const next = await reader.read();\n if (next.done === true) {\n break;\n }\n\n buffer += decoder.decode(next.value, { stream: true });\n const lines = buffer.split(/\\r?\\n/);\n buffer = lines.pop() ?? \"\";\n\n for (const line of lines) {\n const parsed = parseSseLine(line, event);\n event = parsed.event;\n if (parsed.complete === true && parsed.data !== undefined) {\n yield JSON.parse(parsed.data) as TEvent;\n }\n }\n }\n\n buffer += decoder.decode();\n if (buffer.length > 0) {\n const parsed = parseSseLine(buffer, event);\n event = parsed.event;\n if (parsed.complete === true && parsed.data !== undefined) {\n yield JSON.parse(parsed.data) as TEvent;\n }\n }\n const data = flushSseEvent(event);\n if (data !== undefined) {\n yield JSON.parse(data) as TEvent;\n }\n } finally {\n reader.releaseLock();\n }\n}\n\nfunction createEmptySseEvent(): { data: string[] } {\n return { data: [] };\n}\n\nfunction parseSseLine(\n line: string,\n event: { data: string[] },\n): { event: { data: string[] }; complete?: true; data?: string } {\n if (line === \"\") {\n const data = flushSseEvent(event);\n return data === undefined\n ? { event: createEmptySseEvent(), complete: true }\n : { event: createEmptySseEvent(), complete: true, data };\n }\n\n if (line.startsWith(\":\")) {\n return { event };\n }\n\n const separator = line.indexOf(\":\");\n const field = separator === -1 ? line : line.slice(0, separator);\n const value = separator === -1 ? \"\" : line.slice(separator + 1).replace(/^ /, \"\");\n\n if (field === \"data\") {\n event.data.push(value);\n }\n\n return { event };\n}\n\nfunction flushSseEvent(event: { data: string[] }): string | undefined {\n if (event.data.length === 0) {\n return undefined;\n }\n\n return event.data.join(\"\\n\");\n}\n","import { readJsonlStream, readSseStream } from \"./streams\";\nimport type { EventStreamFormat } from \"./types\";\n\nexport type FetchEventStreamOptions = Omit<RequestInit, \"headers\"> & {\n format?: EventStreamFormat;\n fetch?: typeof fetch;\n headers?: HeadersInit;\n};\n\nexport class EventStreamHttpError extends Error {\n constructor(\n readonly response: Response,\n readonly body: string,\n ) {\n super(`Event stream request failed with status ${response.status}`);\n this.name = \"EventStreamHttpError\";\n }\n}\n\nexport async function* fetchEventStream<TEvent>(\n input: string | URL | Request,\n options: FetchEventStreamOptions = {},\n): AsyncIterable<TEvent> {\n const fetchImpl = options.fetch ?? globalThis.fetch;\n if (fetchImpl === undefined) {\n throw new Error(\"fetchEventStream requires a fetch implementation\");\n }\n\n const response = await fetchImpl(input, fetchOptions(options));\n if (!response.ok) {\n throw new EventStreamHttpError(response, await response.text());\n }\n if (response.body === null) {\n throw new Error(\"Event stream response does not include a body\");\n }\n\n const format = options.format ?? inferEventStreamFormat(response.headers.get(\"content-type\"));\n if (format === \"sse\") {\n yield* readSseStream<TEvent>(response.body);\n return;\n }\n\n yield* readJsonlStream<TEvent>(response.body);\n}\n\nfunction fetchOptions(options: FetchEventStreamOptions): RequestInit {\n const { format: _format, fetch: _fetch, ...init } = options;\n return init;\n}\n\nfunction inferEventStreamFormat(contentType: string | null): EventStreamFormat {\n return contentType?.toLowerCase().includes(\"text/event-stream\") ? \"sse\" : \"jsonl\";\n}\n","import { type FetchEventStreamOptions, fetchEventStream } from \"./fetch\";\nimport type { EventStreamFormat, EventTransport } from \"./types\";\n\nexport type CreateFetchTransportOptions<TRequest, TEvent> = {\n endpoint: string | URL | ((request: TRequest) => string | URL);\n method?: string;\n format?: EventStreamFormat;\n fetch?: typeof fetch;\n headers?: HeadersInit | ((request: TRequest) => HeadersInit | Promise<HeadersInit>);\n body?: (request: TRequest) => BodyInit | null | undefined | Promise<BodyInit | null | undefined>;\n init?: Omit<RequestInit, \"body\" | \"headers\" | \"method\" | \"signal\">;\n mapEvent?: (event: unknown) => TEvent;\n};\n\nexport function createFetchTransport<TRequest, TEvent = unknown>(\n options: CreateFetchTransportOptions<TRequest, TEvent>,\n): EventTransport<TRequest, TEvent> {\n return {\n async *send(request, transportOptions = {}) {\n const endpoint =\n typeof options.endpoint === \"function\" ? options.endpoint(request) : options.endpoint;\n const requestHeaders = await resolveHeaders(options.headers, request);\n const headers = mergeHeaders(requestHeaders, transportOptions.headers);\n const method = options.method ?? \"POST\";\n const body = await resolveBody(options.body, request, headers);\n const init: FetchEventStreamOptions = {\n ...(options.init ?? {}),\n method,\n headers,\n format: options.format ?? \"jsonl\",\n };\n\n if (body !== undefined) {\n init.body = body;\n }\n if (transportOptions.signal !== undefined) {\n init.signal = transportOptions.signal;\n }\n if (options.fetch !== undefined) {\n init.fetch = options.fetch;\n }\n\n for await (const event of fetchEventStream<unknown>(endpoint, init)) {\n yield options.mapEvent === undefined ? (event as TEvent) : options.mapEvent(event);\n }\n },\n };\n}\n\nexport function createChatTransport<TRequest, TEvent = unknown>(\n options: CreateFetchTransportOptions<TRequest, TEvent>,\n): EventTransport<TRequest, TEvent> {\n return createFetchTransport(options);\n}\n\nasync function resolveHeaders<TRequest>(\n headers: CreateFetchTransportOptions<TRequest, unknown>[\"headers\"],\n request: TRequest,\n): Promise<HeadersInit | undefined> {\n return typeof headers === \"function\" ? headers(request) : headers;\n}\n\nasync function resolveBody<TRequest>(\n body: CreateFetchTransportOptions<TRequest, unknown>[\"body\"],\n request: TRequest,\n headers: Headers,\n): Promise<BodyInit | null | undefined> {\n if (body !== undefined) {\n return body(request);\n }\n\n if (!headers.has(\"content-type\")) {\n headers.set(\"content-type\", \"application/json\");\n }\n\n return JSON.stringify(request);\n}\n\nfunction mergeHeaders(...values: (HeadersInit | undefined)[]): Headers {\n const headers = new Headers();\n\n for (const value of values) {\n if (value === undefined) {\n continue;\n }\n new Headers(value).forEach((headerValue, key) => {\n headers.set(key, headerValue);\n });\n }\n\n return headers;\n}\n","import { useCallback, useEffect, useMemo, useRef, useState } from \"react\";\n\nimport {\n createMessage,\n defaultCreateRequest,\n defaultEventToDelta,\n defaultEventToFinal,\n} from \"./chat-defaults\";\nimport { createChatTransport } from \"./transport\";\nimport type { ChatMessage, DefaultChatRequest, UseChatOptions, UseChatResult } from \"./types\";\n\nexport function useChat<\n TRequest = DefaultChatRequest,\n TEvent = unknown,\n TMessage extends ChatMessage = ChatMessage,\n>(options: UseChatOptions<TRequest, TEvent, TMessage> = {}): UseChatResult<TEvent, TMessage> {\n const [messages, setMessages] = useState<TMessage[]>(() => [...(options.initialMessages ?? [])]);\n const [events, setEvents] = useState<TEvent[]>([]);\n const [input, setInput] = useState(\"\");\n const [status, setStatus] = useState<UseChatResult<TEvent, TMessage>[\"status\"]>(\"idle\");\n const [error, setError] = useState<unknown>();\n const abortRef = useRef<AbortController | undefined>(undefined);\n const messagesRef = useRef(messages);\n\n useEffect(() => {\n messagesRef.current = messages;\n }, [messages]);\n\n useEffect(() => {\n return () => {\n abortRef.current?.abort();\n };\n }, []);\n\n const transport = useMemo(() => {\n if (options.transport !== undefined) {\n return options.transport;\n }\n if (options.endpoint === undefined) {\n return undefined;\n }\n\n return createChatTransport<TRequest, TEvent>({\n endpoint: options.endpoint,\n format: options.format ?? \"jsonl\",\n });\n }, [options.transport, options.endpoint, options.format]);\n\n const createRequest = options.createRequest ?? defaultCreateRequest<TRequest, TMessage>;\n const eventToDelta = options.eventToDelta ?? defaultEventToDelta<TEvent>;\n const eventToFinal = options.eventToFinal ?? defaultEventToFinal<TEvent>;\n\n const appendAssistantText = useCallback((assistantId: string, text: string) => {\n setMessages((current) =>\n current.map((message) =>\n message.id === assistantId\n ? ({ ...message, content: `${message.content}${text}` } as TMessage)\n : message,\n ),\n );\n }, []);\n\n const replaceAssistantText = useCallback((assistantId: string, text: string) => {\n setMessages((current) =>\n current.map((message) =>\n message.id === assistantId ? ({ ...message, content: text } as TMessage) : message,\n ),\n );\n }, []);\n\n const send = useCallback(\n async (nextInput?: string) => {\n if (transport === undefined) {\n throw new Error(\"useChat requires either transport or endpoint\");\n }\n\n const content = nextInput ?? input;\n if (content.trim().length === 0) {\n return;\n }\n\n abortRef.current?.abort();\n const abortController = new AbortController();\n abortRef.current = abortController;\n\n const userMessage = createMessage<TMessage>(\"user\", content);\n const assistantMessage = createMessage<TMessage>(\"assistant\", \"\");\n const requestMessages = [...messagesRef.current, userMessage];\n const request = createRequest(content, requestMessages);\n\n setInput(\"\");\n setError(undefined);\n setStatus(\"streaming\");\n setEvents([]);\n setMessages([...requestMessages, assistantMessage]);\n\n try {\n for await (const event of transport.send(request, { signal: abortController.signal })) {\n setEvents((current) => [...current, event]);\n options.onEvent?.(event);\n\n const delta = eventToDelta(event);\n if (delta !== undefined && delta.length > 0) {\n appendAssistantText(assistantMessage.id, delta);\n }\n\n const final = eventToFinal(event);\n if (final !== undefined) {\n replaceAssistantText(assistantMessage.id, final);\n }\n }\n\n if (!abortController.signal.aborted) {\n setStatus(\"idle\");\n }\n } catch (caught) {\n if (isAbortError(caught)) {\n setStatus(\"idle\");\n return;\n }\n\n setError(caught);\n setStatus(\"error\");\n options.onError?.(caught);\n } finally {\n if (abortRef.current === abortController) {\n abortRef.current = undefined;\n }\n }\n },\n [\n appendAssistantText,\n createRequest,\n eventToDelta,\n eventToFinal,\n input,\n options,\n replaceAssistantText,\n transport,\n ],\n );\n\n const stop = useCallback(() => {\n abortRef.current?.abort();\n abortRef.current = undefined;\n setStatus(\"idle\");\n }, []);\n\n const reset = useCallback((nextMessages?: TMessage[]) => {\n const resetMessages = nextMessages ?? [];\n messagesRef.current = resetMessages;\n abortRef.current?.abort();\n abortRef.current = undefined;\n setMessages(resetMessages);\n setEvents([]);\n setError(undefined);\n setInput(\"\");\n setStatus(\"idle\");\n }, []);\n\n const text = messages\n .filter((message) => message.role === \"assistant\")\n .map((message) => message.content)\n .join(\"\");\n\n return {\n messages,\n events,\n input,\n setInput,\n send,\n stop,\n reset,\n status,\n error,\n text,\n };\n}\n\nfunction isAbortError(error: unknown): boolean {\n return error instanceof DOMException && error.name === \"AbortError\";\n}\n","import type { ChatMessage, ChatRole, DefaultChatRequest } from \"./types\";\n\nexport function defaultCreateRequest<TRequest, TMessage extends ChatMessage>(\n input: string,\n messages: TMessage[],\n): TRequest {\n return {\n message: input,\n history: messages.slice(0, -1),\n stream: true,\n } as DefaultChatRequest as TRequest;\n}\n\nexport function createMessage<TMessage extends ChatMessage>(\n role: ChatRole,\n content: string,\n): TMessage {\n return {\n id: createId(),\n role,\n content,\n } as TMessage;\n}\n\nexport function defaultEventToDelta<TEvent>(event: TEvent): string | undefined {\n if (!isRecord(event)) {\n return undefined;\n }\n\n return event.type === \"text_delta\" && typeof event.delta === \"string\" ? event.delta : undefined;\n}\n\nexport function defaultEventToFinal<TEvent>(event: TEvent): string | undefined {\n if (!isRecord(event)) {\n return undefined;\n }\n\n return event.type === \"final\" && typeof event.output === \"string\" ? event.output : undefined;\n}\n\nfunction createId(): string {\n return globalThis.crypto?.randomUUID?.() ?? Math.random().toString(36).slice(2);\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null;\n}\n","import { useCallback, useEffect, useMemo, useRef, useState } from \"react\";\n\nimport {\n defaultCompletionEventToDelta,\n defaultCompletionEventToFinal,\n} from \"./completion-defaults\";\nimport { createFetchTransport } from \"./transport\";\nimport type { EventStreamFormat, EventTransport } from \"./types\";\n\nexport type UseCompletionRequest = {\n prompt: string;\n stream: true;\n};\n\nexport type UseCompletionStatus = \"idle\" | \"streaming\" | \"error\";\n\nexport type UseCompletionOptions<TEvent = unknown> = {\n transport?: EventTransport<UseCompletionRequest, TEvent>;\n endpoint?: string | URL;\n format?: EventStreamFormat;\n initialCompletion?: string;\n eventToDelta?: (event: TEvent) => string | undefined;\n eventToFinal?: (event: TEvent) => string | undefined;\n onEvent?: (event: TEvent) => void;\n onError?: (error: unknown) => void;\n};\n\nexport type UseCompletionResult = {\n completion: string;\n input: string;\n setInput(input: string): void;\n complete(prompt?: string): Promise<void>;\n stop(): void;\n reset(completion?: string): void;\n status: UseCompletionStatus;\n error: unknown;\n};\n\nexport function useCompletion<TEvent = unknown>(\n options: UseCompletionOptions<TEvent> = {},\n): UseCompletionResult {\n const [completion, setCompletion] = useState(options.initialCompletion ?? \"\");\n const [input, setInput] = useState(\"\");\n const [status, setStatus] = useState<UseCompletionStatus>(\"idle\");\n const [error, setError] = useState<unknown>();\n const abortRef = useRef<AbortController | undefined>(undefined);\n const completionRef = useRef(completion);\n\n useEffect(() => {\n completionRef.current = completion;\n }, [completion]);\n\n useEffect(() => {\n return () => {\n abortRef.current?.abort();\n };\n }, []);\n\n const transport = useMemo(() => {\n if (options.transport !== undefined) {\n return options.transport;\n }\n if (options.endpoint === undefined) {\n return undefined;\n }\n\n return createFetchTransport<UseCompletionRequest, TEvent>({\n endpoint: options.endpoint,\n format: options.format ?? \"jsonl\",\n });\n }, [options.transport, options.endpoint, options.format]);\n\n const eventToDelta = options.eventToDelta ?? defaultCompletionEventToDelta<TEvent>;\n const eventToFinal = options.eventToFinal ?? defaultCompletionEventToFinal<TEvent>;\n\n const complete = useCallback(\n async (nextInput?: string) => {\n if (transport === undefined) {\n throw new Error(\"useCompletion requires either transport or endpoint\");\n }\n\n const prompt = nextInput ?? input;\n if (prompt.trim().length === 0) {\n return;\n }\n\n abortRef.current?.abort();\n const abortController = new AbortController();\n abortRef.current = abortController;\n\n const request: UseCompletionRequest = { prompt, stream: true };\n\n setInput(\"\");\n setError(undefined);\n setStatus(\"streaming\");\n setCompletion(\"\");\n\n try {\n for await (const event of transport.send(request, { signal: abortController.signal })) {\n options.onEvent?.(event);\n\n const delta = eventToDelta(event);\n if (delta !== undefined && delta.length > 0) {\n setCompletion((current) => `${current}${delta}`);\n }\n\n const final = eventToFinal(event);\n if (final !== undefined) {\n setCompletion(final);\n }\n }\n\n if (!abortController.signal.aborted) {\n setStatus(\"idle\");\n }\n } catch (caught) {\n if (isAbortError(caught)) {\n setStatus(\"idle\");\n return;\n }\n\n setError(caught);\n setStatus(\"error\");\n options.onError?.(caught);\n } finally {\n if (abortRef.current === abortController) {\n abortRef.current = undefined;\n }\n }\n },\n [eventToDelta, eventToFinal, input, options, transport],\n );\n\n const stop = useCallback(() => {\n abortRef.current?.abort();\n abortRef.current = undefined;\n setStatus(\"idle\");\n }, []);\n\n const reset = useCallback((nextCompletion?: string) => {\n abortRef.current?.abort();\n abortRef.current = undefined;\n setCompletion(nextCompletion ?? \"\");\n setError(undefined);\n setInput(\"\");\n setStatus(\"idle\");\n }, []);\n\n return {\n completion,\n input,\n setInput,\n complete,\n stop,\n reset,\n status,\n error,\n };\n}\n\nfunction isAbortError(error: unknown): boolean {\n return error instanceof DOMException && error.name === \"AbortError\";\n}\n","export function defaultCompletionEventToDelta<TEvent>(event: TEvent): string | undefined {\n if (!isRecord(event)) {\n return undefined;\n }\n\n return event.type === \"text_delta\" && typeof event.delta === \"string\" ? event.delta : undefined;\n}\n\nexport function defaultCompletionEventToFinal<TEvent>(event: TEvent): string | undefined {\n if (!isRecord(event) || event.type !== \"final\") {\n return undefined;\n }\n\n const response = event.response;\n if (!isRecord(response) || !Array.isArray(response.choice)) {\n return undefined;\n }\n\n const parts: string[] = [];\n for (const item of response.choice) {\n if (isRecord(item) && item.type === \"text\" && typeof item.text === \"string\") {\n parts.push(item.text);\n }\n }\n\n return parts.length > 0 ? parts.join(\"\") : undefined;\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null;\n}\n"],"mappings":"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","names":["trimmed","text","useCallback","useEffect","useMemo","useRef","useState","isRecord","useState","useRef","useEffect","useMemo","useCallback","isAbortError"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@anvia/react",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.0",
|
|
4
4
|
"description": "React hooks and client transports for Anvia applications.",
|
|
5
5
|
"author": "anvia",
|
|
6
6
|
"maintainer": "Indra Zulfi",
|
|
@@ -29,15 +29,21 @@
|
|
|
29
29
|
"react": ">=18"
|
|
30
30
|
},
|
|
31
31
|
"devDependencies": {
|
|
32
|
+
"@testing-library/react": "^16.3.2",
|
|
32
33
|
"@types/node": "^24.9.1",
|
|
33
34
|
"@types/react": "^19.2.14",
|
|
35
|
+
"@types/react-dom": "^19.2.3",
|
|
36
|
+
"@vitest/coverage-v8": "4.1.5",
|
|
37
|
+
"happy-dom": "20.9.0",
|
|
34
38
|
"react": "^19.2.6",
|
|
39
|
+
"react-dom": "19.2.6",
|
|
35
40
|
"tsup": "^8.5.0",
|
|
36
41
|
"typescript": "^5.9.3",
|
|
37
42
|
"vitest": "^4.0.8"
|
|
38
43
|
},
|
|
39
44
|
"scripts": {
|
|
40
45
|
"build": "tsup src/index.ts --format esm --dts --sourcemap --clean --external react",
|
|
46
|
+
"coverage": "vitest run --coverage",
|
|
41
47
|
"test": "vitest run",
|
|
42
48
|
"typecheck": "tsc --noEmit"
|
|
43
49
|
}
|