@prestyj/ai 5.29.0 → 5.30.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 +192 -20
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +20 -1
- package/dist/index.d.ts +20 -1
- package/dist/index.js +189 -19
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -40,6 +40,7 @@ __export(index_exports, {
|
|
|
40
40
|
classifyProviderError: () => classifyProviderError,
|
|
41
41
|
dropInvalidToolCalls: () => dropInvalidToolCalls,
|
|
42
42
|
environmentSecrets: () => environmentSecrets,
|
|
43
|
+
formatChatError: () => formatChatError,
|
|
43
44
|
formatError: () => formatError,
|
|
44
45
|
formatErrorForDisplay: () => formatErrorForDisplay,
|
|
45
46
|
hasLoneSurrogate: () => hasLoneSurrogate,
|
|
@@ -65,7 +66,8 @@ __export(index_exports, {
|
|
|
65
66
|
toAnthropicMessages: () => toAnthropicMessages,
|
|
66
67
|
toOpenAIMessages: () => toOpenAIMessages,
|
|
67
68
|
toWellFormedText: () => toWellFormedText,
|
|
68
|
-
toolCallNameRuleFor: () => toolCallNameRuleFor
|
|
69
|
+
toolCallNameRuleFor: () => toolCallNameRuleFor,
|
|
70
|
+
usesResponsesLite: () => usesResponsesLite
|
|
69
71
|
});
|
|
70
72
|
module.exports = __toCommonJS(index_exports);
|
|
71
73
|
|
|
@@ -1497,6 +1499,10 @@ function toLocalReasoningEffort(level) {
|
|
|
1497
1499
|
function toGlmReasoningEffort(level) {
|
|
1498
1500
|
return level === "ultra" ? "max" : level;
|
|
1499
1501
|
}
|
|
1502
|
+
function toCodexReasoningEffort(level, model) {
|
|
1503
|
+
if (level !== "ultra") return level;
|
|
1504
|
+
return model === "gpt-6-astra" || model === "gpt-6.1-sol" ? "xhigh" : "max";
|
|
1505
|
+
}
|
|
1500
1506
|
function toOpenAIReasoningEffort(level, model) {
|
|
1501
1507
|
const effort = level === "max" || level === "ultra" ? "xhigh" : level;
|
|
1502
1508
|
if (model.startsWith("fugu") && (effort === "low" || effort === "medium")) {
|
|
@@ -2428,7 +2434,7 @@ async function* runStream2(options) {
|
|
|
2428
2434
|
...options.thinking && !usesThinkingParam && !isKimiK3 && !isKimiK27 && !isLocal ? { reasoning_effort: toOpenAIReasoningEffort(options.thinking, options.model) } : {},
|
|
2429
2435
|
...options.tools?.length ? {
|
|
2430
2436
|
tools: toOpenAITools(options.tools, {
|
|
2431
|
-
strict: supportsStrictToolSampling(options.provider)
|
|
2437
|
+
strict: supportsStrictToolSampling(options.provider) && (options.strictTools ?? true)
|
|
2432
2438
|
})
|
|
2433
2439
|
} : {},
|
|
2434
2440
|
...options.toolChoice && options.tools?.length ? { tool_choice: toOpenAIToolChoice(options.toolChoice) } : {},
|
|
@@ -2762,7 +2768,7 @@ function toError2(err, provider = "openai") {
|
|
|
2762
2768
|
const cleanMessage = isRawHtmlErrorEcho(messageCandidate) ? providerHtmlErrorMessage(err.status) : bodyMessage ? bodyMessage : isRawJsonErrorEcho(err.message) ? emptyProviderErrorMessage(err.status) : err.message;
|
|
2763
2769
|
let hint;
|
|
2764
2770
|
if (modelName === "codex-mini-latest" || cleanMessage.includes("codex-mini-latest")) {
|
|
2765
|
-
hint = "codex-mini-latest
|
|
2771
|
+
hint = "This request could not use codex-mini-latest. Check your account access or choose another available model.";
|
|
2766
2772
|
}
|
|
2767
2773
|
const requestId = err.request_id ?? (typeof body?.request_id === "string" ? body.request_id : void 0);
|
|
2768
2774
|
const code = typeof err.code === "string" ? err.code : void 0;
|
|
@@ -2946,6 +2952,7 @@ async function* runStream3(options, retriedWithoutReasoning = false) {
|
|
|
2946
2952
|
const downgraded = downgradeUnsupportedVideos(downgradedImages, options.supportsVideo);
|
|
2947
2953
|
const { system, input } = toCodexInput(downgraded, { supportsImages: options.supportsImages });
|
|
2948
2954
|
const responsesLite = usesResponsesLite(options.model);
|
|
2955
|
+
const liteShape = options.responsesLite ?? responsesLite;
|
|
2949
2956
|
const body = {
|
|
2950
2957
|
model: options.model,
|
|
2951
2958
|
store: false,
|
|
@@ -2953,11 +2960,11 @@ async function* runStream3(options, retriedWithoutReasoning = false) {
|
|
|
2953
2960
|
instructions: system,
|
|
2954
2961
|
input,
|
|
2955
2962
|
tool_choice: toCodexToolChoice(options.toolChoice, options.tools),
|
|
2956
|
-
parallel_tool_calls: !
|
|
2963
|
+
parallel_tool_calls: !liteShape,
|
|
2957
2964
|
include: ["reasoning.encrypted_content"]
|
|
2958
2965
|
};
|
|
2959
2966
|
if (options.tools?.length) {
|
|
2960
|
-
body.tools = toCodexTools(options.tools);
|
|
2967
|
+
body.tools = toCodexTools(options.tools, options.strictTools ?? true);
|
|
2961
2968
|
}
|
|
2962
2969
|
body.prompt_cache_key = normalizePromptCacheKey(options.promptCacheKey ?? "ezcoder");
|
|
2963
2970
|
if (options.temperature != null && !options.thinking) {
|
|
@@ -2967,9 +2974,9 @@ async function* runStream3(options, retriedWithoutReasoning = false) {
|
|
|
2967
2974
|
// GPT-5.6/6 require at least low; older models still support thinking off.
|
|
2968
2975
|
// Apply the floor here for every caller, including one-off prompt rewrites.
|
|
2969
2976
|
// `ultra` is a client orchestration preset, not a Codex API effort.
|
|
2970
|
-
effort: options.thinking
|
|
2977
|
+
effort: options.thinking ? toCodexReasoningEffort(options.thinking, options.model) : responsesLite ? "low" : "none",
|
|
2971
2978
|
summary: "auto",
|
|
2972
|
-
...
|
|
2979
|
+
...liteShape ? { context: "all_turns" } : {}
|
|
2973
2980
|
};
|
|
2974
2981
|
if (responsesLite) {
|
|
2975
2982
|
body.text = { verbosity: "low" };
|
|
@@ -2981,10 +2988,8 @@ async function* runStream3(options, retriedWithoutReasoning = false) {
|
|
|
2981
2988
|
"OpenAI-Beta": "responses=experimental",
|
|
2982
2989
|
originator: responsesLite ? "codex_cli_rs" : "ezcoder",
|
|
2983
2990
|
"User-Agent": responsesLite ? `codex_cli_rs/${CODEX_CLIENT_VERSION}` : `ezcoder (${import_node_os.default.platform()} ${import_node_os.default.release()}; ${import_node_os.default.arch()})`,
|
|
2984
|
-
...responsesLite ? {
|
|
2985
|
-
|
|
2986
|
-
"X-OpenAI-Internal-Codex-Responses-Lite": "true"
|
|
2987
|
-
} : {}
|
|
2991
|
+
...responsesLite ? { version: CODEX_CLIENT_VERSION } : {},
|
|
2992
|
+
...liteShape ? { "X-OpenAI-Internal-Codex-Responses-Lite": "true" } : {}
|
|
2988
2993
|
};
|
|
2989
2994
|
if (options.accountId) {
|
|
2990
2995
|
headers["chatgpt-account-id"] = options.accountId;
|
|
@@ -3030,9 +3035,9 @@ async function* runStream3(options, retriedWithoutReasoning = false) {
|
|
|
3030
3035
|
if (usageLimit) throw usageLimit;
|
|
3031
3036
|
let hint;
|
|
3032
3037
|
if (response.status === 400 && message === `The '${options.model}' model is not supported when using Codex with a ChatGPT account.`) {
|
|
3033
|
-
hint = "This model is not available through your ChatGPT account.
|
|
3038
|
+
hint = "This model is not available through your ChatGPT account. Choose another available model using the model selector.";
|
|
3034
3039
|
} else if (response.status === 404 && text.includes("does not exist")) {
|
|
3035
|
-
hint = "This model is not in OpenAI's current catalog for your ChatGPT account.
|
|
3040
|
+
hint = "This model is not in OpenAI's current catalog for your ChatGPT account. Choose another available model using the model selector.";
|
|
3036
3041
|
}
|
|
3037
3042
|
throw new ProviderError("openai", message, {
|
|
3038
3043
|
statusCode: response.status,
|
|
@@ -3448,15 +3453,17 @@ function toCodexInput(messages, options) {
|
|
|
3448
3453
|
}
|
|
3449
3454
|
return { system, input };
|
|
3450
3455
|
}
|
|
3451
|
-
function toCodexTools(tools) {
|
|
3456
|
+
function toCodexTools(tools, strictTools) {
|
|
3452
3457
|
return tools.map((tool) => {
|
|
3453
3458
|
let parameters = resolveToolSchema(tool);
|
|
3454
3459
|
let strict = null;
|
|
3455
|
-
|
|
3456
|
-
|
|
3457
|
-
|
|
3458
|
-
|
|
3459
|
-
|
|
3460
|
+
if (strictTools) {
|
|
3461
|
+
try {
|
|
3462
|
+
parameters = makeStrictToolSchema(parameters);
|
|
3463
|
+
strict = true;
|
|
3464
|
+
} catch (error) {
|
|
3465
|
+
if (!(error instanceof UnsupportedStrictSchemaError)) throw error;
|
|
3466
|
+
}
|
|
3460
3467
|
}
|
|
3461
3468
|
return {
|
|
3462
3469
|
type: "function",
|
|
@@ -3503,6 +3510,7 @@ function codexUsageLimitError(errorObj, statusCode, requestId) {
|
|
|
3503
3510
|
const isRateOr429 = CODEX_RATE_LIMIT_CODE.test(code) || statusCode === 429;
|
|
3504
3511
|
if (!isHardUsage && !(isRateOr429 && resetsAt != null)) return null;
|
|
3505
3512
|
return new ProviderError("openai", "ChatGPT usage limit reached", {
|
|
3513
|
+
cause: errorObj,
|
|
3506
3514
|
statusCode: statusCode ?? 429,
|
|
3507
3515
|
...requestId ? { requestId } : {},
|
|
3508
3516
|
...resetsAt ? { resetsAt } : {}
|
|
@@ -3693,6 +3701,17 @@ function stripUnsupportedSchemaFields(value) {
|
|
|
3693
3701
|
}
|
|
3694
3702
|
delete value.$schema;
|
|
3695
3703
|
delete value.additionalProperties;
|
|
3704
|
+
for (const [key, target, step] of [
|
|
3705
|
+
["exclusiveMinimum", "minimum", 1],
|
|
3706
|
+
["exclusiveMaximum", "maximum", -1]
|
|
3707
|
+
]) {
|
|
3708
|
+
const bound = value[key];
|
|
3709
|
+
if (bound === void 0) continue;
|
|
3710
|
+
delete value[key];
|
|
3711
|
+
if (typeof bound === "number" && value[target] === void 0) {
|
|
3712
|
+
value[target] = value.type === "integer" ? bound + step : bound;
|
|
3713
|
+
}
|
|
3714
|
+
}
|
|
3696
3715
|
for (const item of Object.values(value)) {
|
|
3697
3716
|
if (isJsonObject(item) || Array.isArray(item)) {
|
|
3698
3717
|
stripUnsupportedSchemaFields(item);
|
|
@@ -4422,6 +4441,157 @@ function messagesContainVideo(messages) {
|
|
|
4422
4441
|
return false;
|
|
4423
4442
|
}
|
|
4424
4443
|
|
|
4444
|
+
// src/chat-error.ts
|
|
4445
|
+
function causeCode(error) {
|
|
4446
|
+
if (!(error instanceof Error) || !error.cause || typeof error.cause !== "object") return "";
|
|
4447
|
+
const cause = error.cause;
|
|
4448
|
+
if ("code" in cause && typeof cause.code === "string") return cause.code;
|
|
4449
|
+
if ("type" in cause && typeof cause.type === "string") return cause.type;
|
|
4450
|
+
return "";
|
|
4451
|
+
}
|
|
4452
|
+
function formatChatError(error) {
|
|
4453
|
+
const base = formatError(error);
|
|
4454
|
+
const raw = error instanceof Error ? error.message : "";
|
|
4455
|
+
const code = causeCode(error);
|
|
4456
|
+
const text = `${code} ${raw}`.toLowerCase();
|
|
4457
|
+
const provider = /chatgpt/i.test(raw) ? "ChatGPT" : providerLabel(base.provider);
|
|
4458
|
+
const present = (reason, headline, guidance) => ({
|
|
4459
|
+
...base,
|
|
4460
|
+
...raw ? { message: raw } : {},
|
|
4461
|
+
reason,
|
|
4462
|
+
headline,
|
|
4463
|
+
guidance
|
|
4464
|
+
});
|
|
4465
|
+
if (error instanceof VideoUnsupportedError) {
|
|
4466
|
+
return present(
|
|
4467
|
+
"capability",
|
|
4468
|
+
"This model can\u2019t read this video",
|
|
4469
|
+
"Choose a model that supports video."
|
|
4470
|
+
);
|
|
4471
|
+
}
|
|
4472
|
+
if (base.source === "capability") {
|
|
4473
|
+
return present(
|
|
4474
|
+
"unknown",
|
|
4475
|
+
"This request isn\u2019t supported",
|
|
4476
|
+
"Open details to check the request requirements."
|
|
4477
|
+
);
|
|
4478
|
+
}
|
|
4479
|
+
if (/requires a newer version of codex/.test(text)) {
|
|
4480
|
+
return present(
|
|
4481
|
+
"update",
|
|
4482
|
+
"EZ Coder needs an update",
|
|
4483
|
+
"Update the app, or choose another model."
|
|
4484
|
+
);
|
|
4485
|
+
}
|
|
4486
|
+
if (/insufficient.*(?:balance|credits?)|(?:balance|credits?).*(?:insufficient|exhausted|depleted)|credit balance is too low|payment_required/.test(
|
|
4487
|
+
text
|
|
4488
|
+
)) {
|
|
4489
|
+
return present(
|
|
4490
|
+
"billing",
|
|
4491
|
+
`${provider} credits are unavailable`,
|
|
4492
|
+
"Check your balance and billing, or use another provider."
|
|
4493
|
+
);
|
|
4494
|
+
}
|
|
4495
|
+
if (/usage_not_included|does not yet include access|not supported when using codex with a chatgpt account|(?:model[^\n]*(?:not found|not available|does not exist))|model_not_found/.test(
|
|
4496
|
+
text
|
|
4497
|
+
)) {
|
|
4498
|
+
return present(
|
|
4499
|
+
"model_access",
|
|
4500
|
+
"This model isn\u2019t available to this account",
|
|
4501
|
+
"Choose another model available to your account."
|
|
4502
|
+
);
|
|
4503
|
+
}
|
|
4504
|
+
if (/insufficient_quota|exceeded your current quota|billing.?limit|spend.?limit|quota.?exceeded/.test(
|
|
4505
|
+
text
|
|
4506
|
+
)) {
|
|
4507
|
+
return present(
|
|
4508
|
+
"quota",
|
|
4509
|
+
`${provider} quota is unavailable`,
|
|
4510
|
+
"Check your plan or billing, or use another provider."
|
|
4511
|
+
);
|
|
4512
|
+
}
|
|
4513
|
+
if (/^rate_limit_exceeded$/i.test(code)) {
|
|
4514
|
+
return present(
|
|
4515
|
+
"rate_limit",
|
|
4516
|
+
`${provider} is limiting requests`,
|
|
4517
|
+
"Wait a moment before trying again."
|
|
4518
|
+
);
|
|
4519
|
+
}
|
|
4520
|
+
if (/usage limit reached|usage_limit_reached/.test(text)) {
|
|
4521
|
+
return present(
|
|
4522
|
+
"usage_limit",
|
|
4523
|
+
`${provider} usage limit reached`,
|
|
4524
|
+
"Wait for the reset, or use another provider."
|
|
4525
|
+
);
|
|
4526
|
+
}
|
|
4527
|
+
if (base.source === "network") {
|
|
4528
|
+
return present(
|
|
4529
|
+
"network",
|
|
4530
|
+
"Couldn\u2019t reach the provider",
|
|
4531
|
+
"Check your connection before trying again."
|
|
4532
|
+
);
|
|
4533
|
+
}
|
|
4534
|
+
if (base.source === "auth" || base.statusCode === 401) {
|
|
4535
|
+
return present(
|
|
4536
|
+
"auth",
|
|
4537
|
+
`${provider} sign-in needs attention`,
|
|
4538
|
+
"Reconnect your account in provider settings."
|
|
4539
|
+
);
|
|
4540
|
+
}
|
|
4541
|
+
if (base.statusCode === 413 || /context[_ ](?:length|window)|maximum context|request_too_large|prompt is too long/.test(text)) {
|
|
4542
|
+
return present(
|
|
4543
|
+
"context",
|
|
4544
|
+
"This conversation is too large",
|
|
4545
|
+
"Compact the conversation or send a smaller request."
|
|
4546
|
+
);
|
|
4547
|
+
}
|
|
4548
|
+
if (base.statusCode === 429 || /rate_limit|rate limit|too many requests/.test(text)) {
|
|
4549
|
+
return present(
|
|
4550
|
+
"rate_limit",
|
|
4551
|
+
`${provider} is limiting requests`,
|
|
4552
|
+
"Wait a moment before trying again."
|
|
4553
|
+
);
|
|
4554
|
+
}
|
|
4555
|
+
if (base.statusCode === 403) {
|
|
4556
|
+
return present(
|
|
4557
|
+
"model_access",
|
|
4558
|
+
"This account can\u2019t use this request",
|
|
4559
|
+
"Check account access or choose another model."
|
|
4560
|
+
);
|
|
4561
|
+
}
|
|
4562
|
+
if (error instanceof ProviderError) {
|
|
4563
|
+
if (base.statusCode != null && base.statusCode >= 500) {
|
|
4564
|
+
return present(
|
|
4565
|
+
"provider",
|
|
4566
|
+
`${provider} couldn\u2019t complete the request`,
|
|
4567
|
+
"Try again later. Check details if it keeps happening."
|
|
4568
|
+
);
|
|
4569
|
+
}
|
|
4570
|
+
return present(
|
|
4571
|
+
"provider",
|
|
4572
|
+
`${provider} didn\u2019t accept the request`,
|
|
4573
|
+
"Check the details before trying again."
|
|
4574
|
+
);
|
|
4575
|
+
}
|
|
4576
|
+
return present("unknown", "Something went wrong", "Open details to see what was reported.");
|
|
4577
|
+
}
|
|
4578
|
+
function providerLabel(provider) {
|
|
4579
|
+
switch (provider) {
|
|
4580
|
+
case "openai":
|
|
4581
|
+
return "OpenAI";
|
|
4582
|
+
case "anthropic":
|
|
4583
|
+
return "Anthropic";
|
|
4584
|
+
case "gemini":
|
|
4585
|
+
return "Gemini";
|
|
4586
|
+
case "xai":
|
|
4587
|
+
return "xAI";
|
|
4588
|
+
case "local":
|
|
4589
|
+
return "The local server";
|
|
4590
|
+
default:
|
|
4591
|
+
return "The provider";
|
|
4592
|
+
}
|
|
4593
|
+
}
|
|
4594
|
+
|
|
4425
4595
|
// src/error-classification.ts
|
|
4426
4596
|
var CONTEXT_OVERFLOW_PATTERNS = [
|
|
4427
4597
|
/context_length_exceeded/i,
|
|
@@ -4812,6 +4982,7 @@ function registerPalsuProvider(config) {
|
|
|
4812
4982
|
classifyProviderError,
|
|
4813
4983
|
dropInvalidToolCalls,
|
|
4814
4984
|
environmentSecrets,
|
|
4985
|
+
formatChatError,
|
|
4815
4986
|
formatError,
|
|
4816
4987
|
formatErrorForDisplay,
|
|
4817
4988
|
hasLoneSurrogate,
|
|
@@ -4837,6 +5008,7 @@ function registerPalsuProvider(config) {
|
|
|
4837
5008
|
toAnthropicMessages,
|
|
4838
5009
|
toOpenAIMessages,
|
|
4839
5010
|
toWellFormedText,
|
|
4840
|
-
toolCallNameRuleFor
|
|
5011
|
+
toolCallNameRuleFor,
|
|
5012
|
+
usesResponsesLite
|
|
4841
5013
|
});
|
|
4842
5014
|
//# sourceMappingURL=index.cjs.map
|