mirror of
https://github.com/BerriAI/litellm.git
synced 2026-09-09 22:31:41 +00:00
fix(ui): release the plan-mode floor when the non-reasoning tier is cleared
Turning the tier off, or switching to a classifier that cannot emit it, dropped the flag and the pool but left plan_mode_min_tier naming a tier that is no longer active. The backend rejects that on save, and the switch is disabled after a classifier change, so the operator had no way to clear it. Both paths now release the floor when it points at the cleared tier. An orphaned keyword rule is left alone on purpose: getKeywordTierRulesError already names it at the save gate, which is how a removed custom tier behaves.
This commit is contained in:
parent
a4f865b1be
commit
9d7e09e4e8
3 changed files with 48 additions and 10 deletions
|
|
@ -12,11 +12,16 @@ const NonReasoningTierToggle: React.FC<{
|
|||
}> = ({ value, onChange, available }) => {
|
||||
const handleToggle = (enabled: boolean): void => {
|
||||
const { NON_REASONING: existingPool, ...keptTiers } = value.tiers;
|
||||
const next: ComplexityRouterConfigValue = {
|
||||
...value,
|
||||
enable_non_reasoning_tier: enabled ? true : undefined,
|
||||
tiers: enabled ? { ...keptTiers, NON_REASONING: existingPool ?? [] } : keptTiers,
|
||||
};
|
||||
// Turning it off must also release the plan-mode floor, which the backend rejects while it
|
||||
// names an inactive tier. An orphaned keyword rule is left for the save gate to name.
|
||||
const next: ComplexityRouterConfigValue = enabled
|
||||
? { ...value, enable_non_reasoning_tier: true, tiers: { ...keptTiers, NON_REASONING: existingPool ?? [] } }
|
||||
: {
|
||||
...value,
|
||||
enable_non_reasoning_tier: undefined,
|
||||
tiers: keptTiers,
|
||||
plan_mode_min_tier: value.plan_mode_min_tier === "NON_REASONING" ? undefined : value.plan_mode_min_tier,
|
||||
};
|
||||
onChange(next);
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -50,3 +50,22 @@ describe("nonReasoningTierFields", () => {
|
|||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe("stale references to the cleared tier", () => {
|
||||
const withFloorOnTierZero: ComplexityRouterConfigValue = { ...enabledValue, plan_mode_min_tier: "NON_REASONING" };
|
||||
|
||||
it("releases a plan-mode floor pointing at the tier it just cleared", () => {
|
||||
// The backend rejects a floor naming an inactive tier, and the switch is disabled once the
|
||||
// classifier changes, so a floor left behind is a config the operator cannot save or undo.
|
||||
expect(nonReasoningTierFields("heuristic", withFloorOnTierZero).plan_mode_min_tier).toBeUndefined();
|
||||
});
|
||||
|
||||
it("leaves a floor on another tier alone", () => {
|
||||
const floorOnComplex: ComplexityRouterConfigValue = { ...enabledValue, plan_mode_min_tier: "COMPLEX" };
|
||||
expect(nonReasoningTierFields("heuristic", floorOnComplex).plan_mode_min_tier).toBe("COMPLEX");
|
||||
});
|
||||
|
||||
it("keeps the floor while the classifier can still emit the tier", () => {
|
||||
expect(nonReasoningTierFields("llm", withFloorOnTierZero).plan_mode_min_tier).toBe("NON_REASONING");
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -1,14 +1,28 @@
|
|||
import type { ClassifierType, ComplexityRouterConfigValue } from "./ComplexityRouterConfig";
|
||||
|
||||
const NON_REASONING = "NON_REASONING";
|
||||
|
||||
/** The NON_REASONING keys a classifier switch carries forward, or clears for a classifier that
|
||||
* cannot emit the tier. Leaving them set there is a config the backend refuses on save. */
|
||||
* cannot emit the tier. Leaving them set there is a config the backend refuses on save. The floor
|
||||
* goes with them: it is rejected on save while it names an inactive tier, and the switch is
|
||||
* disabled once the classifier changes, so the operator could not clear it themselves.
|
||||
* An orphaned keyword rule is left for getKeywordTierRulesError to name, matching how a removed
|
||||
* custom tier already behaves. */
|
||||
export const nonReasoningTierFields = (
|
||||
classifierType: ClassifierType,
|
||||
value: ComplexityRouterConfigValue,
|
||||
): Pick<ComplexityRouterConfigValue, "enable_non_reasoning_tier" | "tiers"> => {
|
||||
): Pick<ComplexityRouterConfigValue, "enable_non_reasoning_tier" | "tiers" | "plan_mode_min_tier"> => {
|
||||
if (classifierType === "llm") {
|
||||
return { enable_non_reasoning_tier: value.enable_non_reasoning_tier, tiers: value.tiers };
|
||||
return {
|
||||
enable_non_reasoning_tier: value.enable_non_reasoning_tier,
|
||||
tiers: value.tiers,
|
||||
plan_mode_min_tier: value.plan_mode_min_tier,
|
||||
};
|
||||
}
|
||||
const { NON_REASONING: _cleared, ...keptTiers } = value.tiers;
|
||||
return { enable_non_reasoning_tier: undefined, tiers: keptTiers };
|
||||
const { [NON_REASONING]: _cleared, ...tiers } = value.tiers;
|
||||
return {
|
||||
enable_non_reasoning_tier: undefined,
|
||||
tiers,
|
||||
plan_mode_min_tier: value.plan_mode_min_tier === NON_REASONING ? undefined : value.plan_mode_min_tier,
|
||||
};
|
||||
};
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue