ai 2.2.1 → 2.2.2

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,124 @@ 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();
145
+ const decode = createChunkDecoder(isComplexMode);
146
+ let responseMessages = [];
147
+ let streamedResponse = "";
148
+ const replyId = nanoid();
116
149
  let responseMessage = {
117
150
  id: replyId,
118
151
  createdAt,
119
152
  content: "",
120
153
  role: "assistant"
121
154
  };
122
- while (true) {
123
- const { done, value } = await reader.read();
124
- if (done) {
125
- break;
155
+ let responseData = [];
156
+ const prefixMap = {};
157
+ if (isComplexMode) {
158
+ while (true) {
159
+ const { done, value } = await reader.read();
160
+ if (done) {
161
+ break;
162
+ }
163
+ const lines = decode(value);
164
+ if (typeof lines === "string") {
165
+ throw new Error(
166
+ "Invalid response format. Complex mode was set but the response is a string. This should never happen."
167
+ );
168
+ }
169
+ for (const { type, value: value2 } of lines) {
170
+ if (type === "text") {
171
+ if (prefixMap["text"]) {
172
+ prefixMap["text"] = {
173
+ ...prefixMap["text"],
174
+ content: (prefixMap["text"].content || "") + value2
175
+ };
176
+ } else {
177
+ prefixMap["text"] = {
178
+ id: nanoid(),
179
+ role: "assistant",
180
+ content: value2,
181
+ createdAt
182
+ };
183
+ }
184
+ }
185
+ if (type === "function_call") {
186
+ prefixMap["function_call"] = value2;
187
+ }
188
+ if (type === "data") {
189
+ const parsedValue = JSON.parse(value2);
190
+ if (prefixMap["data"]) {
191
+ prefixMap["data"] = [...prefixMap["data"], ...parsedValue];
192
+ } else {
193
+ prefixMap["data"] = parsedValue;
194
+ }
195
+ }
196
+ const data = prefixMap["data"];
197
+ const responseMessage2 = prefixMap["text"];
198
+ let functionCall = prefixMap["function_call"];
199
+ let functionCallMessage = null;
200
+ if (functionCall) {
201
+ const parsedFunctionCall = JSON.parse(functionCall).function_call;
202
+ functionCallMessage = {
203
+ id: nanoid(),
204
+ role: "function",
205
+ content: "",
206
+ name: parsedFunctionCall.name,
207
+ createdAt
208
+ };
209
+ }
210
+ const merged = [functionCallMessage, responseMessage2].filter(
211
+ Boolean
212
+ );
213
+ mutate([...chatRequest.messages, ...merged], false);
214
+ mutateStreamData([...existingData || [], ...data || []]);
215
+ if (abortControllerRef.current === null) {
216
+ reader.cancel();
217
+ break;
218
+ }
219
+ }
220
+ }
221
+ for (const [type, item] of Object.entries(prefixMap)) {
222
+ if (onFinish && type === "text") {
223
+ onFinish(item);
224
+ }
225
+ if (type === "data") {
226
+ responseData.push(item);
227
+ } else {
228
+ responseMessages.push(item);
229
+ }
230
+ }
231
+ return { messages: responseMessages, data: responseData };
232
+ } else {
233
+ while (true) {
234
+ const { done, value } = await reader.read();
235
+ if (done) {
236
+ break;
237
+ }
238
+ streamedResponse += decode(value);
239
+ if (streamedResponse.startsWith('{"function_call":')) {
240
+ responseMessage["function_call"] = streamedResponse;
241
+ } else {
242
+ responseMessage["content"] = streamedResponse;
243
+ }
244
+ mutate([...chatRequest.messages, { ...responseMessage }], false);
245
+ if (abortControllerRef.current === null) {
246
+ reader.cancel();
247
+ break;
248
+ }
126
249
  }
127
- streamedResponse += decode(value);
128
250
  if (streamedResponse.startsWith('{"function_call":')) {
129
- responseMessage["function_call"] = streamedResponse;
130
- } else {
131
- responseMessage["content"] = streamedResponse;
251
+ const parsedFunctionCall = JSON.parse(streamedResponse).function_call;
252
+ responseMessage["function_call"] = parsedFunctionCall;
253
+ mutate([...chatRequest.messages, { ...responseMessage }]);
132
254
  }
133
- mutate([...chatRequest.messages, { ...responseMessage }], false);
134
- if (abortControllerRef.current === null) {
135
- reader.cancel();
136
- break;
255
+ if (onFinish) {
256
+ onFinish(responseMessage);
137
257
  }
258
+ return responseMessage;
138
259
  }
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
260
  };
149
261
  function useChat({
150
262
  api = "/api/chat",
@@ -162,17 +274,20 @@ function useChat({
162
274
  } = {}) {
163
275
  const hookId = (0, import_react.useId)();
164
276
  const chatId = id || hookId;
165
- const { data, mutate } = (0, import_swr.default)([api, chatId], null, {
277
+ const { data: messages, mutate } = (0, import_swr.default)([api, chatId], null, {
166
278
  fallbackData: initialMessages
167
279
  });
168
280
  const { data: isLoading = false, mutate: mutateLoading } = (0, import_swr.default)(
169
281
  [chatId, "loading"],
170
282
  null
171
283
  );
172
- const messages = data;
173
- const messagesRef = (0, import_react.useRef)(messages);
284
+ const { data: streamData, mutate: mutateStreamData } = (0, import_swr.default)(
285
+ [chatId, "streamData"],
286
+ null
287
+ );
288
+ const messagesRef = (0, import_react.useRef)(messages || []);
174
289
  (0, import_react.useEffect)(() => {
175
- messagesRef.current = messages;
290
+ messagesRef.current = messages || [];
176
291
  }, [messages]);
177
292
  const abortControllerRef = (0, import_react.useRef)(null);
178
293
  const extraMetadataRef = (0, import_react.useRef)({
@@ -194,10 +309,12 @@ function useChat({
194
309
  const abortController = new AbortController();
195
310
  abortControllerRef.current = abortController;
196
311
  while (true) {
197
- const streamedResponseMessage = await getStreamedResponse(
312
+ const messagesAndDataOrJustMessage = await getStreamedResponse(
198
313
  api,
199
314
  chatRequest,
200
315
  mutate,
316
+ mutateStreamData,
317
+ streamData,
201
318
  extraMetadataRef,
202
319
  messagesRef,
203
320
  abortControllerRef,
@@ -205,19 +322,41 @@ function useChat({
205
322
  onResponse,
206
323
  sendExtraMessageFields
207
324
  );
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)
325
+ if ("messages" in messagesAndDataOrJustMessage) {
326
+ for (const message of messagesAndDataOrJustMessage.messages) {
327
+ if (message.function_call === void 0 || typeof message.function_call === "string") {
328
+ break;
329
+ }
330
+ if (experimental_onFunctionCall) {
331
+ const functionCall = message.function_call;
332
+ const functionCallResponse = await experimental_onFunctionCall(
333
+ messagesRef.current,
334
+ functionCall
335
+ );
336
+ if (functionCallResponse === void 0)
337
+ break;
338
+ chatRequest = functionCallResponse;
339
+ }
340
+ }
341
+ } else {
342
+ const streamedResponseMessage = messagesAndDataOrJustMessage;
343
+ if (streamedResponseMessage.function_call === void 0 || typeof streamedResponseMessage.function_call === "string") {
215
344
  break;
216
- chatRequest = functionCallResponse;
345
+ }
346
+ if (experimental_onFunctionCall) {
347
+ const functionCall = streamedResponseMessage.function_call;
348
+ const functionCallResponse = await experimental_onFunctionCall(
349
+ messagesRef.current,
350
+ functionCall
351
+ );
352
+ if (functionCallResponse === void 0)
353
+ break;
354
+ chatRequest = functionCallResponse;
355
+ }
217
356
  }
357
+ abortControllerRef.current = null;
358
+ return null;
218
359
  }
219
- abortControllerRef.current = null;
220
- return null;
221
360
  } catch (err) {
222
361
  if (err.name === "AbortError") {
223
362
  abortControllerRef.current = null;
@@ -311,7 +450,7 @@ function useChat({
311
450
  setInput(e.target.value);
312
451
  };
313
452
  return {
314
- messages,
453
+ messages: messages || [],
315
454
  error,
316
455
  append,
317
456
  reload,
@@ -321,7 +460,8 @@ function useChat({
321
460
  setInput,
322
461
  handleInputChange,
323
462
  handleSubmit,
324
- isLoading
463
+ isLoading,
464
+ data: streamData
325
465
  };
326
466
  }
327
467
 
@@ -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,124 @@ 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();
109
+ const decode = createChunkDecoder(isComplexMode);
110
+ let responseMessages = [];
111
+ let streamedResponse = "";
112
+ const replyId = nanoid();
80
113
  let responseMessage = {
81
114
  id: replyId,
82
115
  createdAt,
83
116
  content: "",
84
117
  role: "assistant"
85
118
  };
86
- while (true) {
87
- const { done, value } = await reader.read();
88
- if (done) {
89
- break;
119
+ let responseData = [];
120
+ const prefixMap = {};
121
+ if (isComplexMode) {
122
+ while (true) {
123
+ const { done, value } = await reader.read();
124
+ if (done) {
125
+ break;
126
+ }
127
+ const lines = decode(value);
128
+ if (typeof lines === "string") {
129
+ throw new Error(
130
+ "Invalid response format. Complex mode was set but the response is a string. This should never happen."
131
+ );
132
+ }
133
+ for (const { type, value: value2 } of lines) {
134
+ if (type === "text") {
135
+ if (prefixMap["text"]) {
136
+ prefixMap["text"] = {
137
+ ...prefixMap["text"],
138
+ content: (prefixMap["text"].content || "") + value2
139
+ };
140
+ } else {
141
+ prefixMap["text"] = {
142
+ id: nanoid(),
143
+ role: "assistant",
144
+ content: value2,
145
+ createdAt
146
+ };
147
+ }
148
+ }
149
+ if (type === "function_call") {
150
+ prefixMap["function_call"] = value2;
151
+ }
152
+ if (type === "data") {
153
+ const parsedValue = JSON.parse(value2);
154
+ if (prefixMap["data"]) {
155
+ prefixMap["data"] = [...prefixMap["data"], ...parsedValue];
156
+ } else {
157
+ prefixMap["data"] = parsedValue;
158
+ }
159
+ }
160
+ const data = prefixMap["data"];
161
+ const responseMessage2 = prefixMap["text"];
162
+ let functionCall = prefixMap["function_call"];
163
+ let functionCallMessage = null;
164
+ if (functionCall) {
165
+ const parsedFunctionCall = JSON.parse(functionCall).function_call;
166
+ functionCallMessage = {
167
+ id: nanoid(),
168
+ role: "function",
169
+ content: "",
170
+ name: parsedFunctionCall.name,
171
+ createdAt
172
+ };
173
+ }
174
+ const merged = [functionCallMessage, responseMessage2].filter(
175
+ Boolean
176
+ );
177
+ mutate([...chatRequest.messages, ...merged], false);
178
+ mutateStreamData([...existingData || [], ...data || []]);
179
+ if (abortControllerRef.current === null) {
180
+ reader.cancel();
181
+ break;
182
+ }
183
+ }
184
+ }
185
+ for (const [type, item] of Object.entries(prefixMap)) {
186
+ if (onFinish && type === "text") {
187
+ onFinish(item);
188
+ }
189
+ if (type === "data") {
190
+ responseData.push(item);
191
+ } else {
192
+ responseMessages.push(item);
193
+ }
194
+ }
195
+ return { messages: responseMessages, data: responseData };
196
+ } else {
197
+ while (true) {
198
+ const { done, value } = await reader.read();
199
+ if (done) {
200
+ break;
201
+ }
202
+ streamedResponse += decode(value);
203
+ if (streamedResponse.startsWith('{"function_call":')) {
204
+ responseMessage["function_call"] = streamedResponse;
205
+ } else {
206
+ responseMessage["content"] = streamedResponse;
207
+ }
208
+ mutate([...chatRequest.messages, { ...responseMessage }], false);
209
+ if (abortControllerRef.current === null) {
210
+ reader.cancel();
211
+ break;
212
+ }
90
213
  }
91
- streamedResponse += decode(value);
92
214
  if (streamedResponse.startsWith('{"function_call":')) {
93
- responseMessage["function_call"] = streamedResponse;
94
- } else {
95
- responseMessage["content"] = streamedResponse;
215
+ const parsedFunctionCall = JSON.parse(streamedResponse).function_call;
216
+ responseMessage["function_call"] = parsedFunctionCall;
217
+ mutate([...chatRequest.messages, { ...responseMessage }]);
96
218
  }
97
- mutate([...chatRequest.messages, { ...responseMessage }], false);
98
- if (abortControllerRef.current === null) {
99
- reader.cancel();
100
- break;
219
+ if (onFinish) {
220
+ onFinish(responseMessage);
101
221
  }
222
+ return responseMessage;
102
223
  }
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
224
  };
113
225
  function useChat({
114
226
  api = "/api/chat",
@@ -126,17 +238,20 @@ function useChat({
126
238
  } = {}) {
127
239
  const hookId = useId();
128
240
  const chatId = id || hookId;
129
- const { data, mutate } = useSWR([api, chatId], null, {
241
+ const { data: messages, mutate } = useSWR([api, chatId], null, {
130
242
  fallbackData: initialMessages
131
243
  });
132
244
  const { data: isLoading = false, mutate: mutateLoading } = useSWR(
133
245
  [chatId, "loading"],
134
246
  null
135
247
  );
136
- const messages = data;
137
- const messagesRef = useRef(messages);
248
+ const { data: streamData, mutate: mutateStreamData } = useSWR(
249
+ [chatId, "streamData"],
250
+ null
251
+ );
252
+ const messagesRef = useRef(messages || []);
138
253
  useEffect(() => {
139
- messagesRef.current = messages;
254
+ messagesRef.current = messages || [];
140
255
  }, [messages]);
141
256
  const abortControllerRef = useRef(null);
142
257
  const extraMetadataRef = useRef({
@@ -158,10 +273,12 @@ function useChat({
158
273
  const abortController = new AbortController();
159
274
  abortControllerRef.current = abortController;
160
275
  while (true) {
161
- const streamedResponseMessage = await getStreamedResponse(
276
+ const messagesAndDataOrJustMessage = await getStreamedResponse(
162
277
  api,
163
278
  chatRequest,
164
279
  mutate,
280
+ mutateStreamData,
281
+ streamData,
165
282
  extraMetadataRef,
166
283
  messagesRef,
167
284
  abortControllerRef,
@@ -169,19 +286,41 @@ function useChat({
169
286
  onResponse,
170
287
  sendExtraMessageFields
171
288
  );
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)
289
+ if ("messages" in messagesAndDataOrJustMessage) {
290
+ for (const message of messagesAndDataOrJustMessage.messages) {
291
+ if (message.function_call === void 0 || typeof message.function_call === "string") {
292
+ break;
293
+ }
294
+ if (experimental_onFunctionCall) {
295
+ const functionCall = message.function_call;
296
+ const functionCallResponse = await experimental_onFunctionCall(
297
+ messagesRef.current,
298
+ functionCall
299
+ );
300
+ if (functionCallResponse === void 0)
301
+ break;
302
+ chatRequest = functionCallResponse;
303
+ }
304
+ }
305
+ } else {
306
+ const streamedResponseMessage = messagesAndDataOrJustMessage;
307
+ if (streamedResponseMessage.function_call === void 0 || typeof streamedResponseMessage.function_call === "string") {
179
308
  break;
180
- chatRequest = functionCallResponse;
309
+ }
310
+ if (experimental_onFunctionCall) {
311
+ const functionCall = streamedResponseMessage.function_call;
312
+ const functionCallResponse = await experimental_onFunctionCall(
313
+ messagesRef.current,
314
+ functionCall
315
+ );
316
+ if (functionCallResponse === void 0)
317
+ break;
318
+ chatRequest = functionCallResponse;
319
+ }
181
320
  }
321
+ abortControllerRef.current = null;
322
+ return null;
182
323
  }
183
- abortControllerRef.current = null;
184
- return null;
185
324
  } catch (err) {
186
325
  if (err.name === "AbortError") {
187
326
  abortControllerRef.current = null;
@@ -275,7 +414,7 @@ function useChat({
275
414
  setInput(e.target.value);
276
415
  };
277
416
  return {
278
- messages,
417
+ messages: messages || [],
279
418
  error,
280
419
  append,
281
420
  reload,
@@ -285,7 +424,8 @@ function useChat({
285
424
  setInput,
286
425
  handleInputChange,
287
426
  handleSubmit,
288
- isLoading
427
+ isLoading,
428
+ data: streamData
289
429
  };
290
430
  }
291
431
 
@@ -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;