@lobehub/chat 0.16.1 → 0.18.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 +50 -0
- package/package.json +2 -2
- package/src/locales/default/setting.ts +1 -1
- package/src/pages/chat/[id]/Conversation/ChatList.tsx +9 -3
- package/src/pages/chat/[id]/edit/AgentConfig/index.tsx +31 -29
- package/src/services/chatModel.ts +3 -5
- package/src/store/session/index.ts +1 -0
- package/src/store/session/slices/agentConfig/initialState.ts +8 -1
- package/src/store/session/slices/session/reducers/session.ts +5 -1
- package/src/store/settings/initialState.ts +2 -2
- package/src/types/llm.ts +3 -0
- package/src/types/session.ts +16 -0
- package/src/pages/chat/[id]/edit/FormItem.tsx +0 -26
- package/src/pages/chat/[id]/edit/style.ts +0 -34
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,56 @@
|
|
|
2
2
|
|
|
3
3
|
# Changelog
|
|
4
4
|
|
|
5
|
+
## [Version 0.18.0](https://github.com/lobehub/lobe-chat/compare/v0.17.0...v0.18.0)
|
|
6
|
+
|
|
7
|
+
<sup>Released on **2023-07-24**</sup>
|
|
8
|
+
|
|
9
|
+
#### ✨ Features
|
|
10
|
+
|
|
11
|
+
- **misc**: 实现会话展示模式切换,并优化默认创建角色的配置.
|
|
12
|
+
|
|
13
|
+
<br/>
|
|
14
|
+
|
|
15
|
+
<details>
|
|
16
|
+
<summary><kbd>Improvements and Fixes</kbd></summary>
|
|
17
|
+
|
|
18
|
+
#### What's improved
|
|
19
|
+
|
|
20
|
+
- **misc**: 实现会话展示模式切换,并优化默认创建角色的配置 ([27ae82f](https://github.com/lobehub/lobe-chat/commit/27ae82f))
|
|
21
|
+
|
|
22
|
+
</details>
|
|
23
|
+
|
|
24
|
+
<div align="right">
|
|
25
|
+
|
|
26
|
+
[](#readme-top)
|
|
27
|
+
|
|
28
|
+
</div>
|
|
29
|
+
|
|
30
|
+
## [Version 0.17.0](https://github.com/lobehub/lobe-chat/compare/v0.16.1...v0.17.0)
|
|
31
|
+
|
|
32
|
+
<sup>Released on **2023-07-24**</sup>
|
|
33
|
+
|
|
34
|
+
#### ✨ Features
|
|
35
|
+
|
|
36
|
+
- **misc**: 表单配置支持设定各项高级参数.
|
|
37
|
+
|
|
38
|
+
<br/>
|
|
39
|
+
|
|
40
|
+
<details>
|
|
41
|
+
<summary><kbd>Improvements and Fixes</kbd></summary>
|
|
42
|
+
|
|
43
|
+
#### What's improved
|
|
44
|
+
|
|
45
|
+
- **misc**: 表单配置支持设定各项高级参数 ([6949cc6](https://github.com/lobehub/lobe-chat/commit/6949cc6))
|
|
46
|
+
|
|
47
|
+
</details>
|
|
48
|
+
|
|
49
|
+
<div align="right">
|
|
50
|
+
|
|
51
|
+
[](#readme-top)
|
|
52
|
+
|
|
53
|
+
</div>
|
|
54
|
+
|
|
5
55
|
### [Version 0.16.1](https://github.com/lobehub/lobe-chat/compare/v0.16.0...v0.16.1)
|
|
6
56
|
|
|
7
57
|
<sup>Released on **2023-07-24**</sup>
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lobehub/chat",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.18.0",
|
|
4
4
|
"description": "Lobe Chat is an open-source chatbot client using LangChain, Typescript and Next.js",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"chatbot",
|
|
@@ -63,7 +63,7 @@
|
|
|
63
63
|
"@commitlint/cli": "^17",
|
|
64
64
|
"@emoji-mart/data": "^1",
|
|
65
65
|
"@emoji-mart/react": "^1",
|
|
66
|
-
"@lobehub/ui": "
|
|
66
|
+
"@lobehub/ui": "latest",
|
|
67
67
|
"@vercel/analytics": "^1",
|
|
68
68
|
"ahooks": "^3",
|
|
69
69
|
"ai": "^2",
|
|
@@ -3,7 +3,7 @@ import isEqual from 'fast-deep-equal';
|
|
|
3
3
|
import { ReactNode, memo } from 'react';
|
|
4
4
|
import { shallow } from 'zustand/shallow';
|
|
5
5
|
|
|
6
|
-
import { chatSelectors, useSessionStore } from '@/store/session';
|
|
6
|
+
import { agentSelectors, chatSelectors, useSessionStore } from '@/store/session';
|
|
7
7
|
import { isFunctionMessage } from '@/utils/message';
|
|
8
8
|
|
|
9
9
|
import FunctionMessage from './FunctionMessage';
|
|
@@ -11,8 +11,13 @@ import MessageExtra from './MessageExtra';
|
|
|
11
11
|
|
|
12
12
|
const List = () => {
|
|
13
13
|
const data = useSessionStore(chatSelectors.currentChats, isEqual);
|
|
14
|
-
const [deleteMessage, resendMessage, dispatchMessage] = useSessionStore(
|
|
15
|
-
(s) => [
|
|
14
|
+
const [displayMode, deleteMessage, resendMessage, dispatchMessage] = useSessionStore(
|
|
15
|
+
(s) => [
|
|
16
|
+
agentSelectors.currentAgentConfigSafe(s).displayMode,
|
|
17
|
+
s.deleteMessage,
|
|
18
|
+
s.resendMessage,
|
|
19
|
+
s.dispatchMessage,
|
|
20
|
+
],
|
|
16
21
|
shallow,
|
|
17
22
|
);
|
|
18
23
|
|
|
@@ -45,6 +50,7 @@ const List = () => {
|
|
|
45
50
|
renderMessage={renderMessage}
|
|
46
51
|
renderMessageExtra={MessageExtra}
|
|
47
52
|
style={{ marginTop: 24 }}
|
|
53
|
+
type={displayMode}
|
|
48
54
|
/>
|
|
49
55
|
);
|
|
50
56
|
};
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { Form, ItemGroup } from '@lobehub/ui';
|
|
2
|
-
import { Input, Segmented, Select, Switch } from 'antd';
|
|
2
|
+
import { ConfigProvider, Input, Segmented, Select, Switch } from 'antd';
|
|
3
|
+
import { useTheme } from 'antd-style';
|
|
3
4
|
import isEqual from 'fast-deep-equal';
|
|
4
5
|
import { debounce } from 'lodash-es';
|
|
5
6
|
import { BrainCog, MessagesSquare } from 'lucide-react';
|
|
@@ -15,19 +16,18 @@ import type { LobeAgentConfig } from '@/types/session';
|
|
|
15
16
|
|
|
16
17
|
type SettingItemGroup = ItemGroup & {
|
|
17
18
|
children: {
|
|
18
|
-
name?: keyof LobeAgentConfig;
|
|
19
|
+
name?: keyof LobeAgentConfig | string[];
|
|
19
20
|
}[];
|
|
20
21
|
};
|
|
21
22
|
|
|
22
23
|
const AgentConfig = () => {
|
|
23
24
|
const { t } = useTranslation('setting');
|
|
25
|
+
const theme = useTheme();
|
|
24
26
|
|
|
25
27
|
const config = useSessionStore(agentSelectors.currentAgentConfigSafe, isEqual);
|
|
26
28
|
|
|
27
29
|
const [updateAgentConfig] = useSessionStore((s) => [s.updateAgentConfig], shallow);
|
|
28
30
|
|
|
29
|
-
// TODO: setting 结构嵌套,现在是扁平的 params: { temperature: 0.6 }
|
|
30
|
-
// @ts-ignore
|
|
31
31
|
const chat: SettingItemGroup = useMemo(
|
|
32
32
|
() => ({
|
|
33
33
|
children: [
|
|
@@ -35,20 +35,20 @@ const AgentConfig = () => {
|
|
|
35
35
|
children: (
|
|
36
36
|
<Segmented
|
|
37
37
|
options={[
|
|
38
|
-
{ label: t('settingChat.chatStyleType.type.
|
|
38
|
+
{ label: t('settingChat.chatStyleType.type.chat'), value: 'chat' },
|
|
39
39
|
{ label: t('settingChat.chatStyleType.type.docs'), value: 'docs' },
|
|
40
40
|
]}
|
|
41
41
|
/>
|
|
42
42
|
),
|
|
43
43
|
label: t('settingChat.chatStyleType.title'),
|
|
44
44
|
minWidth: undefined,
|
|
45
|
-
name: '
|
|
45
|
+
name: 'displayMode',
|
|
46
46
|
},
|
|
47
47
|
{
|
|
48
48
|
children: <Input placeholder={t('settingChat.inputTemplate.placeholder')} />,
|
|
49
49
|
desc: t('settingChat.inputTemplate.desc'),
|
|
50
50
|
label: t('settingChat.inputTemplate.title'),
|
|
51
|
-
name: '
|
|
51
|
+
name: 'inputTemplate',
|
|
52
52
|
},
|
|
53
53
|
{
|
|
54
54
|
children: <Switch />,
|
|
@@ -60,8 +60,7 @@ const AgentConfig = () => {
|
|
|
60
60
|
{
|
|
61
61
|
children: <SliderWithInput max={32} min={0} />,
|
|
62
62
|
desc: t('settingChat.historyCount.desc'),
|
|
63
|
-
|
|
64
|
-
hidden: !config.params.enableHistoryCount,
|
|
63
|
+
hidden: !config.enableHistoryCount,
|
|
65
64
|
label: t('settingChat.historyCount.title'),
|
|
66
65
|
name: 'historyCount',
|
|
67
66
|
},
|
|
@@ -75,8 +74,7 @@ const AgentConfig = () => {
|
|
|
75
74
|
{
|
|
76
75
|
children: <SliderWithInput max={32} min={0} />,
|
|
77
76
|
desc: t('settingChat.compressThreshold.desc'),
|
|
78
|
-
|
|
79
|
-
hidden: !config.params.enableCompressThreshold,
|
|
77
|
+
hidden: !config.enableCompressThreshold,
|
|
80
78
|
label: t('settingChat.compressThreshold.title'),
|
|
81
79
|
name: 'compressThreshold',
|
|
82
80
|
},
|
|
@@ -87,8 +85,6 @@ const AgentConfig = () => {
|
|
|
87
85
|
[config],
|
|
88
86
|
);
|
|
89
87
|
|
|
90
|
-
// TODO: setting 结构嵌套,现在是扁平的 params: { temperature: 0.6 }
|
|
91
|
-
// @ts-ignore
|
|
92
88
|
const model: SettingItemGroup = useMemo(
|
|
93
89
|
() => ({
|
|
94
90
|
children: [
|
|
@@ -110,28 +106,28 @@ const AgentConfig = () => {
|
|
|
110
106
|
children: <SliderWithInput max={1} min={0} step={0.1} />,
|
|
111
107
|
desc: t('settingModel.temperature.desc'),
|
|
112
108
|
label: t('settingModel.temperature.title'),
|
|
113
|
-
name: 'temperature',
|
|
109
|
+
name: ['params', 'temperature'],
|
|
114
110
|
tag: 'temperature',
|
|
115
111
|
},
|
|
116
112
|
{
|
|
117
113
|
children: <SliderWithInput max={1} min={0} step={0.1} />,
|
|
118
114
|
desc: t('settingModel.topP.desc'),
|
|
119
115
|
label: t('settingModel.topP.title'),
|
|
120
|
-
name: '
|
|
116
|
+
name: ['params', 'top_p'],
|
|
121
117
|
tag: 'top_p',
|
|
122
118
|
},
|
|
123
119
|
{
|
|
124
120
|
children: <SliderWithInput max={2} min={-2} step={0.1} />,
|
|
125
121
|
desc: t('settingModel.presencePenalty.desc'),
|
|
126
122
|
label: t('settingModel.presencePenalty.title'),
|
|
127
|
-
name: '
|
|
123
|
+
name: ['params', 'presence_penalty'],
|
|
128
124
|
tag: 'presence_penalty',
|
|
129
125
|
},
|
|
130
126
|
{
|
|
131
127
|
children: <SliderWithInput max={2} min={-2} step={0.1} />,
|
|
132
128
|
desc: t('settingModel.frequencyPenalty.desc'),
|
|
133
129
|
label: t('settingModel.frequencyPenalty.title'),
|
|
134
|
-
name: '
|
|
130
|
+
name: ['params', 'frequency_penalty'],
|
|
135
131
|
tag: 'frequency_penalty',
|
|
136
132
|
},
|
|
137
133
|
{
|
|
@@ -144,11 +140,9 @@ const AgentConfig = () => {
|
|
|
144
140
|
{
|
|
145
141
|
children: <SliderWithInput max={32_000} min={0} step={100} />,
|
|
146
142
|
desc: t('settingModel.maxTokens.desc'),
|
|
147
|
-
|
|
148
|
-
// @ts-ignore
|
|
149
|
-
hidden: !config?.params?.enableMaxTokens,
|
|
143
|
+
hidden: !config?.enableMaxTokens,
|
|
150
144
|
label: t('settingModel.maxTokens.title'),
|
|
151
|
-
name: 'params
|
|
145
|
+
name: ['params', 'max_tokens'],
|
|
152
146
|
tag: 'max_tokens',
|
|
153
147
|
},
|
|
154
148
|
],
|
|
@@ -158,15 +152,23 @@ const AgentConfig = () => {
|
|
|
158
152
|
[config],
|
|
159
153
|
);
|
|
160
154
|
|
|
161
|
-
const items = useMemo(() => [chat, model], [config]);
|
|
162
|
-
|
|
163
155
|
return (
|
|
164
|
-
<
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
156
|
+
<ConfigProvider
|
|
157
|
+
theme={{
|
|
158
|
+
components: {
|
|
159
|
+
Segmented: {
|
|
160
|
+
colorBgLayout: theme.isDarkMode ? '#111' : '#f1f1f1',
|
|
161
|
+
},
|
|
162
|
+
},
|
|
163
|
+
}}
|
|
164
|
+
>
|
|
165
|
+
<Form
|
|
166
|
+
initialValues={config}
|
|
167
|
+
items={[chat, model]}
|
|
168
|
+
onValuesChange={debounce(updateAgentConfig, 100)}
|
|
169
|
+
{...FORM_STYLE}
|
|
170
|
+
/>
|
|
171
|
+
</ConfigProvider>
|
|
170
172
|
);
|
|
171
173
|
};
|
|
172
174
|
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { merge } from 'lodash-es';
|
|
2
2
|
|
|
3
|
+
import { initialLobeAgentConfig } from '@/store/session';
|
|
3
4
|
import type { OpenAIStreamPayload } from '@/types/openai';
|
|
4
5
|
|
|
5
6
|
import { URLS } from './url';
|
|
@@ -13,12 +14,9 @@ export const fetchChatModel = (
|
|
|
13
14
|
) => {
|
|
14
15
|
const payload = merge(
|
|
15
16
|
{
|
|
16
|
-
|
|
17
|
-
model: 'gpt-3.5-turbo',
|
|
18
|
-
presence_penalty: 0,
|
|
17
|
+
model: initialLobeAgentConfig.model,
|
|
19
18
|
stream: true,
|
|
20
|
-
|
|
21
|
-
top_p: 1,
|
|
19
|
+
...initialLobeAgentConfig.params,
|
|
22
20
|
},
|
|
23
21
|
params,
|
|
24
22
|
);
|
|
@@ -11,8 +11,15 @@ export interface AgentConfigState {
|
|
|
11
11
|
}
|
|
12
12
|
|
|
13
13
|
export const initialLobeAgentConfig: LobeAgentConfig = {
|
|
14
|
+
displayMode: 'chat',
|
|
14
15
|
model: LanguageModel.GPT3_5,
|
|
15
|
-
params: {
|
|
16
|
+
params: {
|
|
17
|
+
frequency_penalty: 0,
|
|
18
|
+
presence_penalty: 0,
|
|
19
|
+
temperature: 0.6,
|
|
20
|
+
top_p: 1,
|
|
21
|
+
},
|
|
22
|
+
plugins: [],
|
|
16
23
|
systemRole: '',
|
|
17
24
|
};
|
|
18
25
|
|
|
@@ -102,7 +102,11 @@ export const sessionsReducer = (state: LobeSessions, payload: SessionDispatch):
|
|
|
102
102
|
const chat = draft[id];
|
|
103
103
|
if (!chat) return;
|
|
104
104
|
|
|
105
|
-
chat.config = {
|
|
105
|
+
chat.config = {
|
|
106
|
+
...chat.config,
|
|
107
|
+
...config,
|
|
108
|
+
params: { ...chat.config.params, ...config.params },
|
|
109
|
+
};
|
|
106
110
|
});
|
|
107
111
|
}
|
|
108
112
|
|
|
@@ -7,8 +7,8 @@ export const DEFAULT_SETTINGS: ConfigSettings = {
|
|
|
7
7
|
accessCode: '',
|
|
8
8
|
avatar: '',
|
|
9
9
|
compressThreshold: 24,
|
|
10
|
-
enableCompressThreshold:
|
|
11
|
-
enableHistoryCount:
|
|
10
|
+
enableCompressThreshold: false,
|
|
11
|
+
enableHistoryCount: false,
|
|
12
12
|
enableMaxTokens: true,
|
|
13
13
|
endpoint: '',
|
|
14
14
|
fontSize: 14,
|
package/src/types/llm.ts
CHANGED
|
@@ -18,6 +18,7 @@ export enum LanguageModel {
|
|
|
18
18
|
export interface LLMParams {
|
|
19
19
|
/**
|
|
20
20
|
* 控制生成文本中的惩罚系数,用于减少重复性
|
|
21
|
+
* @default 0
|
|
21
22
|
*/
|
|
22
23
|
frequency_penalty?: number;
|
|
23
24
|
/**
|
|
@@ -26,6 +27,7 @@ export interface LLMParams {
|
|
|
26
27
|
max_tokens?: number;
|
|
27
28
|
/**
|
|
28
29
|
* 控制生成文本中的惩罚系数,用于减少主题的变化
|
|
30
|
+
* @default 0
|
|
29
31
|
*/
|
|
30
32
|
presence_penalty?: number;
|
|
31
33
|
/**
|
|
@@ -35,6 +37,7 @@ export interface LLMParams {
|
|
|
35
37
|
temperature?: number;
|
|
36
38
|
/**
|
|
37
39
|
* 控制生成文本中最高概率的单个 token
|
|
40
|
+
* @default 1
|
|
38
41
|
*/
|
|
39
42
|
top_p?: number;
|
|
40
43
|
}
|
package/src/types/session.ts
CHANGED
|
@@ -26,10 +26,26 @@ interface LobeSessionBase extends BaseDataModel {
|
|
|
26
26
|
}
|
|
27
27
|
|
|
28
28
|
export interface LobeAgentConfig {
|
|
29
|
+
compressThreshold?: number;
|
|
30
|
+
displayMode?: 'chat' | 'docs';
|
|
31
|
+
/**
|
|
32
|
+
* 历史消息长度压缩阈值
|
|
33
|
+
*/
|
|
34
|
+
enableCompressThreshold?: boolean;
|
|
35
|
+
/**
|
|
36
|
+
* 开启历史记录条数
|
|
37
|
+
*/
|
|
38
|
+
enableHistoryCount?: boolean;
|
|
39
|
+
enableMaxTokens?: boolean;
|
|
29
40
|
/**
|
|
30
41
|
* 语言模型示例
|
|
31
42
|
*/
|
|
32
43
|
example?: LLMExample;
|
|
44
|
+
/**
|
|
45
|
+
* 历史消息条数
|
|
46
|
+
*/
|
|
47
|
+
historyCount?: number;
|
|
48
|
+
inputTemplate?: string;
|
|
33
49
|
/**
|
|
34
50
|
* 角色所使用的语言模型
|
|
35
51
|
* @default gpt-3.5-turbo
|
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
import { createStyles } from 'antd-style';
|
|
2
|
-
import { ReactNode, memo } from 'react';
|
|
3
|
-
import { Flexbox } from 'react-layout-kit';
|
|
4
|
-
|
|
5
|
-
const useStyles = createStyles(({ css, token }) => ({
|
|
6
|
-
header: css``,
|
|
7
|
-
title: css`
|
|
8
|
-
color: ${token.colorTextSecondary};
|
|
9
|
-
`,
|
|
10
|
-
}));
|
|
11
|
-
|
|
12
|
-
interface FormItemProps {
|
|
13
|
-
children: ReactNode;
|
|
14
|
-
label: string;
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
export const FormItem = memo<FormItemProps>(({ label, children }) => {
|
|
18
|
-
const { styles } = useStyles();
|
|
19
|
-
|
|
20
|
-
return (
|
|
21
|
-
<Flexbox className={styles.header} gap={12}>
|
|
22
|
-
<Flexbox className={styles.title}>{label}</Flexbox>
|
|
23
|
-
<Flexbox>{children}</Flexbox>
|
|
24
|
-
</Flexbox>
|
|
25
|
-
);
|
|
26
|
-
});
|
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
import { createStyles } from 'antd-style';
|
|
2
|
-
|
|
3
|
-
export const useStyles = createStyles(({ css, token }) => ({
|
|
4
|
-
collapseHeader: css`
|
|
5
|
-
.ant-collapse-header {
|
|
6
|
-
align-items: center !important;
|
|
7
|
-
}
|
|
8
|
-
`,
|
|
9
|
-
footer: css`
|
|
10
|
-
position: sticky;
|
|
11
|
-
bottom: 0;
|
|
12
|
-
border-top: 1px solid ${token.colorBorder};
|
|
13
|
-
`,
|
|
14
|
-
form: css`
|
|
15
|
-
overflow-y: auto;
|
|
16
|
-
`,
|
|
17
|
-
header: css`
|
|
18
|
-
background: ${token.colorBgContainer};
|
|
19
|
-
border-bottom: 1px solid ${token.colorSplit};
|
|
20
|
-
`,
|
|
21
|
-
profile: css`
|
|
22
|
-
font-size: 20px;
|
|
23
|
-
font-weight: bold;
|
|
24
|
-
color: ${token.colorText};
|
|
25
|
-
`,
|
|
26
|
-
prompt: css`
|
|
27
|
-
padding: 12px;
|
|
28
|
-
background: ${token.colorFillTertiary};
|
|
29
|
-
`,
|
|
30
|
-
title: css`
|
|
31
|
-
font-size: 16px;
|
|
32
|
-
font-weight: 500;
|
|
33
|
-
`,
|
|
34
|
-
}));
|