mirror of
https://github.com/BerriAI/litellm.git
synced 2026-09-13 23:11:40 +00:00
fix(ui): split semantic cache out of the Redis Type dropdown
Semantic is a caching strategy, not a Redis network topology, so listing it next to Node/Cluster/Sentinel conflated two orthogonal dimensions and confused users. Replace the single Redis Type dropdown with a Cache Type selector (Standard vs Semantic) and a separate Redis Deployment Type selector (Node/Cluster/Sentinel) shown only for standard caching, since redis-semantic connects to a single node only. Also derive redis_type as semantic on read so the selection round-trips on reload.
This commit is contained in:
parent
60729f733e
commit
3b89c594fa
2 changed files with 129 additions and 0 deletions
|
|
@ -0,0 +1,67 @@
|
|||
import { describe, expect, it, vi } from "vitest";
|
||||
import { fireEvent, render, screen, waitFor } from "@testing-library/react";
|
||||
import CacheTypeSelector from "./CacheTypeSelector";
|
||||
|
||||
const renderStandard = (overrides: Partial<React.ComponentProps<typeof CacheTypeSelector>> = {}) =>
|
||||
render(
|
||||
<CacheTypeSelector
|
||||
cacheMode="standard"
|
||||
deploymentType="node"
|
||||
onCacheModeChange={vi.fn()}
|
||||
onDeploymentTypeChange={vi.fn()}
|
||||
{...overrides}
|
||||
/>,
|
||||
);
|
||||
|
||||
const openSelectFor = (labelText: string) => {
|
||||
const selector = screen.getByText(labelText).parentElement!.querySelector(".ant-select-selector");
|
||||
fireEvent.mouseDown(selector as Element);
|
||||
};
|
||||
|
||||
const optionLabels = async (): Promise<string[]> =>
|
||||
waitFor(() => {
|
||||
const options = Array.from(document.querySelectorAll(".ant-select-item-option-content"));
|
||||
expect(options.length).toBeGreaterThan(0);
|
||||
return options.map((el) => el.textContent ?? "");
|
||||
});
|
||||
|
||||
describe("CacheTypeSelector", () => {
|
||||
it("should not offer Semantic as a Redis deployment type", async () => {
|
||||
renderStandard();
|
||||
|
||||
openSelectFor("Redis Deployment Type");
|
||||
|
||||
expect(await optionLabels()).toEqual(["Node (Single Instance)", "Cluster", "Sentinel"]);
|
||||
});
|
||||
|
||||
it("should offer Semantic only as a Cache Type", async () => {
|
||||
renderStandard();
|
||||
|
||||
openSelectFor("Cache Type");
|
||||
|
||||
expect(await optionLabels()).toEqual(["Standard (exact match)", "Semantic (similarity-based)"]);
|
||||
});
|
||||
|
||||
it("should call onCacheModeChange with semantic when the semantic cache type is chosen", async () => {
|
||||
const onCacheModeChange = vi.fn();
|
||||
renderStandard({ onCacheModeChange });
|
||||
|
||||
openSelectFor("Cache Type");
|
||||
const semantic = await waitFor(() => {
|
||||
const match = Array.from(document.querySelectorAll(".ant-select-item-option")).find((el) =>
|
||||
el.textContent?.includes("Semantic"),
|
||||
);
|
||||
expect(match).toBeTruthy();
|
||||
return match as HTMLElement;
|
||||
});
|
||||
fireEvent.click(semantic);
|
||||
|
||||
expect(onCacheModeChange).toHaveBeenCalledWith("semantic");
|
||||
});
|
||||
|
||||
it("should hide the deployment type selector when semantic caching is selected", () => {
|
||||
renderStandard({ cacheMode: "semantic" });
|
||||
|
||||
expect(screen.queryByText("Redis Deployment Type")).not.toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
|
|
@ -0,0 +1,62 @@
|
|||
import React from "react";
|
||||
import { Select } from "antd";
|
||||
import {
|
||||
CACHE_MODES,
|
||||
CACHE_MODE_DESCRIPTIONS,
|
||||
CACHE_MODE_LABELS,
|
||||
CacheMode,
|
||||
REDIS_DEPLOYMENT_DESCRIPTIONS,
|
||||
REDIS_DEPLOYMENT_LABELS,
|
||||
REDIS_DEPLOYMENT_TYPES,
|
||||
RedisDeploymentType,
|
||||
} from "./cacheSettingsFields";
|
||||
|
||||
interface CacheTypeSelectorProps {
|
||||
cacheMode: CacheMode;
|
||||
deploymentType: RedisDeploymentType;
|
||||
onCacheModeChange: (mode: CacheMode) => void;
|
||||
onDeploymentTypeChange: (type: RedisDeploymentType) => void;
|
||||
}
|
||||
|
||||
const cacheModeOptions = CACHE_MODES.map((mode) => ({ value: mode, label: CACHE_MODE_LABELS[mode] }));
|
||||
const deploymentTypeOptions = REDIS_DEPLOYMENT_TYPES.map((type) => ({
|
||||
value: type,
|
||||
label: REDIS_DEPLOYMENT_LABELS[type],
|
||||
}));
|
||||
|
||||
const CacheTypeSelector: React.FC<CacheTypeSelectorProps> = ({
|
||||
cacheMode,
|
||||
deploymentType,
|
||||
onCacheModeChange,
|
||||
onDeploymentTypeChange,
|
||||
}) => {
|
||||
return (
|
||||
<div className="space-y-6">
|
||||
<div className="space-y-2">
|
||||
<label className="text-sm font-medium text-gray-700">Cache Type</label>
|
||||
<Select<CacheMode>
|
||||
value={cacheMode}
|
||||
onChange={(value) => onCacheModeChange(value)}
|
||||
options={cacheModeOptions}
|
||||
style={{ width: "100%" }}
|
||||
/>
|
||||
<p className="text-xs text-gray-500">{CACHE_MODE_DESCRIPTIONS[cacheMode]}</p>
|
||||
</div>
|
||||
|
||||
{cacheMode === "standard" && (
|
||||
<div className="space-y-2">
|
||||
<label className="text-sm font-medium text-gray-700">Redis Deployment Type</label>
|
||||
<Select<RedisDeploymentType>
|
||||
value={deploymentType}
|
||||
onChange={(value) => onDeploymentTypeChange(value)}
|
||||
options={deploymentTypeOptions}
|
||||
style={{ width: "100%" }}
|
||||
/>
|
||||
<p className="text-xs text-gray-500">{REDIS_DEPLOYMENT_DESCRIPTIONS[deploymentType]}</p>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default CacheTypeSelector;
|
||||
Loading…
Add table
Reference in a new issue