@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 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
+ [![](https://img.shields.io/badge/-BACK_TO_TOP-151515?style=flat-square)](#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
+ [![](https://img.shields.io/badge/-BACK_TO_TOP-151515?style=flat-square)](#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.16.1",
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": "^1",
66
+ "@lobehub/ui": "latest",
67
67
  "@vercel/analytics": "^1",
68
68
  "ahooks": "^3",
69
69
  "ai": "^2",
@@ -48,7 +48,7 @@ export default {
48
48
  chatStyleType: {
49
49
  title: '聊天窗口样式',
50
50
  type: {
51
- bubble: '气泡模式',
51
+ chat: '对话模式',
52
52
  docs: '文档模式',
53
53
  },
54
54
  },
@@ -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) => [s.deleteMessage, s.resendMessage, s.dispatchMessage],
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.bubble'), value: 'chat' },
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: 'chatStyleType',
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: 'enableHistoryCount',
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
- // @ts-ignore
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
- // @ts-ignore
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: 'topP',
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: 'presencePenalty',
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: 'frequencyPenalty',
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
- // TODO
148
- // @ts-ignore
149
- hidden: !config?.params?.enableMaxTokens,
143
+ hidden: !config?.enableMaxTokens,
150
144
  label: t('settingModel.maxTokens.title'),
151
- name: 'params.maxTokens',
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
- <Form
165
- initialValues={config}
166
- items={items}
167
- onValuesChange={debounce(updateAgentConfig, 100)}
168
- {...FORM_STYLE}
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
- frequency_penalty: 0,
17
- model: 'gpt-3.5-turbo',
18
- presence_penalty: 0,
17
+ model: initialLobeAgentConfig.model,
19
18
  stream: true,
20
- temperature: 0.6,
21
- top_p: 1,
19
+ ...initialLobeAgentConfig.params,
22
20
  },
23
21
  params,
24
22
  );
@@ -32,4 +32,5 @@ export const useSessionStore = create<SessionStore>()(
32
32
  );
33
33
 
34
34
  export * from './selectors';
35
+ export { initialLobeAgentConfig } from './slices/agentConfig';
35
36
  export type { SessionStore } from './store';
@@ -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: { temperature: 0.6 },
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 = { ...chat.config, ...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: true,
11
- enableHistoryCount: true,
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
  }
@@ -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
- }));