Merge remote-tracking branch 'origin/master' into gitea/feature/end
Resolved conflicts taking origin/master (v0.5.55) as canonical, with local features re-applied: - runtime log level (LOG_LEVEL env + dashboard Settings → Logging, applied immediately and persisted across restarts) - free/noAuth provider enable/disable toggle via providerStrategies.enabled - parallel model testing (Test All Models / Test Selected Keys)
This commit is contained in:
@@ -1,17 +1,26 @@
|
||||
import { getCapabilitiesForModel } from "../../providers/capabilities.js";
|
||||
|
||||
// Strip request params a given provider/model rejects upstream (e.g. HTTP 400).
|
||||
// Config-driven: add a rule instead of scattering `delete body.x` across executors.
|
||||
|
||||
// Each rule: optional provider, regex match on model, list of params to drop.
|
||||
// A param is removed only when it is present (!== undefined).
|
||||
const STRIP_RULES = [
|
||||
// claude-opus-4 series: temperature is deprecated (Anthropic 400). #1748
|
||||
{ match: /claude-opus-4/i, drop: ["temperature"] },
|
||||
// All Claude models: temperature deprecated/rejected upstream (Anthropic 400). #1748
|
||||
{ match: /claude/i, drop: ["temperature"] },
|
||||
// GitHub Copilot gpt-5.4: temperature unsupported.
|
||||
{ provider: "github", match: /gpt-5\.4/i, drop: ["temperature"] },
|
||||
// GitHub Copilot Claude (except opus/sonnet 4.6): thinking + reasoning_effort rejected. #713
|
||||
{ provider: "github", match: (m) => /claude/i.test(m) && !/claude.*(opus|sonnet).*4\.6/i.test(m), drop: ["thinking", "reasoning_effort"] },
|
||||
// Cloudflare Workers AI: content must be plain string, rejects OpenAI content-part array (#1926)
|
||||
{ provider: "cloudflare-ai", flattenContent: true },
|
||||
{ provider: "volcengine-ark", match: /glm-5/i, clampToModelMaxOutput: true },
|
||||
// VolcEngine Ark caps the Kimi family at max_tokens <= 32768, but the model's
|
||||
// advertised ceiling is far higher (Kimi-K2.7-Code resolves to maxOutput 262144),
|
||||
// so clampToModelMaxOutput alone leaves it uncapped and the request 400s with
|
||||
// "integer above maximum value, expected <= 32768". Pin an explicit endpoint cap;
|
||||
// min() with the model ceiling still applies if a variant's own limit is lower.
|
||||
{ provider: "volcengine-ark", match: /kimi/i, maxOutputCap: 32768, clampToModelMaxOutput: true },
|
||||
];
|
||||
|
||||
// Test a rule's match (regex or predicate) against the model id.
|
||||
@@ -20,6 +29,12 @@ function matches(rule, model) {
|
||||
return typeof rule.match === "function" ? rule.match(model) : rule.match.test(model);
|
||||
}
|
||||
|
||||
function clampNumber(body, key, ceiling) {
|
||||
if (typeof body[key] === "number" && Number.isFinite(body[key]) && body[key] > ceiling) {
|
||||
body[key] = ceiling;
|
||||
}
|
||||
}
|
||||
|
||||
// Remove unsupported params from body in place; returns body.
|
||||
export function stripUnsupportedParams(provider, model, body) {
|
||||
if (!model || !body || typeof body !== "object") return body;
|
||||
@@ -39,6 +54,22 @@ export function stripUnsupportedParams(provider, model, body) {
|
||||
}
|
||||
}
|
||||
}
|
||||
if (rule.clampToModelMaxOutput || Number.isFinite(rule.maxOutputCap)) {
|
||||
const modelCeiling = getCapabilitiesForModel(provider, model).maxOutput;
|
||||
const candidates = [];
|
||||
if (rule.clampToModelMaxOutput && Number.isFinite(modelCeiling) && modelCeiling > 0) {
|
||||
candidates.push(modelCeiling);
|
||||
}
|
||||
if (Number.isFinite(rule.maxOutputCap) && rule.maxOutputCap > 0) {
|
||||
candidates.push(rule.maxOutputCap);
|
||||
}
|
||||
if (candidates.length > 0) {
|
||||
const ceiling = Math.min(...candidates);
|
||||
clampNumber(body, "max_tokens", ceiling);
|
||||
clampNumber(body, "max_completion_tokens", ceiling);
|
||||
clampNumber(body, "max_output_tokens", ceiling);
|
||||
}
|
||||
}
|
||||
}
|
||||
return body;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user