@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.cjs
CHANGED
|
@@ -302,6 +302,9 @@ function providerGuidance(provider, message, statusCode) {
|
|
|
302
302
|
if (statusCode === 401 || lower.includes("unauthorized") || lower.includes("invalid api key")) {
|
|
303
303
|
return `Authentication failed with ${name}. Re-authenticate to refresh your credentials.`;
|
|
304
304
|
}
|
|
305
|
+
if (lower.includes("requires a newer version")) {
|
|
306
|
+
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.`;
|
|
307
|
+
}
|
|
305
308
|
if (lower.includes("overloaded") || lower.includes("engine_overloaded")) {
|
|
306
309
|
return `${name}'s servers are overloaded right now. Retry in a moment \u2014 not a EZ Coder issue.`;
|
|
307
310
|
}
|
|
@@ -569,6 +572,108 @@ function normalizeRootForAnthropic(schema) {
|
|
|
569
572
|
return out;
|
|
570
573
|
}
|
|
571
574
|
|
|
575
|
+
// src/utils/strict-tool-schema.ts
|
|
576
|
+
var UnsupportedStrictSchemaError = class extends Error {
|
|
577
|
+
};
|
|
578
|
+
var UNSUPPORTED_KEYS = [
|
|
579
|
+
"$ref",
|
|
580
|
+
"$defs",
|
|
581
|
+
"definitions",
|
|
582
|
+
"allOf",
|
|
583
|
+
"oneOf",
|
|
584
|
+
"patternProperties",
|
|
585
|
+
"dependentSchemas",
|
|
586
|
+
"dependencies",
|
|
587
|
+
"unevaluatedProperties",
|
|
588
|
+
"propertyNames",
|
|
589
|
+
"contains",
|
|
590
|
+
"prefixItems",
|
|
591
|
+
"not",
|
|
592
|
+
"if",
|
|
593
|
+
"then",
|
|
594
|
+
"else"
|
|
595
|
+
];
|
|
596
|
+
function isSchemaObject(value) {
|
|
597
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
598
|
+
}
|
|
599
|
+
function isStructured(value) {
|
|
600
|
+
if (!isSchemaObject(value)) return false;
|
|
601
|
+
const types = typeof value.type === "string" ? [value.type] : Array.isArray(value.type) ? value.type : [];
|
|
602
|
+
return types.includes("object") || types.includes("array") || value.properties !== void 0 || value.items !== void 0;
|
|
603
|
+
}
|
|
604
|
+
function allowsNull(schema) {
|
|
605
|
+
if (!isSchemaObject(schema)) return false;
|
|
606
|
+
if (schema.type === "null" || Array.isArray(schema.type) && schema.type.includes("null"))
|
|
607
|
+
return true;
|
|
608
|
+
if (schema.const === null || Array.isArray(schema.enum) && schema.enum.includes(null))
|
|
609
|
+
return true;
|
|
610
|
+
return Array.isArray(schema.anyOf) && schema.anyOf.some((variant) => allowsNull(variant));
|
|
611
|
+
}
|
|
612
|
+
function makeNodeStrict(schema) {
|
|
613
|
+
if (!isSchemaObject(schema)) {
|
|
614
|
+
throw new UnsupportedStrictSchemaError("boolean schemas are unsupported");
|
|
615
|
+
}
|
|
616
|
+
for (const key of UNSUPPORTED_KEYS) {
|
|
617
|
+
if (schema[key] !== void 0) {
|
|
618
|
+
throw new UnsupportedStrictSchemaError(`${key} schemas are unsupported`);
|
|
619
|
+
}
|
|
620
|
+
}
|
|
621
|
+
if (schema.anyOf !== void 0) {
|
|
622
|
+
if (!Array.isArray(schema.anyOf) || schema.anyOf.length === 0) {
|
|
623
|
+
throw new UnsupportedStrictSchemaError("anyOf must contain at least one schema");
|
|
624
|
+
}
|
|
625
|
+
for (const variant of schema.anyOf) {
|
|
626
|
+
if (isStructured(variant)) {
|
|
627
|
+
throw new UnsupportedStrictSchemaError("object and array unions are unsupported");
|
|
628
|
+
}
|
|
629
|
+
makeNodeStrict(variant);
|
|
630
|
+
}
|
|
631
|
+
}
|
|
632
|
+
if (schema.items !== void 0) {
|
|
633
|
+
if (Array.isArray(schema.items)) {
|
|
634
|
+
throw new UnsupportedStrictSchemaError("tuple schemas are unsupported");
|
|
635
|
+
}
|
|
636
|
+
makeNodeStrict(schema.items);
|
|
637
|
+
}
|
|
638
|
+
const isObjectSchema = schema.type === "object";
|
|
639
|
+
if (schema.properties !== void 0 && !isObjectSchema) {
|
|
640
|
+
throw new UnsupportedStrictSchemaError("properties require type object");
|
|
641
|
+
}
|
|
642
|
+
if (!isObjectSchema) return;
|
|
643
|
+
if (schema.additionalProperties !== void 0 && schema.additionalProperties !== false) {
|
|
644
|
+
throw new UnsupportedStrictSchemaError(
|
|
645
|
+
"schema-valued or true additionalProperties is unsupported"
|
|
646
|
+
);
|
|
647
|
+
}
|
|
648
|
+
if (schema.properties !== void 0 && !isSchemaObject(schema.properties)) {
|
|
649
|
+
throw new UnsupportedStrictSchemaError("object properties must be a schema map");
|
|
650
|
+
}
|
|
651
|
+
const properties = schema.properties ?? {};
|
|
652
|
+
const required = new Set(Array.isArray(schema.required) ? schema.required : []);
|
|
653
|
+
for (const [key, property] of Object.entries(properties)) {
|
|
654
|
+
makeNodeStrict(property);
|
|
655
|
+
if (!required.has(key) && !allowsNull(property)) {
|
|
656
|
+
properties[key] = { anyOf: [property, { type: "null" }] };
|
|
657
|
+
}
|
|
658
|
+
}
|
|
659
|
+
schema.required = Object.keys(properties);
|
|
660
|
+
schema.additionalProperties = false;
|
|
661
|
+
}
|
|
662
|
+
function supportsStrictToolSampling(provider) {
|
|
663
|
+
return provider === "openai";
|
|
664
|
+
}
|
|
665
|
+
function makeStrictToolSchema(schema) {
|
|
666
|
+
const cloned = structuredClone(schema);
|
|
667
|
+
if (!isSchemaObject(cloned)) {
|
|
668
|
+
throw new UnsupportedStrictSchemaError("root schema must be an object");
|
|
669
|
+
}
|
|
670
|
+
makeNodeStrict(cloned);
|
|
671
|
+
if (cloned.type !== "object") {
|
|
672
|
+
throw new UnsupportedStrictSchemaError("root schema must have type object");
|
|
673
|
+
}
|
|
674
|
+
return cloned;
|
|
675
|
+
}
|
|
676
|
+
|
|
572
677
|
// src/providers/reasoning-field.ts
|
|
573
678
|
var REASONING_FIELD_ALIASES = [
|
|
574
679
|
"reasoning_content",
|
|
@@ -1049,7 +1154,7 @@ function toOpenAIMessages(messages, options) {
|
|
|
1049
1154
|
(part) => {
|
|
1050
1155
|
if (part.type === "text") return { type: "text", text: part.text };
|
|
1051
1156
|
if (part.type === "video") {
|
|
1052
|
-
const videoUrl = part.fileId ? { url: `ms://${part.fileId}`, id: part.fileId } : { url: `data:${part.mediaType};base64,${part.data}` };
|
|
1157
|
+
const videoUrl = options?.provider === "moonshot" && part.fileId ? { url: `ms://${part.fileId}`, id: part.fileId } : { url: `data:${part.mediaType};base64,${part.data}` };
|
|
1053
1158
|
return {
|
|
1054
1159
|
type: "video_url",
|
|
1055
1160
|
video_url: videoUrl
|
|
@@ -1153,15 +1258,28 @@ function toOpenAIMessages(messages, options) {
|
|
|
1153
1258
|
}
|
|
1154
1259
|
return out;
|
|
1155
1260
|
}
|
|
1156
|
-
function toOpenAITools(tools) {
|
|
1157
|
-
return tools.map((tool) =>
|
|
1158
|
-
|
|
1159
|
-
|
|
1160
|
-
|
|
1161
|
-
|
|
1162
|
-
|
|
1261
|
+
function toOpenAITools(tools, opts) {
|
|
1262
|
+
return tools.map((tool) => {
|
|
1263
|
+
let parameters = resolveToolSchema(tool);
|
|
1264
|
+
let strict;
|
|
1265
|
+
if (opts?.strict) {
|
|
1266
|
+
try {
|
|
1267
|
+
parameters = makeStrictToolSchema(parameters);
|
|
1268
|
+
strict = true;
|
|
1269
|
+
} catch (error) {
|
|
1270
|
+
if (!(error instanceof UnsupportedStrictSchemaError)) throw error;
|
|
1271
|
+
}
|
|
1163
1272
|
}
|
|
1164
|
-
|
|
1273
|
+
return {
|
|
1274
|
+
type: "function",
|
|
1275
|
+
function: {
|
|
1276
|
+
name: tool.name,
|
|
1277
|
+
description: tool.description,
|
|
1278
|
+
parameters,
|
|
1279
|
+
...strict ? { strict } : {}
|
|
1280
|
+
}
|
|
1281
|
+
};
|
|
1282
|
+
});
|
|
1165
1283
|
}
|
|
1166
1284
|
function toOpenAIToolChoice(choice) {
|
|
1167
1285
|
if (choice === "auto") return "auto";
|
|
@@ -1988,7 +2106,7 @@ async function* runStream2(options) {
|
|
|
1988
2106
|
const k3Effort = options.thinking ? toKimiK3Effort(options.thinking) : void 0;
|
|
1989
2107
|
const isKimiK27 = options.provider === "moonshot" && options.model.startsWith("kimi-k2.7-code");
|
|
1990
2108
|
const hasFixedKimiSampling = isKimiK3 || isKimiK27;
|
|
1991
|
-
const usesThinkingParam = options.provider === "glm" || options.provider === "moonshot" && !isKimiK3 && !isKimiK27 || options.provider === "xiaomi";
|
|
2109
|
+
const usesThinkingParam = options.provider === "deepseek" || options.provider === "glm" || options.provider === "moonshot" && !isKimiK3 && !isKimiK27 || options.provider === "xiaomi";
|
|
1992
2110
|
const downgradedImages = downgradeUnsupportedImages(options.messages, options.supportsImages);
|
|
1993
2111
|
const downgradedMessages = downgradeUnsupportedVideos(downgradedImages, options.supportsVideo);
|
|
1994
2112
|
if (options.provider === "moonshot") {
|
|
@@ -2014,19 +2132,23 @@ async function* runStream2(options) {
|
|
|
2014
2132
|
model: options.model,
|
|
2015
2133
|
messages,
|
|
2016
2134
|
stream: useStreaming,
|
|
2017
|
-
...options.maxTokens ? { max_completion_tokens: options.maxTokens } : {},
|
|
2135
|
+
...options.maxTokens ? options.provider === "deepseek" || options.provider === "glm" || options.provider === "moonshot" ? { max_tokens: options.maxTokens } : { max_completion_tokens: options.maxTokens } : {},
|
|
2018
2136
|
...effectiveTemp != null && !options.thinking && !hasFixedKimiSampling ? { temperature: effectiveTemp } : {},
|
|
2019
2137
|
...options.topP != null && !hasFixedKimiSampling ? { top_p: options.topP } : {},
|
|
2020
2138
|
...options.stop ? { stop: options.stop } : {},
|
|
2021
2139
|
...options.thinking && !usesThinkingParam && !isKimiK3 && !isKimiK27 && !isLocal ? { reasoning_effort: toOpenAIReasoningEffort(options.thinking, options.model) } : {},
|
|
2022
|
-
...options.tools?.length ? {
|
|
2140
|
+
...options.tools?.length ? {
|
|
2141
|
+
tools: toOpenAITools(options.tools, {
|
|
2142
|
+
strict: supportsStrictToolSampling(options.provider)
|
|
2143
|
+
})
|
|
2144
|
+
} : {},
|
|
2023
2145
|
...options.toolChoice && options.tools?.length ? { tool_choice: toOpenAIToolChoice(options.toolChoice) } : {},
|
|
2024
2146
|
...useStreaming ? { stream_options: { include_usage: true } } : {}
|
|
2025
2147
|
};
|
|
2026
2148
|
if (options.provider === "openai" || options.provider === "moonshot") {
|
|
2027
2149
|
const paramsAny = params;
|
|
2028
2150
|
paramsAny.prompt_cache_key = normalizePromptCacheKey(options.promptCacheKey ?? "ezcoder");
|
|
2029
|
-
if (options.provider === "openai" && options.model.startsWith("gpt-5.6")) {
|
|
2151
|
+
if (options.provider === "openai" && (options.model.startsWith("gpt-5.6") || options.model.startsWith("gpt-6"))) {
|
|
2030
2152
|
paramsAny.prompt_cache_options = { mode: "implicit", ttl: "30m" };
|
|
2031
2153
|
} else if (!isKimiK3 && (options.cacheRetention ?? "short") === "long") {
|
|
2032
2154
|
paramsAny.prompt_cache_retention = "24h";
|
|
@@ -2037,6 +2159,9 @@ async function* runStream2(options) {
|
|
|
2037
2159
|
options.thinking
|
|
2038
2160
|
);
|
|
2039
2161
|
}
|
|
2162
|
+
if (options.provider === "sakana" && options.model === "fugu-ultra" && (options.thinking === "max" || options.thinking === "ultra")) {
|
|
2163
|
+
params.reasoning_effort = "max";
|
|
2164
|
+
}
|
|
2040
2165
|
if (options.provider === "openai" && options.serviceTier) {
|
|
2041
2166
|
params.service_tier = options.serviceTier;
|
|
2042
2167
|
}
|
|
@@ -2053,7 +2178,9 @@ async function* runStream2(options) {
|
|
|
2053
2178
|
if (usesThinkingParam) {
|
|
2054
2179
|
if (options.thinking) {
|
|
2055
2180
|
params.thinking = { type: "enabled" };
|
|
2056
|
-
if (options.provider === "
|
|
2181
|
+
if (options.provider === "deepseek") {
|
|
2182
|
+
params.reasoning_effort = options.thinking === "low" ? "low" : options.thinking === "medium" || options.thinking === "high" ? "high" : "max";
|
|
2183
|
+
} else if (options.provider === "glm") {
|
|
2057
2184
|
params.reasoning_effort = toGlmReasoningEffort(
|
|
2058
2185
|
options.thinking
|
|
2059
2186
|
);
|
|
@@ -2448,7 +2575,7 @@ function extractRequestIdFromMessage(message) {
|
|
|
2448
2575
|
|
|
2449
2576
|
// src/providers/openai-codex.ts
|
|
2450
2577
|
var DEFAULT_BASE_URL = "https://chatgpt.com/backend-api";
|
|
2451
|
-
var CODEX_CLIENT_VERSION = "0.
|
|
2578
|
+
var CODEX_CLIENT_VERSION = "0.153.4";
|
|
2452
2579
|
var CODEX_REQUEST_COMPRESSION_MIN_BYTES = 16 * 1024;
|
|
2453
2580
|
var zstdInitPromise;
|
|
2454
2581
|
async function encodeCodexRequest(body) {
|
|
@@ -2494,7 +2621,7 @@ async function encodeCodexRequest(body) {
|
|
|
2494
2621
|
}
|
|
2495
2622
|
}
|
|
2496
2623
|
function usesResponsesLite(model) {
|
|
2497
|
-
return model.startsWith("gpt-5.6-");
|
|
2624
|
+
return model.startsWith("gpt-5.6-") || model.startsWith("gpt-6-");
|
|
2498
2625
|
}
|
|
2499
2626
|
function outputTextKey(itemId, contentIndex) {
|
|
2500
2627
|
return `${itemId ?? ""}:${contentIndex ?? 0}`;
|
|
@@ -2548,8 +2675,10 @@ async function* runStream3(options) {
|
|
|
2548
2675
|
body.temperature = options.temperature;
|
|
2549
2676
|
}
|
|
2550
2677
|
body.reasoning = {
|
|
2678
|
+
// GPT-5.6/6 require at least low; older models still support thinking off.
|
|
2679
|
+
// Apply the floor here for every caller, including one-off prompt rewrites.
|
|
2551
2680
|
// `ultra` is a client orchestration preset, not a Codex API effort.
|
|
2552
|
-
effort: options.thinking === "ultra" ? "max" : options.thinking ?? "none",
|
|
2681
|
+
effort: options.thinking === "ultra" ? "max" : options.thinking ?? (responsesLite ? "low" : "none"),
|
|
2553
2682
|
summary: "auto",
|
|
2554
2683
|
...responsesLite ? { context: "all_turns" } : {}
|
|
2555
2684
|
};
|
|
@@ -2594,14 +2723,10 @@ async function* runStream3(options) {
|
|
|
2594
2723
|
const usageLimit = codexUsageLimitError(parsed.errorObj, response.status, requestId);
|
|
2595
2724
|
if (usageLimit) throw usageLimit;
|
|
2596
2725
|
let hint;
|
|
2597
|
-
if (response.status === 400 &&
|
|
2598
|
-
|
|
2599
|
-
hint = "Use gpt-5.5 instead. OpenAI's Codex model catalog does not list gpt-5.5-pro.";
|
|
2600
|
-
} else {
|
|
2601
|
-
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.";
|
|
2602
|
-
}
|
|
2726
|
+
if (response.status === 400 && message === `The '${options.model}' model is not supported when using Codex with a ChatGPT account.`) {
|
|
2727
|
+
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.";
|
|
2603
2728
|
} else if (response.status === 404 && text.includes("does not exist")) {
|
|
2604
|
-
hint = "This model is not in
|
|
2729
|
+
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.";
|
|
2605
2730
|
}
|
|
2606
2731
|
throw new ProviderError("openai", message, {
|
|
2607
2732
|
statusCode: response.status,
|
|
@@ -2974,13 +3099,23 @@ function toCodexInput(messages, options) {
|
|
|
2974
3099
|
return { system, input };
|
|
2975
3100
|
}
|
|
2976
3101
|
function toCodexTools(tools) {
|
|
2977
|
-
return tools.map((tool) =>
|
|
2978
|
-
|
|
2979
|
-
|
|
2980
|
-
|
|
2981
|
-
|
|
2982
|
-
|
|
2983
|
-
|
|
3102
|
+
return tools.map((tool) => {
|
|
3103
|
+
let parameters = resolveToolSchema(tool);
|
|
3104
|
+
let strict = null;
|
|
3105
|
+
try {
|
|
3106
|
+
parameters = makeStrictToolSchema(parameters);
|
|
3107
|
+
strict = true;
|
|
3108
|
+
} catch (error) {
|
|
3109
|
+
if (!(error instanceof UnsupportedStrictSchemaError)) throw error;
|
|
3110
|
+
}
|
|
3111
|
+
return {
|
|
3112
|
+
type: "function",
|
|
3113
|
+
name: tool.name,
|
|
3114
|
+
description: tool.description,
|
|
3115
|
+
parameters,
|
|
3116
|
+
strict
|
|
3117
|
+
};
|
|
3118
|
+
});
|
|
2984
3119
|
}
|
|
2985
3120
|
function parseCodexErrorBody(text, statusCode) {
|
|
2986
3121
|
if (!text) return {};
|
|
@@ -3041,6 +3176,8 @@ var CODE_ASSIST_SUPPORTED_MODELS = /* @__PURE__ */ new Set([
|
|
|
3041
3176
|
"gemini-3-flash",
|
|
3042
3177
|
"gemini-3.1-flash-lite",
|
|
3043
3178
|
"gemini-3.7-flash",
|
|
3179
|
+
"gemini-3.8-flash",
|
|
3180
|
+
"gemini-3.5-flash-lite",
|
|
3044
3181
|
"gemini-2.5-pro",
|
|
3045
3182
|
"gemini-2.5-flash",
|
|
3046
3183
|
"gemma-4-31b-it",
|
|
@@ -3064,12 +3201,20 @@ var ACCOUNT_GATED_MODELS = /* @__PURE__ */ new Set([
|
|
|
3064
3201
|
"gemini-3.5-flash",
|
|
3065
3202
|
"gemini-3.1-pro-preview",
|
|
3066
3203
|
"gemini-3.1-pro-preview-customtools",
|
|
3067
|
-
"gemini-3.7-flash"
|
|
3204
|
+
"gemini-3.7-flash",
|
|
3205
|
+
"gemini-3.8-flash",
|
|
3206
|
+
"gemini-3.5-flash-lite"
|
|
3068
3207
|
]);
|
|
3069
3208
|
function accountGatedMessage(model) {
|
|
3209
|
+
if (model === "gemini-3.8-flash" || model === "gemini-3.5-flash-lite") {
|
|
3210
|
+
return `${model} is not available through Code Assist for this account. Public Gemini API availability does not guarantee Code Assist OAuth access.`;
|
|
3211
|
+
}
|
|
3070
3212
|
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.`;
|
|
3071
3213
|
}
|
|
3072
|
-
function accountGatedHint() {
|
|
3214
|
+
function accountGatedHint(model) {
|
|
3215
|
+
if (model === "gemini-3.8-flash" || model === "gemini-3.5-flash-lite") {
|
|
3216
|
+
return "Use /model to select Gemini 3.1 Flash Lite, or retry once Google enables this model through Code Assist for your account.";
|
|
3217
|
+
}
|
|
3073
3218
|
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.`;
|
|
3074
3219
|
}
|
|
3075
3220
|
function formatErrorMessage(status, body, model) {
|
|
@@ -3395,7 +3540,7 @@ async function fetchCodeAssist(plan, options) {
|
|
|
3395
3540
|
throw new ProviderError("gemini", message, {
|
|
3396
3541
|
statusCode: response.status,
|
|
3397
3542
|
...resetsAt !== void 0 ? { resetsAt } : {},
|
|
3398
|
-
...accountGated ? { hint: accountGatedHint() } : {}
|
|
3543
|
+
...accountGated ? { hint: accountGatedHint(options.model) } : {}
|
|
3399
3544
|
});
|
|
3400
3545
|
}
|
|
3401
3546
|
return response;
|