diff --git a/src/renderer/src/components/ApiModelLabel.tsx b/src/renderer/src/components/ApiModelLabel.tsx index 68cc3dbbaf..c101689ff9 100644 --- a/src/renderer/src/components/ApiModelLabel.tsx +++ b/src/renderer/src/components/ApiModelLabel.tsx @@ -1,5 +1,5 @@ import { Avatar, cn } from '@heroui/react' -import { getModelLogo } from '@renderer/config/models' +import { getModelLogoById } from '@renderer/config/models' import { ApiModel } from '@renderer/types' import React from 'react' @@ -19,7 +19,10 @@ export interface ModelLabelProps extends Omit export const ApiModelLabel: React.FC = ({ model, className, classNames, ...props }) => { return (
- + {model?.name} | {model?.provider_name} diff --git a/src/renderer/src/components/Avatar/ModelAvatar.tsx b/src/renderer/src/components/Avatar/ModelAvatar.tsx index 22fafcd98f..04e8615fbb 100644 --- a/src/renderer/src/components/Avatar/ModelAvatar.tsx +++ b/src/renderer/src/components/Avatar/ModelAvatar.tsx @@ -14,7 +14,7 @@ interface Props { const ModelAvatar: FC = ({ model, size, props, className }) => { return ( = ({ model, apiFilter, modelFilter, showTa ), icon: ( - + {first(model.name) || 'M'} ), diff --git a/src/renderer/src/components/Popups/SelectModelPopup/popup.tsx b/src/renderer/src/components/Popups/SelectModelPopup/popup.tsx index 0e4ca65036..60ebc3fe77 100644 --- a/src/renderer/src/components/Popups/SelectModelPopup/popup.tsx +++ b/src/renderer/src/components/Popups/SelectModelPopup/popup.tsx @@ -123,7 +123,7 @@ const PopupContainer: React.FC = ({ model, filter: baseFilter, showTagFil ), icon: ( - + {first(model.name) || 'M'} ), diff --git a/src/renderer/src/components/Popups/agent/AgentModal.tsx b/src/renderer/src/components/Popups/agent/AgentModal.tsx index d190c33179..248bfd2823 100644 --- a/src/renderer/src/components/Popups/agent/AgentModal.tsx +++ b/src/renderer/src/components/Popups/agent/AgentModal.tsx @@ -16,7 +16,7 @@ import { import { loggerService } from '@logger' import type { Selection } from '@react-types/shared' import ClaudeIcon from '@renderer/assets/images/models/claude.png' -import { agentModelFilter, getModelLogo } from '@renderer/config/models' +import { agentModelFilter, getModelLogoById } from '@renderer/config/models' import { permissionModeCards } from '@renderer/constants/permissionModes' import { useAgents } from '@renderer/hooks/agents/useAgents' import { useApiModels } from '@renderer/hooks/agents/useModels' @@ -244,7 +244,7 @@ export const AgentModal: React.FC = ({ agent, isOpen: _isOpen, onClose: _ type: 'model', key: model.id, label: model.name, - avatar: getModelLogo(model.id), + avatar: getModelLogoById(model.id), providerId: model.provider, providerName: model.provider_name })) satisfies ModelOption[] diff --git a/src/renderer/src/components/Popups/agent/shared.tsx b/src/renderer/src/components/Popups/agent/shared.tsx index cc67a5a33b..5de33d0bc8 100644 --- a/src/renderer/src/components/Popups/agent/shared.tsx +++ b/src/renderer/src/components/Popups/agent/shared.tsx @@ -7,7 +7,7 @@ export interface BaseOption { key: string label: string // img src - avatar: string + avatar?: string } export interface ModelOption extends BaseOption { diff --git a/src/renderer/src/config/models/logo.ts b/src/renderer/src/config/models/logo.ts index 40df0af30e..ef8cc87125 100644 --- a/src/renderer/src/config/models/logo.ts +++ b/src/renderer/src/config/models/logo.ts @@ -155,8 +155,9 @@ import ZhipuModelLogoDark from '@renderer/assets/images/models/zhipu_dark.png' import YoudaoLogo from '@renderer/assets/images/providers/netease-youdao.svg' import NomicLogo from '@renderer/assets/images/providers/nomic.png' import ZhipuProviderLogo from '@renderer/assets/images/providers/zhipu.png' +import { Model } from '@renderer/types' -export function getModelLogo(modelId: string) { +export function getModelLogoById(modelId: string): string | undefined { const isLight = true if (!modelId) { @@ -289,7 +290,7 @@ export function getModelLogo(modelId: string) { longcat: LongCatAppLogo, bytedance: BytedanceModelLogo, '(V_1|V_1_TURBO|V_2|V_2A|V_2_TURBO|DESCRIBE|UPSCALE)': IdeogramModelLogo - } as const + } as const satisfies Record for (const key in logoMap) { const regex = new RegExp(key, 'i') @@ -300,3 +301,7 @@ export function getModelLogo(modelId: string) { return undefined } + +export function getModelLogo(model: Model | undefined | null): string | undefined { + return model ? (getModelLogoById(model.id) ?? getModelLogoById(model.name)) : undefined +} diff --git a/src/renderer/src/config/models/reasoning.ts b/src/renderer/src/config/models/reasoning.ts index a7e825ef4f..c3134b1f7d 100644 --- a/src/renderer/src/config/models/reasoning.ts +++ b/src/renderer/src/config/models/reasoning.ts @@ -59,7 +59,15 @@ export const MODEL_SUPPORTED_OPTIONS: ThinkingOptionConfig = { deepseek_hybrid: ['off', ...MODEL_SUPPORTED_REASONING_EFFORT.deepseek_hybrid] as const } as const -export const getThinkModelType = (model: Model): ThinkingModelType => { +const withModelIdAndNameAsId = (model: Model, fn: (model: Model) => T): { idResult: T; nameResult: T } => { + const modelWithNameAsId = { ...model, id: model.name } + return { + idResult: fn(model), + nameResult: fn(modelWithNameAsId) + } +} + +const _getThinkModelType = (model: Model): ThinkingModelType => { let thinkingModelType: ThinkingModelType = 'default' const modelId = getLowerBaseModelName(model.id) if (isGPT5SeriesModel(model)) { @@ -99,12 +107,16 @@ export const getThinkModelType = (model: Model): ThinkingModelType => { return thinkingModelType } -/** 用于判断是否支持控制思考,但不一定以reasoning_effort的方式 */ -export function isSupportedThinkingTokenModel(model?: Model): boolean { - if (!model) { - return false +export const getThinkModelType = (model: Model): ThinkingModelType => { + const { idResult, nameResult } = withModelIdAndNameAsId(model, _getThinkModelType) + if (idResult !== 'default') { + return idResult + } else { + return nameResult } +} +function _isSupportedThinkingTokenModel(model: Model): boolean { // Specifically for DeepSeek V3.1. White list for now if (isDeepSeekHybridInferenceModel(model)) { return ( @@ -132,6 +144,13 @@ export function isSupportedThinkingTokenModel(model?: Model): boolean { ) } +/** 用于判断是否支持控制思考,但不一定以reasoning_effort的方式 */ +export function isSupportedThinkingTokenModel(model?: Model): boolean { + if (!model) return false + const { idResult, nameResult } = withModelIdAndNameAsId(model, _isSupportedThinkingTokenModel) + return idResult || nameResult +} + export function isSupportedReasoningEffortModel(model?: Model): boolean { if (!model) { return false diff --git a/src/renderer/src/pages/home/Inputbar/MentionModelsButton.tsx b/src/renderer/src/pages/home/Inputbar/MentionModelsButton.tsx index 27de57c564..1122fef0d8 100644 --- a/src/renderer/src/pages/home/Inputbar/MentionModelsButton.tsx +++ b/src/renderer/src/pages/home/Inputbar/MentionModelsButton.tsx @@ -134,7 +134,7 @@ const MentionModelsButton: FC = ({ ), description: , icon: ( - + {first(m.name)} ), @@ -170,7 +170,7 @@ const MentionModelsButton: FC = ({ ), description: , icon: ( - + {first(m.name)} ), diff --git a/src/renderer/src/pages/home/Messages/ChatFlowHistory.tsx b/src/renderer/src/pages/home/Messages/ChatFlowHistory.tsx index 9cd1db2163..4559387437 100644 --- a/src/renderer/src/pages/home/Messages/ChatFlowHistory.tsx +++ b/src/renderer/src/pages/home/Messages/ChatFlowHistory.tsx @@ -3,7 +3,7 @@ import '@xyflow/react/dist/style.css' import { RobotOutlined, UserOutlined } from '@ant-design/icons' import EmojiAvatar from '@renderer/components/Avatar/EmojiAvatar' import ModelAvatar from '@renderer/components/Avatar/ModelAvatar' -import { getModelLogo } from '@renderer/config/models' +import { getModelLogo, getModelLogoById } from '@renderer/config/models' import { useTheme } from '@renderer/context/ThemeProvider' import useAvatar from '@renderer/hooks/useAvatar' import { useSettings } from '@renderer/hooks/useSettings' @@ -49,6 +49,7 @@ const TooltipFooter = styled.div` ` // 自定义节点组件 +// FIXME: no any plz... const CustomNode: FC<{ data: any }> = ({ data }) => { const { t } = useTranslation() const { setTimeoutTimer } = useTimer() @@ -87,7 +88,7 @@ const CustomNode: FC<{ data: any }> = ({ data }) => { if (data.modelInfo) { avatar = } else if (data.modelId) { - const modelLogo = getModelLogo(data.modelId) + const modelLogo = getModelLogo(data.modelInfo) ?? getModelLogoById(data.modelId) avatar = ( type FlowEdge = Edge @@ -202,6 +204,7 @@ const defaultEdgeOptions = { const ChatFlowHistory: FC = ({ conversationId }) => { const { t } = useTranslation() + // FIXME: no any plz const [nodes, setNodes, onNodesChange] = useNodesState([]) const [edges, setEdges, onEdgesChange] = useEdgesState([]) const [loading, setLoading] = useState(true) @@ -408,6 +411,7 @@ const ChatFlowHistory: FC = ({ conversationId }) => { const assistantNodeId = `orphan-assistant-${aMsg.id}` // 获取模型数据 + // FIXME: No any plz const aMsgAny = aMsg as any // 获取模型名称 diff --git a/src/renderer/src/pages/home/Messages/MessageAnchorLine.tsx b/src/renderer/src/pages/home/Messages/MessageAnchorLine.tsx index f4ac909b91..d36448913f 100644 --- a/src/renderer/src/pages/home/Messages/MessageAnchorLine.tsx +++ b/src/renderer/src/pages/home/Messages/MessageAnchorLine.tsx @@ -1,6 +1,6 @@ import EmojiAvatar from '@renderer/components/Avatar/EmojiAvatar' import { APP_NAME, AppLogo, isLocalAi } from '@renderer/config/env' -import { getModelLogo } from '@renderer/config/models' +import { getModelLogoById } from '@renderer/config/models' import { useTheme } from '@renderer/context/ThemeProvider' import useAvatar from '@renderer/hooks/useAvatar' import { useSettings } from '@renderer/hooks/useSettings' @@ -25,7 +25,7 @@ interface MessageLineProps { const getAvatarSource = (isLocalAi: boolean, modelId: string | undefined) => { if (isLocalAi) return AppLogo - return modelId ? getModelLogo(modelId) : undefined + return modelId ? getModelLogoById(modelId) : undefined } const MessageAnchorLine: FC = ({ messages }) => { diff --git a/src/renderer/src/pages/home/Messages/MessageHeader.tsx b/src/renderer/src/pages/home/Messages/MessageHeader.tsx index 95a6d219cb..b43e12ce18 100644 --- a/src/renderer/src/pages/home/Messages/MessageHeader.tsx +++ b/src/renderer/src/pages/home/Messages/MessageHeader.tsx @@ -2,7 +2,7 @@ import EmojiAvatar from '@renderer/components/Avatar/EmojiAvatar' import { HStack } from '@renderer/components/Layout' import UserPopup from '@renderer/components/Popups/UserPopup' import { APP_NAME, AppLogo, isLocalAi } from '@renderer/config/env' -import { getModelLogo } from '@renderer/config/models' +import { getModelLogoById } from '@renderer/config/models' import { useTheme } from '@renderer/context/ThemeProvider' import { useAgent } from '@renderer/hooks/agents/useAgent' import useAvatar from '@renderer/hooks/useAvatar' @@ -32,7 +32,7 @@ interface Props { const getAvatarSource = (isLocalAi: boolean, modelId: string | undefined) => { if (isLocalAi) return AppLogo - return modelId ? getModelLogo(modelId) : undefined + return modelId ? getModelLogoById(modelId) : undefined } const MessageHeader: FC = memo(({ assistant, model, message, topic, isGroupContextMessage }) => { diff --git a/src/renderer/src/pages/settings/ProviderSettings/ModelList/ManageModelsList.tsx b/src/renderer/src/pages/settings/ProviderSettings/ModelList/ManageModelsList.tsx index 2210c8bd30..064055129b 100644 --- a/src/renderer/src/pages/settings/ProviderSettings/ModelList/ManageModelsList.tsx +++ b/src/renderer/src/pages/settings/ProviderSettings/ModelList/ManageModelsList.tsx @@ -2,7 +2,7 @@ import ExpandableText from '@renderer/components/ExpandableText' import ModelIdWithTags from '@renderer/components/ModelIdWithTags' import CustomTag from '@renderer/components/Tags/CustomTag' import { DynamicVirtualList } from '@renderer/components/VirtualList' -import { getModelLogo } from '@renderer/config/models' +import { getModelLogoById } from '@renderer/config/models' import { isNewApiProvider } from '@renderer/config/providers' import FileItem from '@renderer/pages/files/FileItem' import NewApiBatchAddModelPopup from '@renderer/pages/settings/ProviderSettings/ModelList/NewApiBatchAddModelPopup' @@ -200,7 +200,7 @@ const ModelListItem: React.FC = memo(({ model, provider, onA boxShadow: 'none' }} fileInfo={{ - icon: {model?.name?.[0]?.toUpperCase()}, + icon: {model?.name?.[0]?.toUpperCase()}, name: , extra: model.description && , ext: '.model', diff --git a/src/renderer/src/pages/settings/ProviderSettings/ModelList/ModelListItem.tsx b/src/renderer/src/pages/settings/ProviderSettings/ModelList/ModelListItem.tsx index 186f11d220..24d64fdfbe 100644 --- a/src/renderer/src/pages/settings/ProviderSettings/ModelList/ModelListItem.tsx +++ b/src/renderer/src/pages/settings/ProviderSettings/ModelList/ModelListItem.tsx @@ -36,7 +36,7 @@ const ModelListItem: React.FC = ({ ref, model, modelStatus, return ( - + {model?.name?.[0]?.toUpperCase()}