@revojs/ai 0.3.0 → 0.3.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.
@@ -150,6 +150,24 @@ function toFinishReason(raw) {
150
150
  raw: raw ?? void 0
151
151
  };
152
152
  }
153
+ function toStreamError(chunk) {
154
+ if (typeof chunk.error === "string") return chunk.error;
155
+ if (chunk.error !== void 0) return chunk.error.message ?? "Unknown AI provider error";
156
+ if (chunk.object === "error") return chunk.message ?? "Unknown AI provider error";
157
+ }
158
+ function hasCompleteToolCalls(tools) {
159
+ if (tools.size === 0) return false;
160
+ for (const accumulator of tools.values()) {
161
+ if (accumulator.name.length === 0) return false;
162
+ try {
163
+ const input = JSON.parse(toToolInput(accumulator.arguments));
164
+ if (typeof input !== "object" || input === null || Array.isArray(input)) return false;
165
+ } catch {
166
+ return false;
167
+ }
168
+ }
169
+ return true;
170
+ }
153
171
  async function* readParts(response, warnings) {
154
172
  yield {
155
173
  type: "stream-start",
@@ -160,6 +178,7 @@ async function* readParts(response, warnings) {
160
178
  let textStarted = false;
161
179
  let reasoningStarted = false;
162
180
  let finishRaw;
181
+ let failure;
163
182
  let usage;
164
183
  for await (const data of readDataFrames(response)) {
165
184
  if (data === "[DONE]") break;
@@ -169,6 +188,8 @@ async function* readParts(response, warnings) {
169
188
  } catch {
170
189
  continue;
171
190
  }
191
+ failure = toStreamError(chunk);
192
+ if (failure !== void 0) break;
172
193
  if (!metadataSent) {
173
194
  metadataSent = true;
174
195
  yield {
@@ -240,7 +261,10 @@ async function* readParts(response, warnings) {
240
261
  }
241
262
  }
242
263
  }
243
- if (finishRaw === void 0) throw new Error("Incomplete chat completions stream.");
264
+ if (finishRaw === void 0) {
265
+ if (!hasCompleteToolCalls(tools)) throw new Error(failure ?? "Incomplete chat completions stream.");
266
+ finishRaw = "tool_calls";
267
+ }
244
268
  if (reasoningStarted) yield {
245
269
  type: "reasoning-end",
246
270
  id: "openai-reasoning-0"
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@revojs/ai",
3
- "version": "0.3.0",
3
+ "version": "0.3.2",
4
4
  "license": "MIT",
5
5
  "repository": {
6
6
  "type": "git",
@@ -30,10 +30,10 @@
30
30
  },
31
31
  "dependencies": {
32
32
  "@cfworker/json-schema": "^4.1.1",
33
- "@revojs/server": "0.3.0",
34
- "revojs": "0.3.0"
33
+ "@revojs/server": "0.3.2",
34
+ "revojs": "0.3.2"
35
35
  },
36
36
  "devDependencies": {
37
- "@revojs/tsconfig": "0.3.0"
37
+ "@revojs/tsconfig": "0.3.2"
38
38
  }
39
39
  }