ai 2.2.26 → 2.2.27
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +72 -62
- package/dist/index.mjs +72 -62
- package/package.json +10 -10
- package/react/dist/index.d.ts +9 -3
- package/react/dist/index.js +106 -100
- package/react/dist/index.mjs +106 -100
- package/solid/dist/index.d.ts +2 -0
- package/solid/dist/index.js +113 -80
- package/solid/dist/index.mjs +113 -80
- package/svelte/dist/index.d.ts +2 -0
- package/svelte/dist/index.js +109 -79
- package/svelte/dist/index.mjs +109 -79
- package/vue/dist/index.d.ts +2 -0
- package/vue/dist/index.js +111 -79
- package/vue/dist/index.mjs +111 -79
package/react/dist/index.mjs
CHANGED
@@ -149,21 +149,22 @@ function createChunkDecoder(complex) {
|
|
149
149
|
}
|
150
150
|
var COMPLEX_HEADER = "X-Experimental-Stream-Data";
|
151
151
|
|
152
|
-
// shared/
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
}
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
152
|
+
// shared/read-data-stream.ts
|
153
|
+
var NEWLINE = "\n".charCodeAt(0);
|
154
|
+
function concatChunks(chunks, totalLength) {
|
155
|
+
const concatenatedChunks = new Uint8Array(totalLength);
|
156
|
+
let offset = 0;
|
157
|
+
for (const chunk of chunks) {
|
158
|
+
concatenatedChunks.set(chunk, offset);
|
159
|
+
offset += chunk.length;
|
160
|
+
}
|
161
|
+
chunks.length = 0;
|
162
|
+
return concatenatedChunks;
|
163
|
+
}
|
164
|
+
async function* readDataStream(reader, {
|
165
|
+
isAborted
|
166
|
+
} = {}) {
|
167
|
+
const decoder = new TextDecoder();
|
167
168
|
const chunks = [];
|
168
169
|
let totalLength = 0;
|
169
170
|
while (true) {
|
@@ -178,61 +179,70 @@ async function parseComplexResponse({
|
|
178
179
|
if (chunks.length === 0) {
|
179
180
|
break;
|
180
181
|
}
|
181
|
-
|
182
|
-
let offset = 0;
|
183
|
-
for (const chunk of chunks) {
|
184
|
-
concatenatedChunks.set(chunk, offset);
|
185
|
-
offset += chunk.length;
|
186
|
-
}
|
187
|
-
chunks.length = 0;
|
182
|
+
const concatenatedChunks = concatChunks(chunks, totalLength);
|
188
183
|
totalLength = 0;
|
189
|
-
const
|
190
|
-
|
191
|
-
|
192
|
-
"Invalid response format. Complex mode was set but the response is a string. This should never happen."
|
193
|
-
);
|
184
|
+
const streamParts2 = decoder.decode(concatenatedChunks, { stream: true }).split("\n").filter((line) => line !== "").map(parseStreamPart);
|
185
|
+
for (const streamPart of streamParts2) {
|
186
|
+
yield streamPart;
|
194
187
|
}
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
188
|
+
if (isAborted == null ? void 0 : isAborted()) {
|
189
|
+
reader.cancel();
|
190
|
+
break;
|
191
|
+
}
|
192
|
+
}
|
193
|
+
}
|
194
|
+
|
195
|
+
// shared/parse-complex-response.ts
|
196
|
+
async function parseComplexResponse({
|
197
|
+
reader,
|
198
|
+
abortControllerRef,
|
199
|
+
update,
|
200
|
+
onFinish,
|
201
|
+
generateId = nanoid,
|
202
|
+
getCurrentDate = () => /* @__PURE__ */ new Date()
|
203
|
+
}) {
|
204
|
+
const createdAt = getCurrentDate();
|
205
|
+
const prefixMap = {
|
206
|
+
data: []
|
207
|
+
};
|
208
|
+
for await (const { type, value } of readDataStream(reader, {
|
209
|
+
isAborted: () => (abortControllerRef == null ? void 0 : abortControllerRef.current) === null
|
210
|
+
})) {
|
211
|
+
if (type === "text") {
|
212
|
+
if (prefixMap["text"]) {
|
213
|
+
prefixMap["text"] = {
|
214
|
+
...prefixMap["text"],
|
215
|
+
content: (prefixMap["text"].content || "") + value
|
216
|
+
};
|
217
|
+
} else {
|
218
|
+
prefixMap["text"] = {
|
214
219
|
id: generateId(),
|
215
220
|
role: "assistant",
|
216
|
-
content:
|
217
|
-
function_call: value2.function_call,
|
218
|
-
name: value2.function_call.name,
|
221
|
+
content: value,
|
219
222
|
createdAt
|
220
223
|
};
|
221
|
-
functionCallMessage = prefixMap["function_call"];
|
222
|
-
}
|
223
|
-
if (type === "data") {
|
224
|
-
prefixMap["data"].push(...value2);
|
225
|
-
}
|
226
|
-
const responseMessage = prefixMap["text"];
|
227
|
-
const merged = [functionCallMessage, responseMessage].filter(
|
228
|
-
Boolean
|
229
|
-
);
|
230
|
-
update(merged, [...prefixMap["data"]]);
|
231
|
-
if ((abortControllerRef == null ? void 0 : abortControllerRef.current) === null) {
|
232
|
-
reader.cancel();
|
233
|
-
break;
|
234
224
|
}
|
235
225
|
}
|
226
|
+
let functionCallMessage = null;
|
227
|
+
if (type === "function_call") {
|
228
|
+
prefixMap["function_call"] = {
|
229
|
+
id: generateId(),
|
230
|
+
role: "assistant",
|
231
|
+
content: "",
|
232
|
+
function_call: value.function_call,
|
233
|
+
name: value.function_call.name,
|
234
|
+
createdAt
|
235
|
+
};
|
236
|
+
functionCallMessage = prefixMap["function_call"];
|
237
|
+
}
|
238
|
+
if (type === "data") {
|
239
|
+
prefixMap["data"].push(...value);
|
240
|
+
}
|
241
|
+
const responseMessage = prefixMap["text"];
|
242
|
+
const merged = [functionCallMessage, responseMessage].filter(
|
243
|
+
Boolean
|
244
|
+
);
|
245
|
+
update(merged, [...prefixMap["data"]]);
|
236
246
|
}
|
237
247
|
onFinish == null ? void 0 : onFinish(prefixMap);
|
238
248
|
return {
|
@@ -677,29 +687,6 @@ function useChat({
|
|
677
687
|
// react/use-completion.ts
|
678
688
|
import { useCallback as useCallback2, useEffect as useEffect2, useId as useId2, useRef as useRef2, useState as useState2 } from "react";
|
679
689
|
import useSWR2 from "swr";
|
680
|
-
|
681
|
-
// shared/process-message-stream.ts
|
682
|
-
async function processMessageStream(reader, processMessage) {
|
683
|
-
const decoder = new TextDecoder();
|
684
|
-
let buffer = "";
|
685
|
-
while (true) {
|
686
|
-
const { done, value } = await reader.read();
|
687
|
-
if (done) {
|
688
|
-
if (buffer.length > 0) {
|
689
|
-
processMessage(buffer);
|
690
|
-
}
|
691
|
-
break;
|
692
|
-
}
|
693
|
-
buffer += decoder.decode(value, { stream: true });
|
694
|
-
let endIndex;
|
695
|
-
while ((endIndex = buffer.indexOf("\n")) !== -1) {
|
696
|
-
processMessage(buffer.substring(0, endIndex).trim());
|
697
|
-
buffer = buffer.substring(endIndex + 1);
|
698
|
-
}
|
699
|
-
}
|
700
|
-
}
|
701
|
-
|
702
|
-
// react/use-completion.ts
|
703
690
|
function useCompletion({
|
704
691
|
api = "/api/completion",
|
705
692
|
id,
|
@@ -721,6 +708,7 @@ function useCompletion({
|
|
721
708
|
[completionId, "loading"],
|
722
709
|
null
|
723
710
|
);
|
711
|
+
const { data: streamData, mutate: mutateStreamData } = useSWR2([completionId, "streamData"], null);
|
724
712
|
const [error, setError] = useState2(void 0);
|
725
713
|
const completion = data;
|
726
714
|
const [abortController, setAbortController] = useState2(null);
|
@@ -779,13 +767,24 @@ function useCompletion({
|
|
779
767
|
const reader = res.body.getReader();
|
780
768
|
const isComplexMode = res.headers.get(COMPLEX_HEADER) === "true";
|
781
769
|
if (isComplexMode) {
|
782
|
-
await
|
783
|
-
|
784
|
-
|
785
|
-
|
786
|
-
|
770
|
+
for await (const { type, value } of readDataStream(reader, {
|
771
|
+
isAborted: () => abortController2 === null
|
772
|
+
})) {
|
773
|
+
switch (type) {
|
774
|
+
case "text": {
|
775
|
+
result += value;
|
776
|
+
mutate(result, false);
|
777
|
+
break;
|
778
|
+
}
|
779
|
+
case "data": {
|
780
|
+
mutateStreamData(
|
781
|
+
[...streamData || [], ...value || []],
|
782
|
+
false
|
783
|
+
);
|
784
|
+
break;
|
785
|
+
}
|
787
786
|
}
|
788
|
-
}
|
787
|
+
}
|
789
788
|
} else {
|
790
789
|
const decoder = createChunkDecoder();
|
791
790
|
while (true) {
|
@@ -874,7 +873,8 @@ function useCompletion({
|
|
874
873
|
setInput,
|
875
874
|
handleInputChange,
|
876
875
|
handleSubmit,
|
877
|
-
isLoading
|
876
|
+
isLoading,
|
877
|
+
data: streamData
|
878
878
|
};
|
879
879
|
}
|
880
880
|
|
@@ -882,7 +882,10 @@ function useCompletion({
|
|
882
882
|
import { useState as useState3 } from "react";
|
883
883
|
function experimental_useAssistant({
|
884
884
|
api,
|
885
|
-
threadId: threadIdParam
|
885
|
+
threadId: threadIdParam,
|
886
|
+
credentials,
|
887
|
+
headers,
|
888
|
+
body
|
886
889
|
}) {
|
887
890
|
const [messages, setMessages] = useState3([]);
|
888
891
|
const [input, setInput] = useState3("");
|
@@ -906,8 +909,10 @@ function experimental_useAssistant({
|
|
906
909
|
setInput("");
|
907
910
|
const result = await fetch(api, {
|
908
911
|
method: "POST",
|
909
|
-
|
912
|
+
credentials,
|
913
|
+
headers: { "Content-Type": "application/json", ...headers },
|
910
914
|
body: JSON.stringify({
|
915
|
+
...body,
|
911
916
|
// always use user-provided threadId when available:
|
912
917
|
threadId: (_b = threadIdParam != null ? threadIdParam : threadId) != null ? _b : null,
|
913
918
|
message: input,
|
@@ -918,9 +923,10 @@ function experimental_useAssistant({
|
|
918
923
|
if (result.body == null) {
|
919
924
|
throw new Error("The response body is empty.");
|
920
925
|
}
|
921
|
-
|
922
|
-
|
923
|
-
|
926
|
+
try {
|
927
|
+
for await (const { type, value } of readDataStream(
|
928
|
+
result.body.getReader()
|
929
|
+
)) {
|
924
930
|
switch (type) {
|
925
931
|
case "assistant_message": {
|
926
932
|
setMessages((messages2) => [
|
@@ -947,10 +953,10 @@ function experimental_useAssistant({
|
|
947
953
|
break;
|
948
954
|
}
|
949
955
|
}
|
950
|
-
} catch (error2) {
|
951
|
-
setError(error2);
|
952
956
|
}
|
953
|
-
})
|
957
|
+
} catch (error2) {
|
958
|
+
setError(error2);
|
959
|
+
}
|
954
960
|
setStatus("awaiting_message");
|
955
961
|
};
|
956
962
|
return {
|
package/solid/dist/index.d.ts
CHANGED
@@ -279,6 +279,8 @@ type UseCompletionHelpers = {
|
|
279
279
|
handleSubmit: (e: any) => void;
|
280
280
|
/** Whether the API request is in progress */
|
281
281
|
isLoading: Accessor<boolean>;
|
282
|
+
/** Additional data added on the server via StreamData */
|
283
|
+
data: Accessor<JSONValue[] | undefined>;
|
282
284
|
};
|
283
285
|
declare function useCompletion({ api, id, initialCompletion, initialInput, credentials, headers, body, onResponse, onFinish, onError, }?: UseCompletionOptions): UseCompletionHelpers;
|
284
286
|
|
package/solid/dist/index.js
CHANGED
@@ -30,9 +30,6 @@ var import_solid_js = require("solid-js");
|
|
30
30
|
var import_solid_swr_store = require("solid-swr-store");
|
31
31
|
var import_swr_store = require("swr-store");
|
32
32
|
|
33
|
-
// shared/utils.ts
|
34
|
-
var import_non_secure = require("nanoid/non-secure");
|
35
|
-
|
36
33
|
// shared/stream-parts.ts
|
37
34
|
var textStreamPart = {
|
38
35
|
code: "0",
|
@@ -154,7 +151,51 @@ var parseStreamPart = (line) => {
|
|
154
151
|
return streamPartsByCode[code].parse(jsonValue);
|
155
152
|
};
|
156
153
|
|
154
|
+
// shared/read-data-stream.ts
|
155
|
+
var NEWLINE = "\n".charCodeAt(0);
|
156
|
+
function concatChunks(chunks, totalLength) {
|
157
|
+
const concatenatedChunks = new Uint8Array(totalLength);
|
158
|
+
let offset = 0;
|
159
|
+
for (const chunk of chunks) {
|
160
|
+
concatenatedChunks.set(chunk, offset);
|
161
|
+
offset += chunk.length;
|
162
|
+
}
|
163
|
+
chunks.length = 0;
|
164
|
+
return concatenatedChunks;
|
165
|
+
}
|
166
|
+
async function* readDataStream(reader, {
|
167
|
+
isAborted
|
168
|
+
} = {}) {
|
169
|
+
const decoder = new TextDecoder();
|
170
|
+
const chunks = [];
|
171
|
+
let totalLength = 0;
|
172
|
+
while (true) {
|
173
|
+
const { value } = await reader.read();
|
174
|
+
if (value) {
|
175
|
+
chunks.push(value);
|
176
|
+
totalLength += value.length;
|
177
|
+
if (value[value.length - 1] !== NEWLINE) {
|
178
|
+
continue;
|
179
|
+
}
|
180
|
+
}
|
181
|
+
if (chunks.length === 0) {
|
182
|
+
break;
|
183
|
+
}
|
184
|
+
const concatenatedChunks = concatChunks(chunks, totalLength);
|
185
|
+
totalLength = 0;
|
186
|
+
const streamParts2 = decoder.decode(concatenatedChunks, { stream: true }).split("\n").filter((line) => line !== "").map(parseStreamPart);
|
187
|
+
for (const streamPart of streamParts2) {
|
188
|
+
yield streamPart;
|
189
|
+
}
|
190
|
+
if (isAborted == null ? void 0 : isAborted()) {
|
191
|
+
reader.cancel();
|
192
|
+
break;
|
193
|
+
}
|
194
|
+
}
|
195
|
+
}
|
196
|
+
|
157
197
|
// shared/utils.ts
|
198
|
+
var import_non_secure = require("nanoid/non-secure");
|
158
199
|
var nanoid = (0, import_non_secure.customAlphabet)(
|
159
200
|
"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz",
|
160
201
|
7
|
@@ -185,80 +226,47 @@ async function parseComplexResponse({
|
|
185
226
|
getCurrentDate = () => /* @__PURE__ */ new Date()
|
186
227
|
}) {
|
187
228
|
const createdAt = getCurrentDate();
|
188
|
-
const decode = createChunkDecoder(true);
|
189
229
|
const prefixMap = {
|
190
230
|
data: []
|
191
231
|
};
|
192
|
-
const
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
}
|
204
|
-
if (chunks.length === 0) {
|
205
|
-
break;
|
206
|
-
}
|
207
|
-
let concatenatedChunks = new Uint8Array(totalLength);
|
208
|
-
let offset = 0;
|
209
|
-
for (const chunk of chunks) {
|
210
|
-
concatenatedChunks.set(chunk, offset);
|
211
|
-
offset += chunk.length;
|
212
|
-
}
|
213
|
-
chunks.length = 0;
|
214
|
-
totalLength = 0;
|
215
|
-
const lines = decode(concatenatedChunks);
|
216
|
-
if (typeof lines === "string") {
|
217
|
-
throw new Error(
|
218
|
-
"Invalid response format. Complex mode was set but the response is a string. This should never happen."
|
219
|
-
);
|
220
|
-
}
|
221
|
-
for (const { type, value: value2 } of lines) {
|
222
|
-
if (type === "text") {
|
223
|
-
if (prefixMap["text"]) {
|
224
|
-
prefixMap["text"] = {
|
225
|
-
...prefixMap["text"],
|
226
|
-
content: (prefixMap["text"].content || "") + value2
|
227
|
-
};
|
228
|
-
} else {
|
229
|
-
prefixMap["text"] = {
|
230
|
-
id: generateId(),
|
231
|
-
role: "assistant",
|
232
|
-
content: value2,
|
233
|
-
createdAt
|
234
|
-
};
|
235
|
-
}
|
236
|
-
}
|
237
|
-
let functionCallMessage = null;
|
238
|
-
if (type === "function_call") {
|
239
|
-
prefixMap["function_call"] = {
|
232
|
+
for await (const { type, value } of readDataStream(reader, {
|
233
|
+
isAborted: () => (abortControllerRef == null ? void 0 : abortControllerRef.current) === null
|
234
|
+
})) {
|
235
|
+
if (type === "text") {
|
236
|
+
if (prefixMap["text"]) {
|
237
|
+
prefixMap["text"] = {
|
238
|
+
...prefixMap["text"],
|
239
|
+
content: (prefixMap["text"].content || "") + value
|
240
|
+
};
|
241
|
+
} else {
|
242
|
+
prefixMap["text"] = {
|
240
243
|
id: generateId(),
|
241
244
|
role: "assistant",
|
242
|
-
content:
|
243
|
-
function_call: value2.function_call,
|
244
|
-
name: value2.function_call.name,
|
245
|
+
content: value,
|
245
246
|
createdAt
|
246
247
|
};
|
247
|
-
functionCallMessage = prefixMap["function_call"];
|
248
|
-
}
|
249
|
-
if (type === "data") {
|
250
|
-
prefixMap["data"].push(...value2);
|
251
|
-
}
|
252
|
-
const responseMessage = prefixMap["text"];
|
253
|
-
const merged = [functionCallMessage, responseMessage].filter(
|
254
|
-
Boolean
|
255
|
-
);
|
256
|
-
update(merged, [...prefixMap["data"]]);
|
257
|
-
if ((abortControllerRef == null ? void 0 : abortControllerRef.current) === null) {
|
258
|
-
reader.cancel();
|
259
|
-
break;
|
260
248
|
}
|
261
249
|
}
|
250
|
+
let functionCallMessage = null;
|
251
|
+
if (type === "function_call") {
|
252
|
+
prefixMap["function_call"] = {
|
253
|
+
id: generateId(),
|
254
|
+
role: "assistant",
|
255
|
+
content: "",
|
256
|
+
function_call: value.function_call,
|
257
|
+
name: value.function_call.name,
|
258
|
+
createdAt
|
259
|
+
};
|
260
|
+
functionCallMessage = prefixMap["function_call"];
|
261
|
+
}
|
262
|
+
if (type === "data") {
|
263
|
+
prefixMap["data"].push(...value);
|
264
|
+
}
|
265
|
+
const responseMessage = prefixMap["text"];
|
266
|
+
const merged = [functionCallMessage, responseMessage].filter(
|
267
|
+
Boolean
|
268
|
+
);
|
269
|
+
update(merged, [...prefixMap["data"]]);
|
262
270
|
}
|
263
271
|
onFinish == null ? void 0 : onFinish(prefixMap);
|
264
272
|
return {
|
@@ -597,8 +605,8 @@ function useChat({
|
|
597
605
|
|
598
606
|
// solid/use-completion.ts
|
599
607
|
var import_solid_js2 = require("solid-js");
|
600
|
-
var import_swr_store2 = require("swr-store");
|
601
608
|
var import_solid_swr_store2 = require("solid-swr-store");
|
609
|
+
var import_swr_store2 = require("swr-store");
|
602
610
|
var uniqueId2 = 0;
|
603
611
|
var store2 = {};
|
604
612
|
var completionApiStore = (0, import_swr_store2.createSWRStore)({
|
@@ -633,9 +641,13 @@ function useCompletion({
|
|
633
641
|
};
|
634
642
|
const completion = data;
|
635
643
|
const [error, setError] = (0, import_solid_js2.createSignal)(void 0);
|
644
|
+
const [streamData, setStreamData] = (0, import_solid_js2.createSignal)(
|
645
|
+
void 0
|
646
|
+
);
|
636
647
|
const [isLoading, setIsLoading] = (0, import_solid_js2.createSignal)(false);
|
637
648
|
let abortController = null;
|
638
649
|
async function triggerRequest(prompt, options) {
|
650
|
+
var _a;
|
639
651
|
try {
|
640
652
|
setError(void 0);
|
641
653
|
setIsLoading(true);
|
@@ -674,17 +686,37 @@ function useCompletion({
|
|
674
686
|
}
|
675
687
|
let result = "";
|
676
688
|
const reader = res.body.getReader();
|
677
|
-
const
|
678
|
-
|
679
|
-
const
|
680
|
-
|
681
|
-
|
689
|
+
const isComplexMode = res.headers.get(COMPLEX_HEADER) === "true";
|
690
|
+
if (isComplexMode) {
|
691
|
+
const existingData = (_a = streamData()) != null ? _a : [];
|
692
|
+
for await (const { type, value } of readDataStream(reader, {
|
693
|
+
isAborted: () => abortController === null
|
694
|
+
})) {
|
695
|
+
switch (type) {
|
696
|
+
case "text": {
|
697
|
+
result += value;
|
698
|
+
mutate(result);
|
699
|
+
break;
|
700
|
+
}
|
701
|
+
case "data": {
|
702
|
+
setStreamData([...existingData, ...value != null ? value : []]);
|
703
|
+
break;
|
704
|
+
}
|
705
|
+
}
|
682
706
|
}
|
683
|
-
|
684
|
-
|
685
|
-
|
686
|
-
reader.
|
687
|
-
|
707
|
+
} else {
|
708
|
+
const decoder = createChunkDecoder();
|
709
|
+
while (true) {
|
710
|
+
const { done, value } = await reader.read();
|
711
|
+
if (done) {
|
712
|
+
break;
|
713
|
+
}
|
714
|
+
result += decoder(value);
|
715
|
+
mutate(result);
|
716
|
+
if (abortController === null) {
|
717
|
+
reader.cancel();
|
718
|
+
break;
|
719
|
+
}
|
688
720
|
}
|
689
721
|
}
|
690
722
|
if (onFinish) {
|
@@ -734,7 +766,8 @@ function useCompletion({
|
|
734
766
|
input,
|
735
767
|
setInput,
|
736
768
|
handleSubmit,
|
737
|
-
isLoading
|
769
|
+
isLoading,
|
770
|
+
data: streamData
|
738
771
|
};
|
739
772
|
}
|
740
773
|
// Annotate the CommonJS export names for ESM import in node:
|