mirror of
https://github.com/BerriAI/litellm.git
synced 2026-09-10 22:41:41 +00:00
feat(ui): make automatic auto-router setup discoverable and show what it configured (#40146)
* fix(ui): expand Detailed Configuration after automatic auto-router setup * feat(ui): promote automatic auto-router setup to a callout banner * test(ui): read tier chips through testing-library queries to stay in lint budget * style(ui): drop explanatory comments per repo convention * test(ui): reject unexpected automatic tier models
This commit is contained in:
parent
b618c7ad86
commit
7c1745cc71
2 changed files with 45 additions and 21 deletions
|
|
@ -60,6 +60,20 @@ const optionByLabel = (label: string): HTMLElement | undefined =>
|
|||
|
||||
const isOptionDisabled = (option: HTMLElement): boolean => option.getAttribute("aria-disabled") === "true";
|
||||
|
||||
const tierChips = (tier: string): HTMLElement => {
|
||||
const placeholder = `Select model(s) for ${tier.toLowerCase()} queries`;
|
||||
const chips = screen
|
||||
.getAllByRole("toolbar")
|
||||
.find((candidate) => within(candidate).queryByLabelText(placeholder) !== null);
|
||||
if (!chips) throw new Error(`No tier row found for "${tier}"`);
|
||||
return chips;
|
||||
};
|
||||
|
||||
const expectTierModel = (tier: string, model: string): void => {
|
||||
const chips = within(tierChips(tier)).getAllByLabelText(/.+/, { selector: '[data-slot="combobox-chip"]' });
|
||||
expect(chips.map((chip) => chip.getAttribute("aria-label"))).toEqual([model]);
|
||||
};
|
||||
|
||||
const selectTemplate = async (label: string): Promise<void> => {
|
||||
await userEvent.click(optionByLabel(label)!);
|
||||
};
|
||||
|
|
@ -188,11 +202,10 @@ describe("AddAutoRouterTab", () => {
|
|||
const button = await screen.findByTestId("configure-automatically-button");
|
||||
await userEvent.click(button);
|
||||
|
||||
expect(
|
||||
screen.getByText(
|
||||
/Simple: gpt-5.6-luna.*Medium: claude-sonnet-5.*Complex: claude-opus-5.*Reasoning: claude-opus-5/,
|
||||
),
|
||||
).toBeInTheDocument();
|
||||
expectTierModel("Simple", "gpt-5.6-luna");
|
||||
expectTierModel("Medium", "claude-sonnet-5");
|
||||
expectTierModel("Complex", "claude-opus-5");
|
||||
expectTierModel("Reasoning", "claude-opus-5");
|
||||
expect(toast.success).not.toHaveBeenCalledWith(expect.stringContaining("Configured with"));
|
||||
});
|
||||
|
||||
|
|
@ -209,9 +222,23 @@ describe("AddAutoRouterTab", () => {
|
|||
const button = await screen.findByTestId("configure-automatically-button");
|
||||
await userEvent.click(button);
|
||||
|
||||
expect(
|
||||
screen.getByText(/Simple: gpt-5.6-luna.*Medium: claude-sonnet-5.*Complex: gpt-5.6-sol.*Reasoning: gpt-5.6-sol/),
|
||||
).toBeInTheDocument();
|
||||
expectTierModel("Simple", "gpt-5.6-luna");
|
||||
expectTierModel("Medium", "claude-sonnet-5");
|
||||
expectTierModel("Complex", "gpt-5.6-sol");
|
||||
expectTierModel("Reasoning", "gpt-5.6-sol");
|
||||
});
|
||||
|
||||
it("opens Detailed Configuration on the tiers automatic setup just filled in", async () => {
|
||||
const simpleModel = "gpt-5.6-luna";
|
||||
mockFetchAvailableModels.mockResolvedValue([...ALL_FAMILY_MODELS, { model_group: simpleModel, mode: "chat" }]);
|
||||
renderWithProviders(<Harness />);
|
||||
|
||||
expect(screen.queryByText("Complexity Tier Configuration")).not.toBeInTheDocument();
|
||||
|
||||
await userEvent.click(await screen.findByTestId("configure-automatically-button"));
|
||||
|
||||
expect(screen.getByText("Complexity Tier Configuration")).toBeInTheDocument();
|
||||
expectTierModel("Simple", simpleModel);
|
||||
});
|
||||
|
||||
// Nothing is filled in, so there is nothing to submit. The button reports that itself instead of
|
||||
|
|
|
|||
|
|
@ -207,10 +207,6 @@ const AddAutoRouterTab: React.FC<AddAutoRouterTabProps> = ({
|
|||
const [isSubmitting, setIsSubmitting] = useState(false);
|
||||
|
||||
const [selectedPreset, setSelectedPreset] = useState<string | undefined>(undefined);
|
||||
// Closed by default: a caller opens it deliberately, either by clicking it or by choosing Custom
|
||||
// (which expands it automatically, since there's nothing else to show them their config from). A
|
||||
// preset re-collapses it after prefilling, offering the same "here's what got filled in, expand to
|
||||
// change it" affordance. A caller can always toggle it manually at any point.
|
||||
const [detailsExpanded, setDetailsExpanded] = useState<boolean>(false);
|
||||
|
||||
const [isRoutingTestVisible, setIsRoutingTestVisible] = useState<boolean>(false);
|
||||
|
|
@ -335,7 +331,7 @@ const AddAutoRouterTab: React.FC<AddAutoRouterTabProps> = ({
|
|||
if (automaticRouterConfig === null) return;
|
||||
setSelectedPreset(undefined);
|
||||
applyPrefill({ ...buildEmptyPrefill(), complexityRouterConfig: automaticRouterConfig });
|
||||
setDetailsExpanded(false);
|
||||
setDetailsExpanded(true);
|
||||
toast.success("Automatic setup created", { description: tierConfigSummary(automaticRouterConfig) });
|
||||
};
|
||||
|
||||
|
|
@ -543,14 +539,15 @@ const AddAutoRouterTab: React.FC<AddAutoRouterTabProps> = ({
|
|||
</FormField>
|
||||
|
||||
{!automaticSetupLoading && automaticRouterConfig && (
|
||||
<button
|
||||
type="button"
|
||||
className="mt-3 rounded-sm text-sm font-medium text-blue-600 hover:text-blue-700 hover:underline focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-blue-500 focus-visible:ring-offset-2"
|
||||
data-testid="configure-automatically-button"
|
||||
onClick={handleAutomaticSetup}
|
||||
>
|
||||
Configure automatically
|
||||
</button>
|
||||
<div className="mt-5 flex flex-wrap items-center justify-between gap-3 rounded-lg border border-border bg-muted px-4 py-3">
|
||||
<div>
|
||||
<p className="text-sm font-medium text-foreground">Not sure where to start?</p>
|
||||
<p className="text-sm text-muted-foreground">Let us pick models for each complexity tier.</p>
|
||||
</div>
|
||||
<Button type="button" data-testid="configure-automatically-button" onClick={handleAutomaticSetup}>
|
||||
Configure automatically
|
||||
</Button>
|
||||
</div>
|
||||
)}
|
||||
|
||||
<div className="mt-5">
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue