feat: add ModelTags component

This commit is contained in:
kangfenmao 2025-01-07 09:54:22 +08:00
parent f68bd4d8d8
commit 2e7ecbc753
6 changed files with 52 additions and 43 deletions

View File

@ -0,0 +1,35 @@
import { isEmbeddingModel, isVisionModel, isWebSearchModel } from '@renderer/config/models'
import { Model } from '@renderer/types'
import { isFreeModel } from '@renderer/utils'
import { Tag } from 'antd'
import { FC } from 'react'
import { useTranslation } from 'react-i18next'
import VisionIcon from './Icons/VisionIcon'
import WebSearchIcon from './Icons/WebSearchIcon'
interface ModelTagsProps {
model: Model
}
const ModelTags: FC<ModelTagsProps> = ({ model }) => {
const { t } = useTranslation()
return (
<>
{isVisionModel(model) && <VisionIcon />}
{isWebSearchModel(model) && <WebSearchIcon />}
{isFreeModel(model) && (
<Tag style={{ marginLeft: 10 }} color="green">
{t('models.free')}
</Tag>
)}
{isEmbeddingModel(model) && (
<Tag style={{ marginLeft: 10 }} color="orange">
{t('models.embedding')}
</Tag>
)}
</>
)
}
export default ModelTags

View File

@ -1,7 +1,7 @@
import { PushpinOutlined, SearchOutlined } from '@ant-design/icons'
import VisionIcon from '@renderer/components/Icons/VisionIcon'
import { TopView } from '@renderer/components/TopView'
import { getModelLogo, isEmbeddingModel, isVisionModel, isWebSearchModel } from '@renderer/config/models'
import { getModelLogo, isEmbeddingModel, isVisionModel } from '@renderer/config/models'
import db from '@renderer/databases'
import { useProviders } from '@renderer/hooks/useProvider'
import { getModelUniqId } from '@renderer/services/ModelService'
@ -12,8 +12,8 @@ import { useEffect, useRef, useState } from 'react'
import { useTranslation } from 'react-i18next'
import styled from 'styled-components'
import WebSearchIcon from '../Icons/WebSearchIcon'
import { HStack } from '../Layout'
import ModelTags from '../ModelTags'
import Scrollbar from '../Scrollbar'
type MenuItem = Required<MenuProps>['items'][number]
@ -75,7 +75,7 @@ const PopupContainer: React.FC<PopupContainerProps> = ({ model, resolve }) => {
label: (
<ModelItem>
<span>
{m?.name} {isVisionModel(m) && <VisionIcon />} {isWebSearchModel(m) && <WebSearchIcon />}
{m?.name} <ModelTags model={m} />
</span>
<PinIcon
onClick={(e) => {

View File

@ -1,8 +1,7 @@
import ModelAvatar from '@renderer/components/Avatar/ModelAvatar'
import VisionIcon from '@renderer/components/Icons/VisionIcon'
import ModelTags from '@renderer/components/ModelTags'
import SelectModelPopup from '@renderer/components/Popups/SelectModelPopup'
import { isLocalAi } from '@renderer/config/env'
import { isVisionModel } from '@renderer/config/models'
import { useAssistant } from '@renderer/hooks/useAssistant'
import { getProviderName } from '@renderer/services/ProviderService'
import { Assistant } from '@renderer/types'
@ -40,7 +39,7 @@ const SelectModelButton: FC<Props> = ({ assistant }) => {
<ModelName>
{model ? model.name : t('button.select_model')} {providerName ? '| ' + providerName : ''}
</ModelName>
{isVisionModel(model) && <VisionIcon style={{ marginLeft: 0 }} />}
<ModelTags model={model} />
</ButtonContent>
</DropdownButton>
)
@ -63,7 +62,6 @@ const ButtonContent = styled.div`
`
const ModelName = styled.span`
margin-left: -2px;
font-weight: 500;
`

View File

@ -1,13 +1,12 @@
import { LoadingOutlined, MinusOutlined, PlusOutlined, QuestionCircleOutlined } from '@ant-design/icons'
import VisionIcon from '@renderer/components/Icons/VisionIcon'
import WebSearchIcon from '@renderer/components/Icons/WebSearchIcon'
import { Center } from '@renderer/components/Layout'
import ModelTags from '@renderer/components/ModelTags'
import { getModelLogo, isEmbeddingModel, isVisionModel, isWebSearchModel, SYSTEM_MODELS } from '@renderer/config/models'
import { useProvider } from '@renderer/hooks/useProvider'
import { fetchModels } from '@renderer/services/ApiService'
import { Model, Provider } from '@renderer/types'
import { getDefaultGroupName, isFreeModel, runAsyncFunction } from '@renderer/utils'
import { Avatar, Button, Empty, Flex, Modal, Popover, Radio, Tag, Tooltip } from 'antd'
import { Avatar, Button, Empty, Flex, Modal, Popover, Radio, Tooltip } from 'antd'
import Search from 'antd/es/input/Search'
import { groupBy, isEmpty, uniqBy } from 'lodash'
import { useEffect, useState } from 'react'
@ -156,18 +155,7 @@ const PopupContainer: React.FC<Props> = ({ provider: _provider, resolve }) => {
<Tooltip title={model.id} placement="top">
<span style={{ cursor: 'help' }}>{model.name}</span>
</Tooltip>
{isVisionModel(model) && <VisionIcon />}
{isWebSearchModel(model) && <WebSearchIcon />}
{isFreeModel(model) && (
<Tag style={{ marginLeft: 10 }} color="green">
{t('models.free')}
</Tag>
)}
{isEmbeddingModel(model) && (
<Tag style={{ marginLeft: 10 }} color="orange">
{t('models.embedding')}
</Tag>
)}
<ModelTags model={model} />
{!isEmpty(model.description) && (
<Popover
trigger="click"

View File

@ -7,16 +7,8 @@ import {
PlusOutlined,
SettingOutlined
} from '@ant-design/icons'
import VisionIcon from '@renderer/components/Icons/VisionIcon'
import WebSearchIcon from '@renderer/components/Icons/WebSearchIcon'
import {
EMBEDDING_REGEX,
getModelLogo,
isEmbeddingModel,
isVisionModel,
isWebSearchModel,
VISION_REGEX
} from '@renderer/config/models'
import ModelTags from '@renderer/components/ModelTags'
import { EMBEDDING_REGEX, getModelLogo, VISION_REGEX } from '@renderer/config/models'
import { PROVIDER_CONFIG } from '@renderer/config/providers'
import { useTheme } from '@renderer/context/ThemeProvider'
import { useAssistants, useDefaultModel } from '@renderer/hooks/useAssistant'
@ -27,7 +19,7 @@ import { checkApi } from '@renderer/services/ApiService'
import { useAppDispatch } from '@renderer/store'
import { setModel } from '@renderer/store/assistants'
import { Model, ModelType, Provider } from '@renderer/types'
import { Avatar, Button, Card, Checkbox, Divider, Flex, Input, Popover, Space, Switch, Tag } from 'antd'
import { Avatar, Button, Card, Checkbox, Divider, Flex, Input, Popover, Space, Switch } from 'antd'
import Link from 'antd/es/typography/Link'
import { groupBy, isEmpty } from 'lodash'
import { FC, useEffect, useState } from 'react'
@ -278,13 +270,8 @@ const ProviderSetting: FC<Props> = ({ provider: _provider }) => {
<Avatar src={getModelLogo(model.id)} size={22} style={{ marginRight: '8px' }}>
{model.name[0].toUpperCase()}
</Avatar>
{model.name} {isVisionModel(model) && <VisionIcon />}
{isWebSearchModel(model) && <WebSearchIcon />}
{isEmbeddingModel(model) && (
<Tag style={{ marginLeft: 10 }} color="orange">
{t('models.embedding')}
</Tag>
)}
{model.name}
<ModelTags model={model} />
<Popover content={modelTypeContent(model)} title={t('models.type.select')} trigger="click">
<SettingIcon />
</Popover>

View File

@ -124,7 +124,7 @@ const ProvidersList: FC = () => {
{provider.isSystem ? t(`provider.${provider.id}`) : provider.name}
</ProviderItemName>
{provider.enabled && (
<Tag color="green" style={{ marginLeft: 'auto', borderRadius: 16 }}>
<Tag color="green" style={{ marginLeft: 'auto', marginRight: 0, borderRadius: 16 }}>
ON
</Tag>
)}
@ -163,7 +163,7 @@ const Container = styled.div`
const ProviderListContainer = styled.div`
display: flex;
flex-direction: column;
width: var(--assistants-width);
min-width: calc(var(--settings-width) + 10px);
height: calc(100vh - var(--navbar-height));
border-right: 0.5px solid var(--color-border);
`
@ -173,13 +173,14 @@ const ProviderList = styled.div`
flex: 1;
flex-direction: column;
padding: 8px;
padding-right: 5px;
`
const ProviderListItem = styled.div`
display: flex;
flex-direction: row;
align-items: center;
padding: 5px 8px;
padding: 5px 10px;
width: 100%;
cursor: grab;
border-radius: var(--list-item-border-radius);