feat:webui支持更加优化的模型配置,优化多处UI体验,支持设置视觉和cache价格,修复多重表达不生效的问题,修复表情包路径错误

This commit is contained in:
SengokuCola
2026-05-04 22:52:41 +08:00
parent 14b7bc78a2
commit eea95c1961
38 changed files with 1188 additions and 454 deletions

View File

@@ -55,6 +55,11 @@ export const ModelCardList = React.memo(function ModelCardList({
>
{used ? '已使用' : '未使用'}
</Badge>
{model.visual && (
<Badge variant="outline" className="border-blue-500 text-blue-600">
</Badge>
)}
</div>
<p className="text-xs text-muted-foreground break-all" title={model.model_identifier}>
{model.model_identifier}

View File

@@ -67,6 +67,7 @@ export const ModelTable = React.memo(function ModelTable({
<TableHead></TableHead>
<TableHead></TableHead>
<TableHead></TableHead>
<TableHead className="text-center"></TableHead>
<TableHead className="text-center"></TableHead>
<TableHead className="text-right"></TableHead>
<TableHead className="text-right"></TableHead>
@@ -76,7 +77,7 @@ export const ModelTable = React.memo(function ModelTable({
<TableBody>
{paginatedModels.length === 0 ? (
<TableRow>
<TableCell colSpan={9} className="text-center text-muted-foreground py-8">
<TableCell colSpan={10} className="text-center text-muted-foreground py-8">
{searchQuery ? '未找到匹配的模型' : '暂无模型配置'}
</TableCell>
</TableRow>
@@ -105,6 +106,15 @@ export const ModelTable = React.memo(function ModelTable({
{model.model_identifier}
</TableCell>
<TableCell>{model.api_provider}</TableCell>
<TableCell className="text-center">
{model.visual ? (
<Badge variant="outline" className="border-blue-500 text-blue-600">
</Badge>
) : (
<span className="text-muted-foreground">-</span>
)}
</TableCell>
<TableCell className="text-center">
{model.temperature != null ? model.temperature : <span className="text-muted-foreground">-</span>}
</TableCell>
@@ -139,4 +149,4 @@ export const ModelTable = React.memo(function ModelTable({
</div>
</div>
)
})
})

View File

@@ -13,6 +13,12 @@ import {
SelectTrigger,
SelectValue,
} from '@/components/ui/select'
import {
Tooltip,
TooltipContent,
TooltipProvider,
TooltipTrigger,
} from '@/components/ui/tooltip'
import { cn } from '@/lib/utils'
import type { TaskConfig } from '../types'
@@ -25,9 +31,28 @@ interface TaskConfigCardProps {
hideTemperature?: boolean
hideMaxTokens?: boolean
advanced?: boolean
showAdvancedSettings?: boolean
dataTour?: string
}
const selectionStrategyOptions = [
{
value: 'balance',
label: '负载均衡balance',
description: '优先选择当前使用次数较少的模型,适合多个同类模型共同承担请求。',
},
{
value: 'random',
label: '随机选择random',
description: '每次请求从模型列表中随机选择一个模型,适合简单分散请求。',
},
{
value: 'sequential',
label: '按顺序优先sequential',
description: '优先使用模型列表中靠前的模型,前面的模型不可用时再尝试后面的模型。',
},
]
export const TaskConfigCard = React.memo(function TaskConfigCard({
title,
description,
@@ -37,6 +62,7 @@ export const TaskConfigCard = React.memo(function TaskConfigCard({
hideTemperature = false,
hideMaxTokens = false,
advanced = false,
showAdvancedSettings = false,
dataTour,
}: TaskConfigCardProps) {
const handleModelChange = (values: string[]) => {
@@ -68,8 +94,8 @@ export const TaskConfigCard = React.memo(function TaskConfigCard({
/>
</div>
{/* 温度和最大 Token */}
<div className="grid grid-cols-1 sm:grid-cols-2 gap-4">
{/* 推理参数 */}
<div className="grid grid-cols-1 gap-4 lg:grid-cols-3">
{!hideTemperature && (
<div className="grid gap-3">
<div className="flex items-center justify-between">
@@ -112,51 +138,66 @@ export const TaskConfigCard = React.memo(function TaskConfigCard({
/>
</div>
)}
</div>
{/* 慢请求阈值 */}
<div className="grid gap-2">
<div className="flex items-center justify-between">
<Label> ()</Label>
<span className="text-xs text-muted-foreground"></span>
{/* 模型选择策略 */}
<div className="grid gap-2">
<Label></Label>
<Select
value={taskConfig.selection_strategy ?? 'balance'}
onValueChange={(value) => onChange('selection_strategy', value)}
>
<SelectTrigger>
<SelectValue placeholder="选择模型选择策略" />
</SelectTrigger>
<SelectContent>
<TooltipProvider delayDuration={150}>
{selectionStrategyOptions.map((option) => (
<Tooltip key={option.value}>
<TooltipTrigger asChild>
<SelectItem value={option.value} title={option.description}>
{option.label}
</SelectItem>
</TooltipTrigger>
<TooltipContent
side="right"
align="center"
className="max-w-72 bg-background text-foreground border shadow-lg"
>
{option.description}
</TooltipContent>
</Tooltip>
))}
</TooltipProvider>
</SelectContent>
</Select>
</div>
<Input
type="number"
step="1"
min="1"
value={taskConfig.slow_threshold ?? 15}
onChange={(e) => {
const value = parseInt(e.target.value)
if (!isNaN(value) && value >= 1) {
onChange('slow_threshold', value)
}
}}
placeholder="15"
/>
<p className="text-xs text-muted-foreground">
</p>
</div>
{/* 模型选择策略 */}
<div className="grid gap-2">
<Label></Label>
<Select
value={taskConfig.selection_strategy ?? 'balance'}
onValueChange={(value) => onChange('selection_strategy', value)}
>
<SelectTrigger>
<SelectValue placeholder="选择模型选择策略" />
</SelectTrigger>
<SelectContent>
<SelectItem value="balance">balance</SelectItem>
<SelectItem value="random">random</SelectItem>
</SelectContent>
</Select>
<p className="text-xs text-muted-foreground">
使
</p>
</div>
{showAdvancedSettings && (
<div className="grid gap-2 rounded-md border border-amber-200 bg-amber-50/50 p-3 dark:border-amber-500/40 dark:bg-amber-500/10">
<div className="flex items-center justify-between">
<Label> ()</Label>
<span className="text-xs text-muted-foreground"></span>
</div>
<Input
type="number"
step="1"
min="1"
value={taskConfig.slow_threshold ?? 15}
onChange={(e) => {
const value = parseInt(e.target.value)
if (!isNaN(value) && value >= 1) {
onChange('slow_threshold', value)
}
}}
placeholder="15"
/>
<p className="text-xs text-muted-foreground">
</p>
</div>
)}
</div>
</div>
)