feat(ui): add_model/ComplexityRouterConfig to shadcn

- antd Select/Card/Divider/Space/Tooltip/Typography + @ant-design
  InfoCircleOutlined \u2192 shadcn Select/Card/Tooltip + lucide Info +
  native <hr className='border-border'> and plain h4/p.
- Preserves the full four-tier mapping layout and help card.

Gates: TS \u2713 | Build \u2713.

Co-authored-by: yuneng-jiang <yuneng-berri@users.noreply.github.com>
This commit is contained in:
Cursor Agent 2026-04-23 13:00:56 +00:00
parent 1323d05634
commit 9896a1680b
No known key found for this signature in database

View file

@ -1,10 +1,21 @@
import { InfoCircleOutlined } from "@ant-design/icons";
import { Select as AntdSelect, Card, Divider, Space, Tooltip, Typography } from "antd";
import { Card } from "@/components/ui/card";
import {
Select,
SelectContent,
SelectItem,
SelectTrigger,
SelectValue,
} from "@/components/ui/select";
import {
Tooltip,
TooltipContent,
TooltipProvider,
TooltipTrigger,
} from "@/components/ui/tooltip";
import { Info } from "lucide-react";
import React from "react";
import { ModelGroup } from "../playground/llm_calls/fetch_models";
const { Text } = Typography;
interface ComplexityTiers {
SIMPLE: string;
MEDIUM: string;
@ -18,7 +29,10 @@ interface ComplexityRouterConfigProps {
onChange: (tiers: ComplexityTiers) => void;
}
const TIER_DESCRIPTIONS: Record<keyof ComplexityTiers, { label: string; description: string; examples: string }> = {
const TIER_DESCRIPTIONS: Record<
keyof ComplexityTiers,
{ label: string; description: string; examples: string }
> = {
SIMPLE: {
label: "Simple",
description: "Basic questions, greetings, simple factual queries",
@ -32,7 +46,8 @@ const TIER_DESCRIPTIONS: Record<keyof ComplexityTiers, { label: string; descript
COMPLEX: {
label: "Complex",
description: "Technical, multi-part requests requiring deep knowledge",
examples: '"Design a microservices architecture", "Implement a rate limiter"',
examples:
'"Design a microservices architecture", "Implement a rate limiter"',
},
REASONING: {
label: "Reasoning",
@ -41,8 +56,11 @@ const TIER_DESCRIPTIONS: Record<keyof ComplexityTiers, { label: string; descript
},
};
const ComplexityRouterConfig: React.FC<ComplexityRouterConfigProps> = ({ modelInfo, value, onChange }) => {
// Prepare model options for dropdowns
const ComplexityRouterConfig: React.FC<ComplexityRouterConfigProps> = ({
modelInfo,
value,
onChange,
}) => {
const modelOptions = modelInfo.map((model) => ({
value: model.model_group,
label: model.model_group,
@ -57,64 +75,90 @@ const ComplexityRouterConfig: React.FC<ComplexityRouterConfigProps> = ({ modelIn
return (
<div className="w-full max-w-none">
<Space align="center" style={{ marginBottom: 16 }}>
<Typography.Title level={4} style={{ margin: 0 }}>
<div className="flex items-center gap-2 mb-4">
<h4 className="text-lg font-semibold m-0">
Complexity Tier Configuration
</Typography.Title>
<Tooltip title="Map each complexity tier to a model. Simple queries use cheaper/faster models, complex queries use more capable models.">
<InfoCircleOutlined className="text-gray-400" />
</Tooltip>
</Space>
</h4>
<TooltipProvider>
<Tooltip>
<TooltipTrigger asChild>
<Info className="h-3.5 w-3.5 text-muted-foreground" />
</TooltipTrigger>
<TooltipContent className="max-w-xs">
Map each complexity tier to a model. Simple queries use
cheaper/faster models, complex queries use more capable models.
</TooltipContent>
</Tooltip>
</TooltipProvider>
</div>
<Text type="secondary" style={{ display: "block", marginBottom: 24 }}>
The complexity router automatically classifies requests by complexity using rule-based scoring (no API calls,
&lt;1ms latency). Configure which model handles each tier.
</Text>
<p className="text-sm text-muted-foreground block mb-6">
The complexity router automatically classifies requests by complexity
using rule-based scoring (no API calls, &lt;1ms latency). Configure
which model handles each tier.
</p>
<Card>
{(Object.keys(TIER_DESCRIPTIONS) as Array<keyof ComplexityTiers>).map((tier, index) => {
const tierInfo = TIER_DESCRIPTIONS[tier];
return (
<div key={tier}>
{index > 0 && <Divider style={{ margin: "16px 0" }} />}
<div className="mb-4">
<div className="flex items-center gap-2 mb-2">
<Text strong style={{ fontSize: 16 }}>
{tierInfo.label} Tier
</Text>
<Tooltip title={tierInfo.description}>
<InfoCircleOutlined className="text-gray-400" />
</Tooltip>
<Card className="p-4">
{(Object.keys(TIER_DESCRIPTIONS) as Array<keyof ComplexityTiers>).map(
(tier, index) => {
const tierInfo = TIER_DESCRIPTIONS[tier];
return (
<div key={tier}>
{index > 0 && <hr className="my-4 border-border" />}
<div className="mb-4">
<div className="flex items-center gap-2 mb-2">
<span className="font-bold text-base">
{tierInfo.label} Tier
</span>
<TooltipProvider>
<Tooltip>
<TooltipTrigger asChild>
<Info className="h-3.5 w-3.5 text-muted-foreground" />
</TooltipTrigger>
<TooltipContent className="max-w-xs">
{tierInfo.description}
</TooltipContent>
</Tooltip>
</TooltipProvider>
</div>
<p className="text-xs text-muted-foreground block mb-2">
Examples: {tierInfo.examples}
</p>
<Select
value={value[tier]}
onValueChange={(model) => handleTierChange(tier, model)}
>
<SelectTrigger className="w-full">
<SelectValue
placeholder={`Select model for ${tierInfo.label.toLowerCase()} queries`}
/>
</SelectTrigger>
<SelectContent>
{modelOptions.map((opt) => (
<SelectItem key={opt.value} value={opt.value}>
{opt.label}
</SelectItem>
))}
</SelectContent>
</Select>
</div>
<Text type="secondary" style={{ display: "block", marginBottom: 8, fontSize: 12 }}>
Examples: {tierInfo.examples}
</Text>
<AntdSelect
value={value[tier]}
onChange={(model) => handleTierChange(tier, model)}
placeholder={`Select model for ${tierInfo.label.toLowerCase()} queries`}
showSearch
style={{ width: "100%" }}
options={modelOptions}
/>
</div>
</div>
);
})}
);
},
)}
</Card>
<Divider />
<hr className="my-4 border-border" />
<Card className="bg-gray-50">
<Text strong style={{ display: "block", marginBottom: 8 }}>
How Classification Works
</Text>
<Text type="secondary" style={{ fontSize: 13 }}>
The router scores each request across 7 dimensions: token count, code presence, reasoning markers, technical
terms, simple indicators, multi-step patterns, and question complexity. The weighted score determines the
tier:
</Text>
<ul style={{ marginTop: 8, marginBottom: 0, paddingLeft: 20, fontSize: 13, color: "rgba(0, 0, 0, 0.45)" }}>
<Card className="bg-muted p-4">
<p className="font-bold block mb-2">How Classification Works</p>
<p className="text-[13px] text-muted-foreground">
The router scores each request across 7 dimensions: token count, code
presence, reasoning markers, technical terms, simple indicators,
multi-step patterns, and question complexity. The weighted score
determines the tier:
</p>
<ul className="mt-2 mb-0 pl-5 text-[13px] text-muted-foreground">
<li>
<strong>SIMPLE</strong>: Score &lt; 0.15
</li>
@ -125,7 +169,8 @@ const ComplexityRouterConfig: React.FC<ComplexityRouterConfigProps> = ({ modelIn
<strong>COMPLEX</strong>: Score 0.35 - 0.60
</li>
<li>
<strong>REASONING</strong>: Score &gt; 0.60 (or 2+ reasoning markers)
<strong>REASONING</strong>: Score &gt; 0.60 (or 2+ reasoning
markers)
</li>
</ul>
</Card>