mirror of
https://github.com/BerriAI/litellm.git
synced 2026-10-10 03:28:53 +00:00
fix(ui): name the orphaned keyword rules inside the tier editor before Done
This commit is contained in:
parent
14a34f45d0
commit
b4af020632
5 changed files with 57 additions and 1 deletions
|
|
@ -1094,6 +1094,25 @@ describe("ComplexityRouterConfig tier editing", () => {
|
|||
expect(screen.queryByRole("button", { name: "Edit tiers" })).not.toBeInTheDocument();
|
||||
});
|
||||
|
||||
it("surfaces the caller's orphaned-rule verdict while editing, so Done is not a silent exit", () => {
|
||||
renderEditor(customValue, { keywordRulesError: "Keyword rule(s) 1 route to a tier this router no longer has" });
|
||||
expect(
|
||||
screen.getByText("Keyword rule(s) 1 route to a tier this router no longer has", { exact: false }),
|
||||
).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it("keeps the orphaned-rule verdict out of the collapsed view, where the submit tooltip owns it", () => {
|
||||
renderWithProviders(
|
||||
<ComplexityRouterConfig
|
||||
{...baseProps}
|
||||
value={customValue}
|
||||
onEditingTiersChange={vi.fn()}
|
||||
keywordRulesError="Keyword rule(s) 1 route to a tier this router no longer has"
|
||||
/>,
|
||||
);
|
||||
expect(screen.queryByText("route to a tier this router no longer has", { exact: false })).not.toBeInTheDocument();
|
||||
});
|
||||
|
||||
it("renders the four built-in tiers before any edit, unchanged", () => {
|
||||
renderWithProviders(<ComplexityRouterConfig {...baseProps} onEditingTiersChange={vi.fn()} />);
|
||||
expect(screen.getByRole("button", { name: "Edit tiers" })).toBeInTheDocument();
|
||||
|
|
|
|||
|
|
@ -197,10 +197,11 @@ const TierSetToolbar: React.FC<{
|
|||
isCustomSet: boolean;
|
||||
rowCount: number;
|
||||
rowsError: string | null;
|
||||
keywordRulesError: string | null | undefined;
|
||||
onEditingChange: ((editing: boolean) => void) | undefined;
|
||||
onAdd: () => void;
|
||||
onRestore: () => void;
|
||||
}> = ({ editing, isCustomSet, rowCount, rowsError, onEditingChange, onAdd, onRestore }) => (
|
||||
}> = ({ editing, isCustomSet, rowCount, rowsError, keywordRulesError, onEditingChange, onAdd, onRestore }) => (
|
||||
<>
|
||||
<div className="mt-4 flex flex-wrap items-center gap-2">
|
||||
{editing ? (
|
||||
|
|
@ -234,6 +235,11 @@ const TierSetToolbar: React.FC<{
|
|||
and an edited set requires the LLM classification method
|
||||
</span>
|
||||
)}
|
||||
{editing && keywordRulesError && (
|
||||
<span className="block mt-1 text-xs text-destructive">
|
||||
{keywordRulesError}. Edit the rules under Advanced: Keyword/Semantic Matching, or bring the tier back
|
||||
</span>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
|
||||
|
|
@ -419,6 +425,8 @@ interface ComplexityRouterConfigProps {
|
|||
// rules or semantic matching, so it renders this component without them.
|
||||
keywordTierRules?: KeywordTierRule[];
|
||||
onKeywordTierRulesChange?: (rules: KeywordTierRule[]) => void;
|
||||
/** getKeywordTierRulesError's verdict, owned by the caller: importing it here would be an import cycle. */
|
||||
keywordRulesError?: string | null;
|
||||
semanticMatchingEnabled?: boolean;
|
||||
onSemanticMatchingEnabledChange?: (enabled: boolean) => void;
|
||||
embeddingModel?: string;
|
||||
|
|
@ -569,6 +577,7 @@ const ComplexityRouterConfig: React.FC<ComplexityRouterConfigProps> = ({
|
|||
onCustomTechnicalKeywordsChange,
|
||||
keywordTierRules = [],
|
||||
onKeywordTierRulesChange,
|
||||
keywordRulesError,
|
||||
semanticMatchingEnabled = false,
|
||||
onSemanticMatchingEnabledChange,
|
||||
embeddingModel,
|
||||
|
|
@ -739,6 +748,7 @@ const ComplexityRouterConfig: React.FC<ComplexityRouterConfigProps> = ({
|
|||
isCustomSet={Boolean(customTierSet)}
|
||||
rowCount={tierRows.length}
|
||||
rowsError={tierRowsError}
|
||||
keywordRulesError={keywordRulesError}
|
||||
onEditingChange={onEditingTiersChange}
|
||||
onAdd={addCustomTier}
|
||||
onRestore={exitToBuiltInTiers}
|
||||
|
|
|
|||
|
|
@ -283,6 +283,25 @@ describe("AddAutoRouterTab", () => {
|
|||
expect(screen.queryByText("At least one keyword is required")).not.toBeInTheDocument();
|
||||
});
|
||||
|
||||
it("shows the orphaned-rule reason in the tier editor when a rule's tier is removed", async () => {
|
||||
const user = userEvent.setup();
|
||||
vi.mocked(getMissingTiersError).mockReturnValue(null);
|
||||
|
||||
renderWithProviders(<Harness />);
|
||||
|
||||
await user.type(screen.getByPlaceholderText(/smart_router/i), "orphan-rule-router");
|
||||
expandDetailedConfiguration();
|
||||
await user.click(screen.getByText("Advanced: Keyword/Semantic Matching"));
|
||||
await user.click(screen.getByRole("button", { name: /add keyword rule/i }));
|
||||
await addKeyword(user, screen.getByText("Keywords 1").closest("div") as HTMLElement, "invoice");
|
||||
|
||||
await user.click(screen.getByRole("button", { name: "Edit tiers" }));
|
||||
await user.click(screen.getByRole("button", { name: "Remove the COMPLEX tier" }));
|
||||
|
||||
expect(await screen.findByText(/route to a tier this router no longer has/)).toBeInTheDocument();
|
||||
expect(screen.getByRole("button", { name: /add auto router/i })).toBeDisabled();
|
||||
});
|
||||
|
||||
it("marks only the offending keyword row, leaving a filled one alone", async () => {
|
||||
const user = userEvent.setup();
|
||||
vi.mocked(getMissingTiersError).mockReturnValue(null);
|
||||
|
|
|
|||
|
|
@ -581,6 +581,10 @@ const AddAutoRouterTab: React.FC<AddAutoRouterTabProps> = ({
|
|||
onCustomTechnicalKeywordsChange={setCustomTechnicalKeywords}
|
||||
keywordTierRules={keywordTierRules}
|
||||
onKeywordTierRulesChange={setKeywordTierRules}
|
||||
keywordRulesError={getKeywordTierRulesError(
|
||||
keywordTierRules,
|
||||
activeTierRows(complexityRouterConfig),
|
||||
)}
|
||||
semanticMatchingEnabled={semanticMatchingEnabled}
|
||||
onSemanticMatchingEnabledChange={setSemanticMatchingEnabled}
|
||||
embeddingModel={embeddingModel}
|
||||
|
|
|
|||
|
|
@ -687,6 +687,10 @@ const EditAutoRouterModal: React.FC<EditAutoRouterModalProps> = ({
|
|||
onCustomTechnicalKeywordsChange={setCustomTechnicalKeywords}
|
||||
keywordTierRules={keywordTierRules}
|
||||
onKeywordTierRulesChange={setKeywordTierRules}
|
||||
keywordRulesError={getKeywordTierRulesError(
|
||||
keywordTierRules,
|
||||
activeTierRows(complexityRouterConfig),
|
||||
)}
|
||||
semanticMatchingEnabled={semanticMatchingEnabled}
|
||||
onSemanticMatchingEnabledChange={setSemanticMatchingEnabled}
|
||||
embeddingModel={embeddingModel}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue