mirror of
https://github.com/CherryHQ/cherry-studio.git
synced 2026-01-06 21:35:52 +08:00
feat: add user edit modal & add prompt block
This commit is contained in:
parent
242c39bbc5
commit
0e5d9cf78e
@ -31,7 +31,8 @@
|
|||||||
--color-text: var(--color-text-1);
|
--color-text: var(--color-text-1);
|
||||||
--color-icon: #ffffff99;
|
--color-icon: #ffffff99;
|
||||||
--color-icon-white: #ffffff;
|
--color-icon-white: #ffffff;
|
||||||
--color-border: #ffffff20;
|
--color-border: #000;
|
||||||
|
--color-border-soft: #ffffff20;
|
||||||
--color-error: #f44336;
|
--color-error: #f44336;
|
||||||
--color-link: #1677ff;
|
--color-link: #1677ff;
|
||||||
--color-code-background: #323232;
|
--color-code-background: #323232;
|
||||||
@ -80,6 +81,7 @@ body[theme-mode='light'] {
|
|||||||
--color-icon: #00000099;
|
--color-icon: #00000099;
|
||||||
--color-icon-white: #000000;
|
--color-icon-white: #000000;
|
||||||
--color-border: #00000028;
|
--color-border: #00000028;
|
||||||
|
--color-border-soft: #00000028;
|
||||||
--color-error: #f44336;
|
--color-error: #f44336;
|
||||||
--color-link: #1677ff;
|
--color-link: #1677ff;
|
||||||
--color-code-background: #e3e3e3;
|
--color-code-background: #e3e3e3;
|
||||||
|
|||||||
108
src/renderer/src/components/Popups/UserPopup.tsx
Normal file
108
src/renderer/src/components/Popups/UserPopup.tsx
Normal file
@ -0,0 +1,108 @@
|
|||||||
|
import useAvatar from '@renderer/hooks/useAvatar'
|
||||||
|
import { useSettings } from '@renderer/hooks/useSettings'
|
||||||
|
import LocalStorage from '@renderer/services/storage'
|
||||||
|
import { useAppDispatch } from '@renderer/store'
|
||||||
|
import { setAvatar } from '@renderer/store/runtime'
|
||||||
|
import { setUserName } from '@renderer/store/settings'
|
||||||
|
import { compressImage } from '@renderer/utils'
|
||||||
|
import { Avatar, Input, Modal, Upload } from 'antd'
|
||||||
|
import { useState } from 'react'
|
||||||
|
import { useTranslation } from 'react-i18next'
|
||||||
|
import styled from 'styled-components'
|
||||||
|
|
||||||
|
import { Center, HStack } from '../Layout'
|
||||||
|
import { TopView } from '../TopView'
|
||||||
|
|
||||||
|
interface Props {
|
||||||
|
resolve: (data: any) => void
|
||||||
|
}
|
||||||
|
|
||||||
|
const PopupContainer: React.FC<Props> = ({ resolve }) => {
|
||||||
|
const [open, setOpen] = useState(true)
|
||||||
|
const { t } = useTranslation()
|
||||||
|
const { userName } = useSettings()
|
||||||
|
const dispatch = useAppDispatch()
|
||||||
|
const avatar = useAvatar()
|
||||||
|
|
||||||
|
const onOk = () => {
|
||||||
|
setOpen(false)
|
||||||
|
}
|
||||||
|
|
||||||
|
const onCancel = () => {
|
||||||
|
setOpen(false)
|
||||||
|
}
|
||||||
|
|
||||||
|
const onClose = () => {
|
||||||
|
resolve({})
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Modal
|
||||||
|
width="300px"
|
||||||
|
open={open}
|
||||||
|
footer={null}
|
||||||
|
onOk={onOk}
|
||||||
|
onCancel={onCancel}
|
||||||
|
afterClose={onClose}
|
||||||
|
transitionName="ant-move-down">
|
||||||
|
<Center mt="30px">
|
||||||
|
<Upload
|
||||||
|
customRequest={() => {}}
|
||||||
|
accept="image/png, image/jpeg"
|
||||||
|
itemRender={() => null}
|
||||||
|
maxCount={1}
|
||||||
|
onChange={async ({ file }) => {
|
||||||
|
try {
|
||||||
|
const _file = file.originFileObj as File
|
||||||
|
const compressedFile = await compressImage(_file)
|
||||||
|
await LocalStorage.storeImage('avatar', compressedFile)
|
||||||
|
dispatch(setAvatar(await LocalStorage.getImage('avatar')))
|
||||||
|
} catch (error: any) {
|
||||||
|
window.message.error(error.message)
|
||||||
|
}
|
||||||
|
}}>
|
||||||
|
<UserAvatar src={avatar} />
|
||||||
|
</Upload>
|
||||||
|
</Center>
|
||||||
|
<HStack alignItems="center" gap="10px" p="20px">
|
||||||
|
<Input
|
||||||
|
placeholder={t('settings.general.user_name.placeholder')}
|
||||||
|
value={userName}
|
||||||
|
onChange={(e) => dispatch(setUserName(e.target.value))}
|
||||||
|
style={{ flex: 1, textAlign: 'center', width: '100%' }}
|
||||||
|
maxLength={30}
|
||||||
|
/>
|
||||||
|
</HStack>
|
||||||
|
</Modal>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
const UserAvatar = styled(Avatar)`
|
||||||
|
cursor: pointer;
|
||||||
|
width: 80px;
|
||||||
|
height: 80px;
|
||||||
|
transition: opacity 0.3s ease;
|
||||||
|
&:hover {
|
||||||
|
opacity: 0.8;
|
||||||
|
}
|
||||||
|
`
|
||||||
|
|
||||||
|
export default class UserPopup {
|
||||||
|
static topviewId = 0
|
||||||
|
static hide() {
|
||||||
|
TopView.hide('UserPopup')
|
||||||
|
}
|
||||||
|
static show() {
|
||||||
|
return new Promise<any>((resolve) => {
|
||||||
|
TopView.show(
|
||||||
|
<PopupContainer
|
||||||
|
resolve={(v) => {
|
||||||
|
resolve(v)
|
||||||
|
this.hide()
|
||||||
|
}}
|
||||||
|
/>,
|
||||||
|
'UserPopup'
|
||||||
|
)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -8,6 +8,8 @@ import { FC } from 'react'
|
|||||||
import { Link, useLocation } from 'react-router-dom'
|
import { Link, useLocation } from 'react-router-dom'
|
||||||
import styled from 'styled-components'
|
import styled from 'styled-components'
|
||||||
|
|
||||||
|
import UserPopup from '../Popups/UserPopup'
|
||||||
|
|
||||||
const Sidebar: FC = () => {
|
const Sidebar: FC = () => {
|
||||||
const { pathname } = useLocation()
|
const { pathname } = useLocation()
|
||||||
const avatar = useAvatar()
|
const avatar = useAvatar()
|
||||||
@ -15,11 +17,13 @@ const Sidebar: FC = () => {
|
|||||||
|
|
||||||
const isRoute = (path: string): string => (pathname === path ? 'active' : '')
|
const isRoute = (path: string): string => (pathname === path ? 'active' : '')
|
||||||
|
|
||||||
|
const onEditUser = () => {
|
||||||
|
UserPopup.show()
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Container style={{ backgroundColor: minappShow ? 'var(--color-background)' : 'var(--sidebar-background)' }}>
|
<Container style={{ backgroundColor: minappShow ? 'var(--color-background)' : 'var(--sidebar-background)' }}>
|
||||||
<StyledLink to="/">
|
<AvatarImg src={avatar || Logo} draggable={false} className="dragdisable" onClick={onEditUser} />
|
||||||
<AvatarImg src={avatar || Logo} draggable={false} />
|
|
||||||
</StyledLink>
|
|
||||||
<MainMenus>
|
<MainMenus>
|
||||||
<Menus>
|
<Menus>
|
||||||
<StyledLink to="/">
|
<StyledLink to="/">
|
||||||
@ -71,6 +75,7 @@ const AvatarImg = styled(Avatar)`
|
|||||||
margin-bottom: ${isMac ? '12px' : '12px'};
|
margin-bottom: ${isMac ? '12px' : '12px'};
|
||||||
margin-top: ${isMac ? '5px' : '2px'};
|
margin-top: ${isMac ? '5px' : '2px'};
|
||||||
border: none;
|
border: none;
|
||||||
|
cursor: pointer;
|
||||||
`
|
`
|
||||||
const MainMenus = styled.div`
|
const MainMenus = styled.div`
|
||||||
display: flex;
|
display: flex;
|
||||||
|
|||||||
@ -56,13 +56,13 @@ const AppsPage: FC = () => {
|
|||||||
<ContentContainer>
|
<ContentContainer>
|
||||||
<AssistantsContainer>
|
<AssistantsContainer>
|
||||||
<HStack alignItems="center" style={{ marginBottom: 16 }}>
|
<HStack alignItems="center" style={{ marginBottom: 16 }}>
|
||||||
<Title level={3}>{t('agents.my_agents')}</Title>
|
<Title level={4}>{t('agents.my_agents')}</Title>
|
||||||
{agents.length > 0 && <ManageIcon onClick={ManageAgentsPopup.show} />}
|
{agents.length > 0 && <ManageIcon onClick={ManageAgentsPopup.show} />}
|
||||||
</HStack>
|
</HStack>
|
||||||
<UserAgents onAdd={onAddAgentConfirm} />
|
<UserAgents onAdd={onAddAgentConfirm} />
|
||||||
{Object.keys(agentGroups).map((group) => (
|
{Object.keys(agentGroups).map((group) => (
|
||||||
<div key={group}>
|
<div key={group}>
|
||||||
<Title level={3} key={group} style={{ marginBottom: 16 }}>
|
<Title level={4} key={group} style={{ marginBottom: 16 }}>
|
||||||
{group}
|
{group}
|
||||||
</Title>
|
</Title>
|
||||||
<Row gutter={16}>
|
<Row gutter={16}>
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
import { Agent } from '@renderer/types'
|
import { Agent } from '@renderer/types'
|
||||||
import { Col, Typography } from 'antd'
|
import { Col } from 'antd'
|
||||||
import styled from 'styled-components'
|
import styled from 'styled-components'
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
@ -7,17 +7,13 @@ interface Props {
|
|||||||
onClick?: () => void
|
onClick?: () => void
|
||||||
}
|
}
|
||||||
|
|
||||||
const { Title } = Typography
|
|
||||||
|
|
||||||
const AgentCard: React.FC<Props> = ({ agent, onClick }) => {
|
const AgentCard: React.FC<Props> = ({ agent, onClick }) => {
|
||||||
return (
|
return (
|
||||||
<Container onClick={onClick}>
|
<Container onClick={onClick}>
|
||||||
{agent.emoji && <EmojiHeader>{agent.emoji}</EmojiHeader>}
|
{agent.emoji && <EmojiHeader>{agent.emoji}</EmojiHeader>}
|
||||||
<Col>
|
<Col>
|
||||||
<AgentHeader>
|
<AgentHeader>
|
||||||
<AgentName level={5} style={{ marginBottom: 0 }}>
|
<AgentName style={{ marginBottom: 0 }}>{agent.name}</AgentName>
|
||||||
{agent.name}
|
|
||||||
</AgentName>
|
|
||||||
</AgentHeader>
|
</AgentHeader>
|
||||||
<AgentCardPrompt>{agent.prompt}</AgentCardPrompt>
|
<AgentCardPrompt>{agent.prompt}</AgentCardPrompt>
|
||||||
</Col>
|
</Col>
|
||||||
@ -41,14 +37,14 @@ const Container = styled.div`
|
|||||||
}
|
}
|
||||||
`
|
`
|
||||||
const EmojiHeader = styled.div`
|
const EmojiHeader = styled.div`
|
||||||
width: 25px;
|
width: 20px;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
margin-right: 5px;
|
margin-right: 5px;
|
||||||
font-size: 25px;
|
font-size: 20px;
|
||||||
line-height: 25px;
|
line-height: 20px;
|
||||||
`
|
`
|
||||||
|
|
||||||
const AgentHeader = styled.div`
|
const AgentHeader = styled.div`
|
||||||
@ -58,15 +54,13 @@ const AgentHeader = styled.div`
|
|||||||
align-items: center;
|
align-items: center;
|
||||||
`
|
`
|
||||||
|
|
||||||
const AgentName = styled(Title)`
|
const AgentName = styled.div`
|
||||||
font-size: 18px;
|
|
||||||
line-height: 1.2;
|
line-height: 1.2;
|
||||||
display: -webkit-box;
|
display: -webkit-box;
|
||||||
-webkit-line-clamp: 1;
|
-webkit-line-clamp: 1;
|
||||||
-webkit-box-orient: vertical;
|
-webkit-box-orient: vertical;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
color: var(--color-white);
|
color: var(--color-text-1);
|
||||||
font-weight: 900;
|
|
||||||
`
|
`
|
||||||
|
|
||||||
const AgentCardPrompt = styled.div`
|
const AgentCardPrompt = styled.div`
|
||||||
@ -76,6 +70,7 @@ const AgentCardPrompt = styled.div`
|
|||||||
-webkit-line-clamp: 1;
|
-webkit-line-clamp: 1;
|
||||||
-webkit-box-orient: vertical;
|
-webkit-box-orient: vertical;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
|
font-size: 12px;
|
||||||
`
|
`
|
||||||
|
|
||||||
export default AgentCard
|
export default AgentCard
|
||||||
|
|||||||
@ -41,10 +41,10 @@ const AssistantCardContainer = styled.div`
|
|||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
padding: 20px;
|
padding: 20px;
|
||||||
border: 1px dashed var(--color-border);
|
border: 1px dashed var(--color-border-soft);
|
||||||
border-radius: 10px;
|
border-radius: 10px;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
min-height: 84px;
|
min-height: 72px;
|
||||||
.anticon {
|
.anticon {
|
||||||
font-size: 16px;
|
font-size: 16px;
|
||||||
color: var(--color-icon);
|
color: var(--color-icon);
|
||||||
|
|||||||
@ -145,7 +145,7 @@ const AssistantItem = styled.div`
|
|||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
padding: 7px 10px;
|
padding: 7px 10px;
|
||||||
position: relative;
|
position: relative;
|
||||||
border-radius: 8px;
|
border-radius: 4px;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
font-family: Ubuntu;
|
font-family: Ubuntu;
|
||||||
.anticon {
|
.anticon {
|
||||||
|
|||||||
@ -6,7 +6,7 @@ import { FC } from 'react'
|
|||||||
import styled from 'styled-components'
|
import styled from 'styled-components'
|
||||||
|
|
||||||
import Inputbar from './Inputbar/Inputbar'
|
import Inputbar from './Inputbar/Inputbar'
|
||||||
import Messages from './Messages'
|
import Messages from './Messages/Messages'
|
||||||
import RightSidebar from './RightSidebar'
|
import RightSidebar from './RightSidebar'
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
|
|||||||
@ -9,9 +9,9 @@ import { Switch } from 'antd'
|
|||||||
import { FC, useState } from 'react'
|
import { FC, useState } from 'react'
|
||||||
import styled from 'styled-components'
|
import styled from 'styled-components'
|
||||||
|
|
||||||
|
import AddAssistantPopup from '../../components/Popups/AddAssistantPopup'
|
||||||
import Assistants from './Assistants'
|
import Assistants from './Assistants'
|
||||||
import Chat from './Chat'
|
import Chat from './Chat'
|
||||||
import AddAssistantPopup from './components/AddAssistantPopup'
|
|
||||||
import Navigation from './Header'
|
import Navigation from './Header'
|
||||||
|
|
||||||
let _activeAssistant: Assistant
|
let _activeAssistant: Assistant
|
||||||
|
|||||||
@ -240,7 +240,7 @@ const Container = styled.div`
|
|||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
height: var(--input-bar-height);
|
height: var(--input-bar-height);
|
||||||
border: 1px solid var(--color-border);
|
border: 1px solid var(--color-border-soft);
|
||||||
transition: all 0.3s ease;
|
transition: all 0.3s ease;
|
||||||
position: relative;
|
position: relative;
|
||||||
margin: 0 20px 15px 20px;
|
margin: 0 20px 15px 20px;
|
||||||
|
|||||||
@ -23,8 +23,8 @@ import { FC, memo, useCallback, useMemo, useState } from 'react'
|
|||||||
import { useTranslation } from 'react-i18next'
|
import { useTranslation } from 'react-i18next'
|
||||||
import styled from 'styled-components'
|
import styled from 'styled-components'
|
||||||
|
|
||||||
import SelectModelDropdown from './components/SelectModelDropdown'
|
import SelectModelDropdown from '../components/SelectModelDropdown'
|
||||||
import Markdown from './Markdown/Markdown'
|
import Markdown from '../Markdown/Markdown'
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
message: Message
|
message: Message
|
||||||
@ -208,7 +208,7 @@ const MessageContainer = styled.div`
|
|||||||
&.user {
|
&.user {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 10px;
|
top: 10px;
|
||||||
right: 10px;
|
right: 15px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
&:hover {
|
&:hover {
|
||||||
@ -10,11 +10,12 @@ import { getBriefInfo, runAsyncFunction, uuid } from '@renderer/utils'
|
|||||||
import { t } from 'i18next'
|
import { t } from 'i18next'
|
||||||
import localforage from 'localforage'
|
import localforage from 'localforage'
|
||||||
import { last, reverse } from 'lodash'
|
import { last, reverse } from 'lodash'
|
||||||
import { FC, useCallback, useEffect, useMemo, useRef, useState } from 'react'
|
import { FC, useCallback, useEffect, useRef, useState } from 'react'
|
||||||
import styled from 'styled-components'
|
import styled from 'styled-components'
|
||||||
|
|
||||||
import Suggestions from './components/Suggestions'
|
import Suggestions from '../components/Suggestions'
|
||||||
import MessageItem from './Message'
|
import MessageItem from './Message'
|
||||||
|
import Prompt from './Prompt'
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
assistant: Assistant
|
assistant: Assistant
|
||||||
@ -28,19 +29,6 @@ const Messages: FC<Props> = ({ assistant, topic }) => {
|
|||||||
const containerRef = useRef<HTMLDivElement>(null)
|
const containerRef = useRef<HTMLDivElement>(null)
|
||||||
const { updateTopic } = useAssistant(assistant.id)
|
const { updateTopic } = useAssistant(assistant.id)
|
||||||
|
|
||||||
const assistantDefaultMessage: Message = useMemo(
|
|
||||||
() => ({
|
|
||||||
id: 'assistant',
|
|
||||||
role: 'assistant',
|
|
||||||
content: assistant.description || assistant.prompt || t('chat.default.description'),
|
|
||||||
assistantId: assistant.id,
|
|
||||||
topicId: topic.id,
|
|
||||||
status: 'pending',
|
|
||||||
createdAt: new Date().toISOString()
|
|
||||||
}),
|
|
||||||
[assistant.description, assistant.id, assistant.prompt, topic.id]
|
|
||||||
)
|
|
||||||
|
|
||||||
const onSendMessage = useCallback(
|
const onSendMessage = useCallback(
|
||||||
(message: Message) => {
|
(message: Message) => {
|
||||||
const _messages = [...messages, message]
|
const _messages = [...messages, message]
|
||||||
@ -123,7 +111,7 @@ const Messages: FC<Props> = ({ assistant, topic }) => {
|
|||||||
{reverse([...messages]).map((message, index) => (
|
{reverse([...messages]).map((message, index) => (
|
||||||
<MessageItem key={message.id} message={message} showMenu index={index} onDeleteMessage={onDeleteMessage} />
|
<MessageItem key={message.id} message={message} showMenu index={index} onDeleteMessage={onDeleteMessage} />
|
||||||
))}
|
))}
|
||||||
<MessageItem message={assistantDefaultMessage} />
|
<Prompt assistant={assistant} key={assistant.prompt} />
|
||||||
</Container>
|
</Container>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
54
src/renderer/src/pages/home/Messages/Prompt.tsx
Normal file
54
src/renderer/src/pages/home/Messages/Prompt.tsx
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
import AssistantSettingPopup from '@renderer/components/Popups/AssistantSettingPopup'
|
||||||
|
import { useAssistant } from '@renderer/hooks/useAssistant'
|
||||||
|
import { syncAsistantToAgent } from '@renderer/services/assistant'
|
||||||
|
import { Assistant } from '@renderer/types'
|
||||||
|
import { FC } from 'react'
|
||||||
|
import { useTranslation } from 'react-i18next'
|
||||||
|
import styled from 'styled-components'
|
||||||
|
|
||||||
|
interface Props {
|
||||||
|
assistant: Assistant
|
||||||
|
}
|
||||||
|
|
||||||
|
const Prompt: FC<Props> = ({ assistant }) => {
|
||||||
|
const { t } = useTranslation()
|
||||||
|
const { updateAssistant } = useAssistant(assistant.id)
|
||||||
|
|
||||||
|
const prompt = assistant.prompt || t('chat.default.description')
|
||||||
|
|
||||||
|
const onEdit = async () => {
|
||||||
|
const _assistant = await AssistantSettingPopup.show({ assistant })
|
||||||
|
updateAssistant(_assistant)
|
||||||
|
syncAsistantToAgent(_assistant)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!prompt) {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Container onClick={onEdit}>
|
||||||
|
<Text>{prompt}</Text>
|
||||||
|
</Container>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
const Container = styled.div`
|
||||||
|
padding: 10px 20px;
|
||||||
|
background-color: var(--color-background-soft);
|
||||||
|
margin-bottom: 20px;
|
||||||
|
margin: 0 20px 20px 20px;
|
||||||
|
border-radius: 6px;
|
||||||
|
cursor: pointer;
|
||||||
|
`
|
||||||
|
|
||||||
|
const Text = styled.div`
|
||||||
|
color: var(--color-text-3);
|
||||||
|
font-size: 12px;
|
||||||
|
display: -webkit-box;
|
||||||
|
-webkit-line-clamp: 2;
|
||||||
|
-webkit-box-orient: vertical;
|
||||||
|
overflow: hidden;
|
||||||
|
`
|
||||||
|
|
||||||
|
export default Prompt
|
||||||
@ -142,12 +142,11 @@ const Container = styled.div`
|
|||||||
const TopicListItem = styled.div`
|
const TopicListItem = styled.div`
|
||||||
padding: 7px 10px;
|
padding: 7px 10px;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
border-radius: 8px;
|
border-radius: 4px;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
text-overflow: ellipsis;
|
text-overflow: ellipsis;
|
||||||
font-family: Ubuntu;
|
font-family: Ubuntu;
|
||||||
transition: all 0.3s;
|
|
||||||
&:hover {
|
&:hover {
|
||||||
background-color: var(--color-background-soft);
|
background-color: var(--color-background-soft);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -95,7 +95,7 @@ const ProviderSetting: FC<Props> = ({ provider: _provider }) => {
|
|||||||
</SettingTitle>
|
</SettingTitle>
|
||||||
<Divider style={{ width: '100%', margin: '10px 0' }} />
|
<Divider style={{ width: '100%', margin: '10px 0' }} />
|
||||||
<SettingSubtitle style={{ marginTop: 5 }}>{t('settings.provider.api_key')}</SettingSubtitle>
|
<SettingSubtitle style={{ marginTop: 5 }}>{t('settings.provider.api_key')}</SettingSubtitle>
|
||||||
<Space.Compact style={{ width: '100%' }}>
|
<Space.Compact style={{ width: '100%', marginTop: 5 }}>
|
||||||
<Input.Password
|
<Input.Password
|
||||||
value={apiKey}
|
value={apiKey}
|
||||||
placeholder={t('settings.provider.api_key')}
|
placeholder={t('settings.provider.api_key')}
|
||||||
@ -117,7 +117,7 @@ const ProviderSetting: FC<Props> = ({ provider: _provider }) => {
|
|||||||
</HelpTextRow>
|
</HelpTextRow>
|
||||||
)}
|
)}
|
||||||
<SettingSubtitle>{t('settings.provider.api_host')}</SettingSubtitle>
|
<SettingSubtitle>{t('settings.provider.api_host')}</SettingSubtitle>
|
||||||
<Space.Compact style={{ width: '100%' }}>
|
<Space.Compact style={{ width: '100%', marginTop: 5 }}>
|
||||||
<Input
|
<Input
|
||||||
value={apiHost}
|
value={apiHost}
|
||||||
placeholder={t('settings.provider.api_host')}
|
placeholder={t('settings.provider.api_host')}
|
||||||
@ -128,7 +128,7 @@ const ProviderSetting: FC<Props> = ({ provider: _provider }) => {
|
|||||||
{apiEditable && <Button onClick={onReset}>{t('settings.provider.api.url.reset')}</Button>}
|
{apiEditable && <Button onClick={onReset}>{t('settings.provider.api.url.reset')}</Button>}
|
||||||
</Space.Compact>
|
</Space.Compact>
|
||||||
{provider.id === 'ollama' && <OllamSettings />}
|
{provider.id === 'ollama' && <OllamSettings />}
|
||||||
<SettingSubtitle>{t('common.models')}</SettingSubtitle>
|
<SettingSubtitle style={{ marginBottom: 5 }}>{t('common.models')}</SettingSubtitle>
|
||||||
{Object.keys(modelGroups).map((group) => (
|
{Object.keys(modelGroups).map((group) => (
|
||||||
<Card key={group} type="inner" title={group} style={{ marginBottom: '10px' }} size="small">
|
<Card key={group} type="inner" title={group} style={{ marginBottom: '10px' }} size="small">
|
||||||
{modelGroups[group].map((model) => (
|
{modelGroups[group].map((model) => (
|
||||||
|
|||||||
@ -257,7 +257,7 @@ const InputContainer = styled.div`
|
|||||||
flex: 1;
|
flex: 1;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
border: 1px solid var(--color-border);
|
border: 1px solid var(--color-border-soft);
|
||||||
border-radius: 10px;
|
border-radius: 10px;
|
||||||
`
|
`
|
||||||
|
|
||||||
|
|||||||
@ -23,8 +23,7 @@ const AntdProvider: FC<PropsWithChildren> = ({ children }) => {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
token: {
|
token: {
|
||||||
colorPrimary: '#00b96b',
|
colorPrimary: '#00b96b'
|
||||||
borderRadius: 8
|
|
||||||
}
|
}
|
||||||
}}>
|
}}>
|
||||||
{children}
|
{children}
|
||||||
|
|||||||
@ -123,7 +123,7 @@ export async function fetchMessagesSummary({ messages, assistant }: { messages:
|
|||||||
const providerSdk = new ProviderSDK(provider)
|
const providerSdk = new ProviderSDK(provider)
|
||||||
|
|
||||||
try {
|
try {
|
||||||
return await providerSdk.summaries(messages, assistant)
|
return await providerSdk.summaries(filterMessages(messages), assistant)
|
||||||
} catch (error: any) {
|
} catch (error: any) {
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user