mirror of
https://github.com/diegosouzapw/OmniRoute.git
synced 2026-08-11 01:32:22 +03:00
fix(opencode-zen): add current free-tier models to registry to enable combo context pre-filtering (#8841)
Co-authored-by: diegosouzapw <diegosouzapw@users.noreply.github.com>
This commit is contained in:
committed by
GitHub
parent
904e8af09a
commit
7be4e55e7e
1
changelog.d/fixes/8841-fix.plan.md
Normal file
1
changelog.d/fixes/8841-fix.plan.md
Normal file
@@ -0,0 +1 @@
|
||||
- fix(opencode-zen): add current free-tier models to registry to enable combo context pre-filtering (#8841)
|
||||
@@ -85,14 +85,13 @@ export const opencode_zenProvider: RegistryEntry = {
|
||||
{ id: "qwen3.6-plus", name: "Qwen3.6 Plus", targetFormat: "claude", supportsVision: false },
|
||||
|
||||
// ── Free Tier ──────────────────────────────────────────────
|
||||
// #6998 (2026-07-14): upstream free tier rotated — minimax-m2.5-free,
|
||||
// nemotron-3-super-free and qwen3.6-plus-free were delisted (401). Replaced
|
||||
// by the 4 entries below with upstream-verified limits.
|
||||
{ id: "deepseek-v4-flash-free", name: "DeepSeek V4 Flash Free", supportsReasoning: true },
|
||||
{ id: "minimax-m2.5-free", name: "MiniMax M2.5 Free", contextLength: 204800 },
|
||||
{ id: "nemotron-3-super-free", name: "Nemotron 3 Super Free", contextLength: 1000000 },
|
||||
{
|
||||
id: "qwen3.6-plus-free",
|
||||
name: "Qwen3.6 Plus Free",
|
||||
targetFormat: "claude",
|
||||
contextLength: 200000,
|
||||
},
|
||||
{ id: "mimo-v2.5-free", name: "MiMo V2.5 Free", contextLength: 200000 },
|
||||
{ id: "hy3-free", name: "HY3 Free", contextLength: 200000 },
|
||||
{ id: "nemotron-3-ultra-free", name: "Nemotron 3 Ultra Free", contextLength: 1000000 },
|
||||
{ id: "north-mini-code-free", name: "North Mini Code Free", contextLength: 200000 },
|
||||
],
|
||||
};
|
||||
|
||||
117
tests/unit/repro-8841-context-overflow-opencode.test.ts
Normal file
117
tests/unit/repro-8841-context-overflow-opencode.test.ts
Normal file
@@ -0,0 +1,117 @@
|
||||
import test from "node:test";
|
||||
import assert from "node:assert/strict";
|
||||
import fs from "node:fs";
|
||||
import os from "node:os";
|
||||
import path from "node:path";
|
||||
|
||||
const TEST_DATA_DIR = fs.mkdtempSync(
|
||||
path.join(os.tmpdir(), "omniroute-repro-8841-")
|
||||
);
|
||||
const ORIGINAL_DATA_DIR = process.env.DATA_DIR;
|
||||
process.env.DATA_DIR = TEST_DATA_DIR;
|
||||
|
||||
const { getResolvedModelCapabilities } = await import(
|
||||
"../../src/lib/modelCapabilities.ts"
|
||||
);
|
||||
const { getKnownContextOverflow, handleComboChat } = await import(
|
||||
"../../open-sse/services/combo.ts"
|
||||
);
|
||||
const { getTokenLimit } = await import(
|
||||
"../../open-sse/services/contextManager.ts"
|
||||
);
|
||||
const core = await import("../../src/lib/db/core.ts");
|
||||
|
||||
test.after(() => {
|
||||
core.resetDbInstance();
|
||||
if (ORIGINAL_DATA_DIR === undefined) delete process.env.DATA_DIR;
|
||||
else process.env.DATA_DIR = ORIGINAL_DATA_DIR;
|
||||
fs.rmSync(TEST_DATA_DIR, { recursive: true, force: true });
|
||||
});
|
||||
|
||||
const noopLog = {
|
||||
info() {},
|
||||
warn() {},
|
||||
error() {},
|
||||
debug() {},
|
||||
};
|
||||
|
||||
const target = (m) => ({
|
||||
kind: "model",
|
||||
stepId: m,
|
||||
executionKey: m,
|
||||
modelStr: m,
|
||||
provider: "opencode-zen",
|
||||
providerId: null,
|
||||
connectionId: null,
|
||||
weight: 1,
|
||||
label: null,
|
||||
});
|
||||
|
||||
function largeBody() {
|
||||
return {
|
||||
messages: [{ role: "user", content: "x".repeat(840_000) }],
|
||||
max_tokens: 8192,
|
||||
};
|
||||
}
|
||||
|
||||
function upstreamContextOverflowResponse() {
|
||||
return new Response(
|
||||
JSON.stringify({
|
||||
error: {
|
||||
code: "context_length_exceeded",
|
||||
message:
|
||||
"Input exceeds the context window for opencode/north-mini-code-free: estimated 210724 input tokens, limit 200000. Reduce the prompt or route to a model with a larger context window.",
|
||||
},
|
||||
}),
|
||||
{
|
||||
status: 400,
|
||||
headers: { "Content-Type": "application/json" },
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
test("#8841 advertised vs compat-filter limit agree", () => {
|
||||
const advertised = getTokenLimit("opencode-zen", "north-mini-code-free");
|
||||
const caps = getResolvedModelCapabilities("opencode/north-mini-code-free");
|
||||
assert.ok(advertised > 0);
|
||||
assert.ok(
|
||||
caps.contextWindow != null && caps.contextWindow > 0,
|
||||
`contextWindow known (got ${caps.contextWindow})`
|
||||
);
|
||||
});
|
||||
|
||||
test("#8841 oversized request rejected up front (no dispatch)", async () => {
|
||||
const body = largeBody();
|
||||
const pool = [
|
||||
target("opencode/north-mini-code-free"),
|
||||
target("opencode/hy3-free"),
|
||||
];
|
||||
|
||||
assert.ok(getKnownContextOverflow(pool, body), "overflow before dispatch");
|
||||
|
||||
let dispatches = 0;
|
||||
const result = await handleComboChat({
|
||||
body,
|
||||
combo: {
|
||||
name: "pro-coding-repro-8841",
|
||||
strategy: "priority",
|
||||
models: [
|
||||
"opencode/north-mini-code-free",
|
||||
"opencode/hy3-free",
|
||||
],
|
||||
},
|
||||
handleSingleModel: async () => {
|
||||
dispatches += 1;
|
||||
return upstreamContextOverflowResponse();
|
||||
},
|
||||
log: noopLog,
|
||||
settings: {},
|
||||
allCombos: [],
|
||||
});
|
||||
|
||||
assert.equal(dispatches, 0, `no upstream dispatch (got ${dispatches})`);
|
||||
assert.equal(result.status, 400);
|
||||
const json = await result.json();
|
||||
assert.equal(json.error?.code, "context_length_exceeded");
|
||||
assert.equal(json.diagnostics?.attempted, 0);
|
||||
});
|
||||
Reference in New Issue
Block a user