mirror of
https://github.com/CherryHQ/cherry-studio.git
synced 2026-01-06 21:35:52 +08:00
feature: add topic prompt (#1696)
* feat: 新增话题补充提示词 * feat: 新增话题补充提示词 * feat: 新增话题补充提示词 * feat: 新增话题补充提示词 * feat: 新增话题补充提示词
This commit is contained in:
parent
5dcc892f31
commit
f20bccfd7d
@ -17,8 +17,10 @@ export function useActiveTopic(_assistant: Assistant, topic?: Topic) {
|
|||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
// activeTopic not in assistant.topics
|
// activeTopic not in assistant.topics
|
||||||
if (assistant && !find(assistant.topics, { id: activeTopic?.id })) {
|
const topicTarget = find(assistant.topics, { id: activeTopic?.id })
|
||||||
setActiveTopic(assistant.topics[0])
|
// if (assistant && !find(assistant.topics, { id: activeTopic?.id })) {
|
||||||
|
if (assistant) {
|
||||||
|
setActiveTopic(topicTarget || assistant.topics[0])
|
||||||
}
|
}
|
||||||
}, [activeTopic?.id, assistant])
|
}, [activeTopic?.id, assistant])
|
||||||
|
|
||||||
|
|||||||
@ -136,7 +136,10 @@
|
|||||||
"topics.pinned": "Pinned Topics",
|
"topics.pinned": "Pinned Topics",
|
||||||
"topics.title": "Topics",
|
"topics.title": "Topics",
|
||||||
"topics.unpinned": "Unpinned Topics",
|
"topics.unpinned": "Unpinned Topics",
|
||||||
"translate": "Translate"
|
"translate": "Translate",
|
||||||
|
"topics.prompt": "Topic Prompts",
|
||||||
|
"topics.prompt.tips": "Topic Prompts: Additional supplementary prompts provided for the current topic",
|
||||||
|
"topics.prompt.edit.title": "Edit Topic Prompts"
|
||||||
},
|
},
|
||||||
"common": {
|
"common": {
|
||||||
"add": "Add",
|
"add": "Add",
|
||||||
|
|||||||
@ -136,7 +136,10 @@
|
|||||||
"topics.pinned": "トピックを固定",
|
"topics.pinned": "トピックを固定",
|
||||||
"topics.title": "トピック",
|
"topics.title": "トピック",
|
||||||
"topics.unpinned": "固定解除",
|
"topics.unpinned": "固定解除",
|
||||||
"translate": "翻訳"
|
"translate": "翻訳",
|
||||||
|
"topics.prompt": "トピック提示語",
|
||||||
|
"topics.prompt.tips": "トピック提示語:現在のトピックに対して追加の補足提示語を提供",
|
||||||
|
"topics.prompt.edit.title": "トピック提示語を編集する"
|
||||||
},
|
},
|
||||||
"common": {
|
"common": {
|
||||||
"add": "追加",
|
"add": "追加",
|
||||||
|
|||||||
@ -136,7 +136,10 @@
|
|||||||
"topics.pinned": "Закрепленные темы",
|
"topics.pinned": "Закрепленные темы",
|
||||||
"topics.title": "Топики",
|
"topics.title": "Топики",
|
||||||
"topics.unpinned": "Открепленные темы",
|
"topics.unpinned": "Открепленные темы",
|
||||||
"translate": "Перевести"
|
"translate": "Перевести",
|
||||||
|
"topics.prompt": "Тематические подсказки",
|
||||||
|
"topics.prompt.tips": "Тематические подсказки: Дополнительные подсказки, предоставленные для текущей темы",
|
||||||
|
"topics.prompt.edit.title": "Редактировать подсказки темы"
|
||||||
},
|
},
|
||||||
"common": {
|
"common": {
|
||||||
"add": "Добавить",
|
"add": "Добавить",
|
||||||
|
|||||||
@ -136,7 +136,10 @@
|
|||||||
"topics.pinned": "固定话题",
|
"topics.pinned": "固定话题",
|
||||||
"topics.title": "话题",
|
"topics.title": "话题",
|
||||||
"topics.unpinned": "取消固定",
|
"topics.unpinned": "取消固定",
|
||||||
"translate": "翻译"
|
"translate": "翻译",
|
||||||
|
"topics.prompt": "话题提示词",
|
||||||
|
"topics.prompt.tips": "话题提示词: 针对当前话题提供额外的补充提示词",
|
||||||
|
"topics.prompt.edit.title": "编辑话题提示词"
|
||||||
},
|
},
|
||||||
"common": {
|
"common": {
|
||||||
"add": "添加",
|
"add": "添加",
|
||||||
|
|||||||
@ -136,7 +136,10 @@
|
|||||||
"topics.pinned": "固定話題",
|
"topics.pinned": "固定話題",
|
||||||
"topics.title": "話題",
|
"topics.title": "話題",
|
||||||
"topics.unpinned": "取消固定",
|
"topics.unpinned": "取消固定",
|
||||||
"translate": "翻譯"
|
"translate": "翻譯",
|
||||||
|
"topics.prompt": "話題提示詞",
|
||||||
|
"topics.prompt.tips": "話題提示詞:針對目前話題提供額外的補充提示詞",
|
||||||
|
"topics.prompt.edit.title": "編輯話題提示詞"
|
||||||
},
|
},
|
||||||
"common": {
|
"common": {
|
||||||
"add": "添加",
|
"add": "添加",
|
||||||
|
|||||||
@ -118,8 +118,12 @@ const MessageItem: FC<Props> = ({
|
|||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (topic && onGetMessages && onSetMessages) {
|
if (topic && onGetMessages && onSetMessages) {
|
||||||
if (message.status === 'sending') {
|
if (message.status === 'sending') {
|
||||||
|
const _assistant = {
|
||||||
|
...assistant,
|
||||||
|
prompt: `${assistant?.prompt || ''}\n${topic?.prompt || ''}`
|
||||||
|
}
|
||||||
const messages = onGetMessages()
|
const messages = onGetMessages()
|
||||||
const assistantWithModel = message.model ? { ...assistant, model: message.model } : assistant
|
const assistantWithModel = message.model ? { ..._assistant, model: message.model } : _assistant
|
||||||
|
|
||||||
fetchChatCompletion({
|
fetchChatCompletion({
|
||||||
message,
|
message,
|
||||||
|
|||||||
@ -315,7 +315,7 @@ const Messages: FC<Props> = ({ assistant, topic, setActiveTopic }) => {
|
|||||||
))}
|
))}
|
||||||
</ScrollContainer>
|
</ScrollContainer>
|
||||||
</InfiniteScroll>
|
</InfiniteScroll>
|
||||||
<Prompt assistant={assistant} key={assistant.prompt} />
|
<Prompt assistant={assistant} key={assistant.prompt} topic={topic} />
|
||||||
</NarrowLayout>
|
</NarrowLayout>
|
||||||
</Container>
|
</Container>
|
||||||
)
|
)
|
||||||
@ -349,8 +349,7 @@ interface ContainerProps {
|
|||||||
const Container = styled(Scrollbar)<ContainerProps>`
|
const Container = styled(Scrollbar)<ContainerProps>`
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column-reverse;
|
flex-direction: column-reverse;
|
||||||
padding: 10px 0;
|
padding: 10px 0 20px;
|
||||||
padding-bottom: 20px;
|
|
||||||
overflow-x: hidden;
|
overflow-x: hidden;
|
||||||
background-color: var(--color-background);
|
background-color: var(--color-background);
|
||||||
`
|
`
|
||||||
|
|||||||
@ -1,22 +1,22 @@
|
|||||||
import AssistantSettingsPopup from '@renderer/pages/settings/AssistantSettings'
|
import AssistantSettingsPopup from '@renderer/pages/settings/AssistantSettings'
|
||||||
import { Assistant } from '@renderer/types'
|
import { Assistant, Topic } from '@renderer/types'
|
||||||
import { FC } from 'react'
|
import { FC } from 'react'
|
||||||
import { useTranslation } from 'react-i18next'
|
import { useTranslation } from 'react-i18next'
|
||||||
import styled from 'styled-components'
|
import styled from 'styled-components'
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
assistant: Assistant
|
assistant: Assistant
|
||||||
|
topic?: Topic
|
||||||
}
|
}
|
||||||
|
|
||||||
const Prompt: FC<Props> = ({ assistant }) => {
|
const Prompt: FC<Props> = ({ assistant, topic }) => {
|
||||||
const { t } = useTranslation()
|
const { t } = useTranslation()
|
||||||
|
|
||||||
const prompt = assistant.prompt || t('chat.default.description')
|
const prompt = assistant.prompt || t('chat.default.description')
|
||||||
|
const topicPrompt = topic?.prompt || ''
|
||||||
if (!prompt) {
|
if (!prompt && !topicPrompt) {
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Container className="system-prompt" onClick={() => AssistantSettingsPopup.show({ assistant })}>
|
<Container className="system-prompt" onClick={() => AssistantSettingsPopup.show({ assistant })}>
|
||||||
<Text>{prompt}</Text>
|
<Text>{prompt}</Text>
|
||||||
|
|||||||
@ -5,6 +5,7 @@ import {
|
|||||||
EditOutlined,
|
EditOutlined,
|
||||||
FolderOutlined,
|
FolderOutlined,
|
||||||
PushpinOutlined,
|
PushpinOutlined,
|
||||||
|
QuestionCircleOutlined,
|
||||||
UploadOutlined
|
UploadOutlined
|
||||||
} from '@ant-design/icons'
|
} from '@ant-design/icons'
|
||||||
import DragableList from '@renderer/components/DragableList'
|
import DragableList from '@renderer/components/DragableList'
|
||||||
@ -20,7 +21,7 @@ import store from '@renderer/store'
|
|||||||
import { setGenerating } from '@renderer/store/runtime'
|
import { setGenerating } from '@renderer/store/runtime'
|
||||||
import { Assistant, Topic } from '@renderer/types'
|
import { Assistant, Topic } from '@renderer/types'
|
||||||
import { exportTopicAsMarkdown, exportTopicToNotion, topicToMarkdown } from '@renderer/utils/export'
|
import { exportTopicAsMarkdown, exportTopicToNotion, topicToMarkdown } from '@renderer/utils/export'
|
||||||
import { Dropdown, MenuProps } from 'antd'
|
import { Dropdown, MenuProps, Tooltip } from 'antd'
|
||||||
import dayjs from 'dayjs'
|
import dayjs from 'dayjs'
|
||||||
import { findIndex } from 'lodash'
|
import { findIndex } from 'lodash'
|
||||||
import { FC, useCallback } from 'react'
|
import { FC, useCallback } from 'react'
|
||||||
@ -115,6 +116,28 @@ const Topics: FC<Props> = ({ assistant: _assistant, activeTopic, setActiveTopic
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
label: t('chat.topics.prompt'),
|
||||||
|
key: 'topic-prompt',
|
||||||
|
icon: <i className="iconfont icon-ai-model1" style={{ fontSize: '14px' }} />,
|
||||||
|
extra: (
|
||||||
|
<Tooltip title={t('chat.topics.prompt.tips')}>
|
||||||
|
<QuestionIcon />
|
||||||
|
</Tooltip>
|
||||||
|
),
|
||||||
|
async onClick() {
|
||||||
|
const prompt = await PromptPopup.show({
|
||||||
|
title: t('chat.topics.prompt.edit.title'),
|
||||||
|
message: '',
|
||||||
|
defaultValue: topic?.prompt || '',
|
||||||
|
inputProps: {
|
||||||
|
rows: 8,
|
||||||
|
allowClear: true
|
||||||
|
}
|
||||||
|
})
|
||||||
|
if (prompt !== null) updateTopic({ ...topic, prompt })
|
||||||
|
}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
label: topic.pinned ? t('chat.topics.unpinned') : t('chat.topics.pinned'),
|
label: topic.pinned ? t('chat.topics.unpinned') : t('chat.topics.pinned'),
|
||||||
key: 'pin',
|
key: 'pin',
|
||||||
@ -211,6 +234,11 @@ const Topics: FC<Props> = ({ assistant: _assistant, activeTopic, setActiveTopic
|
|||||||
onClick={() => onSwitchTopic(topic)}
|
onClick={() => onSwitchTopic(topic)}
|
||||||
style={{ borderRadius }}>
|
style={{ borderRadius }}>
|
||||||
<TopicName className="name">{topic.name.replace('`', '')}</TopicName>
|
<TopicName className="name">{topic.name.replace('`', '')}</TopicName>
|
||||||
|
{topic.prompt && (
|
||||||
|
<TopicPromptText className="prompt">
|
||||||
|
{t('common.prompt')}: {topic.prompt}
|
||||||
|
</TopicPromptText>
|
||||||
|
)}
|
||||||
{showTopicTime && (
|
{showTopicTime && (
|
||||||
<TopicTime className="time">{dayjs(topic.createdAt).format('MM/DD HH:mm')}</TopicTime>
|
<TopicTime className="time">{dayjs(topic.createdAt).format('MM/DD HH:mm')}</TopicTime>
|
||||||
)}
|
)}
|
||||||
@ -291,6 +319,18 @@ const TopicName = styled.div`
|
|||||||
font-size: 13px;
|
font-size: 13px;
|
||||||
`
|
`
|
||||||
|
|
||||||
|
const TopicPromptText = styled.div`
|
||||||
|
color: var(--color-text-2);
|
||||||
|
font-size: 12px;
|
||||||
|
display: -webkit-box;
|
||||||
|
-webkit-line-clamp: 2;
|
||||||
|
-webkit-box-orient: vertical;
|
||||||
|
overflow: hidden;
|
||||||
|
~ .prompt-text {
|
||||||
|
margin-top: 10px;
|
||||||
|
}
|
||||||
|
`
|
||||||
|
|
||||||
const TopicTime = styled.div`
|
const TopicTime = styled.div`
|
||||||
color: var(--color-text-3);
|
color: var(--color-text-3);
|
||||||
font-size: 11px;
|
font-size: 11px;
|
||||||
@ -310,5 +350,10 @@ const MenuButton = styled.div`
|
|||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
}
|
}
|
||||||
`
|
`
|
||||||
|
const QuestionIcon = styled(QuestionCircleOutlined)`
|
||||||
|
font-size: 14px;
|
||||||
|
cursor: pointer;
|
||||||
|
color: var(--color-text-3);
|
||||||
|
`
|
||||||
|
|
||||||
export default Topics
|
export default Topics
|
||||||
|
|||||||
@ -89,6 +89,7 @@ export type Topic = {
|
|||||||
updatedAt: string
|
updatedAt: string
|
||||||
messages: Message[]
|
messages: Message[]
|
||||||
pinned?: boolean
|
pinned?: boolean
|
||||||
|
prompt?: string
|
||||||
}
|
}
|
||||||
|
|
||||||
export type User = {
|
export type User = {
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user