diff --git a/ui/litellm-dashboard/src/components/add_model/add_auto_router_tab.test.tsx b/ui/litellm-dashboard/src/components/add_model/add_auto_router_tab.test.tsx
index 5304a4b2811..79fa2dab4f8 100644
--- a/ui/litellm-dashboard/src/components/add_model/add_auto_router_tab.test.tsx
+++ b/ui/litellm-dashboard/src/components/add_model/add_auto_router_tab.test.tsx
@@ -210,6 +210,29 @@ describe("AddAutoRouterTab", () => {
expect(handleAddAutoRouterSubmit).not.toHaveBeenCalled();
});
+ it("creates the router once when the form is submitted again mid dry-run", async () => {
+ vi.mocked(getMissingTiersError).mockReturnValue(null);
+ let resolveVerdict: (verdict: { valid: boolean }) => void = () => {};
+ validateAutoRouterConfig.mockImplementationOnce(
+ () =>
+ new Promise((resolve) => {
+ resolveVerdict = resolve;
+ }),
+ );
+
+ const { container } = renderWithProviders();
+ fireEvent.change(screen.getByPlaceholderText(/smart_router/i), { target: { value: "double-submit-router" } });
+
+ fireEvent.submit(container.querySelector("form")!);
+ await waitFor(() => expect(screen.getByRole("button", { name: /add auto router/i })).toBeDisabled());
+ fireEvent.submit(container.querySelector("form")!);
+
+ resolveVerdict({ valid: true });
+ await waitFor(() => expect(screen.getByRole("button", { name: /add auto router/i })).toBeEnabled());
+ expect(validateAutoRouterConfig).toHaveBeenCalledTimes(1);
+ expect(handleAddAutoRouterSubmit).toHaveBeenCalledTimes(1);
+ });
+
it("submits when the dry-run passes, so the gate is not simply blocking everything", async () => {
const user = userEvent.setup();
vi.mocked(getMissingTiersError).mockReturnValue(null);
@@ -652,6 +675,27 @@ describe("AddAutoRouterTab", () => {
await waitFor(() => expect(toast.fromError).toHaveBeenCalledWith(expect.stringContaining("no longer available")));
expect(handleAddAutoRouterSubmit).not.toHaveBeenCalled();
});
+
+ it("carries a preset's per-tier reasoning effort through to the create payload", async () => {
+ const user = userEvent.setup();
+ mockFetchAvailableModels.mockResolvedValue(ALL_FAMILY_MODELS);
+
+ renderWithProviders();
+ await waitForPresetEnabled("Anthropic Family");
+ await selectTemplate("Anthropic Family");
+
+ await user.type(screen.getByPlaceholderText(/smart_router/i), "anthropic-router");
+ await user.click(screen.getByRole("button", { name: /add auto router/i }));
+
+ await waitFor(() => expect(handleAddAutoRouterSubmit).toHaveBeenCalled());
+ expect(vi.mocked(handleAddAutoRouterSubmit).mock.calls.at(-1)?.[0]).toMatchObject({
+ complexity_router_config: {
+ tier_model_configs: {
+ REASONING: [{ model_name: "claude-opus-5", litellm_params: { reasoning_effort: "high" } }],
+ },
+ },
+ });
+ });
});
describe("default model pin", () => {
diff --git a/ui/litellm-dashboard/src/components/add_model/add_auto_router_tab.tsx b/ui/litellm-dashboard/src/components/add_model/add_auto_router_tab.tsx
index 18a0c231899..df6b5334d55 100644
--- a/ui/litellm-dashboard/src/components/add_model/add_auto_router_tab.tsx
+++ b/ui/litellm-dashboard/src/components/add_model/add_auto_router_tab.tsx
@@ -425,6 +425,7 @@ const AddAutoRouterTab: React.FC = ({
};
const handleAutoRouterSubmit = async () => {
+ if (isSubmitting) return;
const name = form.getValues("auto_router_name");
if (!name) {
setShowValidationErrors(true);