feat: add ModelTags component
This commit is contained in:
parent
f68bd4d8d8
commit
2e7ecbc753
35
src/renderer/src/components/ModelTags.tsx
Normal file
35
src/renderer/src/components/ModelTags.tsx
Normal 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
|
||||||
@ -1,7 +1,7 @@
|
|||||||
import { PushpinOutlined, SearchOutlined } from '@ant-design/icons'
|
import { PushpinOutlined, SearchOutlined } from '@ant-design/icons'
|
||||||
import VisionIcon from '@renderer/components/Icons/VisionIcon'
|
import VisionIcon from '@renderer/components/Icons/VisionIcon'
|
||||||
import { TopView } from '@renderer/components/TopView'
|
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 db from '@renderer/databases'
|
||||||
import { useProviders } from '@renderer/hooks/useProvider'
|
import { useProviders } from '@renderer/hooks/useProvider'
|
||||||
import { getModelUniqId } from '@renderer/services/ModelService'
|
import { getModelUniqId } from '@renderer/services/ModelService'
|
||||||
@ -12,8 +12,8 @@ import { useEffect, useRef, useState } from 'react'
|
|||||||
import { useTranslation } from 'react-i18next'
|
import { useTranslation } from 'react-i18next'
|
||||||
import styled from 'styled-components'
|
import styled from 'styled-components'
|
||||||
|
|
||||||
import WebSearchIcon from '../Icons/WebSearchIcon'
|
|
||||||
import { HStack } from '../Layout'
|
import { HStack } from '../Layout'
|
||||||
|
import ModelTags from '../ModelTags'
|
||||||
import Scrollbar from '../Scrollbar'
|
import Scrollbar from '../Scrollbar'
|
||||||
|
|
||||||
type MenuItem = Required<MenuProps>['items'][number]
|
type MenuItem = Required<MenuProps>['items'][number]
|
||||||
@ -75,7 +75,7 @@ const PopupContainer: React.FC<PopupContainerProps> = ({ model, resolve }) => {
|
|||||||
label: (
|
label: (
|
||||||
<ModelItem>
|
<ModelItem>
|
||||||
<span>
|
<span>
|
||||||
{m?.name} {isVisionModel(m) && <VisionIcon />} {isWebSearchModel(m) && <WebSearchIcon />}
|
{m?.name} <ModelTags model={m} />
|
||||||
</span>
|
</span>
|
||||||
<PinIcon
|
<PinIcon
|
||||||
onClick={(e) => {
|
onClick={(e) => {
|
||||||
|
|||||||
@ -1,8 +1,7 @@
|
|||||||
import ModelAvatar from '@renderer/components/Avatar/ModelAvatar'
|
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 SelectModelPopup from '@renderer/components/Popups/SelectModelPopup'
|
||||||
import { isLocalAi } from '@renderer/config/env'
|
import { isLocalAi } from '@renderer/config/env'
|
||||||
import { isVisionModel } from '@renderer/config/models'
|
|
||||||
import { useAssistant } from '@renderer/hooks/useAssistant'
|
import { useAssistant } from '@renderer/hooks/useAssistant'
|
||||||
import { getProviderName } from '@renderer/services/ProviderService'
|
import { getProviderName } from '@renderer/services/ProviderService'
|
||||||
import { Assistant } from '@renderer/types'
|
import { Assistant } from '@renderer/types'
|
||||||
@ -40,7 +39,7 @@ const SelectModelButton: FC<Props> = ({ assistant }) => {
|
|||||||
<ModelName>
|
<ModelName>
|
||||||
{model ? model.name : t('button.select_model')} {providerName ? '| ' + providerName : ''}
|
{model ? model.name : t('button.select_model')} {providerName ? '| ' + providerName : ''}
|
||||||
</ModelName>
|
</ModelName>
|
||||||
{isVisionModel(model) && <VisionIcon style={{ marginLeft: 0 }} />}
|
<ModelTags model={model} />
|
||||||
</ButtonContent>
|
</ButtonContent>
|
||||||
</DropdownButton>
|
</DropdownButton>
|
||||||
)
|
)
|
||||||
@ -63,7 +62,6 @@ const ButtonContent = styled.div`
|
|||||||
`
|
`
|
||||||
|
|
||||||
const ModelName = styled.span`
|
const ModelName = styled.span`
|
||||||
margin-left: -2px;
|
|
||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
`
|
`
|
||||||
|
|
||||||
|
|||||||
@ -1,13 +1,12 @@
|
|||||||
import { LoadingOutlined, MinusOutlined, PlusOutlined, QuestionCircleOutlined } from '@ant-design/icons'
|
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 { Center } from '@renderer/components/Layout'
|
||||||
|
import ModelTags from '@renderer/components/ModelTags'
|
||||||
import { getModelLogo, isEmbeddingModel, isVisionModel, isWebSearchModel, SYSTEM_MODELS } from '@renderer/config/models'
|
import { getModelLogo, isEmbeddingModel, isVisionModel, isWebSearchModel, SYSTEM_MODELS } from '@renderer/config/models'
|
||||||
import { useProvider } from '@renderer/hooks/useProvider'
|
import { useProvider } from '@renderer/hooks/useProvider'
|
||||||
import { fetchModels } from '@renderer/services/ApiService'
|
import { fetchModels } from '@renderer/services/ApiService'
|
||||||
import { Model, Provider } from '@renderer/types'
|
import { Model, Provider } from '@renderer/types'
|
||||||
import { getDefaultGroupName, isFreeModel, runAsyncFunction } from '@renderer/utils'
|
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 Search from 'antd/es/input/Search'
|
||||||
import { groupBy, isEmpty, uniqBy } from 'lodash'
|
import { groupBy, isEmpty, uniqBy } from 'lodash'
|
||||||
import { useEffect, useState } from 'react'
|
import { useEffect, useState } from 'react'
|
||||||
@ -156,18 +155,7 @@ const PopupContainer: React.FC<Props> = ({ provider: _provider, resolve }) => {
|
|||||||
<Tooltip title={model.id} placement="top">
|
<Tooltip title={model.id} placement="top">
|
||||||
<span style={{ cursor: 'help' }}>{model.name}</span>
|
<span style={{ cursor: 'help' }}>{model.name}</span>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
{isVisionModel(model) && <VisionIcon />}
|
<ModelTags model={model} />
|
||||||
{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>
|
|
||||||
)}
|
|
||||||
{!isEmpty(model.description) && (
|
{!isEmpty(model.description) && (
|
||||||
<Popover
|
<Popover
|
||||||
trigger="click"
|
trigger="click"
|
||||||
|
|||||||
@ -7,16 +7,8 @@ import {
|
|||||||
PlusOutlined,
|
PlusOutlined,
|
||||||
SettingOutlined
|
SettingOutlined
|
||||||
} from '@ant-design/icons'
|
} from '@ant-design/icons'
|
||||||
import VisionIcon from '@renderer/components/Icons/VisionIcon'
|
import ModelTags from '@renderer/components/ModelTags'
|
||||||
import WebSearchIcon from '@renderer/components/Icons/WebSearchIcon'
|
import { EMBEDDING_REGEX, getModelLogo, VISION_REGEX } from '@renderer/config/models'
|
||||||
import {
|
|
||||||
EMBEDDING_REGEX,
|
|
||||||
getModelLogo,
|
|
||||||
isEmbeddingModel,
|
|
||||||
isVisionModel,
|
|
||||||
isWebSearchModel,
|
|
||||||
VISION_REGEX
|
|
||||||
} from '@renderer/config/models'
|
|
||||||
import { PROVIDER_CONFIG } from '@renderer/config/providers'
|
import { PROVIDER_CONFIG } from '@renderer/config/providers'
|
||||||
import { useTheme } from '@renderer/context/ThemeProvider'
|
import { useTheme } from '@renderer/context/ThemeProvider'
|
||||||
import { useAssistants, useDefaultModel } from '@renderer/hooks/useAssistant'
|
import { useAssistants, useDefaultModel } from '@renderer/hooks/useAssistant'
|
||||||
@ -27,7 +19,7 @@ import { checkApi } from '@renderer/services/ApiService'
|
|||||||
import { useAppDispatch } from '@renderer/store'
|
import { useAppDispatch } from '@renderer/store'
|
||||||
import { setModel } from '@renderer/store/assistants'
|
import { setModel } from '@renderer/store/assistants'
|
||||||
import { Model, ModelType, Provider } from '@renderer/types'
|
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 Link from 'antd/es/typography/Link'
|
||||||
import { groupBy, isEmpty } from 'lodash'
|
import { groupBy, isEmpty } from 'lodash'
|
||||||
import { FC, useEffect, useState } from 'react'
|
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' }}>
|
<Avatar src={getModelLogo(model.id)} size={22} style={{ marginRight: '8px' }}>
|
||||||
{model.name[0].toUpperCase()}
|
{model.name[0].toUpperCase()}
|
||||||
</Avatar>
|
</Avatar>
|
||||||
{model.name} {isVisionModel(model) && <VisionIcon />}
|
{model.name}
|
||||||
{isWebSearchModel(model) && <WebSearchIcon />}
|
<ModelTags model={model} />
|
||||||
{isEmbeddingModel(model) && (
|
|
||||||
<Tag style={{ marginLeft: 10 }} color="orange">
|
|
||||||
{t('models.embedding')}
|
|
||||||
</Tag>
|
|
||||||
)}
|
|
||||||
<Popover content={modelTypeContent(model)} title={t('models.type.select')} trigger="click">
|
<Popover content={modelTypeContent(model)} title={t('models.type.select')} trigger="click">
|
||||||
<SettingIcon />
|
<SettingIcon />
|
||||||
</Popover>
|
</Popover>
|
||||||
|
|||||||
@ -124,7 +124,7 @@ const ProvidersList: FC = () => {
|
|||||||
{provider.isSystem ? t(`provider.${provider.id}`) : provider.name}
|
{provider.isSystem ? t(`provider.${provider.id}`) : provider.name}
|
||||||
</ProviderItemName>
|
</ProviderItemName>
|
||||||
{provider.enabled && (
|
{provider.enabled && (
|
||||||
<Tag color="green" style={{ marginLeft: 'auto', borderRadius: 16 }}>
|
<Tag color="green" style={{ marginLeft: 'auto', marginRight: 0, borderRadius: 16 }}>
|
||||||
ON
|
ON
|
||||||
</Tag>
|
</Tag>
|
||||||
)}
|
)}
|
||||||
@ -163,7 +163,7 @@ const Container = styled.div`
|
|||||||
const ProviderListContainer = styled.div`
|
const ProviderListContainer = styled.div`
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
width: var(--assistants-width);
|
min-width: calc(var(--settings-width) + 10px);
|
||||||
height: calc(100vh - var(--navbar-height));
|
height: calc(100vh - var(--navbar-height));
|
||||||
border-right: 0.5px solid var(--color-border);
|
border-right: 0.5px solid var(--color-border);
|
||||||
`
|
`
|
||||||
@ -173,13 +173,14 @@ const ProviderList = styled.div`
|
|||||||
flex: 1;
|
flex: 1;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
padding: 8px;
|
padding: 8px;
|
||||||
|
padding-right: 5px;
|
||||||
`
|
`
|
||||||
|
|
||||||
const ProviderListItem = styled.div`
|
const ProviderListItem = styled.div`
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
padding: 5px 8px;
|
padding: 5px 10px;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
cursor: grab;
|
cursor: grab;
|
||||||
border-radius: var(--list-item-border-radius);
|
border-radius: var(--list-item-border-radius);
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user