mirror of
https://github.com/BerriAI/litellm.git
synced 2026-10-07 02:59:05 +00:00
feat(ui): add 1M context auto-router preset (#39490)
* feat(ui): add 1M context auto-router preset * feat(ui): use heuristic v2 for 1M preset * fix(ui): keep 1M preset test within lint budget
This commit is contained in:
parent
99da04a1b0
commit
534003da03
4 changed files with 74 additions and 3 deletions
|
|
@ -1,4 +1,26 @@
|
|||
{
|
||||
"1m_context": {
|
||||
"label": "1M Context",
|
||||
"description": "Routes across models with 1M-token context windows: Luna for simple queries, Terra for medium, Opus 5 for complex, Opus 5 at high thinking for reasoning.",
|
||||
"complexity_router_config": {
|
||||
"tiers": {
|
||||
"SIMPLE": ["gpt-5.6-luna"],
|
||||
"MEDIUM": ["gpt-5.6-terra"],
|
||||
"COMPLEX": ["claude-opus-5"],
|
||||
"REASONING": ["claude-opus-5"]
|
||||
},
|
||||
"tier_model_configs": {
|
||||
"REASONING": [{ "model_name": "claude-opus-5", "litellm_params": { "reasoning_effort": "high" } }]
|
||||
},
|
||||
"classifier_type": "heuristic_v2",
|
||||
"escalation_keywords": ["LITELLM ESCALATE"],
|
||||
"classification_mode": "every_request",
|
||||
"session_affinity": false,
|
||||
"modality_routing": false,
|
||||
"modality_pin_override": false,
|
||||
"deployment_affinity": true
|
||||
}
|
||||
},
|
||||
"anthropic_family": {
|
||||
"label": "Anthropic Family",
|
||||
"description": "Routes across the Claude model family: Haiku for simple queries, Sonnet for medium, Opus for complex, Opus at high thinking for reasoning.",
|
||||
|
|
|
|||
|
|
@ -1104,6 +1104,16 @@ def test_get_autorouter_presets_local_mode_serves_bundled_catalog(
|
|||
assert response.status_code == 200
|
||||
payload = response.json()
|
||||
assert "anthropic_family" in payload
|
||||
assert payload["1m_context"]["complexity_router_config"]["classifier_type"] == "heuristic_v2"
|
||||
assert payload["1m_context"]["complexity_router_config"]["tiers"] == {
|
||||
"SIMPLE": ["gpt-5.6-luna"],
|
||||
"MEDIUM": ["gpt-5.6-terra"],
|
||||
"COMPLEX": ["claude-opus-5"],
|
||||
"REASONING": ["claude-opus-5"],
|
||||
}
|
||||
assert payload["1m_context"]["complexity_router_config"]["tier_model_configs"] == {
|
||||
"REASONING": [{"model_name": "claude-opus-5", "litellm_params": {"reasoning_effort": "high"}}]
|
||||
}
|
||||
for preset in payload.values():
|
||||
assert isinstance(preset["label"], str)
|
||||
assert isinstance(preset["description"], str)
|
||||
|
|
|
|||
|
|
@ -636,7 +636,14 @@ describe("AddAutoRouterTab", () => {
|
|||
|
||||
const labels = visibleOptions().map((option) => option.querySelector(".font-medium")?.textContent);
|
||||
|
||||
expect(labels).toEqual(["Anthropic Family", "Gemini Family", "Lite", "OpenAI Family", "Custom Configuration"]);
|
||||
expect(labels).toEqual([
|
||||
"1M Context",
|
||||
"Anthropic Family",
|
||||
"Gemini Family",
|
||||
"Lite",
|
||||
"OpenAI Family",
|
||||
"Custom Configuration",
|
||||
]);
|
||||
});
|
||||
|
||||
describe("routing test", () => {
|
||||
|
|
@ -1060,7 +1067,14 @@ describe("AddAutoRouterTab", () => {
|
|||
expect(isOptionDisabled(optionByLabel("Anthropic Family")!)).toBe(false);
|
||||
});
|
||||
const labels = visibleOptions().map((option) => option.querySelector(".font-medium")?.textContent);
|
||||
expect(labels).toEqual(["Anthropic Family", "Gemini Family", "Lite", "OpenAI Family", "Custom Configuration"]);
|
||||
expect(labels).toEqual([
|
||||
"Anthropic Family",
|
||||
"1M Context",
|
||||
"Gemini Family",
|
||||
"Lite",
|
||||
"OpenAI Family",
|
||||
"Custom Configuration",
|
||||
]);
|
||||
});
|
||||
|
||||
it.each([
|
||||
|
|
|
|||
|
|
@ -28,7 +28,13 @@ const getPresetByKey = (key: string): AutoRouterPreset | undefined => PRESETS.fi
|
|||
describe("autorouter_presets", () => {
|
||||
it("hydrates exactly the bundled presets", () => {
|
||||
const presets = getAllPresets();
|
||||
expect(presets.map((p) => p.label).sort()).toEqual(["Anthropic Family", "Gemini Family", "Lite", "OpenAI Family"]);
|
||||
expect(presets.map((p) => p.label).sort()).toEqual([
|
||||
"1M Context",
|
||||
"Anthropic Family",
|
||||
"Gemini Family",
|
||||
"Lite",
|
||||
"OpenAI Family",
|
||||
]);
|
||||
// Every preset carries all four fields the UI relies on; a JSON typo dropping one fails here.
|
||||
for (const p of presets) {
|
||||
expect(p).toMatchObject({ key: expect.any(String), label: expect.any(String), description: expect.any(String) });
|
||||
|
|
@ -202,6 +208,25 @@ describe("autorouter_presets", () => {
|
|||
});
|
||||
});
|
||||
|
||||
it("pins the 1M context preset to Luna, Terra, and Opus at high thinking", () => {
|
||||
const preset = getPresetByKey("1m_context")!;
|
||||
const expectedTiers = {
|
||||
SIMPLE: ["gpt-5.6-luna"],
|
||||
MEDIUM: ["gpt-5.6-terra"],
|
||||
COMPLEX: ["claude-opus-5"],
|
||||
REASONING: ["claude-opus-5"],
|
||||
};
|
||||
expect(preset.complexity_router_config.classifier_type).toBe("heuristic_v2");
|
||||
expect(preset.complexity_router_config.tiers).toEqual(expectedTiers);
|
||||
expect(preset.complexity_router_config.tier_model_configs).toEqual({
|
||||
REASONING: [{ model_name: "claude-opus-5", litellm_params: { reasoning_effort: "high" } }],
|
||||
});
|
||||
const prefill = buildPresetPrefill(preset.complexity_router_config, groupsOnly(getRequiredModelsInPreset(preset)));
|
||||
expect(prefill.complexityRouterConfig.tier_model_params).toEqual({
|
||||
REASONING: { "claude-opus-5": { reasoning_effort: "high" } },
|
||||
});
|
||||
});
|
||||
|
||||
it("pins the gemini preset to concrete model ids, never Google's hot-swapping -latest aliases", () => {
|
||||
const gemini = getPresetByKey("gemini_family")!;
|
||||
const config = gemini.complexity_router_config;
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue