ai 2.2.1 → 2.2.3

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.
@@ -46,17 +46,48 @@ var nanoid = (0, import_non_secure.customAlphabet)(
46
46
  "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz",
47
47
  7
48
48
  );
49
- function createChunkDecoder() {
49
+ function createChunkDecoder(complex) {
50
50
  const decoder = new TextDecoder();
51
+ if (!complex) {
52
+ return function(chunk) {
53
+ if (!chunk)
54
+ return "";
55
+ return decoder.decode(chunk, { stream: true });
56
+ };
57
+ }
51
58
  return function(chunk) {
52
- if (!chunk)
53
- return "";
54
- return decoder.decode(chunk, { stream: true });
59
+ const decoded = decoder.decode(chunk, { stream: true }).split("\n");
60
+ return decoded.map(getStreamStringTypeAndValue).filter(Boolean);
55
61
  };
56
62
  }
63
+ var StreamStringPrefixes = {
64
+ text: 0,
65
+ function_call: 1,
66
+ data: 2
67
+ // user_err: 3?
68
+ };
69
+ var getStreamStringTypeAndValue = (line) => {
70
+ const firstSeperatorIndex = line.indexOf(":");
71
+ const prefix = line.slice(0, firstSeperatorIndex);
72
+ const type = Object.keys(StreamStringPrefixes).find(
73
+ (key) => StreamStringPrefixes[key] === Number(prefix)
74
+ );
75
+ const val = line.slice(firstSeperatorIndex + 1);
76
+ let parsedVal = val;
77
+ if (!val) {
78
+ return { type, value: "" };
79
+ }
80
+ try {
81
+ parsedVal = JSON.parse(val);
82
+ } catch (e) {
83
+ console.error("Failed to parse JSON value:", val);
84
+ }
85
+ return { type, value: parsedVal };
86
+ };
87
+ var COMPLEX_HEADER = "X-Experimental-Stream-Data";
57
88
 
58
89
  // react/use-chat.ts
59
- var getStreamedResponse = async (api, chatRequest, mutate, extraMetadataRef, messagesRef, abortControllerRef, onFinish, onResponse, sendExtraMessageFields) => {
90
+ var getStreamedResponse = async (api, chatRequest, mutate, mutateStreamData, existingData, extraMetadataRef, messagesRef, abortControllerRef, onFinish, onResponse, sendExtraMessageFields) => {
60
91
  var _a, _b;
61
92
  const previousMessages = messagesRef.current;
62
93
  mutate(chatRequest.messages, false);
@@ -108,43 +139,126 @@ var getStreamedResponse = async (api, chatRequest, mutate, extraMetadataRef, mes
108
139
  if (!res.body) {
109
140
  throw new Error("The response body is empty.");
110
141
  }
111
- let streamedResponse = "";
142
+ const isComplexMode = res.headers.get(COMPLEX_HEADER) === "true";
112
143
  const createdAt = /* @__PURE__ */ new Date();
113
- const replyId = nanoid();
114
144
  const reader = res.body.getReader();
115
- const decode = createChunkDecoder();
116
- let responseMessage = {
117
- id: replyId,
118
- createdAt,
119
- content: "",
120
- role: "assistant"
121
- };
122
- while (true) {
123
- const { done, value } = await reader.read();
124
- if (done) {
125
- break;
145
+ const decode = createChunkDecoder(isComplexMode);
146
+ let responseMessages = [];
147
+ let responseData = [];
148
+ const prefixMap = {};
149
+ if (isComplexMode) {
150
+ while (true) {
151
+ const { done, value } = await reader.read();
152
+ if (done) {
153
+ break;
154
+ }
155
+ const lines = decode(value);
156
+ if (typeof lines === "string") {
157
+ throw new Error(
158
+ "Invalid response format. Complex mode was set but the response is a string. This should never happen."
159
+ );
160
+ }
161
+ for (const { type, value: value2 } of lines) {
162
+ if (type === "text") {
163
+ if (prefixMap["text"]) {
164
+ prefixMap["text"] = {
165
+ ...prefixMap["text"],
166
+ content: (prefixMap["text"].content || "") + value2
167
+ };
168
+ } else {
169
+ prefixMap["text"] = {
170
+ id: nanoid(),
171
+ role: "assistant",
172
+ content: value2,
173
+ createdAt
174
+ };
175
+ }
176
+ }
177
+ let functionCallMessage = null;
178
+ if (type === "function_call") {
179
+ prefixMap["function_call"] = value2;
180
+ let functionCall = prefixMap["function_call"];
181
+ if (functionCall && typeof functionCall === "string") {
182
+ const parsedFunctionCall = JSON.parse(functionCall).function_call;
183
+ functionCallMessage = {
184
+ id: nanoid(),
185
+ role: "assistant",
186
+ content: "",
187
+ function_call: parsedFunctionCall,
188
+ name: parsedFunctionCall.name,
189
+ createdAt
190
+ };
191
+ prefixMap["function_call"] = functionCallMessage;
192
+ }
193
+ }
194
+ if (type === "data") {
195
+ const parsedValue = JSON.parse(value2);
196
+ if (prefixMap["data"]) {
197
+ prefixMap["data"] = [...prefixMap["data"], ...parsedValue];
198
+ } else {
199
+ prefixMap["data"] = parsedValue;
200
+ }
201
+ }
202
+ const data = prefixMap["data"];
203
+ const responseMessage = prefixMap["text"];
204
+ const merged = [functionCallMessage, responseMessage].filter(
205
+ Boolean
206
+ );
207
+ mutate([...chatRequest.messages, ...merged], false);
208
+ mutateStreamData([...existingData || [], ...data || []], false);
209
+ if (abortControllerRef.current === null) {
210
+ reader.cancel();
211
+ break;
212
+ }
213
+ }
214
+ }
215
+ for (const [type, item] of Object.entries(prefixMap)) {
216
+ if (onFinish && type === "text") {
217
+ onFinish(item);
218
+ }
219
+ if (type === "data") {
220
+ responseData.push(item);
221
+ } else {
222
+ responseMessages.push(item);
223
+ }
224
+ }
225
+ return { messages: responseMessages, data: responseData };
226
+ } else {
227
+ let streamedResponse = "";
228
+ const replyId = nanoid();
229
+ let responseMessage = {
230
+ id: replyId,
231
+ createdAt,
232
+ content: "",
233
+ role: "assistant"
234
+ };
235
+ while (true) {
236
+ const { done, value } = await reader.read();
237
+ if (done) {
238
+ break;
239
+ }
240
+ streamedResponse += decode(value);
241
+ if (streamedResponse.startsWith('{"function_call":')) {
242
+ responseMessage["function_call"] = streamedResponse;
243
+ } else {
244
+ responseMessage["content"] = streamedResponse;
245
+ }
246
+ mutate([...chatRequest.messages, { ...responseMessage }], false);
247
+ if (abortControllerRef.current === null) {
248
+ reader.cancel();
249
+ break;
250
+ }
126
251
  }
127
- streamedResponse += decode(value);
128
252
  if (streamedResponse.startsWith('{"function_call":')) {
129
- responseMessage["function_call"] = streamedResponse;
130
- } else {
131
- responseMessage["content"] = streamedResponse;
253
+ const parsedFunctionCall = JSON.parse(streamedResponse).function_call;
254
+ responseMessage["function_call"] = parsedFunctionCall;
255
+ mutate([...chatRequest.messages, { ...responseMessage }]);
132
256
  }
133
- mutate([...chatRequest.messages, { ...responseMessage }], false);
134
- if (abortControllerRef.current === null) {
135
- reader.cancel();
136
- break;
257
+ if (onFinish) {
258
+ onFinish(responseMessage);
137
259
  }
260
+ return responseMessage;
138
261
  }
139
- if (streamedResponse.startsWith('{"function_call":')) {
140
- const parsedFunctionCall = JSON.parse(streamedResponse).function_call;
141
- responseMessage["function_call"] = parsedFunctionCall;
142
- mutate([...chatRequest.messages, { ...responseMessage }]);
143
- }
144
- if (onFinish) {
145
- onFinish(responseMessage);
146
- }
147
- return responseMessage;
148
262
  };
149
263
  function useChat({
150
264
  api = "/api/chat",
@@ -162,17 +276,20 @@ function useChat({
162
276
  } = {}) {
163
277
  const hookId = (0, import_react.useId)();
164
278
  const chatId = id || hookId;
165
- const { data, mutate } = (0, import_swr.default)([api, chatId], null, {
279
+ const { data: messages, mutate } = (0, import_swr.default)([api, chatId], null, {
166
280
  fallbackData: initialMessages
167
281
  });
168
282
  const { data: isLoading = false, mutate: mutateLoading } = (0, import_swr.default)(
169
283
  [chatId, "loading"],
170
284
  null
171
285
  );
172
- const messages = data;
173
- const messagesRef = (0, import_react.useRef)(messages);
286
+ const { data: streamData, mutate: mutateStreamData } = (0, import_swr.default)(
287
+ [chatId, "streamData"],
288
+ null
289
+ );
290
+ const messagesRef = (0, import_react.useRef)(messages || []);
174
291
  (0, import_react.useEffect)(() => {
175
- messagesRef.current = messages;
292
+ messagesRef.current = messages || [];
176
293
  }, [messages]);
177
294
  const abortControllerRef = (0, import_react.useRef)(null);
178
295
  const extraMetadataRef = (0, import_react.useRef)({
@@ -194,10 +311,12 @@ function useChat({
194
311
  const abortController = new AbortController();
195
312
  abortControllerRef.current = abortController;
196
313
  while (true) {
197
- const streamedResponseMessage = await getStreamedResponse(
314
+ const messagesAndDataOrJustMessage = await getStreamedResponse(
198
315
  api,
199
316
  chatRequest,
200
317
  mutate,
318
+ mutateStreamData,
319
+ streamData,
201
320
  extraMetadataRef,
202
321
  messagesRef,
203
322
  abortControllerRef,
@@ -205,19 +324,41 @@ function useChat({
205
324
  onResponse,
206
325
  sendExtraMessageFields
207
326
  );
208
- if (streamedResponseMessage.function_call === void 0 || typeof streamedResponseMessage.function_call === "string") {
209
- break;
210
- }
211
- if (experimental_onFunctionCall) {
212
- const functionCall = streamedResponseMessage.function_call;
213
- const functionCallResponse = await experimental_onFunctionCall(messagesRef.current, functionCall);
214
- if (functionCallResponse === void 0)
327
+ if ("messages" in messagesAndDataOrJustMessage) {
328
+ for (const message of messagesAndDataOrJustMessage.messages) {
329
+ if (message.function_call === void 0 || typeof message.function_call === "string") {
330
+ break;
331
+ }
332
+ if (experimental_onFunctionCall) {
333
+ const functionCall = message.function_call;
334
+ const functionCallResponse = await experimental_onFunctionCall(
335
+ messagesRef.current,
336
+ functionCall
337
+ );
338
+ if (functionCallResponse === void 0)
339
+ break;
340
+ chatRequest = functionCallResponse;
341
+ }
342
+ }
343
+ } else {
344
+ const streamedResponseMessage = messagesAndDataOrJustMessage;
345
+ if (streamedResponseMessage.function_call === void 0 || typeof streamedResponseMessage.function_call === "string") {
215
346
  break;
216
- chatRequest = functionCallResponse;
347
+ }
348
+ if (experimental_onFunctionCall) {
349
+ const functionCall = streamedResponseMessage.function_call;
350
+ const functionCallResponse = await experimental_onFunctionCall(
351
+ messagesRef.current,
352
+ functionCall
353
+ );
354
+ if (functionCallResponse === void 0)
355
+ break;
356
+ chatRequest = functionCallResponse;
357
+ }
217
358
  }
359
+ abortControllerRef.current = null;
360
+ return null;
218
361
  }
219
- abortControllerRef.current = null;
220
- return null;
221
362
  } catch (err) {
222
363
  if (err.name === "AbortError") {
223
364
  abortControllerRef.current = null;
@@ -311,7 +452,7 @@ function useChat({
311
452
  setInput(e.target.value);
312
453
  };
313
454
  return {
314
- messages,
455
+ messages: messages || [],
315
456
  error,
316
457
  append,
317
458
  reload,
@@ -321,7 +462,8 @@ function useChat({
321
462
  setInput,
322
463
  handleInputChange,
323
464
  handleSubmit,
324
- isLoading
465
+ isLoading,
466
+ data: streamData
325
467
  };
326
468
  }
327
469
 
@@ -10,17 +10,48 @@ var nanoid = customAlphabet(
10
10
  "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz",
11
11
  7
12
12
  );
13
- function createChunkDecoder() {
13
+ function createChunkDecoder(complex) {
14
14
  const decoder = new TextDecoder();
15
+ if (!complex) {
16
+ return function(chunk) {
17
+ if (!chunk)
18
+ return "";
19
+ return decoder.decode(chunk, { stream: true });
20
+ };
21
+ }
15
22
  return function(chunk) {
16
- if (!chunk)
17
- return "";
18
- return decoder.decode(chunk, { stream: true });
23
+ const decoded = decoder.decode(chunk, { stream: true }).split("\n");
24
+ return decoded.map(getStreamStringTypeAndValue).filter(Boolean);
19
25
  };
20
26
  }
27
+ var StreamStringPrefixes = {
28
+ text: 0,
29
+ function_call: 1,
30
+ data: 2
31
+ // user_err: 3?
32
+ };
33
+ var getStreamStringTypeAndValue = (line) => {
34
+ const firstSeperatorIndex = line.indexOf(":");
35
+ const prefix = line.slice(0, firstSeperatorIndex);
36
+ const type = Object.keys(StreamStringPrefixes).find(
37
+ (key) => StreamStringPrefixes[key] === Number(prefix)
38
+ );
39
+ const val = line.slice(firstSeperatorIndex + 1);
40
+ let parsedVal = val;
41
+ if (!val) {
42
+ return { type, value: "" };
43
+ }
44
+ try {
45
+ parsedVal = JSON.parse(val);
46
+ } catch (e) {
47
+ console.error("Failed to parse JSON value:", val);
48
+ }
49
+ return { type, value: parsedVal };
50
+ };
51
+ var COMPLEX_HEADER = "X-Experimental-Stream-Data";
21
52
 
22
53
  // react/use-chat.ts
23
- var getStreamedResponse = async (api, chatRequest, mutate, extraMetadataRef, messagesRef, abortControllerRef, onFinish, onResponse, sendExtraMessageFields) => {
54
+ var getStreamedResponse = async (api, chatRequest, mutate, mutateStreamData, existingData, extraMetadataRef, messagesRef, abortControllerRef, onFinish, onResponse, sendExtraMessageFields) => {
24
55
  var _a, _b;
25
56
  const previousMessages = messagesRef.current;
26
57
  mutate(chatRequest.messages, false);
@@ -72,43 +103,126 @@ var getStreamedResponse = async (api, chatRequest, mutate, extraMetadataRef, mes
72
103
  if (!res.body) {
73
104
  throw new Error("The response body is empty.");
74
105
  }
75
- let streamedResponse = "";
106
+ const isComplexMode = res.headers.get(COMPLEX_HEADER) === "true";
76
107
  const createdAt = /* @__PURE__ */ new Date();
77
- const replyId = nanoid();
78
108
  const reader = res.body.getReader();
79
- const decode = createChunkDecoder();
80
- let responseMessage = {
81
- id: replyId,
82
- createdAt,
83
- content: "",
84
- role: "assistant"
85
- };
86
- while (true) {
87
- const { done, value } = await reader.read();
88
- if (done) {
89
- break;
109
+ const decode = createChunkDecoder(isComplexMode);
110
+ let responseMessages = [];
111
+ let responseData = [];
112
+ const prefixMap = {};
113
+ if (isComplexMode) {
114
+ while (true) {
115
+ const { done, value } = await reader.read();
116
+ if (done) {
117
+ break;
118
+ }
119
+ const lines = decode(value);
120
+ if (typeof lines === "string") {
121
+ throw new Error(
122
+ "Invalid response format. Complex mode was set but the response is a string. This should never happen."
123
+ );
124
+ }
125
+ for (const { type, value: value2 } of lines) {
126
+ if (type === "text") {
127
+ if (prefixMap["text"]) {
128
+ prefixMap["text"] = {
129
+ ...prefixMap["text"],
130
+ content: (prefixMap["text"].content || "") + value2
131
+ };
132
+ } else {
133
+ prefixMap["text"] = {
134
+ id: nanoid(),
135
+ role: "assistant",
136
+ content: value2,
137
+ createdAt
138
+ };
139
+ }
140
+ }
141
+ let functionCallMessage = null;
142
+ if (type === "function_call") {
143
+ prefixMap["function_call"] = value2;
144
+ let functionCall = prefixMap["function_call"];
145
+ if (functionCall && typeof functionCall === "string") {
146
+ const parsedFunctionCall = JSON.parse(functionCall).function_call;
147
+ functionCallMessage = {
148
+ id: nanoid(),
149
+ role: "assistant",
150
+ content: "",
151
+ function_call: parsedFunctionCall,
152
+ name: parsedFunctionCall.name,
153
+ createdAt
154
+ };
155
+ prefixMap["function_call"] = functionCallMessage;
156
+ }
157
+ }
158
+ if (type === "data") {
159
+ const parsedValue = JSON.parse(value2);
160
+ if (prefixMap["data"]) {
161
+ prefixMap["data"] = [...prefixMap["data"], ...parsedValue];
162
+ } else {
163
+ prefixMap["data"] = parsedValue;
164
+ }
165
+ }
166
+ const data = prefixMap["data"];
167
+ const responseMessage = prefixMap["text"];
168
+ const merged = [functionCallMessage, responseMessage].filter(
169
+ Boolean
170
+ );
171
+ mutate([...chatRequest.messages, ...merged], false);
172
+ mutateStreamData([...existingData || [], ...data || []], false);
173
+ if (abortControllerRef.current === null) {
174
+ reader.cancel();
175
+ break;
176
+ }
177
+ }
178
+ }
179
+ for (const [type, item] of Object.entries(prefixMap)) {
180
+ if (onFinish && type === "text") {
181
+ onFinish(item);
182
+ }
183
+ if (type === "data") {
184
+ responseData.push(item);
185
+ } else {
186
+ responseMessages.push(item);
187
+ }
188
+ }
189
+ return { messages: responseMessages, data: responseData };
190
+ } else {
191
+ let streamedResponse = "";
192
+ const replyId = nanoid();
193
+ let responseMessage = {
194
+ id: replyId,
195
+ createdAt,
196
+ content: "",
197
+ role: "assistant"
198
+ };
199
+ while (true) {
200
+ const { done, value } = await reader.read();
201
+ if (done) {
202
+ break;
203
+ }
204
+ streamedResponse += decode(value);
205
+ if (streamedResponse.startsWith('{"function_call":')) {
206
+ responseMessage["function_call"] = streamedResponse;
207
+ } else {
208
+ responseMessage["content"] = streamedResponse;
209
+ }
210
+ mutate([...chatRequest.messages, { ...responseMessage }], false);
211
+ if (abortControllerRef.current === null) {
212
+ reader.cancel();
213
+ break;
214
+ }
90
215
  }
91
- streamedResponse += decode(value);
92
216
  if (streamedResponse.startsWith('{"function_call":')) {
93
- responseMessage["function_call"] = streamedResponse;
94
- } else {
95
- responseMessage["content"] = streamedResponse;
217
+ const parsedFunctionCall = JSON.parse(streamedResponse).function_call;
218
+ responseMessage["function_call"] = parsedFunctionCall;
219
+ mutate([...chatRequest.messages, { ...responseMessage }]);
96
220
  }
97
- mutate([...chatRequest.messages, { ...responseMessage }], false);
98
- if (abortControllerRef.current === null) {
99
- reader.cancel();
100
- break;
221
+ if (onFinish) {
222
+ onFinish(responseMessage);
101
223
  }
224
+ return responseMessage;
102
225
  }
103
- if (streamedResponse.startsWith('{"function_call":')) {
104
- const parsedFunctionCall = JSON.parse(streamedResponse).function_call;
105
- responseMessage["function_call"] = parsedFunctionCall;
106
- mutate([...chatRequest.messages, { ...responseMessage }]);
107
- }
108
- if (onFinish) {
109
- onFinish(responseMessage);
110
- }
111
- return responseMessage;
112
226
  };
113
227
  function useChat({
114
228
  api = "/api/chat",
@@ -126,17 +240,20 @@ function useChat({
126
240
  } = {}) {
127
241
  const hookId = useId();
128
242
  const chatId = id || hookId;
129
- const { data, mutate } = useSWR([api, chatId], null, {
243
+ const { data: messages, mutate } = useSWR([api, chatId], null, {
130
244
  fallbackData: initialMessages
131
245
  });
132
246
  const { data: isLoading = false, mutate: mutateLoading } = useSWR(
133
247
  [chatId, "loading"],
134
248
  null
135
249
  );
136
- const messages = data;
137
- const messagesRef = useRef(messages);
250
+ const { data: streamData, mutate: mutateStreamData } = useSWR(
251
+ [chatId, "streamData"],
252
+ null
253
+ );
254
+ const messagesRef = useRef(messages || []);
138
255
  useEffect(() => {
139
- messagesRef.current = messages;
256
+ messagesRef.current = messages || [];
140
257
  }, [messages]);
141
258
  const abortControllerRef = useRef(null);
142
259
  const extraMetadataRef = useRef({
@@ -158,10 +275,12 @@ function useChat({
158
275
  const abortController = new AbortController();
159
276
  abortControllerRef.current = abortController;
160
277
  while (true) {
161
- const streamedResponseMessage = await getStreamedResponse(
278
+ const messagesAndDataOrJustMessage = await getStreamedResponse(
162
279
  api,
163
280
  chatRequest,
164
281
  mutate,
282
+ mutateStreamData,
283
+ streamData,
165
284
  extraMetadataRef,
166
285
  messagesRef,
167
286
  abortControllerRef,
@@ -169,19 +288,41 @@ function useChat({
169
288
  onResponse,
170
289
  sendExtraMessageFields
171
290
  );
172
- if (streamedResponseMessage.function_call === void 0 || typeof streamedResponseMessage.function_call === "string") {
173
- break;
174
- }
175
- if (experimental_onFunctionCall) {
176
- const functionCall = streamedResponseMessage.function_call;
177
- const functionCallResponse = await experimental_onFunctionCall(messagesRef.current, functionCall);
178
- if (functionCallResponse === void 0)
291
+ if ("messages" in messagesAndDataOrJustMessage) {
292
+ for (const message of messagesAndDataOrJustMessage.messages) {
293
+ if (message.function_call === void 0 || typeof message.function_call === "string") {
294
+ break;
295
+ }
296
+ if (experimental_onFunctionCall) {
297
+ const functionCall = message.function_call;
298
+ const functionCallResponse = await experimental_onFunctionCall(
299
+ messagesRef.current,
300
+ functionCall
301
+ );
302
+ if (functionCallResponse === void 0)
303
+ break;
304
+ chatRequest = functionCallResponse;
305
+ }
306
+ }
307
+ } else {
308
+ const streamedResponseMessage = messagesAndDataOrJustMessage;
309
+ if (streamedResponseMessage.function_call === void 0 || typeof streamedResponseMessage.function_call === "string") {
179
310
  break;
180
- chatRequest = functionCallResponse;
311
+ }
312
+ if (experimental_onFunctionCall) {
313
+ const functionCall = streamedResponseMessage.function_call;
314
+ const functionCallResponse = await experimental_onFunctionCall(
315
+ messagesRef.current,
316
+ functionCall
317
+ );
318
+ if (functionCallResponse === void 0)
319
+ break;
320
+ chatRequest = functionCallResponse;
321
+ }
181
322
  }
323
+ abortControllerRef.current = null;
324
+ return null;
182
325
  }
183
- abortControllerRef.current = null;
184
- return null;
185
326
  } catch (err) {
186
327
  if (err.name === "AbortError") {
187
328
  abortControllerRef.current = null;
@@ -275,7 +416,7 @@ function useChat({
275
416
  setInput(e.target.value);
276
417
  };
277
418
  return {
278
- messages,
419
+ messages: messages || [],
279
420
  error,
280
421
  append,
281
422
  reload,
@@ -285,7 +426,8 @@ function useChat({
285
426
  setInput,
286
427
  handleInputChange,
287
428
  handleSubmit,
288
- isLoading
429
+ isLoading,
430
+ data: streamData
289
431
  };
290
432
  }
291
433
 
@@ -36,14 +36,44 @@ var nanoid = (0, import_non_secure.customAlphabet)(
36
36
  "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz",
37
37
  7
38
38
  );
39
- function createChunkDecoder() {
39
+ function createChunkDecoder(complex) {
40
40
  const decoder = new TextDecoder();
41
+ if (!complex) {
42
+ return function(chunk) {
43
+ if (!chunk)
44
+ return "";
45
+ return decoder.decode(chunk, { stream: true });
46
+ };
47
+ }
41
48
  return function(chunk) {
42
- if (!chunk)
43
- return "";
44
- return decoder.decode(chunk, { stream: true });
49
+ const decoded = decoder.decode(chunk, { stream: true }).split("\n");
50
+ return decoded.map(getStreamStringTypeAndValue).filter(Boolean);
45
51
  };
46
52
  }
53
+ var StreamStringPrefixes = {
54
+ text: 0,
55
+ function_call: 1,
56
+ data: 2
57
+ // user_err: 3?
58
+ };
59
+ var getStreamStringTypeAndValue = (line) => {
60
+ const firstSeperatorIndex = line.indexOf(":");
61
+ const prefix = line.slice(0, firstSeperatorIndex);
62
+ const type = Object.keys(StreamStringPrefixes).find(
63
+ (key) => StreamStringPrefixes[key] === Number(prefix)
64
+ );
65
+ const val = line.slice(firstSeperatorIndex + 1);
66
+ let parsedVal = val;
67
+ if (!val) {
68
+ return { type, value: "" };
69
+ }
70
+ try {
71
+ parsedVal = JSON.parse(val);
72
+ } catch (e) {
73
+ console.error("Failed to parse JSON value:", val);
74
+ }
75
+ return { type, value: parsedVal };
76
+ };
47
77
 
48
78
  // solid/use-chat.ts
49
79
  var uniqueId = 0;