@prestyj/ai 5.3.0 → 5.4.0
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.cjs +64 -27
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +4 -4
- package/dist/index.d.ts +4 -4
- package/dist/index.js +64 -27
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.cts
CHANGED
|
@@ -343,15 +343,15 @@ declare const providerRegistry: ProviderRegistryImpl;
|
|
|
343
343
|
*
|
|
344
344
|
* Every error users see should answer one question: "is this me or them?"
|
|
345
345
|
* That answer drives whether they retry, switch model, log in, or report a
|
|
346
|
-
*
|
|
346
|
+
* EZ Coder bug. The `FormattedError` shape captures it in plain English:
|
|
347
347
|
*
|
|
348
348
|
* ✗ OpenAI returned an error.
|
|
349
349
|
* An error occurred while processing your request...
|
|
350
|
-
* → This is an OpenAI issue, not
|
|
350
|
+
* → This is an OpenAI issue, not EZ Coder. Retry — if it persists, check status.openai.com.
|
|
351
351
|
*
|
|
352
|
-
* ✗
|
|
352
|
+
* ✗ EZ Coder hit an unexpected error.
|
|
353
353
|
* Cannot read property 'foo' of undefined
|
|
354
|
-
* → This is a
|
|
354
|
+
* → This is a EZ Coder bug — please report it.
|
|
355
355
|
*/
|
|
356
356
|
type ErrorSource = "provider" | "ezcoder" | "network" | "auth" | "capability";
|
|
357
357
|
interface FormattedError {
|
package/dist/index.d.ts
CHANGED
|
@@ -343,15 +343,15 @@ declare const providerRegistry: ProviderRegistryImpl;
|
|
|
343
343
|
*
|
|
344
344
|
* Every error users see should answer one question: "is this me or them?"
|
|
345
345
|
* That answer drives whether they retry, switch model, log in, or report a
|
|
346
|
-
*
|
|
346
|
+
* EZ Coder bug. The `FormattedError` shape captures it in plain English:
|
|
347
347
|
*
|
|
348
348
|
* ✗ OpenAI returned an error.
|
|
349
349
|
* An error occurred while processing your request...
|
|
350
|
-
* → This is an OpenAI issue, not
|
|
350
|
+
* → This is an OpenAI issue, not EZ Coder. Retry — if it persists, check status.openai.com.
|
|
351
351
|
*
|
|
352
|
-
* ✗
|
|
352
|
+
* ✗ EZ Coder hit an unexpected error.
|
|
353
353
|
* Cannot read property 'foo' of undefined
|
|
354
|
-
* → This is a
|
|
354
|
+
* → This is a EZ Coder bug — please report it.
|
|
355
355
|
*/
|
|
356
356
|
type ErrorSource = "provider" | "ezcoder" | "network" | "auth" | "capability";
|
|
357
357
|
interface FormattedError {
|
package/dist/index.js
CHANGED
|
@@ -117,7 +117,7 @@ function formatError(err) {
|
|
|
117
117
|
provider: err.provider,
|
|
118
118
|
statusCode: err.statusCode,
|
|
119
119
|
...err.requestId ? { requestId: err.requestId } : {},
|
|
120
|
-
guidance: "Request access via your Anthropic account team (see platform.claude.com/docs/en/about-claude/models/overview), or switch to
|
|
120
|
+
guidance: "Request access via your Anthropic account team (see platform.claude.com/docs/en/about-claude/models/overview), or switch to Claude Fable 5 via the model selector \u2014 same underlying model, generally available."
|
|
121
121
|
};
|
|
122
122
|
}
|
|
123
123
|
if (isUsageLimitError(err)) {
|
|
@@ -159,7 +159,7 @@ function finaliseBySource(source, message, requestId, hint) {
|
|
|
159
159
|
headline: "Network error \u2014 couldn't reach the provider.",
|
|
160
160
|
source,
|
|
161
161
|
message,
|
|
162
|
-
guidance: hint ?? "Check your internet connection. Not a
|
|
162
|
+
guidance: hint ?? "Check your internet connection. Not a EZ Coder issue \u2014 retry shortly.",
|
|
163
163
|
...requestId ? { requestId } : {}
|
|
164
164
|
};
|
|
165
165
|
case "auth":
|
|
@@ -167,7 +167,7 @@ function finaliseBySource(source, message, requestId, hint) {
|
|
|
167
167
|
headline: "Authentication issue.",
|
|
168
168
|
source,
|
|
169
169
|
message,
|
|
170
|
-
guidance: hint ?? "
|
|
170
|
+
guidance: hint ?? "Re-authenticate to refresh your credentials.",
|
|
171
171
|
...requestId ? { requestId } : {}
|
|
172
172
|
};
|
|
173
173
|
case "provider":
|
|
@@ -183,15 +183,15 @@ function finaliseBySource(source, message, requestId, hint) {
|
|
|
183
183
|
headline: message,
|
|
184
184
|
source,
|
|
185
185
|
message: "",
|
|
186
|
-
guidance: hint ?? "Only Kimi, Gemini, MiniMax, and MiMo-V2.5 can analyze video. Switch
|
|
186
|
+
guidance: hint ?? "Only Kimi, Gemini, MiniMax, and MiMo-V2.5 can analyze video. Switch to one of those via the model selector.",
|
|
187
187
|
...requestId ? { requestId } : {}
|
|
188
188
|
};
|
|
189
189
|
case "ezcoder":
|
|
190
190
|
return {
|
|
191
|
-
headline: "
|
|
191
|
+
headline: "EZ Coder hit an unexpected error.",
|
|
192
192
|
source,
|
|
193
193
|
message,
|
|
194
|
-
guidance: hint ?? "This looks like a
|
|
194
|
+
guidance: hint ?? "This looks like a EZ Coder bug \u2014 please report it to the developer (see /help).",
|
|
195
195
|
...requestId ? { requestId } : {}
|
|
196
196
|
};
|
|
197
197
|
}
|
|
@@ -222,36 +222,39 @@ function providerGuidance(provider, message, statusCode) {
|
|
|
222
222
|
const status = provider ? PROVIDER_STATUS_URL[provider] : void 0;
|
|
223
223
|
const lower = message.toLowerCase();
|
|
224
224
|
if (statusCode === 401 || lower.includes("unauthorized") || lower.includes("invalid api key")) {
|
|
225
|
-
return `Authentication failed with ${name}.
|
|
225
|
+
return `Authentication failed with ${name}. Re-authenticate to refresh your credentials.`;
|
|
226
226
|
}
|
|
227
227
|
if (lower.includes("overloaded") || lower.includes("engine_overloaded")) {
|
|
228
|
-
return `${name}'s servers are overloaded right now. Retry in a moment \u2014 not a
|
|
228
|
+
return `${name}'s servers are overloaded right now. Retry in a moment \u2014 not a EZ Coder issue.`;
|
|
229
229
|
}
|
|
230
230
|
if (lower.includes("insufficient balance") || lower.includes("quota exceeded") || lower.includes("recharge") || lower.includes("no resource package")) {
|
|
231
|
-
return `Your ${name} account has a billing or quota issue \u2014 check your balance. Not a
|
|
231
|
+
return `Your ${name} account has a billing or quota issue \u2014 check your balance. Not a EZ Coder issue.`;
|
|
232
232
|
}
|
|
233
233
|
if (statusCode === 429 || lower.includes("rate limit") || lower.includes("too many requests")) {
|
|
234
|
-
return `${name} rate limit hit. Wait a moment then retry \u2014 not a
|
|
234
|
+
return `${name} rate limit hit. Wait a moment then retry \u2014 not a EZ Coder issue.`;
|
|
235
235
|
}
|
|
236
236
|
if (statusCode === 502 || lower.includes("bad gateway")) {
|
|
237
|
-
return `${name} returned a bad gateway. Retry \u2014 this is on their side, not
|
|
237
|
+
return `${name} returned a bad gateway. Retry \u2014 this is on their side, not EZ Coder.`;
|
|
238
238
|
}
|
|
239
239
|
if (statusCode === 503 || lower.includes("service unavailable")) {
|
|
240
|
-
return `${name} is temporarily unavailable. Retry shortly \u2014 not a
|
|
240
|
+
return `${name} is temporarily unavailable. Retry shortly \u2014 not a EZ Coder issue.`;
|
|
241
241
|
}
|
|
242
242
|
if (statusCode === 500 || lower.includes("server_error") || lower.includes("500") && lower.includes("internal server error")) {
|
|
243
|
-
return status ? `This is an error from ${name}, not
|
|
243
|
+
return status ? `This is an error from ${name}, not EZ Coder. Retry \u2014 if it keeps happening, check ${status}.` : `This is an error from ${name}, not EZ Coder. Retry \u2014 if it keeps happening, try a different model via the model selector.`;
|
|
244
244
|
}
|
|
245
245
|
if (lower.includes("timeout") || lower.includes("timed out")) {
|
|
246
|
-
return `Request to ${name} timed out. Their servers may be slow \u2014 retry. Not a
|
|
246
|
+
return `Request to ${name} timed out. Their servers may be slow \u2014 retry. Not a EZ Coder issue.`;
|
|
247
247
|
}
|
|
248
248
|
if (lower.includes("does not recognize the requested model") || lower.includes("model") && (lower.includes("not exist") || lower.includes("not found") || lower.includes("no access"))) {
|
|
249
|
-
return `${name} doesn't recognise this model on your account.
|
|
249
|
+
return `${name} doesn't recognise this model on your account. Switch to a different model via the model selector, or check your subscription tier.`;
|
|
250
250
|
}
|
|
251
251
|
if (lower.includes("context_length_exceeded") || lower.includes("prompt is too long")) {
|
|
252
|
-
return `Context window for this ${name} model is full.
|
|
252
|
+
return `Context window for this ${name} model is full. Compact the conversation to shrink history, or start a new session.`;
|
|
253
253
|
}
|
|
254
|
-
|
|
254
|
+
if (statusCode === 413 || lower.includes("request_too_large") || lower.includes("request exceeds the maximum size")) {
|
|
255
|
+
return `The request to ${name} is too large. Compact the conversation to shrink history, or start a new session.`;
|
|
256
|
+
}
|
|
257
|
+
return status ? `This is an error from ${name}, not EZ Coder. Retry \u2014 if it persists, check ${status}.` : `This is an error from ${name}, not EZ Coder. Retry \u2014 if it persists, try a different model via the model selector.`;
|
|
255
258
|
}
|
|
256
259
|
|
|
257
260
|
// src/providers/anthropic.ts
|
|
@@ -1036,6 +1039,12 @@ function parseToolArguments(argsJson) {
|
|
|
1036
1039
|
// src/providers/anthropic.ts
|
|
1037
1040
|
var NON_STREAMING_TIMEOUT_MS = 60 * 60 * 1e3;
|
|
1038
1041
|
var anthropicClientCache = /* @__PURE__ */ new Map();
|
|
1042
|
+
function fineGrainedToolStreamingEnabled() {
|
|
1043
|
+
const raw = process.env.GG_FINE_GRAINED_TOOL_STREAMING ?? process.env.CLAUDE_CODE_ENABLE_FINE_GRAINED_TOOL_STREAMING;
|
|
1044
|
+
if (!raw) return false;
|
|
1045
|
+
const v = raw.trim().toLowerCase();
|
|
1046
|
+
return v === "1" || v === "true" || v === "yes" || v === "on";
|
|
1047
|
+
}
|
|
1039
1048
|
function createClient(options) {
|
|
1040
1049
|
const isOAuth = options.apiKey?.startsWith("sk-ant-oat");
|
|
1041
1050
|
const userAgent = isOAuth ? options.userAgent ?? "claude-cli/2.1.75 (external, cli)" : "";
|
|
@@ -1093,7 +1102,9 @@ async function prewarmAnthropicCache(options) {
|
|
|
1093
1102
|
] : system;
|
|
1094
1103
|
const tools = options.tools?.length ? toAnthropicTools(options.tools, {
|
|
1095
1104
|
cacheControl,
|
|
1096
|
-
|
|
1105
|
+
// Keep the serialized tool bytes identical to runStream so the
|
|
1106
|
+
// prewarmed prompt cache actually hits — both are gated by the flag.
|
|
1107
|
+
enableFineGrainedToolStreaming: fineGrainedToolStreamingEnabled()
|
|
1097
1108
|
}) : void 0;
|
|
1098
1109
|
await client.messages.create(
|
|
1099
1110
|
{
|
|
@@ -1173,7 +1184,7 @@ async function* runStream(options) {
|
|
|
1173
1184
|
options.tools.filter((t) => !reservedServerNames.has(t.name)),
|
|
1174
1185
|
{
|
|
1175
1186
|
...supportsFirstPartyToolExtras && cacheControl ? { cacheControl } : {},
|
|
1176
|
-
...supportsFirstPartyToolExtras ? { enableFineGrainedToolStreaming: true } : {}
|
|
1187
|
+
...supportsFirstPartyToolExtras && fineGrainedToolStreamingEnabled() ? { enableFineGrainedToolStreaming: true } : {}
|
|
1177
1188
|
}
|
|
1178
1189
|
) : [];
|
|
1179
1190
|
return {
|
|
@@ -1199,7 +1210,10 @@ async function* runStream(options) {
|
|
|
1199
1210
|
...isOAuth ? ["claude-code-20250219", "oauth-2025-04-20"] : [],
|
|
1200
1211
|
...options.compaction ? ["compact-2026-01-12"] : [],
|
|
1201
1212
|
...options.clearToolUses ? ["context-management-2025-06-27"] : [],
|
|
1202
|
-
|
|
1213
|
+
// Eager tool-input streaming beta — opt-in only (see
|
|
1214
|
+
// fineGrainedToolStreamingEnabled). Off by default: the un-buffered stream
|
|
1215
|
+
// truncates large tool payloads into malformed JSON → phantom empty calls.
|
|
1216
|
+
...fineGrainedToolStreamingEnabled() ? ["fine-grained-tool-streaming-2025-05-14"] : [],
|
|
1203
1217
|
...!hasAdaptiveThinking ? ["interleaved-thinking-2025-05-14"] : [],
|
|
1204
1218
|
// The 1-h cache TTL (cacheRetention "long") is gated behind this beta. Without
|
|
1205
1219
|
// it Anthropic silently ignores ttl:"1h" and falls back to the 5-min default,
|
|
@@ -1332,7 +1346,14 @@ async function* runStream(options) {
|
|
|
1332
1346
|
try {
|
|
1333
1347
|
const parsed = JSON.parse(accum.argsJson);
|
|
1334
1348
|
args = isJsonObject(parsed) ? parsed : {};
|
|
1335
|
-
} catch {
|
|
1349
|
+
} catch (parseErr) {
|
|
1350
|
+
const rawPartial = accum.argsJson;
|
|
1351
|
+
const snippet = rawPartial.length > 200 ? `${rawPartial.slice(0, 200)}\u2026` : rawPartial;
|
|
1352
|
+
throw new ProviderError(
|
|
1353
|
+
"anthropic",
|
|
1354
|
+
`Tool "${accum.toolName}" input JSON was truncated in the stream (${rawPartial.length} bytes): ${snippet}; ${parseErr.message}`,
|
|
1355
|
+
{ cause: parseErr }
|
|
1356
|
+
);
|
|
1336
1357
|
}
|
|
1337
1358
|
}
|
|
1338
1359
|
const tc = {
|
|
@@ -1553,6 +1574,7 @@ function readUnifiedRateLimit(headers) {
|
|
|
1553
1574
|
return { rejected: status === "rejected", ...resetsAt ? { resetsAt } : {} };
|
|
1554
1575
|
}
|
|
1555
1576
|
function toError(err) {
|
|
1577
|
+
if (err instanceof ProviderError) return err;
|
|
1556
1578
|
if (err instanceof Anthropic.APIError) {
|
|
1557
1579
|
const errorBody = err.error;
|
|
1558
1580
|
const nestedError = errorBody?.error;
|
|
@@ -2183,10 +2205,10 @@ async function* runStream3(options) {
|
|
|
2183
2205
|
if (options.model === "gpt-5.5-pro") {
|
|
2184
2206
|
hint = "Use gpt-5.5 instead. OpenAI's Codex model catalog does not list gpt-5.5-pro.";
|
|
2185
2207
|
} else {
|
|
2186
|
-
hint = "This model is not available through Codex for the authenticated account.
|
|
2208
|
+
hint = "This model is not available through Codex for the authenticated account. Switch to a model listed for OpenAI Codex via the model selector, or check your Codex usage limits.";
|
|
2187
2209
|
}
|
|
2188
2210
|
} else if (response.status === 404 && text.includes("does not exist")) {
|
|
2189
|
-
hint = "This model is not in the current OpenAI Codex catalog for this account.
|
|
2211
|
+
hint = "This model is not in the current OpenAI Codex catalog for this account. Switch to gpt-5.6-sol, gpt-5.6-terra, gpt-5.6-luna, or gpt-5.5 via the model selector.";
|
|
2190
2212
|
}
|
|
2191
2213
|
throw new ProviderError("openai", message, {
|
|
2192
2214
|
statusCode: response.status,
|
|
@@ -2610,10 +2632,11 @@ var CODE_ASSIST_SUPPORTED_MODELS = /* @__PURE__ */ new Set([
|
|
|
2610
2632
|
"gemini-3.1-pro-preview",
|
|
2611
2633
|
"gemini-3.1-pro-preview-customtools",
|
|
2612
2634
|
"gemini-3-flash-preview",
|
|
2613
|
-
"gemini-3.
|
|
2635
|
+
"gemini-3.5-flash",
|
|
2636
|
+
"gemini-3-flash",
|
|
2637
|
+
"gemini-3.1-flash-lite",
|
|
2614
2638
|
"gemini-2.5-pro",
|
|
2615
2639
|
"gemini-2.5-flash",
|
|
2616
|
-
"gemini-2.5-flash-lite",
|
|
2617
2640
|
"gemma-4-31b-it",
|
|
2618
2641
|
"gemma-4-26b-a4b-it"
|
|
2619
2642
|
]);
|
|
@@ -2630,6 +2653,18 @@ function getCodeAssistEndpoint(method) {
|
|
|
2630
2653
|
function formatUnsupportedModelMessage(model) {
|
|
2631
2654
|
return `Gemini OAuth is configured to use the Gemini Code Assist subscription endpoint only. That endpoint does not currently expose model "${model}".`;
|
|
2632
2655
|
}
|
|
2656
|
+
var ACCOUNT_GATED_MODELS = /* @__PURE__ */ new Set([
|
|
2657
|
+
"gemini-3-flash",
|
|
2658
|
+
"gemini-3.5-flash",
|
|
2659
|
+
"gemini-3.1-pro-preview",
|
|
2660
|
+
"gemini-3.1-pro-preview-customtools"
|
|
2661
|
+
]);
|
|
2662
|
+
function accountGatedMessage(model) {
|
|
2663
|
+
return `Your Google account isn't entitled to "${model}" over Gemini Code Assist OAuth, so the API reports it as not found. This is an account-access limit, not a ezcoder bug.`;
|
|
2664
|
+
}
|
|
2665
|
+
function accountGatedHint() {
|
|
2666
|
+
return `Newer Gemini models (3.5 Flash, 3.1 Pro Preview) are available only to Code Assist Standard/Enterprise accounts with preview/GA access enabled by a cloud admin \u2014 free/personal accounts usually can't call them. Switch to Gemini 3.1 Flash Lite (it works on this account) with /model, or sign in with a Code Assist Standard/Enterprise account that has preview access.`;
|
|
2667
|
+
}
|
|
2633
2668
|
function formatErrorMessage(status, body, model) {
|
|
2634
2669
|
if (status === 404 && !CODE_ASSIST_SUPPORTED_MODELS.has(model)) {
|
|
2635
2670
|
return `Gemini API error (404): ${body}
|
|
@@ -2940,7 +2975,8 @@ async function fetchCodeAssist(plan, options) {
|
|
|
2940
2975
|
if (!response.ok) {
|
|
2941
2976
|
const text = await response.text().catch(() => "");
|
|
2942
2977
|
const quota = parseGeminiQuota(response.status, text);
|
|
2943
|
-
|
|
2978
|
+
const accountGated = response.status === 404 && ACCOUNT_GATED_MODELS.has(options.model);
|
|
2979
|
+
let message = accountGated ? accountGatedMessage(options.model) : formatErrorMessage(response.status, text, options.model);
|
|
2944
2980
|
let resetsAt;
|
|
2945
2981
|
if (quota?.exhausted) {
|
|
2946
2982
|
message = `Gemini quota exhausted \u2014 usage limit reached. ${message}`;
|
|
@@ -2949,7 +2985,8 @@ async function fetchCodeAssist(plan, options) {
|
|
|
2949
2985
|
}
|
|
2950
2986
|
throw new ProviderError("gemini", message, {
|
|
2951
2987
|
statusCode: response.status,
|
|
2952
|
-
...resetsAt !== void 0 ? { resetsAt } : {}
|
|
2988
|
+
...resetsAt !== void 0 ? { resetsAt } : {},
|
|
2989
|
+
...accountGated ? { hint: accountGatedHint() } : {}
|
|
2953
2990
|
});
|
|
2954
2991
|
}
|
|
2955
2992
|
return response;
|