feat(agent): support selecting models from api with calculated prices
parent
109d9cc779
commit
7cf68160a8
11
src/api.ts
11
src/api.ts
|
|
@ -111,6 +111,17 @@ export interface ChatHistoryResp {
|
|||
branches: Record<string, BranchInfo>;
|
||||
}
|
||||
|
||||
export interface AiModel {
|
||||
model_name: string;
|
||||
icon: string;
|
||||
model_ratio: number;
|
||||
completion_ratio: number;
|
||||
}
|
||||
|
||||
export const ModelAPI = {
|
||||
list: () => api.get<{ data: AiModel[] }>('/models').then((r) => r.data.data),
|
||||
};
|
||||
|
||||
export const AgentAPI = {
|
||||
list: () => api.get<Agent[]>('/agents').then((r) => r.data),
|
||||
detail: (id: string) => api.get<Agent>(`/agents/${id}`).then((r) => r.data),
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ import { useEffect, useRef, useState } from 'react';
|
|||
import { Button, Form, Input, InputNumber, Modal, Upload, App as AntApp, List, Popconfirm, Tag, Switch, Select, Collapse } 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 } from '../api';
|
||||
import { Agent, AgentAPI, ImageAPI, KnowledgeStatus, SkillType, Team, TeamAPI, AiModel, ModelAPI } from '../api';
|
||||
import SkillEditor from '../components/SkillEditor';
|
||||
import McpPanel from '../components/McpPanel';
|
||||
import ChatPreview from '../components/ChatPreview';
|
||||
|
|
@ -37,6 +37,7 @@ export default function AgentEditor() {
|
|||
const [agent, setAgent] = useState<Agent | null>(null);
|
||||
const [saving, setSaving] = useState(false);
|
||||
const [teams, setTeams] = useState<Team[]>([]);
|
||||
const [models, setModels] = useState<AiModel[]>([]);
|
||||
const [autoSaveStatus, setAutoSaveStatus] = useState<'saved' | 'saving' | 'error'>('saved');
|
||||
const [initModalOpen, setInitModalOpen] = useState(isNew);
|
||||
const [selectedAvatar, setSelectedAvatar] = useState(DEFAULT_AVATAR);
|
||||
|
|
@ -74,6 +75,9 @@ export default function AgentEditor() {
|
|||
TeamAPI.list()
|
||||
.then(setTeams)
|
||||
.catch(() => setTeams([]));
|
||||
ModelAPI.list()
|
||||
.then(setModels)
|
||||
.catch(() => setModels([]));
|
||||
if (isNew) {
|
||||
setInitModalOpen(true);
|
||||
setSelectedAvatar(DEFAULT_AVATAR);
|
||||
|
|
@ -475,9 +479,29 @@ export default function AgentEditor() {
|
|||
label="模型"
|
||||
className="mb-0"
|
||||
>
|
||||
<Input
|
||||
placeholder="默认模型"
|
||||
style={{ borderRadius: 12, height: 42 }}
|
||||
<Select
|
||||
placeholder="选择模型"
|
||||
style={{ height: 42 }}
|
||||
dropdownStyle={{ borderRadius: 12 }}
|
||||
options={models.map((m) => {
|
||||
const inputPrice = 2 * m.model_ratio;
|
||||
const outputPrice = inputPrice * m.completion_ratio;
|
||||
return {
|
||||
value: m.model_name,
|
||||
label: (
|
||||
<div className="flex items-center justify-between w-full py-1">
|
||||
<div className="flex items-center gap-2">
|
||||
<img src={m.icon} alt={m.model_name} className="w-5 h-5 object-contain rounded" />
|
||||
<span className="font-medium text-gray-800">{m.model_name}</span>
|
||||
</div>
|
||||
<div className="flex flex-col items-end justify-center text-[10px] text-gray-400">
|
||||
<span>输入: ${inputPrice.toFixed(2)}/M</span>
|
||||
<span>输出: ${outputPrice.toFixed(2)}/M</span>
|
||||
</div>
|
||||
</div>
|
||||
),
|
||||
};
|
||||
})}
|
||||
/>
|
||||
</Form.Item>
|
||||
<Form.Item
|
||||
|
|
|
|||
Loading…
Reference in New Issue