mirror of
https://github.com/BerriAI/litellm.git
synced 2026-09-13 23:11:40 +00:00
fix(ui): require object JSON for routing_strategy_args and render cleared args as unset
This commit is contained in:
parent
a29bf27913
commit
c816a6aac6
4 changed files with 65 additions and 6 deletions
|
|
@ -6,7 +6,7 @@ import TextArea from "antd/es/input/TextArea";
|
|||
import { InfoCircleOutlined } from "@ant-design/icons";
|
||||
import { Team } from "../key_team_helpers/key_list";
|
||||
import CacheControlSettings from "./cache_control_settings";
|
||||
import { ROUTING_STRATEGY_OPTIONS } from "./routing_strategy_options";
|
||||
import { formItemValidateJSONObject, ROUTING_STRATEGY_OPTIONS } from "./routing_strategy_options";
|
||||
import VectorStoreSelector from "../vector_store_management/VectorStoreSelector";
|
||||
import { Tag } from "../tag_management/types";
|
||||
import { formItemValidateJSON } from "../../utils/textUtils";
|
||||
|
|
@ -197,7 +197,7 @@ const AdvancedSettings: React.FC<AdvancedSettingsProps> = ({
|
|||
label="Routing Strategy Args"
|
||||
name="routing_strategy_args"
|
||||
className="mb-4"
|
||||
rules={[{ validator: formItemValidateJSON }]}
|
||||
rules={[{ validator: formItemValidateJSONObject }]}
|
||||
help="Optional JSON args for the selected strategy, e.g. latency window TTL."
|
||||
>
|
||||
<TextArea rows={2} placeholder='{"ttl": 3600}' />
|
||||
|
|
|
|||
|
|
@ -0,0 +1,37 @@
|
|||
import { describe, expect, it } from "vitest";
|
||||
import { formItemValidateJSONObject, hasRoutingStrategyArgs, routingStrategyLabel } from "./routing_strategy_options";
|
||||
|
||||
describe("formItemValidateJSONObject", () => {
|
||||
it("accepts empty input and JSON objects", async () => {
|
||||
await expect(formItemValidateJSONObject(undefined, "")).resolves.toBeUndefined();
|
||||
await expect(formItemValidateJSONObject(undefined, '{"ttl": 3600}')).resolves.toBeUndefined();
|
||||
await expect(formItemValidateJSONObject(undefined, "{}")).resolves.toBeUndefined();
|
||||
});
|
||||
|
||||
it("rejects JSON that is not an object", async () => {
|
||||
await expect(formItemValidateJSONObject(undefined, "[1, 2]")).rejects.toMatch(/JSON object/);
|
||||
await expect(formItemValidateJSONObject(undefined, "3600")).rejects.toMatch(/JSON object/);
|
||||
await expect(formItemValidateJSONObject(undefined, "null")).rejects.toMatch(/JSON object/);
|
||||
});
|
||||
|
||||
it("rejects invalid JSON", async () => {
|
||||
await expect(formItemValidateJSONObject(undefined, "{ttl:")).rejects.toMatch(/valid JSON/);
|
||||
});
|
||||
});
|
||||
|
||||
describe("hasRoutingStrategyArgs", () => {
|
||||
it("treats empty and missing objects as unset", () => {
|
||||
expect(hasRoutingStrategyArgs(undefined)).toBe(false);
|
||||
expect(hasRoutingStrategyArgs(null)).toBe(false);
|
||||
expect(hasRoutingStrategyArgs({})).toBe(false);
|
||||
expect(hasRoutingStrategyArgs({ ttl: 3600 })).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
describe("routingStrategyLabel", () => {
|
||||
it("labels known strategies and defaults the rest", () => {
|
||||
expect(routingStrategyLabel("cost-based-routing")).toContain("Cost-Based");
|
||||
expect(routingStrategyLabel(undefined)).toBe("Inherit router default");
|
||||
expect(routingStrategyLabel("")).toBe("Inherit router default");
|
||||
});
|
||||
});
|
||||
|
|
@ -11,3 +11,20 @@ export const routingStrategyLabel = (value: string | undefined | null): string =
|
|||
const match = ROUTING_STRATEGY_OPTIONS.find((o) => o.value === value);
|
||||
return match ? match.label : "Inherit router default";
|
||||
};
|
||||
|
||||
export const hasRoutingStrategyArgs = (args: object | undefined | null): boolean => Object.keys(args ?? {}).length > 0;
|
||||
|
||||
export const formItemValidateJSONObject = (_: unknown, value: string) => {
|
||||
if (!value) {
|
||||
return Promise.resolve();
|
||||
}
|
||||
try {
|
||||
const parsed = JSON.parse(value);
|
||||
if (parsed === null || Array.isArray(parsed) || typeof parsed !== "object") {
|
||||
return Promise.reject('Must be a JSON object, e.g. {"ttl": 3600}');
|
||||
}
|
||||
return Promise.resolve();
|
||||
} catch (error) {
|
||||
return Promise.reject("Please enter valid JSON");
|
||||
}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -18,7 +18,12 @@ import {
|
|||
Button as TremorButton,
|
||||
} from "@tremor/react";
|
||||
import { Button, Form, Input, Modal, Select, Tooltip } from "antd";
|
||||
import { ROUTING_STRATEGY_OPTIONS, routingStrategyLabel } from "./add_model/routing_strategy_options";
|
||||
import {
|
||||
formItemValidateJSONObject,
|
||||
hasRoutingStrategyArgs,
|
||||
ROUTING_STRATEGY_OPTIONS,
|
||||
routingStrategyLabel,
|
||||
} from "./add_model/routing_strategy_options";
|
||||
import VectorStoreSelector from "./vector_store_management/VectorStoreSelector";
|
||||
import { CheckIcon, CopyIcon } from "lucide-react";
|
||||
import { useEffect, useMemo, useState } from "react";
|
||||
|
|
@ -819,7 +824,7 @@ export default function ModelInfoView({
|
|||
tags: Array.isArray(localModelData.litellm_params?.tags) ? localModelData.litellm_params.tags : [],
|
||||
health_check_model: isWildcardModel ? localModelData.model_info?.health_check_model : null,
|
||||
routing_strategy: localModelData.model_info?.routing_strategy || "",
|
||||
routing_strategy_args: localModelData.model_info?.routing_strategy_args
|
||||
routing_strategy_args: hasRoutingStrategyArgs(localModelData.model_info?.routing_strategy_args)
|
||||
? JSON.stringify(localModelData.model_info.routing_strategy_args)
|
||||
: "",
|
||||
litellm_credential_name: localModelData.litellm_params?.litellm_credential_name || "",
|
||||
|
|
@ -1115,13 +1120,13 @@ export default function ModelInfoView({
|
|||
<Form.Item
|
||||
name="routing_strategy_args"
|
||||
className="mb-0"
|
||||
rules={[{ validator: formItemValidateJSON }]}
|
||||
rules={[{ validator: formItemValidateJSONObject }]}
|
||||
>
|
||||
<Input placeholder='{"ttl": 3600}' />
|
||||
</Form.Item>
|
||||
) : (
|
||||
<div className="mt-1 p-2 bg-gray-50 rounded-sm">
|
||||
{localModelData.model_info?.routing_strategy_args
|
||||
{hasRoutingStrategyArgs(localModelData.model_info?.routing_strategy_args)
|
||||
? JSON.stringify(localModelData.model_info.routing_strategy_args)
|
||||
: "Not Set"}
|
||||
</div>
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue