@lobehub/chat 0.22.2 → 0.24.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +12 -0
- package/locales/en_US/common.json +26 -0
- package/locales/en_US/setting.json +15 -3
- package/locales/zh_CN/common.json +27 -3
- package/locales/zh_CN/setting.json +14 -3
- package/package.json +5 -3
- package/src/components/HeaderTitle/index.tsx +6 -1
- package/src/components/SliderWithInput/index.tsx +32 -7
- package/src/features/SideBar/index.tsx +103 -4
- package/src/locales/default/common.ts +22 -1
- package/src/pages/chat/SessionList/List/SessionItem.tsx +129 -71
- package/src/pages/chat/SessionList/List/style.ts +9 -17
- package/src/pages/chat/[id]/Config/SideBar.tsx +3 -3
- package/src/pages/chat/[id]/Config/TopicItem.tsx +78 -22
- package/src/pages/chat/[id]/Conversation/ChatList.tsx +11 -0
- package/src/pages/chat/[id]/Conversation/Input/Action.tsx +4 -1
- package/src/pages/chat/[id]/Conversation/Input/Token.tsx +5 -1
- package/src/pages/chat/[id]/edit/AgentPrompt/index.tsx +1 -1
- package/src/pages/chat/[id]/edit/Header.tsx +24 -7
- package/src/pages/setting/Header.tsx +3 -1
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,18 @@
|
|
|
2
2
|
|
|
3
3
|
# Changelog
|
|
4
4
|
|
|
5
|
+
# [0.24.0](https://github.com/lobehub/lobe-chat/compare/v0.23.0...v0.24.0) (2023-07-26)
|
|
6
|
+
|
|
7
|
+
### ✨ Features
|
|
8
|
+
|
|
9
|
+
- Add new translations, update existing translations, add functionality to components, modify styling, and adjust placeholder text ([da4ae72](https://github.com/lobehub/lobe-chat/commit/da4ae72))
|
|
10
|
+
|
|
11
|
+
# [0.23.0](https://github.com/lobehub/lobe-chat/compare/v0.22.2...v0.23.0) (2023-07-26)
|
|
12
|
+
|
|
13
|
+
### ✨ Features
|
|
14
|
+
|
|
15
|
+
- Add new features, update URLs, customize appearance, and implement components ([4b61bf4](https://github.com/lobehub/lobe-chat/commit/4b61bf4))
|
|
16
|
+
|
|
5
17
|
### [Version 0.22.2](https://github.com/lobehub/lobe-chat/compare/v0.22.1...v0.22.2)
|
|
6
18
|
|
|
7
19
|
<sup>Released on **2023-07-26**</sup>
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"DefaultSession": "Default Session",
|
|
3
|
+
"about": "About",
|
|
3
4
|
"advanceSettings": "Advanced Settings",
|
|
4
5
|
"agentMaxToken": "Max Token Length",
|
|
5
6
|
"agentModel": "Model",
|
|
@@ -9,25 +10,50 @@
|
|
|
9
10
|
"autoGenerate": "Auto Generate",
|
|
10
11
|
"autoGenerateTooltip": "Auto generate assistant description based on prompts",
|
|
11
12
|
"cancel": "Cancel",
|
|
13
|
+
"changelog": "Changelog",
|
|
12
14
|
"clearCurrentMessages": "Clear Current Session Messages",
|
|
13
15
|
"close": "Close",
|
|
14
16
|
"confirmClearCurrentMessages": "You are about to clear the current session messages. Once cleared, they cannot be recovered. Please confirm your action.",
|
|
15
17
|
"confirmRemoveSessionItemAlert": "You are about to delete this assistant. Once deleted, it cannot be recovered. Please confirm your action.",
|
|
18
|
+
"copy": "Copy",
|
|
19
|
+
"copySuccess": "Copy Success",
|
|
16
20
|
"defaultAgent": "Default Assistant",
|
|
17
21
|
"defaultSession": "Default Session",
|
|
22
|
+
"delete": "Delete",
|
|
18
23
|
"edit": "Edit",
|
|
19
24
|
"export": "Export",
|
|
25
|
+
"exportType": {
|
|
26
|
+
"agent": "Export Agent Settings",
|
|
27
|
+
"agentWithMessage": "Export Agent Settings and Messages",
|
|
28
|
+
"all": "Export Global Settings and All Agent Data",
|
|
29
|
+
"allAgent": "Export All Agent Settings",
|
|
30
|
+
"allAgentWithMessage": "Export All Agent Settings and Messages",
|
|
31
|
+
"globalSetting": "Export Global Settings"
|
|
32
|
+
},
|
|
33
|
+
"feedback": "Feedback",
|
|
34
|
+
"import": "Import Configuration",
|
|
20
35
|
"newAgent": "New Assistant",
|
|
21
36
|
"noDescription": "No description available",
|
|
22
37
|
"ok": "OK",
|
|
38
|
+
"overload": "Exceed Limit",
|
|
39
|
+
"pin": "Pin",
|
|
40
|
+
"pinOff": "Unpin",
|
|
41
|
+
"regenerate": "Regenerate",
|
|
42
|
+
"rename": "Rename",
|
|
23
43
|
"reset": "Reset",
|
|
44
|
+
"roleAndArchive": "Roles and Archives",
|
|
24
45
|
"searchAgentPlaceholder": "Search assistants and sessions...",
|
|
25
46
|
"send": "Send",
|
|
26
47
|
"sendPlaceholder": "Enter chat content...",
|
|
27
48
|
"sessionSetting": "Session Settings",
|
|
28
49
|
"setting": "Settings",
|
|
29
50
|
"share": "Share",
|
|
51
|
+
"temp": "Temporary",
|
|
30
52
|
"tokenDetail": "System Role Token: {{systemRoleToken}} Chats Token: {{chatsToken}}",
|
|
53
|
+
"topic": {
|
|
54
|
+
"saveCurrentMessages": "Save Current Conversation as Topic",
|
|
55
|
+
"searchPlaceholder": "Search Topics..."
|
|
56
|
+
},
|
|
31
57
|
"updateAgent": "Update Assistant Profile",
|
|
32
58
|
"updatePrompt": "Update Prompts"
|
|
33
59
|
}
|
|
@@ -15,7 +15,11 @@
|
|
|
15
15
|
"title": "Reset All Settings"
|
|
16
16
|
}
|
|
17
17
|
},
|
|
18
|
-
"header":
|
|
18
|
+
"header": {
|
|
19
|
+
"global": "Global Settings",
|
|
20
|
+
"session": "Session Settings",
|
|
21
|
+
"sessionWithName": "Session Settings · {{name}}"
|
|
22
|
+
},
|
|
19
23
|
"settingAgent": {
|
|
20
24
|
"avatar": {
|
|
21
25
|
"title": "Avatar"
|
|
@@ -61,7 +65,14 @@
|
|
|
61
65
|
"title": "User Input Preprocessing",
|
|
62
66
|
"placeholder": "Enter pre-processing template, {text} will be replaced with real-time input information"
|
|
63
67
|
},
|
|
64
|
-
"title": "Chat Settings"
|
|
68
|
+
"title": "Chat Settings",
|
|
69
|
+
"chatStyleType": {
|
|
70
|
+
"title": "Chat Window Style",
|
|
71
|
+
"type": {
|
|
72
|
+
"chat": "Chat Mode",
|
|
73
|
+
"docs": "Document Mode"
|
|
74
|
+
}
|
|
75
|
+
}
|
|
65
76
|
},
|
|
66
77
|
"settingModel": {
|
|
67
78
|
"enableMaxTokens": {
|
|
@@ -91,7 +102,8 @@
|
|
|
91
102
|
},
|
|
92
103
|
"temperature": {
|
|
93
104
|
"desc": "The higher the value, the more random the reply",
|
|
94
|
-
"title": "Randomness"
|
|
105
|
+
"title": "Randomness",
|
|
106
|
+
"titleWithValue": "Randomness {{value}}"
|
|
95
107
|
},
|
|
96
108
|
"title": "Model Settings",
|
|
97
109
|
"topP": {
|
|
@@ -1,32 +1,56 @@
|
|
|
1
1
|
{
|
|
2
|
+
"about": "关于",
|
|
2
3
|
"advanceSettings": "高级设置",
|
|
3
4
|
"agentMaxToken": "会话最大长度",
|
|
4
5
|
"agentModel": "模型",
|
|
5
6
|
"agentProfile": "助手信息",
|
|
6
7
|
"archive": "归档",
|
|
7
|
-
"archiveCurrentMessages": "归档当前会话",
|
|
8
8
|
"autoGenerate": "自动补全",
|
|
9
9
|
"autoGenerateTooltip": "基于提示词自动补全助手描述",
|
|
10
10
|
"cancel": "取消",
|
|
11
|
+
"changelog": "更新日志",
|
|
11
12
|
"clearCurrentMessages": "清空当前会话消息",
|
|
12
13
|
"close": "关闭",
|
|
13
14
|
"confirmClearCurrentMessages": "即将清空当前会话消息,清空后将无法找回,请确认你的操作",
|
|
14
15
|
"confirmRemoveSessionItemAlert": "即将删除该助手,删除后该将无法找回,请确认你的操作",
|
|
16
|
+
"copy": "复制",
|
|
17
|
+
"copySuccess": "复制成功",
|
|
15
18
|
"defaultAgent": "默认助手",
|
|
16
19
|
"defaultSession": "默认对话",
|
|
20
|
+
"delete": "删除",
|
|
17
21
|
"edit": "编辑",
|
|
18
|
-
"export": "
|
|
22
|
+
"export": "导出配置",
|
|
23
|
+
"exportType": {
|
|
24
|
+
"agent": "导出助手设定",
|
|
25
|
+
"agentWithMessage": "导出助手和消息",
|
|
26
|
+
"all": "导出全局设置和所有助手数据",
|
|
27
|
+
"allAgent": "导出所有助手设定",
|
|
28
|
+
"allAgentWithMessage": "导出所有助手和消息",
|
|
29
|
+
"globalSetting": "导出全局设置"
|
|
30
|
+
},
|
|
31
|
+
"feedback": "反馈与建议",
|
|
32
|
+
"import": "导入配置",
|
|
19
33
|
"newAgent": "新建助手",
|
|
20
34
|
"noDescription": "暂无描述",
|
|
21
35
|
"ok": "确定",
|
|
36
|
+
"overload": "超过限制",
|
|
37
|
+
"pin": "置顶",
|
|
38
|
+
"pinOff": "取消置顶",
|
|
39
|
+
"regenerate": "重新生成",
|
|
40
|
+
"rename": "重命名",
|
|
22
41
|
"reset": "重置",
|
|
42
|
+
"roleAndArchive": "角色与记录",
|
|
23
43
|
"searchAgentPlaceholder": "搜索助手和对话...",
|
|
24
44
|
"send": "发送",
|
|
25
45
|
"sendPlaceholder": "输入聊天内容...",
|
|
26
|
-
"sessionSetting": "会话设置",
|
|
27
46
|
"setting": "设置",
|
|
28
47
|
"share": "分享",
|
|
48
|
+
"temp": "临时",
|
|
29
49
|
"tokenDetail": "系统设定: {{systemRoleToken}} 历史消息: {{chatsToken}}",
|
|
50
|
+
"topic": {
|
|
51
|
+
"saveCurrentMessages": "将当前会话保存为话题",
|
|
52
|
+
"searchPlaceholder": "搜索话题..."
|
|
53
|
+
},
|
|
30
54
|
"updateAgent": "更新助理信息",
|
|
31
55
|
"updatePrompt": "更新提示词"
|
|
32
56
|
}
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
{
|
|
2
|
-
"agentHeader": "编辑助手信息",
|
|
3
2
|
"danger": {
|
|
4
3
|
"clear": {
|
|
5
4
|
"action": "立即清除",
|
|
@@ -15,7 +14,11 @@
|
|
|
15
14
|
"title": "重置所有设置"
|
|
16
15
|
}
|
|
17
16
|
},
|
|
18
|
-
"header":
|
|
17
|
+
"header": {
|
|
18
|
+
"global": "全局设置",
|
|
19
|
+
"session": "会话设置",
|
|
20
|
+
"sessionWithName": "会话设置 · {{name}}"
|
|
21
|
+
},
|
|
19
22
|
"settingAgent": {
|
|
20
23
|
"avatar": {
|
|
21
24
|
"title": "头像"
|
|
@@ -42,6 +45,13 @@
|
|
|
42
45
|
"title": "助手信息"
|
|
43
46
|
},
|
|
44
47
|
"settingChat": {
|
|
48
|
+
"chatStyleType": {
|
|
49
|
+
"title": "聊天窗口样式",
|
|
50
|
+
"type": {
|
|
51
|
+
"chat": "对话模式",
|
|
52
|
+
"docs": "文档模式"
|
|
53
|
+
}
|
|
54
|
+
},
|
|
45
55
|
"compressThreshold": {
|
|
46
56
|
"desc": "当未压缩的历史消息超过该值时,将进行压缩",
|
|
47
57
|
"title": "历史消息长度压缩阈值"
|
|
@@ -91,7 +101,8 @@
|
|
|
91
101
|
},
|
|
92
102
|
"temperature": {
|
|
93
103
|
"desc": "值越大,回复越随机",
|
|
94
|
-
"title": "随机性"
|
|
104
|
+
"title": "随机性",
|
|
105
|
+
"titleWithValue": "随机性 {{value}}"
|
|
95
106
|
},
|
|
96
107
|
"title": "模型设置",
|
|
97
108
|
"topP": {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lobehub/chat",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.24.0",
|
|
4
4
|
"description": "Lobe Chat is an open-source chatbot client using LangChain, Typescript and Next.js",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"chatbot",
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
],
|
|
12
12
|
"homepage": "https://github.com/lobehub/lobe-chat",
|
|
13
13
|
"bugs": {
|
|
14
|
-
"url": "https://github.com/lobehub/lobe-chat/issues/new"
|
|
14
|
+
"url": "https://github.com/lobehub/lobe-chat/issues/new/choose"
|
|
15
15
|
},
|
|
16
16
|
"repository": {
|
|
17
17
|
"type": "git",
|
|
@@ -30,6 +30,7 @@
|
|
|
30
30
|
"lint:style": "stylelint \"{src,tests}/**/*.{js,jsx,ts,tsx}\" --fix",
|
|
31
31
|
"prepare": "husky install",
|
|
32
32
|
"prettier": "prettier -c --write \"**/**\"",
|
|
33
|
+
"pull": "git pull",
|
|
33
34
|
"release": "semantic-release",
|
|
34
35
|
"start": "next start",
|
|
35
36
|
"stylelint": "stylelint \"src/**/*.{js,jsx,ts,tsx}\" --fix",
|
|
@@ -141,5 +142,6 @@
|
|
|
141
142
|
"publishConfig": {
|
|
142
143
|
"access": "public",
|
|
143
144
|
"registry": "https://registry.npmjs.org"
|
|
144
|
-
}
|
|
145
|
+
},
|
|
146
|
+
"changelog": "https://github.com/lobehub/lobe-chat"
|
|
145
147
|
}
|
|
@@ -36,7 +36,12 @@ const HeaderTitle = memo<HeaderTitleProps>(({ title, desc, tag }) => {
|
|
|
36
36
|
</Flexbox>
|
|
37
37
|
</Flexbox>
|
|
38
38
|
);
|
|
39
|
-
return
|
|
39
|
+
return (
|
|
40
|
+
<Flexbox align={'center'} className={styles.title} gap={8} horizontal>
|
|
41
|
+
{title}
|
|
42
|
+
{tag}
|
|
43
|
+
</Flexbox>
|
|
44
|
+
);
|
|
40
45
|
});
|
|
41
46
|
|
|
42
47
|
export default HeaderTitle;
|
|
@@ -1,36 +1,61 @@
|
|
|
1
|
-
import { InputNumber, Slider } from 'antd';
|
|
1
|
+
import { InputNumber, type InputNumberProps, Slider } from 'antd';
|
|
2
2
|
import { SliderSingleProps } from 'antd/es/slider';
|
|
3
3
|
import { isNull } from 'lodash-es';
|
|
4
4
|
import { memo, useCallback } from 'react';
|
|
5
5
|
import { Flexbox } from 'react-layout-kit';
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
|
|
7
|
+
export interface SliderWithInputProps extends SliderSingleProps {
|
|
8
|
+
controls?: InputNumberProps['controls'];
|
|
9
|
+
size?: InputNumberProps['size'];
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
const SliderWithInput = memo<SliderWithInputProps>(
|
|
13
|
+
({
|
|
14
|
+
step,
|
|
15
|
+
value,
|
|
16
|
+
onChange,
|
|
17
|
+
max,
|
|
18
|
+
min,
|
|
19
|
+
defaultValue,
|
|
20
|
+
size,
|
|
21
|
+
controls,
|
|
22
|
+
style,
|
|
23
|
+
className,
|
|
24
|
+
...props
|
|
25
|
+
}) => {
|
|
9
26
|
const handleOnchange = useCallback((value: number | null) => {
|
|
10
27
|
if (Number.isNaN(value) || isNull(value)) return;
|
|
11
28
|
onChange?.(value);
|
|
12
29
|
}, []);
|
|
13
30
|
|
|
14
31
|
return (
|
|
15
|
-
<Flexbox
|
|
32
|
+
<Flexbox
|
|
33
|
+
align={'center'}
|
|
34
|
+
className={className}
|
|
35
|
+
direction={'horizontal'}
|
|
36
|
+
gap={8}
|
|
37
|
+
style={style}
|
|
38
|
+
>
|
|
16
39
|
<Slider
|
|
17
40
|
defaultValue={defaultValue}
|
|
18
41
|
max={max}
|
|
19
42
|
min={min}
|
|
20
43
|
onChange={handleOnchange}
|
|
21
44
|
step={step}
|
|
22
|
-
style={{ flex: 1 }}
|
|
23
|
-
tooltip={{
|
|
45
|
+
style={size === 'small' ? { flex: 1, margin: 0 } : { flex: 1 }}
|
|
46
|
+
tooltip={{ open: false }}
|
|
24
47
|
value={typeof value === 'number' ? value : 0}
|
|
25
48
|
{...props}
|
|
26
49
|
/>
|
|
27
50
|
<InputNumber
|
|
51
|
+
controls={size !== 'small' || controls}
|
|
28
52
|
defaultValue={defaultValue}
|
|
29
53
|
max={max}
|
|
30
54
|
min={min}
|
|
31
55
|
onChange={handleOnchange}
|
|
56
|
+
size={size}
|
|
32
57
|
step={Number.isNaN(step) || isNull(step) ? undefined : step}
|
|
33
|
-
style={{ flex: 1, maxWidth: 64 }}
|
|
58
|
+
style={{ flex: 1, maxWidth: size === 'small' ? 40 : 64 }}
|
|
34
59
|
value={typeof value === 'number' ? value : 0}
|
|
35
60
|
/>
|
|
36
61
|
</Flexbox>
|
|
@@ -1,18 +1,117 @@
|
|
|
1
|
-
import { ActionIcon, SideNav } from '@lobehub/ui';
|
|
2
|
-
import {
|
|
1
|
+
import { ActionIcon, Icon, SideNav } from '@lobehub/ui';
|
|
2
|
+
import { Dropdown, type MenuProps } from 'antd';
|
|
3
|
+
import {
|
|
4
|
+
Feather,
|
|
5
|
+
FileClock,
|
|
6
|
+
FolderInput,
|
|
7
|
+
FolderOutput,
|
|
8
|
+
Github,
|
|
9
|
+
Heart,
|
|
10
|
+
MessageSquare,
|
|
11
|
+
Settings,
|
|
12
|
+
Settings2,
|
|
13
|
+
Sticker,
|
|
14
|
+
} from 'lucide-react';
|
|
3
15
|
import Router from 'next/router';
|
|
4
|
-
import { memo } from 'react';
|
|
16
|
+
import { memo, useMemo } from 'react';
|
|
17
|
+
import { useTranslation } from 'react-i18next';
|
|
5
18
|
import { shallow } from 'zustand/shallow';
|
|
6
19
|
|
|
20
|
+
import { bugs, homepage } from '@/../package.json';
|
|
7
21
|
import AvatarWithUpload from '@/features/AvatarWithUpload';
|
|
8
22
|
import { useSettings } from '@/store/settings';
|
|
9
23
|
|
|
10
24
|
export default memo(() => {
|
|
11
25
|
const [tab, setTab] = useSettings((s) => [s.sidebarKey, s.switchSideBar], shallow);
|
|
26
|
+
const { t } = useTranslation('common');
|
|
27
|
+
const items: MenuProps['items'] = useMemo(
|
|
28
|
+
() => [
|
|
29
|
+
{
|
|
30
|
+
icon: <Icon icon={FolderInput} />,
|
|
31
|
+
key: 'import',
|
|
32
|
+
label: <div>{t('import')}</div>,
|
|
33
|
+
},
|
|
34
|
+
{
|
|
35
|
+
children: [
|
|
36
|
+
{
|
|
37
|
+
key: 'allAgent',
|
|
38
|
+
label: <div>{t('exportType.allAgent')}</div>,
|
|
39
|
+
},
|
|
40
|
+
{
|
|
41
|
+
key: 'allAgentWithMessage',
|
|
42
|
+
label: <div>{t('exportType.allAgentWithMessage')}</div>,
|
|
43
|
+
},
|
|
44
|
+
{
|
|
45
|
+
key: 'globalSetting',
|
|
46
|
+
label: <div>{t('exportType.globalSetting')}</div>,
|
|
47
|
+
},
|
|
48
|
+
{
|
|
49
|
+
type: 'divider',
|
|
50
|
+
},
|
|
51
|
+
{
|
|
52
|
+
key: 'all',
|
|
53
|
+
label: <div>{t('exportType.all')}</div>,
|
|
54
|
+
},
|
|
55
|
+
],
|
|
56
|
+
icon: <Icon icon={FolderOutput} />,
|
|
57
|
+
key: 'export',
|
|
58
|
+
label: t('export'),
|
|
59
|
+
},
|
|
60
|
+
{
|
|
61
|
+
type: 'divider',
|
|
62
|
+
},
|
|
63
|
+
{
|
|
64
|
+
icon: <Icon icon={Feather} />,
|
|
65
|
+
key: 'feedback',
|
|
66
|
+
label: (
|
|
67
|
+
<a href={bugs.url} rel="noreferrer" target={'_blank'}>
|
|
68
|
+
{t('feedback')}
|
|
69
|
+
</a>
|
|
70
|
+
),
|
|
71
|
+
},
|
|
72
|
+
{
|
|
73
|
+
icon: <Icon icon={FileClock} />,
|
|
74
|
+
key: 'changelog',
|
|
75
|
+
label: (
|
|
76
|
+
<a href={`${homepage}/blob/master/CHANGELOG.md`} rel="noreferrer" target={'_blank'}>
|
|
77
|
+
{t('changelog')}
|
|
78
|
+
</a>
|
|
79
|
+
),
|
|
80
|
+
},
|
|
81
|
+
{
|
|
82
|
+
icon: <Icon icon={Heart} />,
|
|
83
|
+
key: 'about',
|
|
84
|
+
label: (
|
|
85
|
+
<a href={homepage} rel="noreferrer" target={'_blank'}>
|
|
86
|
+
{t('about')}
|
|
87
|
+
</a>
|
|
88
|
+
),
|
|
89
|
+
},
|
|
90
|
+
{
|
|
91
|
+
type: 'divider',
|
|
92
|
+
},
|
|
93
|
+
{
|
|
94
|
+
icon: <Icon icon={Settings} />,
|
|
95
|
+
key: 'setting',
|
|
96
|
+
label: <div onClick={() => Router.push('/setting')}>{t('setting')}</div>,
|
|
97
|
+
},
|
|
98
|
+
],
|
|
99
|
+
[],
|
|
100
|
+
);
|
|
101
|
+
|
|
12
102
|
return (
|
|
13
103
|
<SideNav
|
|
14
104
|
avatar={<AvatarWithUpload />}
|
|
15
|
-
bottomActions={
|
|
105
|
+
bottomActions={
|
|
106
|
+
<>
|
|
107
|
+
<a href={homepage} rel="noreferrer" target={'_blank'}>
|
|
108
|
+
<ActionIcon icon={Github} />
|
|
109
|
+
</a>
|
|
110
|
+
<Dropdown arrow={false} menu={{ items }} trigger={['click']}>
|
|
111
|
+
<ActionIcon icon={Settings2} />
|
|
112
|
+
</Dropdown>
|
|
113
|
+
</>
|
|
114
|
+
}
|
|
16
115
|
style={{ height: '100vh' }}
|
|
17
116
|
topActions={
|
|
18
117
|
<>
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
export default {
|
|
2
|
+
about: '关于',
|
|
2
3
|
advanceSettings: '高级设置',
|
|
3
4
|
agentMaxToken: '会话最大长度',
|
|
4
5
|
agentModel: '模型',
|
|
@@ -7,17 +8,36 @@ export default {
|
|
|
7
8
|
autoGenerate: '自动补全',
|
|
8
9
|
autoGenerateTooltip: '基于提示词自动补全助手描述',
|
|
9
10
|
cancel: '取消',
|
|
11
|
+
changelog: '更新日志',
|
|
10
12
|
clearCurrentMessages: '清空当前会话消息',
|
|
11
13
|
close: '关闭',
|
|
12
14
|
confirmClearCurrentMessages: '即将清空当前会话消息,清空后将无法找回,请确认你的操作',
|
|
13
15
|
confirmRemoveSessionItemAlert: '即将删除该助手,删除后该将无法找回,请确认你的操作',
|
|
16
|
+
copy: '复制',
|
|
17
|
+
copySuccess: '复制成功',
|
|
14
18
|
defaultAgent: '默认助手',
|
|
15
19
|
defaultSession: '默认对话',
|
|
20
|
+
delete: '删除',
|
|
16
21
|
edit: '编辑',
|
|
17
|
-
export: '
|
|
22
|
+
export: '导出配置',
|
|
23
|
+
exportType: {
|
|
24
|
+
agent: '导出助手设定',
|
|
25
|
+
agentWithMessage: '导出助手和消息',
|
|
26
|
+
all: '导出全局设置和所有助手数据',
|
|
27
|
+
allAgent: '导出所有助手设定',
|
|
28
|
+
allAgentWithMessage: '导出所有助手和消息',
|
|
29
|
+
globalSetting: '导出全局设置',
|
|
30
|
+
},
|
|
31
|
+
feedback: '反馈与建议',
|
|
32
|
+
import: '导入配置',
|
|
18
33
|
newAgent: '新建助手',
|
|
19
34
|
noDescription: '暂无描述',
|
|
20
35
|
ok: '确定',
|
|
36
|
+
overload: '超过限制',
|
|
37
|
+
pin: '置顶',
|
|
38
|
+
pinOff: '取消置顶',
|
|
39
|
+
regenerate: '重新生成',
|
|
40
|
+
rename: '重命名',
|
|
21
41
|
reset: '重置',
|
|
22
42
|
roleAndArchive: '角色与记录',
|
|
23
43
|
searchAgentPlaceholder: '搜索助手和对话...',
|
|
@@ -25,6 +45,7 @@ export default {
|
|
|
25
45
|
sendPlaceholder: '输入聊天内容...',
|
|
26
46
|
setting: '设置',
|
|
27
47
|
share: '分享',
|
|
48
|
+
temp: '临时',
|
|
28
49
|
tokenDetail: '系统设定: {{systemRoleToken}} 历史消息: {{chatsToken}}',
|
|
29
50
|
topic: {
|
|
30
51
|
saveCurrentMessages: '将当前会话保存为话题',
|
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
import { ActionIcon, Avatar, List } from '@lobehub/ui';
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
1
|
+
import { ActionIcon, Avatar, Icon, List } from '@lobehub/ui';
|
|
2
|
+
import { useHover } from 'ahooks';
|
|
3
|
+
import { Dropdown, type MenuProps, Popconfirm, Tag } from 'antd';
|
|
4
|
+
import { FolderOutput, MoreVertical, Pin, PinOff, Trash } from 'lucide-react';
|
|
5
|
+
import { FC, memo, useMemo, useRef, useState } from 'react';
|
|
5
6
|
import { useTranslation } from 'react-i18next';
|
|
6
7
|
import { Flexbox } from 'react-layout-kit';
|
|
7
8
|
import { shallow } from 'zustand/shallow';
|
|
@@ -14,14 +15,20 @@ import { useStyles } from './style';
|
|
|
14
15
|
const { Item } = List;
|
|
15
16
|
|
|
16
17
|
interface SessionItemProps {
|
|
17
|
-
active
|
|
18
|
+
active?: boolean;
|
|
18
19
|
id: string;
|
|
19
|
-
loading
|
|
20
|
+
loading?: boolean;
|
|
21
|
+
pin?: boolean;
|
|
20
22
|
}
|
|
21
23
|
|
|
22
|
-
const SessionItem: FC<SessionItemProps> = memo(({ id, active = true, loading }) => {
|
|
24
|
+
const SessionItem: FC<SessionItemProps> = memo(({ id, active = true, loading, pin }) => {
|
|
25
|
+
const ref = useRef(null);
|
|
26
|
+
const isHovering = useHover(ref);
|
|
27
|
+
const [popOpen, setPopOpen] = useState(false);
|
|
28
|
+
const [dropdownOpen, setDropdownOpen] = useState(false);
|
|
23
29
|
const { t } = useTranslation('common');
|
|
24
|
-
const
|
|
30
|
+
const isHighlight = isHovering || dropdownOpen;
|
|
31
|
+
const { styles, theme, cx } = useStyles(isHighlight);
|
|
25
32
|
const [defaultModel] = useSettings((s) => [s.settings.model], shallow);
|
|
26
33
|
|
|
27
34
|
const [
|
|
@@ -51,75 +58,126 @@ const SessionItem: FC<SessionItemProps> = memo(({ id, active = true, loading })
|
|
|
51
58
|
];
|
|
52
59
|
}, shallow);
|
|
53
60
|
|
|
61
|
+
// TODO: 动作绑定
|
|
62
|
+
const items: MenuProps['items'] = useMemo(
|
|
63
|
+
() => [
|
|
64
|
+
{
|
|
65
|
+
icon: <Icon icon={pin ? PinOff : Pin} />,
|
|
66
|
+
key: 'pin',
|
|
67
|
+
label: t(pin ? 'pinOff' : 'pin'),
|
|
68
|
+
},
|
|
69
|
+
{
|
|
70
|
+
children: [
|
|
71
|
+
{
|
|
72
|
+
key: 'agent',
|
|
73
|
+
label: <div>{t('exportType.agent')}</div>,
|
|
74
|
+
},
|
|
75
|
+
{
|
|
76
|
+
key: 'agentWithMessage',
|
|
77
|
+
label: <div>{t('exportType.agentWithMessage')}</div>,
|
|
78
|
+
},
|
|
79
|
+
],
|
|
80
|
+
icon: <Icon icon={FolderOutput} />,
|
|
81
|
+
key: 'export',
|
|
82
|
+
label: t('export'),
|
|
83
|
+
},
|
|
84
|
+
{
|
|
85
|
+
icon: <Icon icon={Trash} />,
|
|
86
|
+
key: 'delete',
|
|
87
|
+
label: t('delete'),
|
|
88
|
+
onClick: () => setPopOpen(true),
|
|
89
|
+
},
|
|
90
|
+
],
|
|
91
|
+
[id],
|
|
92
|
+
);
|
|
93
|
+
|
|
54
94
|
const showModel = model !== defaultModel;
|
|
55
95
|
const showChatLength = chatLength > 0;
|
|
56
96
|
|
|
57
97
|
return (
|
|
58
|
-
<
|
|
59
|
-
<
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
98
|
+
<div ref={ref}>
|
|
99
|
+
<Flexbox className={cx(styles.container, pin && styles.pin)} style={{ position: 'relative' }}>
|
|
100
|
+
<Item
|
|
101
|
+
active={active}
|
|
102
|
+
avatar={
|
|
103
|
+
<Avatar
|
|
104
|
+
animation={isHovering}
|
|
105
|
+
avatar={avatar}
|
|
106
|
+
background={avatarBackground}
|
|
107
|
+
shape="circle"
|
|
108
|
+
size={46}
|
|
109
|
+
title={title}
|
|
110
|
+
/>
|
|
111
|
+
}
|
|
112
|
+
className={isHighlight ? styles.hover : undefined}
|
|
113
|
+
classNames={{ time: cx('session-time', styles.time) }}
|
|
114
|
+
date={updateAt}
|
|
115
|
+
description={
|
|
116
|
+
<Flexbox gap={4}>
|
|
117
|
+
<Flexbox>{description || systemRole}</Flexbox>
|
|
75
118
|
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
/>
|
|
100
|
-
<Popconfirm
|
|
101
|
-
arrow={false}
|
|
102
|
-
cancelText={t('cancel')}
|
|
103
|
-
okButtonProps={{ danger: true }}
|
|
104
|
-
okText={t('ok')}
|
|
105
|
-
onConfirm={(e) => {
|
|
106
|
-
e?.stopPropagation();
|
|
107
|
-
removeSession(id);
|
|
108
|
-
}}
|
|
109
|
-
overlayStyle={{ width: 280 }}
|
|
110
|
-
title={t('confirmRemoveSessionItemAlert')}
|
|
111
|
-
>
|
|
112
|
-
<ActionIcon
|
|
113
|
-
className="session-remove"
|
|
114
|
-
icon={X}
|
|
115
|
-
onClick={(e) => {
|
|
116
|
-
e.preventDefault();
|
|
117
|
-
e.stopPropagation();
|
|
118
|
-
}}
|
|
119
|
-
size={'small'}
|
|
119
|
+
{!(showModel || showChatLength) ? undefined : (
|
|
120
|
+
<Flexbox horizontal>
|
|
121
|
+
{showModel && (
|
|
122
|
+
<Tag bordered={false} style={{ color: theme.colorTextSecondary }}>
|
|
123
|
+
{model}
|
|
124
|
+
</Tag>
|
|
125
|
+
)}
|
|
126
|
+
{/*{showChatLength && (*/}
|
|
127
|
+
{/* <Tag*/}
|
|
128
|
+
{/* bordered={false}*/}
|
|
129
|
+
{/* style={{ color: theme.colorTextSecondary, display: 'flex', gap: 4 }}*/}
|
|
130
|
+
{/* >*/}
|
|
131
|
+
{/* <Icon icon={LucideMessageCircle} />*/}
|
|
132
|
+
{/* {chatLength}*/}
|
|
133
|
+
{/* </Tag>*/}
|
|
134
|
+
{/*)}*/}
|
|
135
|
+
</Flexbox>
|
|
136
|
+
)}
|
|
137
|
+
</Flexbox>
|
|
138
|
+
}
|
|
139
|
+
loading={loading}
|
|
140
|
+
style={{ color: theme.colorText }}
|
|
141
|
+
title={title}
|
|
120
142
|
/>
|
|
121
|
-
|
|
122
|
-
|
|
143
|
+
<Popconfirm
|
|
144
|
+
arrow={false}
|
|
145
|
+
cancelText={t('cancel')}
|
|
146
|
+
okButtonProps={{ danger: true }}
|
|
147
|
+
okText={t('ok')}
|
|
148
|
+
onCancel={() => setPopOpen(false)}
|
|
149
|
+
onConfirm={(e) => {
|
|
150
|
+
e?.stopPropagation();
|
|
151
|
+
removeSession(id);
|
|
152
|
+
setPopOpen(false);
|
|
153
|
+
}}
|
|
154
|
+
open={popOpen}
|
|
155
|
+
overlayStyle={{ width: 280 }}
|
|
156
|
+
title={t('confirmRemoveSessionItemAlert')}
|
|
157
|
+
>
|
|
158
|
+
<Dropdown
|
|
159
|
+
arrow={false}
|
|
160
|
+
menu={{ items }}
|
|
161
|
+
onOpenChange={setDropdownOpen}
|
|
162
|
+
open={dropdownOpen}
|
|
163
|
+
trigger={['click']}
|
|
164
|
+
>
|
|
165
|
+
<ActionIcon
|
|
166
|
+
className="session-remove"
|
|
167
|
+
icon={MoreVertical}
|
|
168
|
+
onClick={(e) => {
|
|
169
|
+
e.preventDefault();
|
|
170
|
+
e.stopPropagation();
|
|
171
|
+
}}
|
|
172
|
+
size={{
|
|
173
|
+
blockSize: 28,
|
|
174
|
+
fontSize: 16,
|
|
175
|
+
}}
|
|
176
|
+
/>
|
|
177
|
+
</Dropdown>
|
|
178
|
+
</Popconfirm>
|
|
179
|
+
</Flexbox>
|
|
180
|
+
</div>
|
|
123
181
|
);
|
|
124
182
|
}, shallow);
|
|
125
183
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { createStyles } from 'antd-style';
|
|
2
2
|
import { rgba } from 'polished';
|
|
3
3
|
|
|
4
|
-
export const useStyles = createStyles(({ css, token }) => {
|
|
4
|
+
export const useStyles = createStyles(({ css, token }, isHighlight: boolean) => {
|
|
5
5
|
return {
|
|
6
6
|
active: css`
|
|
7
7
|
display: flex;
|
|
@@ -22,7 +22,6 @@ export const useStyles = createStyles(({ css, token }) => {
|
|
|
22
22
|
background: ${rgba(token.colorBgLayout, 0.5)};
|
|
23
23
|
backdrop-filter: blur(8px);
|
|
24
24
|
`,
|
|
25
|
-
|
|
26
25
|
container: css`
|
|
27
26
|
position: relative;
|
|
28
27
|
|
|
@@ -32,24 +31,11 @@ export const useStyles = createStyles(({ css, token }) => {
|
|
|
32
31
|
right: 16px;
|
|
33
32
|
transform: translateY(-50%);
|
|
34
33
|
|
|
35
|
-
|
|
36
|
-
height: 16px;
|
|
37
|
-
|
|
38
|
-
font-size: 10px;
|
|
39
|
-
|
|
40
|
-
opacity: 0;
|
|
41
|
-
background-color: ${token.colorFillTertiary};
|
|
42
|
-
|
|
43
|
-
transition: color 600ms ${token.motionEaseOut}, scale 400ms ${token.motionEaseOut},
|
|
44
|
-
background-color 100ms ${token.motionEaseOut}, opacity 100ms ${token.motionEaseOut};
|
|
45
|
-
|
|
46
|
-
&:hover {
|
|
47
|
-
background-color: ${token.colorFill};
|
|
48
|
-
}
|
|
34
|
+
opacity: ${isHighlight ? 1 : 0};
|
|
49
35
|
}
|
|
50
36
|
|
|
51
37
|
.session-time {
|
|
52
|
-
opacity: 1;
|
|
38
|
+
opacity: ${isHighlight ? 0 : 1};
|
|
53
39
|
transition: opacity 100ms ${token.motionEaseOut};
|
|
54
40
|
}
|
|
55
41
|
|
|
@@ -63,6 +49,12 @@ export const useStyles = createStyles(({ css, token }) => {
|
|
|
63
49
|
}
|
|
64
50
|
}
|
|
65
51
|
`,
|
|
52
|
+
hover: css`
|
|
53
|
+
background-color: ${token.colorFillSecondary};
|
|
54
|
+
`,
|
|
55
|
+
pin: css`
|
|
56
|
+
background-color: ${token.colorFillTertiary};
|
|
57
|
+
`,
|
|
66
58
|
time: css`
|
|
67
59
|
align-self: flex-start;
|
|
68
60
|
`,
|
|
@@ -28,7 +28,7 @@ const useStyles = createStyles(({ css, token }) => ({
|
|
|
28
28
|
opacity: 0.75;
|
|
29
29
|
border-bottom: 1px solid ${token.colorBorder};
|
|
30
30
|
|
|
31
|
-
transition: 200ms ${token.motionEaseOut};
|
|
31
|
+
transition: opacity 200ms ${token.motionEaseOut};
|
|
32
32
|
|
|
33
33
|
&:hover {
|
|
34
34
|
opacity: 1;
|
|
@@ -79,8 +79,8 @@ const SideBar = memo(() => {
|
|
|
79
79
|
}}
|
|
80
80
|
value={systemRole}
|
|
81
81
|
/>
|
|
82
|
-
<Flexbox gap={
|
|
83
|
-
<SearchBar placeholder={t('topic.searchPlaceholder')} type={'
|
|
82
|
+
<Flexbox gap={16} style={{ padding: 16 }}>
|
|
83
|
+
<SearchBar placeholder={t('topic.searchPlaceholder')} spotlight type={'ghost'} />
|
|
84
84
|
<Topic />
|
|
85
85
|
</Flexbox>
|
|
86
86
|
</DraggablePanelBody>
|
|
@@ -1,16 +1,20 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { ActionIcon, Icon } from '@lobehub/ui';
|
|
2
|
+
import { Dropdown, type MenuProps, Tag, Typography } from 'antd';
|
|
3
3
|
import { createStyles } from 'antd-style';
|
|
4
|
-
import {
|
|
5
|
-
import { memo } from 'react';
|
|
4
|
+
import { MessageSquareDashed, MoreVertical, PencilLine, Share2, Star, Trash } from 'lucide-react';
|
|
5
|
+
import { memo, useMemo, useState } from 'react';
|
|
6
|
+
import { useTranslation } from 'react-i18next';
|
|
6
7
|
import { Flexbox } from 'react-layout-kit';
|
|
7
8
|
import { shallow } from 'zustand/shallow';
|
|
8
9
|
|
|
9
10
|
import { useSessionStore } from '@/store/session';
|
|
10
11
|
|
|
11
|
-
const
|
|
12
|
+
const { Paragraph } = Typography;
|
|
13
|
+
|
|
14
|
+
const useStyles = createStyles(({ css, token, isDarkMode }) => ({
|
|
12
15
|
active: css`
|
|
13
|
-
background: ${token.
|
|
16
|
+
background: ${isDarkMode ? token.colorFillTertiary : token.colorFillSecondary};
|
|
17
|
+
transition: background 200ms ${token.motionEaseOut};
|
|
14
18
|
|
|
15
19
|
&:hover {
|
|
16
20
|
background: ${token.colorFill};
|
|
@@ -18,11 +22,20 @@ const useStyles = createStyles(({ css, token }) => ({
|
|
|
18
22
|
`,
|
|
19
23
|
container: css`
|
|
20
24
|
cursor: pointer;
|
|
21
|
-
|
|
22
|
-
border-radius:
|
|
25
|
+
padding: 12px 8px;
|
|
26
|
+
border-radius: ${token.borderRadius}px;
|
|
27
|
+
|
|
28
|
+
.topic-more {
|
|
29
|
+
opacity: 0;
|
|
30
|
+
transition: opacity 400ms ${token.motionEaseOut};
|
|
31
|
+
}
|
|
23
32
|
|
|
24
33
|
&:hover {
|
|
25
34
|
background: ${token.colorFillSecondary};
|
|
35
|
+
|
|
36
|
+
.topic-more {
|
|
37
|
+
opacity: 1;
|
|
38
|
+
}
|
|
26
39
|
}
|
|
27
40
|
`,
|
|
28
41
|
split: css`
|
|
@@ -39,13 +52,36 @@ export interface ConfigCellProps {
|
|
|
39
52
|
}
|
|
40
53
|
|
|
41
54
|
const TopicItem = memo<ConfigCellProps>(({ title, active, id, showFav, fav }) => {
|
|
55
|
+
const [dropdownOpen, setDropdownOpen] = useState(false);
|
|
42
56
|
const { styles, theme, cx } = useStyles();
|
|
57
|
+
const { t } = useTranslation('common');
|
|
43
58
|
|
|
44
59
|
const [dispatchTopic, toggleTopic] = useSessionStore(
|
|
45
60
|
(s) => [s.dispatchTopic, s.toggleTopic],
|
|
46
61
|
shallow,
|
|
47
62
|
);
|
|
48
|
-
|
|
63
|
+
|
|
64
|
+
// TODO: 动作绑定
|
|
65
|
+
const items: MenuProps['items'] = useMemo(
|
|
66
|
+
() => [
|
|
67
|
+
{
|
|
68
|
+
icon: <Icon icon={PencilLine} />,
|
|
69
|
+
key: 'rename',
|
|
70
|
+
label: t('rename'),
|
|
71
|
+
},
|
|
72
|
+
{
|
|
73
|
+
icon: <Icon icon={Share2} />,
|
|
74
|
+
key: 'share',
|
|
75
|
+
label: t('share'),
|
|
76
|
+
},
|
|
77
|
+
{
|
|
78
|
+
icon: <Icon icon={Trash} />,
|
|
79
|
+
key: 'delete',
|
|
80
|
+
label: t('delete'),
|
|
81
|
+
},
|
|
82
|
+
],
|
|
83
|
+
[],
|
|
84
|
+
);
|
|
49
85
|
|
|
50
86
|
return (
|
|
51
87
|
<Flexbox
|
|
@@ -56,23 +92,43 @@ const TopicItem = memo<ConfigCellProps>(({ title, active, id, showFav, fav }) =>
|
|
|
56
92
|
onClick={() => {
|
|
57
93
|
toggleTopic(id);
|
|
58
94
|
}}
|
|
59
|
-
padding={'10px 12px'}
|
|
60
95
|
>
|
|
61
|
-
{
|
|
62
|
-
|
|
96
|
+
<Flexbox align={'center'} gap={8} horizontal>
|
|
97
|
+
{!showFav ? (
|
|
98
|
+
<Flexbox align={'center'} height={24} justify={'center'} width={24}>
|
|
99
|
+
<Icon color={theme.colorTextDescription} icon={MessageSquareDashed} />
|
|
100
|
+
</Flexbox>
|
|
101
|
+
) : (
|
|
102
|
+
<ActionIcon
|
|
103
|
+
color={fav ? theme.colorWarning : undefined}
|
|
104
|
+
fill={fav ? theme.colorWarning : 'transparent'}
|
|
105
|
+
icon={Star}
|
|
106
|
+
onClick={() => {
|
|
107
|
+
if (!id) return;
|
|
108
|
+
dispatchTopic({ id, key: 'favorite', type: 'updateChatTopic', value: !fav });
|
|
109
|
+
}}
|
|
110
|
+
size={'small'}
|
|
111
|
+
/>
|
|
112
|
+
)}
|
|
113
|
+
<Paragraph ellipsis={{ rows: 2 }} style={{ margin: 0 }}>
|
|
114
|
+
{title}
|
|
115
|
+
</Paragraph>
|
|
116
|
+
{id ? '' : <Tag>{t('temp')}</Tag>}
|
|
117
|
+
</Flexbox>
|
|
118
|
+
<Dropdown
|
|
119
|
+
arrow={false}
|
|
120
|
+
menu={{ items }}
|
|
121
|
+
onOpenChange={setDropdownOpen}
|
|
122
|
+
open={dropdownOpen}
|
|
123
|
+
trigger={['click']}
|
|
124
|
+
>
|
|
63
125
|
<ActionIcon
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
if (!id) return;
|
|
67
|
-
|
|
68
|
-
dispatchTopic({ id, key: 'favorite', type: 'updateChatTopic', value: !fav });
|
|
69
|
-
}}
|
|
126
|
+
className="topic-more"
|
|
127
|
+
icon={MoreVertical}
|
|
70
128
|
size={'small'}
|
|
71
|
-
style={{
|
|
72
|
-
color: fav ? theme.yellow : undefined,
|
|
73
|
-
}}
|
|
129
|
+
style={dropdownOpen ? { opacity: 1 } : {}}
|
|
74
130
|
/>
|
|
75
|
-
|
|
131
|
+
</Dropdown>
|
|
76
132
|
</Flexbox>
|
|
77
133
|
);
|
|
78
134
|
});
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { ChatList, ChatMessage } from '@lobehub/ui';
|
|
2
2
|
import isEqual from 'fast-deep-equal';
|
|
3
3
|
import { ReactNode, memo } from 'react';
|
|
4
|
+
import { useTranslation } from 'react-i18next';
|
|
4
5
|
import { shallow } from 'zustand/shallow';
|
|
5
6
|
|
|
6
7
|
import { agentSelectors, chatSelectors, useSessionStore } from '@/store/session';
|
|
@@ -10,6 +11,7 @@ import FunctionMessage from './FunctionMessage';
|
|
|
10
11
|
import MessageExtra from './MessageExtra';
|
|
11
12
|
|
|
12
13
|
const List = () => {
|
|
14
|
+
const { t } = useTranslation('common');
|
|
13
15
|
const data = useSessionStore(chatSelectors.currentChats, isEqual);
|
|
14
16
|
const [displayMode, deleteMessage, resendMessage, dispatchMessage] = useSessionStore(
|
|
15
17
|
(s) => [
|
|
@@ -50,6 +52,15 @@ const List = () => {
|
|
|
50
52
|
renderMessage={renderMessage}
|
|
51
53
|
renderMessageExtra={MessageExtra}
|
|
52
54
|
style={{ marginTop: 24 }}
|
|
55
|
+
text={{
|
|
56
|
+
cancel: t('cancel'),
|
|
57
|
+
confirm: t('ok'),
|
|
58
|
+
copy: t('copy'),
|
|
59
|
+
copySuccess: t('copySuccess'),
|
|
60
|
+
delete: t('delete'),
|
|
61
|
+
edit: t('edit'),
|
|
62
|
+
regenerate: t('regenerate'),
|
|
63
|
+
}}
|
|
53
64
|
type={displayMode}
|
|
54
65
|
/>
|
|
55
66
|
);
|
|
@@ -39,15 +39,18 @@ const InputActions = memo(() => {
|
|
|
39
39
|
<ActionIcon icon={BrainCog} placement={'bottom'} title={t('settingModel.model.title')} />
|
|
40
40
|
</Dropdown>
|
|
41
41
|
<Popover
|
|
42
|
+
arrow={false}
|
|
42
43
|
content={
|
|
43
44
|
<SliderWithInput
|
|
45
|
+
controls={false}
|
|
44
46
|
max={1}
|
|
45
47
|
min={0}
|
|
46
48
|
onChange={(v) => {
|
|
47
49
|
updateAgentConfig({ params: { temperature: v } });
|
|
48
50
|
}}
|
|
51
|
+
size={'small'}
|
|
49
52
|
step={0.1}
|
|
50
|
-
style={{ width:
|
|
53
|
+
style={{ width: 160 }}
|
|
51
54
|
value={temperature}
|
|
52
55
|
/>
|
|
53
56
|
}
|
|
@@ -24,7 +24,11 @@ const Token = memo<{ input: string }>(({ input }) => {
|
|
|
24
24
|
|
|
25
25
|
return (
|
|
26
26
|
<Tooltip title={t('tokenDetail', { chatsToken, systemRoleToken })}>
|
|
27
|
-
<TokenTag
|
|
27
|
+
<TokenTag
|
|
28
|
+
maxValue={ModelTokens[model]}
|
|
29
|
+
text={{ overload: t('overload') }}
|
|
30
|
+
value={totalToken + inputTokenCount}
|
|
31
|
+
/>
|
|
28
32
|
</Tooltip>
|
|
29
33
|
);
|
|
30
34
|
});
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { ActionIcon, ChatHeader } from '@lobehub/ui';
|
|
2
|
-
import {
|
|
2
|
+
import { Dropdown, MenuProps } from 'antd';
|
|
3
|
+
import { FolderOutput, Share2 } from 'lucide-react';
|
|
3
4
|
import Router from 'next/router';
|
|
4
|
-
import { memo } from 'react';
|
|
5
|
+
import { memo, useMemo } from 'react';
|
|
5
6
|
import { useTranslation } from 'react-i18next';
|
|
6
7
|
|
|
7
8
|
import HeaderTitle from '@/components/HeaderTitle';
|
|
@@ -9,6 +10,20 @@ import HeaderTitle from '@/components/HeaderTitle';
|
|
|
9
10
|
const Header = memo(() => {
|
|
10
11
|
const { t } = useTranslation('setting');
|
|
11
12
|
|
|
13
|
+
const items: MenuProps['items'] = useMemo(
|
|
14
|
+
() => [
|
|
15
|
+
{
|
|
16
|
+
key: 'agent',
|
|
17
|
+
label: <div>{t('exportType.agent', { ns: 'common' })}</div>,
|
|
18
|
+
},
|
|
19
|
+
{
|
|
20
|
+
key: 'agentWithMessage',
|
|
21
|
+
label: <div>{t('exportType.agentWithMessage', { ns: 'common' })}</div>,
|
|
22
|
+
},
|
|
23
|
+
],
|
|
24
|
+
[],
|
|
25
|
+
);
|
|
26
|
+
|
|
12
27
|
return (
|
|
13
28
|
<ChatHeader
|
|
14
29
|
left={<HeaderTitle title={t('header.session')} />}
|
|
@@ -16,11 +31,13 @@ const Header = memo(() => {
|
|
|
16
31
|
right={
|
|
17
32
|
<>
|
|
18
33
|
<ActionIcon icon={Share2} size={{ fontSize: 24 }} title={t('share', { ns: 'common' })} />
|
|
19
|
-
<
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
34
|
+
<Dropdown arrow={false} menu={{ items }} trigger={['click']}>
|
|
35
|
+
<ActionIcon
|
|
36
|
+
icon={FolderOutput}
|
|
37
|
+
size={{ fontSize: 24 }}
|
|
38
|
+
title={t('export', { ns: 'common' })}
|
|
39
|
+
/>
|
|
40
|
+
</Dropdown>
|
|
24
41
|
</>
|
|
25
42
|
}
|
|
26
43
|
showBackButton
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
import { ChatHeader } from '@lobehub/ui';
|
|
2
|
+
import { Tag } from 'antd';
|
|
2
3
|
import Router from 'next/router';
|
|
3
4
|
import { memo } from 'react';
|
|
4
5
|
import { useTranslation } from 'react-i18next';
|
|
5
6
|
|
|
7
|
+
import { version } from '@/../package.json';
|
|
6
8
|
import HeaderTitle from '@/components/HeaderTitle';
|
|
7
9
|
|
|
8
10
|
const Header = memo(() => {
|
|
@@ -10,7 +12,7 @@ const Header = memo(() => {
|
|
|
10
12
|
|
|
11
13
|
return (
|
|
12
14
|
<ChatHeader
|
|
13
|
-
left={<HeaderTitle title={t('header.global')} />}
|
|
15
|
+
left={<HeaderTitle tag={<Tag>{`v${version}`}</Tag>} title={t('header.global')} />}
|
|
14
16
|
onBackClick={() => Router.back()}
|
|
15
17
|
showBackButton
|
|
16
18
|
/>
|