@jxsuite/ai 0.37.1 → 0.37.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.
- package/package.json +3 -3
- package/src/streaming-client.ts +46 -12
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jxsuite/ai",
|
|
3
|
-
"version": "0.37.
|
|
3
|
+
"version": "0.37.2",
|
|
4
4
|
"description": "AI infrastructure for Jx Suite — streaming LLM client abstraction, tool registry, and reactive chat state",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -28,8 +28,8 @@
|
|
|
28
28
|
"upgrade": "bun update --latest && bun install"
|
|
29
29
|
},
|
|
30
30
|
"dependencies": {
|
|
31
|
-
"@jxsuite/protocol": "^2.3.
|
|
32
|
-
"@vue/reactivity": "3.5.
|
|
31
|
+
"@jxsuite/protocol": "^2.3.1",
|
|
32
|
+
"@vue/reactivity": "3.5.43"
|
|
33
33
|
},
|
|
34
34
|
"devDependencies": {
|
|
35
35
|
"@happy-dom/global-registrator": "^20.14.5"
|
package/src/streaming-client.ts
CHANGED
|
@@ -144,6 +144,45 @@ interface ErrorResponseBody {
|
|
|
144
144
|
* reading a sentence and deciding what it meant.
|
|
145
145
|
*/
|
|
146
146
|
code?: string;
|
|
147
|
+
/**
|
|
148
|
+
* An array-shaped envelope, as Cloudflare's own REST API uses for a BYOK base URL pointed
|
|
149
|
+
* directly at it: `{ success: false, errors: [{ code, message }] }`, with no top-level `error`
|
|
150
|
+
* key at all. Reachable only when `baseUrl` bypasses the Studio proxy and talks to such a
|
|
151
|
+
* provider directly — the proxy itself normalizes this shape before it ever reaches a client.
|
|
152
|
+
*/
|
|
153
|
+
errors?: { code?: number; message?: string }[];
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
/**
|
|
157
|
+
* Extract a human-readable message from an error body, falling back to the raw body (or `fallback`
|
|
158
|
+
* when the body is empty).
|
|
159
|
+
*/
|
|
160
|
+
function extractErrorMessage(rawBody: string, fallback: string): string {
|
|
161
|
+
if (!rawBody) {
|
|
162
|
+
return fallback;
|
|
163
|
+
}
|
|
164
|
+
try {
|
|
165
|
+
const { error, errors } = JSON.parse(rawBody) as ErrorResponseBody;
|
|
166
|
+
if (typeof error === "string") {
|
|
167
|
+
return error;
|
|
168
|
+
}
|
|
169
|
+
if (error) {
|
|
170
|
+
const { message } = error;
|
|
171
|
+
if (message) {
|
|
172
|
+
return message;
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
const [first] = errors ?? [];
|
|
176
|
+
if (first) {
|
|
177
|
+
const { message } = first;
|
|
178
|
+
if (message) {
|
|
179
|
+
return message;
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
} catch {
|
|
183
|
+
/* Not JSON — use the raw body. */
|
|
184
|
+
}
|
|
185
|
+
return rawBody;
|
|
147
186
|
}
|
|
148
187
|
|
|
149
188
|
// ─── Type definitions ────────────────────────────────────────────────────────
|
|
@@ -275,9 +314,10 @@ export function createOpenAIStreamingClient({
|
|
|
275
314
|
} catch {
|
|
276
315
|
/* Ignore */
|
|
277
316
|
}
|
|
317
|
+
const message = extractErrorMessage(errorBody, response.statusText);
|
|
278
318
|
yield {
|
|
279
319
|
type: "error",
|
|
280
|
-
message: `API error ${response.status}: ${
|
|
320
|
+
message: `API error ${response.status}: ${message}`,
|
|
281
321
|
code: String(response.status),
|
|
282
322
|
};
|
|
283
323
|
return;
|
|
@@ -543,23 +583,17 @@ export function createProxyStreamingClient({
|
|
|
543
583
|
} catch {
|
|
544
584
|
/* Ignore */
|
|
545
585
|
}
|
|
546
|
-
//
|
|
547
|
-
|
|
548
|
-
let cleanMessage = errorBody || response.statusText;
|
|
586
|
+
// Extract a clean message from the JSON error body — see extractErrorMessage.
|
|
587
|
+
const cleanMessage = extractErrorMessage(errorBody, response.statusText);
|
|
549
588
|
/* The body's machine code beats the status. `code` was `String(response.status)`
|
|
550
589
|
unconditionally, so a proxy answering 401 `{ code: "cf_reconnect_required" }` reached the
|
|
551
590
|
client as `"401"` — indistinguishable from a bad BYOK key, and the one reading that would
|
|
552
591
|
have put a Reconnect button on screen was thrown away at the only place it arrived. */
|
|
553
592
|
let machineCode = "";
|
|
554
593
|
try {
|
|
555
|
-
const
|
|
556
|
-
if (typeof
|
|
557
|
-
|
|
558
|
-
} else if (parsed.error?.message) {
|
|
559
|
-
cleanMessage = parsed.error.message;
|
|
560
|
-
}
|
|
561
|
-
if (typeof parsed.code === "string" && parsed.code) {
|
|
562
|
-
machineCode = parsed.code;
|
|
594
|
+
const { code } = JSON.parse(errorBody) as ErrorResponseBody;
|
|
595
|
+
if (typeof code === "string" && code) {
|
|
596
|
+
machineCode = code;
|
|
563
597
|
}
|
|
564
598
|
} catch {
|
|
565
599
|
/* Not JSON — use the raw body. */
|