@prestyj/ai 5.16.1 → 5.17.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 +179 -34
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +179 -34
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -235,6 +235,9 @@ function providerGuidance(provider, message, statusCode) {
|
|
|
235
235
|
if (statusCode === 401 || lower.includes("unauthorized") || lower.includes("invalid api key")) {
|
|
236
236
|
return `Authentication failed with ${name}. Re-authenticate to refresh your credentials.`;
|
|
237
237
|
}
|
|
238
|
+
if (lower.includes("requires a newer version")) {
|
|
239
|
+
return `${name} needs a newer EZ Coder to serve this model. Update EZ Coder to the latest version and retry, or switch to another ${name} model via the model selector.`;
|
|
240
|
+
}
|
|
238
241
|
if (lower.includes("overloaded") || lower.includes("engine_overloaded")) {
|
|
239
242
|
return `${name}'s servers are overloaded right now. Retry in a moment \u2014 not a EZ Coder issue.`;
|
|
240
243
|
}
|
|
@@ -502,6 +505,108 @@ function normalizeRootForAnthropic(schema) {
|
|
|
502
505
|
return out;
|
|
503
506
|
}
|
|
504
507
|
|
|
508
|
+
// src/utils/strict-tool-schema.ts
|
|
509
|
+
var UnsupportedStrictSchemaError = class extends Error {
|
|
510
|
+
};
|
|
511
|
+
var UNSUPPORTED_KEYS = [
|
|
512
|
+
"$ref",
|
|
513
|
+
"$defs",
|
|
514
|
+
"definitions",
|
|
515
|
+
"allOf",
|
|
516
|
+
"oneOf",
|
|
517
|
+
"patternProperties",
|
|
518
|
+
"dependentSchemas",
|
|
519
|
+
"dependencies",
|
|
520
|
+
"unevaluatedProperties",
|
|
521
|
+
"propertyNames",
|
|
522
|
+
"contains",
|
|
523
|
+
"prefixItems",
|
|
524
|
+
"not",
|
|
525
|
+
"if",
|
|
526
|
+
"then",
|
|
527
|
+
"else"
|
|
528
|
+
];
|
|
529
|
+
function isSchemaObject(value) {
|
|
530
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
531
|
+
}
|
|
532
|
+
function isStructured(value) {
|
|
533
|
+
if (!isSchemaObject(value)) return false;
|
|
534
|
+
const types = typeof value.type === "string" ? [value.type] : Array.isArray(value.type) ? value.type : [];
|
|
535
|
+
return types.includes("object") || types.includes("array") || value.properties !== void 0 || value.items !== void 0;
|
|
536
|
+
}
|
|
537
|
+
function allowsNull(schema) {
|
|
538
|
+
if (!isSchemaObject(schema)) return false;
|
|
539
|
+
if (schema.type === "null" || Array.isArray(schema.type) && schema.type.includes("null"))
|
|
540
|
+
return true;
|
|
541
|
+
if (schema.const === null || Array.isArray(schema.enum) && schema.enum.includes(null))
|
|
542
|
+
return true;
|
|
543
|
+
return Array.isArray(schema.anyOf) && schema.anyOf.some((variant) => allowsNull(variant));
|
|
544
|
+
}
|
|
545
|
+
function makeNodeStrict(schema) {
|
|
546
|
+
if (!isSchemaObject(schema)) {
|
|
547
|
+
throw new UnsupportedStrictSchemaError("boolean schemas are unsupported");
|
|
548
|
+
}
|
|
549
|
+
for (const key of UNSUPPORTED_KEYS) {
|
|
550
|
+
if (schema[key] !== void 0) {
|
|
551
|
+
throw new UnsupportedStrictSchemaError(`${key} schemas are unsupported`);
|
|
552
|
+
}
|
|
553
|
+
}
|
|
554
|
+
if (schema.anyOf !== void 0) {
|
|
555
|
+
if (!Array.isArray(schema.anyOf) || schema.anyOf.length === 0) {
|
|
556
|
+
throw new UnsupportedStrictSchemaError("anyOf must contain at least one schema");
|
|
557
|
+
}
|
|
558
|
+
for (const variant of schema.anyOf) {
|
|
559
|
+
if (isStructured(variant)) {
|
|
560
|
+
throw new UnsupportedStrictSchemaError("object and array unions are unsupported");
|
|
561
|
+
}
|
|
562
|
+
makeNodeStrict(variant);
|
|
563
|
+
}
|
|
564
|
+
}
|
|
565
|
+
if (schema.items !== void 0) {
|
|
566
|
+
if (Array.isArray(schema.items)) {
|
|
567
|
+
throw new UnsupportedStrictSchemaError("tuple schemas are unsupported");
|
|
568
|
+
}
|
|
569
|
+
makeNodeStrict(schema.items);
|
|
570
|
+
}
|
|
571
|
+
const isObjectSchema = schema.type === "object";
|
|
572
|
+
if (schema.properties !== void 0 && !isObjectSchema) {
|
|
573
|
+
throw new UnsupportedStrictSchemaError("properties require type object");
|
|
574
|
+
}
|
|
575
|
+
if (!isObjectSchema) return;
|
|
576
|
+
if (schema.additionalProperties !== void 0 && schema.additionalProperties !== false) {
|
|
577
|
+
throw new UnsupportedStrictSchemaError(
|
|
578
|
+
"schema-valued or true additionalProperties is unsupported"
|
|
579
|
+
);
|
|
580
|
+
}
|
|
581
|
+
if (schema.properties !== void 0 && !isSchemaObject(schema.properties)) {
|
|
582
|
+
throw new UnsupportedStrictSchemaError("object properties must be a schema map");
|
|
583
|
+
}
|
|
584
|
+
const properties = schema.properties ?? {};
|
|
585
|
+
const required = new Set(Array.isArray(schema.required) ? schema.required : []);
|
|
586
|
+
for (const [key, property] of Object.entries(properties)) {
|
|
587
|
+
makeNodeStrict(property);
|
|
588
|
+
if (!required.has(key) && !allowsNull(property)) {
|
|
589
|
+
properties[key] = { anyOf: [property, { type: "null" }] };
|
|
590
|
+
}
|
|
591
|
+
}
|
|
592
|
+
schema.required = Object.keys(properties);
|
|
593
|
+
schema.additionalProperties = false;
|
|
594
|
+
}
|
|
595
|
+
function supportsStrictToolSampling(provider) {
|
|
596
|
+
return provider === "openai";
|
|
597
|
+
}
|
|
598
|
+
function makeStrictToolSchema(schema) {
|
|
599
|
+
const cloned = structuredClone(schema);
|
|
600
|
+
if (!isSchemaObject(cloned)) {
|
|
601
|
+
throw new UnsupportedStrictSchemaError("root schema must be an object");
|
|
602
|
+
}
|
|
603
|
+
makeNodeStrict(cloned);
|
|
604
|
+
if (cloned.type !== "object") {
|
|
605
|
+
throw new UnsupportedStrictSchemaError("root schema must have type object");
|
|
606
|
+
}
|
|
607
|
+
return cloned;
|
|
608
|
+
}
|
|
609
|
+
|
|
505
610
|
// src/providers/reasoning-field.ts
|
|
506
611
|
var REASONING_FIELD_ALIASES = [
|
|
507
612
|
"reasoning_content",
|
|
@@ -982,7 +1087,7 @@ function toOpenAIMessages(messages, options) {
|
|
|
982
1087
|
(part) => {
|
|
983
1088
|
if (part.type === "text") return { type: "text", text: part.text };
|
|
984
1089
|
if (part.type === "video") {
|
|
985
|
-
const videoUrl = part.fileId ? { url: `ms://${part.fileId}`, id: part.fileId } : { url: `data:${part.mediaType};base64,${part.data}` };
|
|
1090
|
+
const videoUrl = options?.provider === "moonshot" && part.fileId ? { url: `ms://${part.fileId}`, id: part.fileId } : { url: `data:${part.mediaType};base64,${part.data}` };
|
|
986
1091
|
return {
|
|
987
1092
|
type: "video_url",
|
|
988
1093
|
video_url: videoUrl
|
|
@@ -1086,15 +1191,28 @@ function toOpenAIMessages(messages, options) {
|
|
|
1086
1191
|
}
|
|
1087
1192
|
return out;
|
|
1088
1193
|
}
|
|
1089
|
-
function toOpenAITools(tools) {
|
|
1090
|
-
return tools.map((tool) =>
|
|
1091
|
-
|
|
1092
|
-
|
|
1093
|
-
|
|
1094
|
-
|
|
1095
|
-
|
|
1194
|
+
function toOpenAITools(tools, opts) {
|
|
1195
|
+
return tools.map((tool) => {
|
|
1196
|
+
let parameters = resolveToolSchema(tool);
|
|
1197
|
+
let strict;
|
|
1198
|
+
if (opts?.strict) {
|
|
1199
|
+
try {
|
|
1200
|
+
parameters = makeStrictToolSchema(parameters);
|
|
1201
|
+
strict = true;
|
|
1202
|
+
} catch (error) {
|
|
1203
|
+
if (!(error instanceof UnsupportedStrictSchemaError)) throw error;
|
|
1204
|
+
}
|
|
1096
1205
|
}
|
|
1097
|
-
|
|
1206
|
+
return {
|
|
1207
|
+
type: "function",
|
|
1208
|
+
function: {
|
|
1209
|
+
name: tool.name,
|
|
1210
|
+
description: tool.description,
|
|
1211
|
+
parameters,
|
|
1212
|
+
...strict ? { strict } : {}
|
|
1213
|
+
}
|
|
1214
|
+
};
|
|
1215
|
+
});
|
|
1098
1216
|
}
|
|
1099
1217
|
function toOpenAIToolChoice(choice) {
|
|
1100
1218
|
if (choice === "auto") return "auto";
|
|
@@ -1921,7 +2039,7 @@ async function* runStream2(options) {
|
|
|
1921
2039
|
const k3Effort = options.thinking ? toKimiK3Effort(options.thinking) : void 0;
|
|
1922
2040
|
const isKimiK27 = options.provider === "moonshot" && options.model.startsWith("kimi-k2.7-code");
|
|
1923
2041
|
const hasFixedKimiSampling = isKimiK3 || isKimiK27;
|
|
1924
|
-
const usesThinkingParam = options.provider === "glm" || options.provider === "moonshot" && !isKimiK3 && !isKimiK27 || options.provider === "xiaomi";
|
|
2042
|
+
const usesThinkingParam = options.provider === "deepseek" || options.provider === "glm" || options.provider === "moonshot" && !isKimiK3 && !isKimiK27 || options.provider === "xiaomi";
|
|
1925
2043
|
const downgradedImages = downgradeUnsupportedImages(options.messages, options.supportsImages);
|
|
1926
2044
|
const downgradedMessages = downgradeUnsupportedVideos(downgradedImages, options.supportsVideo);
|
|
1927
2045
|
if (options.provider === "moonshot") {
|
|
@@ -1947,19 +2065,23 @@ async function* runStream2(options) {
|
|
|
1947
2065
|
model: options.model,
|
|
1948
2066
|
messages,
|
|
1949
2067
|
stream: useStreaming,
|
|
1950
|
-
...options.maxTokens ? { max_completion_tokens: options.maxTokens } : {},
|
|
2068
|
+
...options.maxTokens ? options.provider === "deepseek" || options.provider === "glm" || options.provider === "moonshot" ? { max_tokens: options.maxTokens } : { max_completion_tokens: options.maxTokens } : {},
|
|
1951
2069
|
...effectiveTemp != null && !options.thinking && !hasFixedKimiSampling ? { temperature: effectiveTemp } : {},
|
|
1952
2070
|
...options.topP != null && !hasFixedKimiSampling ? { top_p: options.topP } : {},
|
|
1953
2071
|
...options.stop ? { stop: options.stop } : {},
|
|
1954
2072
|
...options.thinking && !usesThinkingParam && !isKimiK3 && !isKimiK27 && !isLocal ? { reasoning_effort: toOpenAIReasoningEffort(options.thinking, options.model) } : {},
|
|
1955
|
-
...options.tools?.length ? {
|
|
2073
|
+
...options.tools?.length ? {
|
|
2074
|
+
tools: toOpenAITools(options.tools, {
|
|
2075
|
+
strict: supportsStrictToolSampling(options.provider)
|
|
2076
|
+
})
|
|
2077
|
+
} : {},
|
|
1956
2078
|
...options.toolChoice && options.tools?.length ? { tool_choice: toOpenAIToolChoice(options.toolChoice) } : {},
|
|
1957
2079
|
...useStreaming ? { stream_options: { include_usage: true } } : {}
|
|
1958
2080
|
};
|
|
1959
2081
|
if (options.provider === "openai" || options.provider === "moonshot") {
|
|
1960
2082
|
const paramsAny = params;
|
|
1961
2083
|
paramsAny.prompt_cache_key = normalizePromptCacheKey(options.promptCacheKey ?? "ezcoder");
|
|
1962
|
-
if (options.provider === "openai" && options.model.startsWith("gpt-5.6")) {
|
|
2084
|
+
if (options.provider === "openai" && (options.model.startsWith("gpt-5.6") || options.model.startsWith("gpt-6"))) {
|
|
1963
2085
|
paramsAny.prompt_cache_options = { mode: "implicit", ttl: "30m" };
|
|
1964
2086
|
} else if (!isKimiK3 && (options.cacheRetention ?? "short") === "long") {
|
|
1965
2087
|
paramsAny.prompt_cache_retention = "24h";
|
|
@@ -1970,6 +2092,9 @@ async function* runStream2(options) {
|
|
|
1970
2092
|
options.thinking
|
|
1971
2093
|
);
|
|
1972
2094
|
}
|
|
2095
|
+
if (options.provider === "sakana" && options.model === "fugu-ultra" && (options.thinking === "max" || options.thinking === "ultra")) {
|
|
2096
|
+
params.reasoning_effort = "max";
|
|
2097
|
+
}
|
|
1973
2098
|
if (options.provider === "openai" && options.serviceTier) {
|
|
1974
2099
|
params.service_tier = options.serviceTier;
|
|
1975
2100
|
}
|
|
@@ -1986,7 +2111,9 @@ async function* runStream2(options) {
|
|
|
1986
2111
|
if (usesThinkingParam) {
|
|
1987
2112
|
if (options.thinking) {
|
|
1988
2113
|
params.thinking = { type: "enabled" };
|
|
1989
|
-
if (options.provider === "
|
|
2114
|
+
if (options.provider === "deepseek") {
|
|
2115
|
+
params.reasoning_effort = options.thinking === "low" ? "low" : options.thinking === "medium" || options.thinking === "high" ? "high" : "max";
|
|
2116
|
+
} else if (options.provider === "glm") {
|
|
1990
2117
|
params.reasoning_effort = toGlmReasoningEffort(
|
|
1991
2118
|
options.thinking
|
|
1992
2119
|
);
|
|
@@ -2381,7 +2508,7 @@ function extractRequestIdFromMessage(message) {
|
|
|
2381
2508
|
|
|
2382
2509
|
// src/providers/openai-codex.ts
|
|
2383
2510
|
var DEFAULT_BASE_URL = "https://chatgpt.com/backend-api";
|
|
2384
|
-
var CODEX_CLIENT_VERSION = "0.
|
|
2511
|
+
var CODEX_CLIENT_VERSION = "0.153.4";
|
|
2385
2512
|
var CODEX_REQUEST_COMPRESSION_MIN_BYTES = 16 * 1024;
|
|
2386
2513
|
var zstdInitPromise;
|
|
2387
2514
|
async function encodeCodexRequest(body) {
|
|
@@ -2427,7 +2554,7 @@ async function encodeCodexRequest(body) {
|
|
|
2427
2554
|
}
|
|
2428
2555
|
}
|
|
2429
2556
|
function usesResponsesLite(model) {
|
|
2430
|
-
return model.startsWith("gpt-5.6-");
|
|
2557
|
+
return model.startsWith("gpt-5.6-") || model.startsWith("gpt-6-");
|
|
2431
2558
|
}
|
|
2432
2559
|
function outputTextKey(itemId, contentIndex) {
|
|
2433
2560
|
return `${itemId ?? ""}:${contentIndex ?? 0}`;
|
|
@@ -2481,8 +2608,10 @@ async function* runStream3(options) {
|
|
|
2481
2608
|
body.temperature = options.temperature;
|
|
2482
2609
|
}
|
|
2483
2610
|
body.reasoning = {
|
|
2611
|
+
// GPT-5.6/6 require at least low; older models still support thinking off.
|
|
2612
|
+
// Apply the floor here for every caller, including one-off prompt rewrites.
|
|
2484
2613
|
// `ultra` is a client orchestration preset, not a Codex API effort.
|
|
2485
|
-
effort: options.thinking === "ultra" ? "max" : options.thinking ?? "none",
|
|
2614
|
+
effort: options.thinking === "ultra" ? "max" : options.thinking ?? (responsesLite ? "low" : "none"),
|
|
2486
2615
|
summary: "auto",
|
|
2487
2616
|
...responsesLite ? { context: "all_turns" } : {}
|
|
2488
2617
|
};
|
|
@@ -2527,14 +2656,10 @@ async function* runStream3(options) {
|
|
|
2527
2656
|
const usageLimit = codexUsageLimitError(parsed.errorObj, response.status, requestId);
|
|
2528
2657
|
if (usageLimit) throw usageLimit;
|
|
2529
2658
|
let hint;
|
|
2530
|
-
if (response.status === 400 &&
|
|
2531
|
-
|
|
2532
|
-
hint = "Use gpt-5.5 instead. OpenAI's Codex model catalog does not list gpt-5.5-pro.";
|
|
2533
|
-
} else {
|
|
2534
|
-
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.";
|
|
2535
|
-
}
|
|
2659
|
+
if (response.status === 400 && message === `The '${options.model}' model is not supported when using Codex with a ChatGPT account.`) {
|
|
2660
|
+
hint = "This model is not available through your ChatGPT account. Switch to a model listed for OpenAI via the model selector, or check your ChatGPT usage limits.";
|
|
2536
2661
|
} else if (response.status === 404 && text.includes("does not exist")) {
|
|
2537
|
-
hint = "This model is not in
|
|
2662
|
+
hint = "This model is not in OpenAI's current catalog for your ChatGPT account. Switch to GPT-6 Astra, GPT-5.6 Sol, GPT-5.6 Terra, or GPT-5.6 Luna via the model selector.";
|
|
2538
2663
|
}
|
|
2539
2664
|
throw new ProviderError("openai", message, {
|
|
2540
2665
|
statusCode: response.status,
|
|
@@ -2907,13 +3032,23 @@ function toCodexInput(messages, options) {
|
|
|
2907
3032
|
return { system, input };
|
|
2908
3033
|
}
|
|
2909
3034
|
function toCodexTools(tools) {
|
|
2910
|
-
return tools.map((tool) =>
|
|
2911
|
-
|
|
2912
|
-
|
|
2913
|
-
|
|
2914
|
-
|
|
2915
|
-
|
|
2916
|
-
|
|
3035
|
+
return tools.map((tool) => {
|
|
3036
|
+
let parameters = resolveToolSchema(tool);
|
|
3037
|
+
let strict = null;
|
|
3038
|
+
try {
|
|
3039
|
+
parameters = makeStrictToolSchema(parameters);
|
|
3040
|
+
strict = true;
|
|
3041
|
+
} catch (error) {
|
|
3042
|
+
if (!(error instanceof UnsupportedStrictSchemaError)) throw error;
|
|
3043
|
+
}
|
|
3044
|
+
return {
|
|
3045
|
+
type: "function",
|
|
3046
|
+
name: tool.name,
|
|
3047
|
+
description: tool.description,
|
|
3048
|
+
parameters,
|
|
3049
|
+
strict
|
|
3050
|
+
};
|
|
3051
|
+
});
|
|
2917
3052
|
}
|
|
2918
3053
|
function parseCodexErrorBody(text, statusCode) {
|
|
2919
3054
|
if (!text) return {};
|
|
@@ -2974,6 +3109,8 @@ var CODE_ASSIST_SUPPORTED_MODELS = /* @__PURE__ */ new Set([
|
|
|
2974
3109
|
"gemini-3-flash",
|
|
2975
3110
|
"gemini-3.1-flash-lite",
|
|
2976
3111
|
"gemini-3.7-flash",
|
|
3112
|
+
"gemini-3.8-flash",
|
|
3113
|
+
"gemini-3.5-flash-lite",
|
|
2977
3114
|
"gemini-2.5-pro",
|
|
2978
3115
|
"gemini-2.5-flash",
|
|
2979
3116
|
"gemma-4-31b-it",
|
|
@@ -2997,12 +3134,20 @@ var ACCOUNT_GATED_MODELS = /* @__PURE__ */ new Set([
|
|
|
2997
3134
|
"gemini-3.5-flash",
|
|
2998
3135
|
"gemini-3.1-pro-preview",
|
|
2999
3136
|
"gemini-3.1-pro-preview-customtools",
|
|
3000
|
-
"gemini-3.7-flash"
|
|
3137
|
+
"gemini-3.7-flash",
|
|
3138
|
+
"gemini-3.8-flash",
|
|
3139
|
+
"gemini-3.5-flash-lite"
|
|
3001
3140
|
]);
|
|
3002
3141
|
function accountGatedMessage(model) {
|
|
3142
|
+
if (model === "gemini-3.8-flash" || model === "gemini-3.5-flash-lite") {
|
|
3143
|
+
return `${model} is not available through Code Assist for this account. Public Gemini API availability does not guarantee Code Assist OAuth access.`;
|
|
3144
|
+
}
|
|
3003
3145
|
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.`;
|
|
3004
3146
|
}
|
|
3005
|
-
function accountGatedHint() {
|
|
3147
|
+
function accountGatedHint(model) {
|
|
3148
|
+
if (model === "gemini-3.8-flash" || model === "gemini-3.5-flash-lite") {
|
|
3149
|
+
return "Use /model to select Gemini 3.1 Flash Lite, or retry once Google enables this model through Code Assist for your account.";
|
|
3150
|
+
}
|
|
3006
3151
|
return `Newer Gemini models (3.7 Flash, 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.`;
|
|
3007
3152
|
}
|
|
3008
3153
|
function formatErrorMessage(status, body, model) {
|
|
@@ -3328,7 +3473,7 @@ async function fetchCodeAssist(plan, options) {
|
|
|
3328
3473
|
throw new ProviderError("gemini", message, {
|
|
3329
3474
|
statusCode: response.status,
|
|
3330
3475
|
...resetsAt !== void 0 ? { resetsAt } : {},
|
|
3331
|
-
...accountGated ? { hint: accountGatedHint() } : {}
|
|
3476
|
+
...accountGated ? { hint: accountGatedHint(options.model) } : {}
|
|
3332
3477
|
});
|
|
3333
3478
|
}
|
|
3334
3479
|
return response;
|