mirror of
https://github.com/diegosouzapw/OmniRoute.git
synced 2026-08-19 21:52:21 +03:00
Integrated into release/v3.8.6.
This commit is contained in:
committed by
GitHub
parent
283c05d3d0
commit
fee1c17d51
@@ -14,6 +14,7 @@
|
||||
|
||||
### 🔧 Bug Fixes
|
||||
|
||||
- **fix(opencode-go,opencode-zen):** mark qwen3.7-max / 3.6-plus / 3.5-plus as supportsVision:false to stop forwarding image blocks to vision-incapable upstream models ([#2822])
|
||||
- **nous-research:** append /chat/completions to provider baseUrl so DefaultExecutor's default URL builder hits the correct endpoint instead of returning 404 ([#2826])
|
||||
- **fix(quota):** honor explicit per-connection `quotaPreflightEnabled: false` even when the provider has global window defaults — adds early-return guard before the AND-of-negations gate in auth.ts ([#2831])
|
||||
- **api:** include noAuth providers (opencode, etc.) in `/v1/models` active aliases so their models surface without a DB connection row (#2798)
|
||||
|
||||
@@ -1296,9 +1296,12 @@ export const REGISTRY: Record<string, RegistryEntry> = {
|
||||
// ("Model qwen3.x-* is not supported for format oa-compat") — same
|
||||
// upstream behavior already declared for opencode-zen. Route them
|
||||
// through /messages with the Claude translator.
|
||||
{ id: "qwen3.7-max", name: "Qwen3.7 Max", targetFormat: "claude" },
|
||||
{ id: "qwen3.6-plus", name: "Qwen3.6 Plus", targetFormat: "claude" },
|
||||
{ id: "qwen3.5-plus", name: "Qwen3.5 Plus", targetFormat: "claude" },
|
||||
// Issue #2822: These models are text-only — mark supportsVision: false
|
||||
// so combo routing skips them when the request contains image blocks,
|
||||
// preventing image content from reaching a vision-incapable upstream.
|
||||
{ id: "qwen3.7-max", name: "Qwen3.7 Max", targetFormat: "claude", supportsVision: false },
|
||||
{ id: "qwen3.6-plus", name: "Qwen3.6 Plus", targetFormat: "claude", supportsVision: false },
|
||||
{ id: "qwen3.5-plus", name: "Qwen3.5 Plus", targetFormat: "claude", supportsVision: false },
|
||||
{ id: "hy3-preview", name: "Hunyuan3 Preview" },
|
||||
{ id: "deepseek-v4-pro", name: "DeepSeek V4 Pro", supportsReasoning: true },
|
||||
{ id: "deepseek-v4-flash", name: "DeepSeek V4 Flash", supportsReasoning: true },
|
||||
@@ -1374,8 +1377,10 @@ export const REGISTRY: Record<string, RegistryEntry> = {
|
||||
// Issue #2292: Qwen models return Claude-format SSE bodies even
|
||||
// when hitting /chat/completions. targetFormat: "claude" routes
|
||||
// through /messages and the Claude translator.
|
||||
{ id: "qwen3.5-plus", name: "Qwen3.5 Plus", targetFormat: "claude" },
|
||||
{ id: "qwen3.6-plus", name: "Qwen3.6 Plus", targetFormat: "claude" },
|
||||
// Issue #2822: These models are text-only — supportsVision: false
|
||||
// ensures combo routing skips them on image-bearing requests.
|
||||
{ id: "qwen3.5-plus", name: "Qwen3.5 Plus", targetFormat: "claude", supportsVision: false },
|
||||
{ id: "qwen3.6-plus", name: "Qwen3.6 Plus", targetFormat: "claude", supportsVision: false },
|
||||
|
||||
// ── Free Tier ──────────────────────────────────────────────
|
||||
{ id: "deepseek-v4-flash-free", name: "DeepSeek V4 Flash Free", supportsReasoning: true },
|
||||
|
||||
111
tests/unit/provider-registry-qwen-vision.test.ts
Normal file
111
tests/unit/provider-registry-qwen-vision.test.ts
Normal file
@@ -0,0 +1,111 @@
|
||||
/**
|
||||
* Issue #2822 — qwen3.7-max (opencode-go) retorna 500 em inputs com imagem.
|
||||
*
|
||||
* qwen3.7-max, qwen3.6-plus e qwen3.5-plus nos providers opencode-go e
|
||||
* opencode-zen não possuíam supportsVision: false. Isso fazia com que
|
||||
* blocos de imagem chegassem ao upstream (que não suporta visão),
|
||||
* gerando 500s que esgotavam todo o orçamento de retentativas.
|
||||
*
|
||||
* Este teste garante que todos os modelos afetados tenham
|
||||
* supportsVision !== true (i.e. false ou não definido como true).
|
||||
*/
|
||||
import test from "node:test";
|
||||
import assert from "node:assert/strict";
|
||||
|
||||
const { REGISTRY } = await import("../../open-sse/config/providerRegistry.ts");
|
||||
|
||||
type ModelEntry = {
|
||||
id: string;
|
||||
supportsVision?: boolean;
|
||||
[key: string]: unknown;
|
||||
};
|
||||
|
||||
type ProviderEntry = {
|
||||
models?: ModelEntry[];
|
||||
[key: string]: unknown;
|
||||
};
|
||||
|
||||
function getModel(providerId: string, modelId: string): ModelEntry | undefined {
|
||||
const provider = (REGISTRY as Record<string, ProviderEntry>)[providerId];
|
||||
if (!provider) return undefined;
|
||||
return provider.models?.find((m) => m.id === modelId);
|
||||
}
|
||||
|
||||
// ── opencode-go ─────────────────────────────────────────────────────────────
|
||||
|
||||
test("#2822 opencode-go/qwen3.7-max deve ter supportsVision !== true", () => {
|
||||
const model = getModel("opencode-go", "qwen3.7-max");
|
||||
assert.ok(model, "qwen3.7-max deve estar registrado em opencode-go");
|
||||
assert.notEqual(
|
||||
model.supportsVision,
|
||||
true,
|
||||
"opencode-go/qwen3.7-max não suporta visão — supportsVision deve ser false ou ausente"
|
||||
);
|
||||
assert.strictEqual(
|
||||
model.supportsVision,
|
||||
false,
|
||||
"opencode-go/qwen3.7-max deve ter supportsVision: false explícito para bloquear seleção em combo com imagens"
|
||||
);
|
||||
});
|
||||
|
||||
test("#2822 opencode-go/qwen3.6-plus deve ter supportsVision !== true", () => {
|
||||
const model = getModel("opencode-go", "qwen3.6-plus");
|
||||
assert.ok(model, "qwen3.6-plus deve estar registrado em opencode-go");
|
||||
assert.notEqual(
|
||||
model.supportsVision,
|
||||
true,
|
||||
"opencode-go/qwen3.6-plus não suporta visão — supportsVision deve ser false ou ausente"
|
||||
);
|
||||
assert.strictEqual(
|
||||
model.supportsVision,
|
||||
false,
|
||||
"opencode-go/qwen3.6-plus deve ter supportsVision: false explícito para bloquear seleção em combo com imagens"
|
||||
);
|
||||
});
|
||||
|
||||
test("#2822 opencode-go/qwen3.5-plus deve ter supportsVision !== true", () => {
|
||||
const model = getModel("opencode-go", "qwen3.5-plus");
|
||||
assert.ok(model, "qwen3.5-plus deve estar registrado em opencode-go");
|
||||
assert.notEqual(
|
||||
model.supportsVision,
|
||||
true,
|
||||
"opencode-go/qwen3.5-plus não suporta visão — supportsVision deve ser false ou ausente"
|
||||
);
|
||||
assert.strictEqual(
|
||||
model.supportsVision,
|
||||
false,
|
||||
"opencode-go/qwen3.5-plus deve ter supportsVision: false explícito para bloquear seleção em combo com imagens"
|
||||
);
|
||||
});
|
||||
|
||||
// ── opencode-zen ─────────────────────────────────────────────────────────────
|
||||
|
||||
test("#2822 opencode-zen/qwen3.5-plus deve ter supportsVision !== true", () => {
|
||||
const model = getModel("opencode-zen", "qwen3.5-plus");
|
||||
assert.ok(model, "qwen3.5-plus deve estar registrado em opencode-zen");
|
||||
assert.notEqual(
|
||||
model.supportsVision,
|
||||
true,
|
||||
"opencode-zen/qwen3.5-plus não suporta visão — supportsVision deve ser false ou ausente"
|
||||
);
|
||||
assert.strictEqual(
|
||||
model.supportsVision,
|
||||
false,
|
||||
"opencode-zen/qwen3.5-plus deve ter supportsVision: false explícito para bloquear seleção em combo com imagens"
|
||||
);
|
||||
});
|
||||
|
||||
test("#2822 opencode-zen/qwen3.6-plus deve ter supportsVision !== true", () => {
|
||||
const model = getModel("opencode-zen", "qwen3.6-plus");
|
||||
assert.ok(model, "qwen3.6-plus deve estar registrado em opencode-zen");
|
||||
assert.notEqual(
|
||||
model.supportsVision,
|
||||
true,
|
||||
"opencode-zen/qwen3.6-plus não suporta visão — supportsVision deve ser false ou ausente"
|
||||
);
|
||||
assert.strictEqual(
|
||||
model.supportsVision,
|
||||
false,
|
||||
"opencode-zen/qwen3.6-plus deve ter supportsVision: false explícito para bloquear seleção em combo com imagens"
|
||||
);
|
||||
});
|
||||
Reference in New Issue
Block a user