+
+
+
+ Keyword Tier Overrides
+
+
+
+
+
+
} onClick={addRule}>
+ Add keyword rule
+
+
+
+ Optional: route requests containing specific keywords directly to a tier, e.g. route "invoice, refund,
+ billing" to the medium tier.
+
+
+ {rules.length === 0 ? (
+
+
+
+ ) : (
+
+ {rules.map((rule, index) => (
+
+
+
+
+ Keywords {index + 1}
+
+
updateRule(rule.id, { keywords })}
+ placeholder="e.g., invoice, refund, billing"
+ tokenSeparators={[","]}
+ open={false}
+ suffixIcon={null}
+ style={{ width: "100%" }}
+ allowClear
+ />
+
+
+
+ Route to tier
+
+
updateRule(rule.id, { tier })}
+ options={TIER_OPTIONS}
+ style={{ width: "100%" }}
+ />
+
+
}
+ aria-label={`Remove keyword rule ${index + 1}`}
+ onClick={() => removeRule(rule.id)}
+ />
+
+
+ ))}
+
+ )}
+
+ );
+};
+
+export default KeywordTierRules;
diff --git a/ui/litellm-dashboard/src/components/add_model/SemanticKeywordMatching.tsx b/ui/litellm-dashboard/src/components/add_model/SemanticKeywordMatching.tsx
new file mode 100644
index 00000000000..0f9907ac6c9
--- /dev/null
+++ b/ui/litellm-dashboard/src/components/add_model/SemanticKeywordMatching.tsx
@@ -0,0 +1,84 @@
+import { InfoCircleOutlined } from "@ant-design/icons";
+import { Card, InputNumber, Select as AntdSelect, Switch, Tooltip, Typography } from "antd";
+import React from "react";
+import { ModelGroup } from "@/components/llm_calls/fetch_models";
+
+const { Text } = Typography;
+
+const DEFAULT_MATCH_THRESHOLD = 0.5;
+
+interface SemanticKeywordMatchingProps {
+ enabled: boolean;
+ onEnabledChange: (enabled: boolean) => void;
+ embeddingModel: string | undefined;
+ onEmbeddingModelChange: (model: string) => void;
+ matchThreshold: number;
+ onMatchThresholdChange: (threshold: number) => void;
+ modelInfo: ModelGroup[];
+}
+
+const SemanticKeywordMatching: React.FC