@xsai/stream-text 0.2.0-beta.4 → 0.2.0-beta.5

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 CHANGED
@@ -74,22 +74,23 @@ interface StreamTextStep {
74
74
  }
75
75
  /** @internal */
76
76
  interface StreamTextChoice {
77
- finish_reason?: FinishReason | null;
77
+ finishReason?: FinishReason | null;
78
78
  index: number;
79
79
  message: StreamTextMessage;
80
80
  }
81
81
  /** @internal */
82
82
  interface StreamTextMessage extends Omit<AssistantMessage, 'tool_calls'> {
83
83
  content?: string;
84
- tool_calls?: {
85
- [id: string]: StreamTextToolCall;
84
+ toolCalls?: {
85
+ [id: number]: StreamTextToolCall;
86
86
  };
87
87
  }
88
88
  /** @internal */
89
89
  interface StreamTextToolCall extends ToolCall {
90
90
  function: ToolCall['function'] & {
91
- parsed_arguments: Record<string, unknown>;
91
+ parsedArguments: Record<string, unknown>;
92
92
  };
93
+ index: number;
93
94
  }
94
95
  declare const streamText: (options: StreamTextOptions) => Promise<StreamTextResult>;
95
96
 
package/dist/index.js CHANGED
@@ -62,12 +62,12 @@ const streamText = async (options) => {
62
62
  const choiceState = {};
63
63
  let buffer = "";
64
64
  let shouldOutputText = true;
65
- const endToolCall = (state, id) => {
66
- if (state.endedToolCallIDs.has(id)) {
65
+ const endToolCallByIndex = (state, idx) => {
66
+ if (state.endedToolCallIndex.has(idx)) {
67
67
  return;
68
68
  }
69
- state.endedToolCallIDs.add(id);
70
- state.currentToolID = null;
69
+ state.endedToolCallIndex.add(idx);
70
+ state.currentToolIndex = null;
71
71
  };
72
72
  await chat({
73
73
  ...options2,
@@ -111,7 +111,7 @@ const streamText = async (options) => {
111
111
  }
112
112
  const { delta, finish_reason, index, ...rest } = choice;
113
113
  const choiceSnapshot = step.choices[index] ??= {
114
- finish_reason,
114
+ finishReason: finish_reason,
115
115
  index,
116
116
  message: {
117
117
  role: "assistant"
@@ -119,7 +119,7 @@ const streamText = async (options) => {
119
119
  };
120
120
  if (finish_reason !== void 0) {
121
121
  step.finishReason = finish_reason;
122
- choiceSnapshot.finish_reason = finish_reason;
122
+ choiceSnapshot.finishReason = finish_reason;
123
123
  if (finish_reason === "length") {
124
124
  throw new XSAIError("length exceeded");
125
125
  }
@@ -132,44 +132,45 @@ const streamText = async (options) => {
132
132
  const message = choiceSnapshot.message;
133
133
  Object.assign(message, rests);
134
134
  if (refusal !== void 0) {
135
- message.refusal = (message.refusal || "") + refusal;
135
+ message.refusal = (message.refusal || "") + (refusal || "");
136
136
  }
137
137
  if (content !== void 0) {
138
- message.content = (message.content || "") + content;
138
+ message.content = (message.content || "") + (content || "");
139
139
  shouldOutputText && textCtrl?.enqueue(content);
140
140
  }
141
- for (const { function: fn, id, type } of tool_calls || []) {
142
- message.tool_calls ??= {};
143
- const toolCall = message.tool_calls[id] ??= {
141
+ for (const { function: fn, id, index: index2, type } of tool_calls || []) {
142
+ message.toolCalls ??= {};
143
+ const toolCall = message.toolCalls[index2] ??= {
144
144
  function: {
145
145
  arguments: "",
146
146
  name: fn.name,
147
- parsed_arguments: {}
147
+ parsedArguments: {}
148
148
  },
149
149
  id,
150
+ index: index2,
150
151
  type
151
152
  };
152
153
  toolCall.function.arguments += fn.arguments;
153
154
  }
154
155
  const state = choiceState[index] ??= {
155
- calledToolCallIDs: /* @__PURE__ */ new Set(),
156
- currentToolID: null,
157
- endedToolCallIDs: /* @__PURE__ */ new Set(),
156
+ calledToolCallIndex: /* @__PURE__ */ new Set(),
157
+ currentToolIndex: null,
158
+ endedToolCallIndex: /* @__PURE__ */ new Set(),
158
159
  index,
159
160
  toolCallErrors: {},
160
161
  toolCallResults: {}
161
162
  };
162
163
  if (finish_reason) {
163
- if (state.currentToolID !== null) {
164
- endToolCall(state, state.currentToolID);
164
+ if (state.currentToolIndex !== null) {
165
+ endToolCallByIndex(state, state.currentToolIndex);
165
166
  }
166
167
  }
167
168
  for (const toolCall of delta.tool_calls || []) {
168
- if (state.currentToolID !== null && state.currentToolID !== toolCall.id) {
169
- endToolCall(state, state.currentToolID);
169
+ if (state.currentToolIndex !== toolCall.index && state.currentToolIndex !== null) {
170
+ endToolCallByIndex(state, state.currentToolIndex);
170
171
  }
171
- state.calledToolCallIDs.add(toolCall.id);
172
- state.currentToolID = toolCall.id;
172
+ state.calledToolCallIndex.add(toolCall.index);
173
+ state.currentToolIndex = toolCall.index;
173
174
  }
174
175
  }
175
176
  }))
@@ -177,19 +178,28 @@ const streamText = async (options) => {
177
178
  step.messages.push({
178
179
  content: step.choices[0]?.message.content ?? "",
179
180
  refusal: step.choices[0]?.message.refusal,
180
- role: "assistant"
181
+ role: "assistant",
182
+ tool_calls: Object.values(step.choices[0]?.message.toolCalls ?? {}).map((toolCall) => ({
183
+ function: {
184
+ arguments: toolCall.function.arguments,
185
+ name: toolCall.function.name
186
+ },
187
+ id: toolCall.id,
188
+ index: toolCall.index,
189
+ type: toolCall.type
190
+ }))
181
191
  });
182
192
  await Promise.allSettled(step.choices.map(async (choice) => {
183
193
  const state = choiceState[choice.index];
184
- return Promise.allSettled([...state.endedToolCallIDs].map(async (id) => {
185
- const toolCall = choice.message.tool_calls[id];
194
+ return Promise.allSettled([...state.endedToolCallIndex].map(async (idx) => {
195
+ const toolCall = choice.message.toolCalls[idx];
186
196
  step.toolCalls.push({
187
197
  args: toolCall.function.arguments,
188
- toolCallId: id,
198
+ toolCallId: toolCall.id,
189
199
  toolCallType: "function",
190
200
  toolName: toolCall.function.name
191
201
  });
192
- if (state.toolCallResults[id]) {
202
+ if (state.toolCallResults[toolCall.id]) {
193
203
  return;
194
204
  }
195
205
  try {
@@ -199,21 +209,21 @@ const streamText = async (options) => {
199
209
  toolCall,
200
210
  tools: options2.tools
201
211
  });
202
- toolCall.function.parsed_arguments = parsedArgs;
203
- state.toolCallResults[id] = result;
212
+ toolCall.function.parsedArguments = parsedArgs;
213
+ state.toolCallResults[toolCall.id] = result;
204
214
  step.messages.push({
205
215
  content: result,
206
216
  role: "tool",
207
- tool_call_id: id
217
+ tool_call_id: toolCall.id
208
218
  });
209
219
  step.toolResults.push({
210
220
  args: parsedArgs,
211
221
  result,
212
- toolCallId: id,
222
+ toolCallId: toolCall.id,
213
223
  toolName
214
224
  });
215
225
  } catch (error) {
216
- state.toolCallErrors[id] = error;
226
+ state.toolCallErrors[idx] = error;
217
227
  }
218
228
  }));
219
229
  }));
package/package.json CHANGED
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "name": "@xsai/stream-text",
3
3
  "type": "module",
4
- "version": "0.2.0-beta.4",
5
- "description": "extra-small AI SDK for Browser, Node.js, Deno, Bun or Edge Runtime.",
4
+ "version": "0.2.0-beta.5",
5
+ "description": "extra-small AI SDK.",
6
6
  "author": "Moeru AI",
7
7
  "license": "MIT",
8
8
  "homepage": "https://xsai.js.org",