@cmnd-ai/chatbot-react 1.6.0 → 1.7.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,11 @@
1
+ declare class StreamError extends Error {
2
+ name: string;
3
+ path: string[];
4
+ error: string;
5
+ constructor({ message, path, error, }: {
6
+ message: string;
7
+ path?: string[];
8
+ error: string;
9
+ });
10
+ }
11
+ export default StreamError;
@@ -0,0 +1,12 @@
1
+ class StreamError extends Error {
2
+ name;
3
+ path;
4
+ error;
5
+ constructor({ message, path, error, }) {
6
+ super(message);
7
+ this.name = "StreamError";
8
+ this.path = path || [];
9
+ this.error = error;
10
+ }
11
+ }
12
+ export default StreamError;
@@ -1,77 +1,91 @@
1
+ import StreamError from "./StreamError.js";
1
2
  const processStream = async (reader, onData) => {
2
3
  if (!onData)
3
4
  return;
4
5
  let fullAssistantMessage = "";
5
- let fullMessageContext = "";
6
+ let buffer = ""; // buffer to store incomplete JSON string fragments
6
7
  try {
7
8
  while (true) {
8
9
  const { value, done } = await reader.read();
9
10
  if (done) {
10
11
  break;
11
12
  }
12
- // Process the incoming chunk of data
13
- const chunk = value; // Assuming `value` is a string
14
- // Split the chunk by lines
13
+ const chunk = typeof value === "string" ? value : new TextDecoder().decode(value);
15
14
  const lines = chunk.split("\n");
16
15
  for (const line of lines) {
17
- let dataString = line;
18
- if (line === "") {
19
- // skip empty line of content
16
+ if (line.trim() === "")
20
17
  continue;
21
- }
22
- if (line.startsWith("data: ")) {
23
- dataString = line.slice(6);
24
- }
18
+ const dataString = line.startsWith("data: ") ? line.slice(6) : line;
25
19
  if (dataString === "[DONE]") {
26
20
  onData({
27
21
  completionFinished: true,
28
22
  finalResponseWithUsageData: false,
29
23
  });
24
+ continue;
30
25
  }
31
- else {
32
- try {
33
- const dataObject = JSON.parse(fullMessageContext + dataString);
34
- if (dataObject.error) {
35
- throw new Error(dataObject.error);
36
- }
37
- if (dataObject.content) {
38
- fullAssistantMessage += dataObject.content;
39
- onData({
40
- completionFinished: false,
41
- finalResponseWithUsageData: false,
42
- message: fullAssistantMessage,
43
- });
44
- }
45
- else {
46
- //at this point, the dataObject does not have a content propery
47
- //and it is completed
48
- //get the last message from the dataObject to check if it is a function call
49
- const { messages, completionFinished, finalResponseWithUsageData, chatbotConversationId, conversationId, totalTokens, totalCost, } = dataObject;
50
- onData({
51
- messages,
52
- completionFinished,
53
- finalResponseWithUsageData,
54
- conversationId,
55
- chatbotConversationId,
56
- totalTokens,
57
- totalCost,
58
- });
59
- }
26
+ // Accumulate and try parsing
27
+ buffer += dataString;
28
+ try {
29
+ const dataObject = JSON.parse(buffer);
30
+ buffer = ""; // Clear the buffer after successful parse
31
+ if (dataObject.error) {
32
+ throw new StreamError({
33
+ error: dataObject.error,
34
+ path: dataObject.path,
35
+ message: dataObject.error,
36
+ });
37
+ }
38
+ if (dataObject.content) {
39
+ fullAssistantMessage += dataObject.content;
40
+ onData({
41
+ completionFinished: false,
42
+ finalResponseWithUsageData: false,
43
+ message: fullAssistantMessage,
44
+ });
60
45
  }
61
- catch (error) {
46
+ else if (dataObject.function_call) {
47
+ // console.log("no processing necessary");
48
+ }
49
+ else {
50
+ //at this point, the dataObject does not have a content propery
51
+ //and it is completed
52
+ //get the last message from the dataObject to check if it is a function call
53
+ const { messages, completionFinished, finalResponseWithUsageData, conversationId, chatbotConversationId, totalTokens, totalCost, } = dataObject;
62
54
  onData({
63
- completionFinished: true,
64
- message: error instanceof Error
65
- ? error.message
66
- : "Oops! I ran into a problem.",
67
- finalResponseWithUsageData: true,
55
+ messages,
56
+ completionFinished,
57
+ finalResponseWithUsageData,
58
+ conversationId,
59
+ chatbotConversationId,
60
+ totalTokens,
61
+ totalCost,
68
62
  });
69
63
  }
70
64
  }
65
+ catch (error) {
66
+ // Only handle as error if it's NOT a syntax error
67
+ if (error instanceof SyntaxError) {
68
+ // Wait for more data
69
+ continue;
70
+ }
71
+ console.error("StreamError caught", error);
72
+ onData({
73
+ completionFinished: true,
74
+ message: error instanceof StreamError
75
+ ? error.message
76
+ : "Oops! I ran into a problem.",
77
+ finalResponseWithUsageData: true,
78
+ });
79
+ }
71
80
  }
72
81
  }
82
+ // Final check for any leftover buffered content
83
+ if (buffer.trim()) {
84
+ console.warn("Leftover data in buffer at stream end:", buffer);
85
+ }
73
86
  }
74
87
  catch (error) {
88
+ console.error("Error processing stream", error);
75
89
  onData({
76
90
  completionFinished: true,
77
91
  message: "Oops! I ran into a problem.",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cmnd-ai/chatbot-react",
3
- "version": "1.6.0",
3
+ "version": "1.7.1",
4
4
  "main": "dist/index.js",
5
5
  "description": "",
6
6
  "type": "module",