fix: fix show model name

main
yannyang 2026-08-03 21:24:12 +08:00
parent cabea3f83a
commit 46ddf0652a
3 changed files with 50 additions and 16 deletions

View File

@ -1,17 +1,23 @@
import { useEffect, useMemo, useState } from 'react'; import { useEffect, useMemo, useState } from 'react';
import { Agent, AgentAPI } from '../../api'; import { Agent, AgentAPI, ModelAPI, AiModel } from '../../api';
import { useAuth } from '../../store/auth'; import { useAuth } from '../../store/auth';
export function useAgentListLogic() { export function useAgentListLogic() {
const { user } = useAuth(); const { user } = useAuth();
const [list, setList] = useState<Agent[]>([]); const [list, setList] = useState<Agent[]>([]);
const [models, setModels] = useState<AiModel[]>([]);
const [loading, setLoading] = useState(false); const [loading, setLoading] = useState(false);
const load = async () => { const load = async () => {
if (!user?.phone) return; if (!user?.phone) return;
setLoading(true); setLoading(true);
try { try {
setList(await AgentAPI.mine(user.phone)); const [agentList, modelList] = await Promise.all([
AgentAPI.mine(user.phone),
ModelAPI.list()
]);
setList(agentList);
setModels(modelList);
} finally { } finally {
setLoading(false); setLoading(false);
} }
@ -29,9 +35,17 @@ export function useAgentListLogic() {
const isImageUrl = (url?: string): boolean => !!(url?.startsWith('http') || url?.startsWith('/')); const isImageUrl = (url?: string): boolean => !!(url?.startsWith('http') || url?.startsWith('/'));
const getModelLabel = (value: unknown): string => { const getModelLabel = (value: unknown): string => {
const findModelName = (id: string) => {
const model = models.find(m => m.id === id);
return model ? model.model_name : id;
};
if (Array.isArray(value)) { if (Array.isArray(value)) {
const names = value const names = value
.map((item: any) => (typeof item === 'string' ? item : item?.name)) .map((item: any) => {
if (typeof item === 'string') return findModelName(item);
return item?.name || findModelName(item?.id);
})
.map((v) => String(v || '').trim()) .map((v) => String(v || '').trim())
.filter(Boolean); .filter(Boolean);
return names.join('、'); return names.join('、');
@ -43,7 +57,10 @@ export function useAgentListLogic() {
const parsed = JSON.parse(raw); const parsed = JSON.parse(raw);
if (Array.isArray(parsed)) { if (Array.isArray(parsed)) {
const names = parsed const names = parsed
.map((item: any) => (typeof item === 'string' ? item : item?.name)) .map((item: any) => {
if (typeof item === 'string') return findModelName(item);
return item?.name || findModelName(item?.id);
})
.map((v) => String(v || '').trim()) .map((v) => String(v || '').trim())
.filter(Boolean); .filter(Boolean);
return names.join('、'); return names.join('、');
@ -54,11 +71,11 @@ export function useAgentListLogic() {
if (raw.includes(',')) { if (raw.includes(',')) {
return raw return raw
.split(',') .split(',')
.map((s) => s.trim()) .map((s) => findModelName(s.trim()))
.filter(Boolean) .filter(Boolean)
.join('、'); .join('、');
} }
return raw; return findModelName(raw);
}; };
const publicCount = useMemo(() => list.filter((a) => a.visibility === 'public').length, [list]); const publicCount = useMemo(() => list.filter((a) => a.visibility === 'public').length, [list]);

View File

@ -80,7 +80,9 @@ export default function AgentListWeb({ logic }: Props) {
</div> </div>
) : ( ) : (
<Row gutter={[18, 18]}> <Row gutter={[18, 18]}>
{list.map((a) => ( {list.map((a) => {
const modelLabel = getModelLabel(a.model);
return (
<Col xs={24} sm={12} md={8} lg={6} key={a.id}> <Col xs={24} sm={12} md={8} lg={6} key={a.id}>
<div className="agent-card"> <div className="agent-card">
<div className="agent-card-header"> <div className="agent-card-header">
@ -124,14 +126,14 @@ export default function AgentListWeb({ logic }: Props) {
</Tag> </Tag>
)} )}
{getModelLabel(a.model) && ( {modelLabel && (
<Tag <Tag
bordered={false} bordered={false}
className="agent-card-tag-model" className="agent-card-tag-model"
style={{ background: 'var(--color-brand-soft)', color: 'var(--color-brand)', borderRadius: 999, margin: 0, maxWidth: '100%' }} style={{ background: 'var(--color-brand-soft)', color: 'var(--color-brand)', borderRadius: 999, margin: 0, maxWidth: '100%' }}
> >
<span className="agent-card-tag-model-text"> <span className="agent-card-tag-model-text">
{getModelLabel(a.model)} {modelLabel}
</span> </span>
</Tag> </Tag>
)} )}
@ -168,7 +170,7 @@ export default function AgentListWeb({ logic }: Props) {
</div> </div>
</div> </div>
</Col> </Col>
))} )})}
</Row> </Row>
)} )}

View File

@ -1,9 +1,15 @@
import { useState, useEffect } from 'react';
import { ApiOutlined, DeleteOutlined, EditOutlined, SettingOutlined, EllipsisOutlined, HistoryOutlined, LogoutOutlined } from '@ant-design/icons'; import { ApiOutlined, DeleteOutlined, EditOutlined, SettingOutlined, EllipsisOutlined, HistoryOutlined, LogoutOutlined } from '@ant-design/icons';
import { Button, Dropdown, Modal, Switch } from 'antd'; import { Button, Dropdown, Modal, Switch } from 'antd';
import type { Agent } from '../../../api'; import { Agent, ModelAPI, AiModel } from '../../../api';
import './ChatHeader.css'; import './ChatHeader.css';
function formatAgentModel(raw: string | null | undefined) { function formatAgentModel(raw: string | null | undefined, models: AiModel[]) {
const findModelName = (id: string) => {
const model = models.find(m => m.id === id);
return model ? model.model_name : id;
};
const s = String(raw ?? '').trim(); const s = String(raw ?? '').trim();
if (!s) return '默认模型'; if (!s) return '默认模型';
if (s.startsWith('[') || s.startsWith('{')) { if (s.startsWith('[') || s.startsWith('{')) {
@ -11,19 +17,22 @@ function formatAgentModel(raw: string | null | undefined) {
const parsed = JSON.parse(s); const parsed = JSON.parse(s);
if (Array.isArray(parsed)) { if (Array.isArray(parsed)) {
const names = parsed const names = parsed
.map((x: any) => String(x?.name || x?.model || x?.id || '').trim()) .map((x: any) => {
if (typeof x === 'string') return findModelName(x);
return String(x?.name || x?.model || findModelName(x?.id) || '').trim();
})
.filter(Boolean); .filter(Boolean);
if (names.length > 2) { if (names.length > 2) {
return names.slice(0, 2).join(', ') + '...'; return names.slice(0, 2).join(', ') + '...';
} }
if (names.length) return names.join(', '); if (names.length) return names.join(', ');
} else if (parsed && typeof parsed === 'object') { } else if (parsed && typeof parsed === 'object') {
const name = String((parsed as any).name || (parsed as any).model || (parsed as any).id || '').trim(); const name = String((parsed as any).name || (parsed as any).model || findModelName((parsed as any).id) || '').trim();
if (name) return name; if (name) return name;
} }
} catch {} } catch {}
} }
return s; return findModelName(s);
} }
const isImageUrl = (url: string) => url?.startsWith('http') || url?.startsWith('/'); const isImageUrl = (url: string) => url?.startsWith('http') || url?.startsWith('/');
@ -40,7 +49,13 @@ export default function ChatHeader(props: {
onLogout?: () => void; onLogout?: () => void;
}) { }) {
const { agent, useStream, setUseStream, onOpenHistory, onOpenParams, onOpenMcp, onManageAgent, onClear, onLogout } = props; const { agent, useStream, setUseStream, onOpenHistory, onOpenParams, onOpenMcp, onManageAgent, onClear, onLogout } = props;
const modelText = formatAgentModel(agent.model); const [models, setModels] = useState<AiModel[]>([]);
useEffect(() => {
ModelAPI.list().then(setModels).catch(console.error);
}, []);
const modelText = formatAgentModel(agent.model, models);
return ( return (
<div className="chat-header"> <div className="chat-header">