refactor(agent-editor): use dropdown checkbox model picker

main
sp mac bookpro 2605 2026-05-29 14:05:12 +08:00
parent 1d79e929f9
commit 6ad8a1517f
2 changed files with 111 additions and 26 deletions

View File

@ -1,5 +1,5 @@
import { useEffect, useRef, useState } from 'react';
import { Button, Form, Input, InputNumber, Modal, Upload, App as AntApp, List, Popconfirm, Tag, Switch, Select, Collapse, Checkbox } from 'antd';
import { Button, Form, Input, InputNumber, Modal, Upload, App as AntApp, List, Popconfirm, Tag, Switch, Select, Collapse, Checkbox, Dropdown } from 'antd';
import type { UploadFile } from 'antd/es/upload/interface';
import { useNavigate, useParams } from 'react-router-dom';
import { Agent, AgentAPI, ImageAPI, KnowledgeStatus, SkillType, Team, TeamAPI, AiModel, ModelAPI } from '../api';
@ -7,7 +7,7 @@ import { DEFAULT_RH_40X40_GRAY } from '../constants';
import SkillEditor from '../components/SkillEditor';
import McpPanel from '../components/McpPanel';
import ChatPreview from '../components/ChatPreview';
import { ArrowLeftOutlined, SaveOutlined, FileTextOutlined, RocketOutlined, ToolOutlined, DatabaseOutlined, SettingOutlined, UploadOutlined } from '@ant-design/icons';
import { ArrowLeftOutlined, SaveOutlined, FileTextOutlined, RocketOutlined, ToolOutlined, DatabaseOutlined, SettingOutlined, UploadOutlined, DownOutlined } from '@ant-design/icons';
const STATUS_TAG: Record<KnowledgeStatus, { color: string; text: string }> = {
pending: { color: 'default', text: '待处理' },
@ -35,6 +35,67 @@ const parseModelSelections = (value?: string | string[]) =>
.map((item) => item.trim())
.filter(Boolean);
function ModelCheckboxDropdown({
value = [],
onChange,
models,
}: {
value?: string[];
onChange?: (value: string[]) => void;
models: AiModel[];
}) {
const [open, setOpen] = useState(false);
const summary = value.length ? `${value.length} 个已选` : '选择模型';
return (
<Dropdown
trigger={['click']}
open={open}
onOpenChange={setOpen}
popupRender={() => (
<div className="agent-model-dropdown-panel" onClick={(e) => e.stopPropagation()}>
<Checkbox.Group
value={value}
onChange={(checked) => onChange?.(checked.map((item) => String(item)))}
className="agent-model-checkbox-group"
>
{models.map((m) => {
const inputPrice = 2 * m.model_ratio;
const outputPrice = inputPrice * m.completion_ratio;
return (
<Checkbox key={m.model_name} value={m.model_name} className="agent-model-checkbox-item">
<div className="agent-model-checkbox-content">
<div className="agent-model-checkbox-meta">
<img
src={m.icon || DEFAULT_RH_40X40_GRAY}
alt={m.model_name}
className="agent-model-checkbox-icon"
/>
<span className="agent-model-checkbox-name">{m.model_name}</span>
</div>
<div className="agent-model-checkbox-price">
<span>: ${inputPrice.toFixed(2)}/M</span>
<span>: ${outputPrice.toFixed(2)}/M</span>
</div>
</div>
</Checkbox>
);
})}
</Checkbox.Group>
</div>
)}
>
<button type="button" className="agent-model-dropdown-trigger">
<span className="agent-model-dropdown-summary">{summary}</span>
<span className="agent-model-dropdown-values">
{value.length ? value.join(', ') : '未选择'}
</span>
<DownOutlined className="agent-model-dropdown-arrow" />
</button>
</Dropdown>
);
}
export default function AgentEditor() {
const { id } = useParams();
const isNew = !id;
@ -493,30 +554,7 @@ export default function AgentEditor() {
Array.isArray(value) ? value.map((item) => String(item).trim()).filter(Boolean).join(', ') : ''
}
>
<Checkbox.Group className="agent-model-checkbox-group">
{models.map((m) => {
const inputPrice = 2 * m.model_ratio;
const outputPrice = inputPrice * m.completion_ratio;
return (
<Checkbox key={m.model_name} value={m.model_name} className="agent-model-checkbox-item">
<div className="agent-model-checkbox-content">
<div className="agent-model-checkbox-meta">
<img
src={m.icon || DEFAULT_RH_40X40_GRAY}
alt={m.model_name}
className="agent-model-checkbox-icon"
/>
<span className="agent-model-checkbox-name">{m.model_name}</span>
</div>
<div className="agent-model-checkbox-price">
<span>: ${inputPrice.toFixed(2)}/M</span>
<span>: ${outputPrice.toFixed(2)}/M</span>
</div>
</div>
</Checkbox>
);
})}
</Checkbox.Group>
<ModelCheckboxDropdown models={models} />
</Form.Item>
<Form.Item
name="temperature"

View File

@ -561,6 +561,53 @@ body {
box-shadow: var(--shadow-focus);
}
.agent-model-dropdown-trigger {
width: 100%;
min-height: 42px;
display: flex;
align-items: center;
gap: 10px;
padding: 10px 12px;
border: 1px solid var(--color-border);
border-radius: 12px;
background: var(--color-surface);
color: var(--color-text);
cursor: pointer;
text-align: left;
}
.agent-model-dropdown-summary {
flex-shrink: 0;
font-weight: 500;
}
.agent-model-dropdown-values {
flex: 1;
min-width: 0;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
color: var(--color-text-secondary);
font-size: 13px;
}
.agent-model-dropdown-arrow {
flex-shrink: 0;
font-size: 12px;
color: var(--color-text-tertiary);
}
.agent-model-dropdown-panel {
width: min(720px, calc(100vw - 64px));
max-height: 360px;
overflow-y: auto;
padding: 12px;
background: var(--color-surface);
border: 1px solid var(--color-border);
border-radius: 12px;
box-shadow: var(--shadow-lg);
}
.agent-model-checkbox-group {
display: flex;
flex-direction: column;