@lobehub/chat 0.83.2 → 0.83.4

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.83.4](https://github.com/lobehub/lobe-chat/compare/v0.83.3...v0.83.4)
6
+
7
+ <sup>Released on **2023-10-06**</sup>
8
+
9
+ #### 🐛 Bug Fixes
10
+
11
+ - **misc**: Fix agent settings.
12
+
13
+ <br/>
14
+
15
+ <details>
16
+ <summary><kbd>Improvements and Fixes</kbd></summary>
17
+
18
+ #### What's fixed
19
+
20
+ - **misc**: Fix agent settings, closes [#271](https://github.com/lobehub/lobe-chat/issues/271) ([aac9a70](https://github.com/lobehub/lobe-chat/commit/aac9a70))
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.83.3](https://github.com/lobehub/lobe-chat/compare/v0.83.2...v0.83.3)
31
+
32
+ <sup>Released on **2023-10-06**</sup>
33
+
34
+ #### ♻ Code Refactoring
35
+
36
+ - **misc**: Refactor the settings layout to rsc.
37
+
38
+ <br/>
39
+
40
+ <details>
41
+ <summary><kbd>Improvements and Fixes</kbd></summary>
42
+
43
+ #### Code refactoring
44
+
45
+ - **misc**: Refactor the settings layout to rsc ([b840f44](https://github.com/lobehub/lobe-chat/commit/b840f44))
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.83.2](https://github.com/lobehub/lobe-chat/compare/v0.83.1...v0.83.2)
6
56
 
7
57
  <sup>Released on **2023-10-06**</sup>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lobehub/chat",
3
- "version": "0.83.2",
3
+ "version": "0.83.4",
4
4
  "description": "An open-source, extensible (Function Calling), high-performance chatbot framework. It supports one-click free deployment of your private ChatGPT/LLM web application",
5
5
  "keywords": [
6
6
  "chatbot",
@@ -1,21 +1,32 @@
1
1
  'use client';
2
2
 
3
+ import isEqual from 'fast-deep-equal';
3
4
  import { memo } from 'react';
4
5
 
6
+ import AgentSetting from '@/features/AgentSetting';
7
+ import { settingsSelectors, useGlobalStore } from '@/store/global';
5
8
  import { useSwitchSideBarOnInit } from '@/store/global/hooks/useSwitchSettingsOnInit';
6
9
  import { SettingsTabs } from '@/store/global/initialState';
7
10
 
8
- import Layout from '../index';
9
- import Agent from './Agent';
10
-
11
- const AgentSetting = memo(() => {
11
+ const Agent = memo(() => {
12
12
  useSwitchSideBarOnInit(SettingsTabs.Agent);
13
13
 
14
+ const config = useGlobalStore(settingsSelectors.defaultAgentConfig, isEqual);
15
+ const meta = useGlobalStore(settingsSelectors.defaultAgentMeta, isEqual);
16
+ const [updateAgent] = useGlobalStore((s) => [s.updateDefaultAgent]);
17
+
14
18
  return (
15
- <Layout>
16
- <Agent />
17
- </Layout>
19
+ <AgentSetting
20
+ config={config}
21
+ meta={meta}
22
+ onConfigChange={(config) => {
23
+ updateAgent({ config });
24
+ }}
25
+ onMetaChange={(meta) => {
26
+ updateAgent({ meta });
27
+ }}
28
+ />
18
29
  );
19
30
  });
20
31
 
21
- export default AgentSetting;
32
+ export default Agent;
@@ -5,16 +5,11 @@ import { memo } from 'react';
5
5
  import { useSwitchSideBarOnInit } from '@/store/global/hooks/useSwitchSettingsOnInit';
6
6
  import { SettingsTabs } from '@/store/global/initialState';
7
7
 
8
- import Layout from '../index';
9
8
  import Common from './Common';
10
9
 
11
10
  const CommonSetting = memo(() => {
12
11
  useSwitchSideBarOnInit(SettingsTabs.Common);
13
- return (
14
- <Layout>
15
- <Common />
16
- </Layout>
17
- );
12
+ return <Common />;
18
13
  });
19
14
 
20
15
  export default CommonSetting;
@@ -4,8 +4,8 @@ import { Center, Flexbox } from 'react-layout-kit';
4
4
  import SafeSpacing from '@/components/SafeSpacing';
5
5
  import AppLayout from '@/layout/AppLayout';
6
6
 
7
- import Header from './features/Header';
8
- import SideBar from './features/SideBar';
7
+ import Header from '../features/Header';
8
+ import SideBar from '../features/SideBar';
9
9
 
10
10
  const SettingLayout = memo<{ children: ReactNode }>(({ children }) => {
11
11
  return (
@@ -1,16 +1,16 @@
1
1
  'use client';
2
2
 
3
3
  import { useResponsive } from 'antd-style';
4
- import Head from 'next/head';
5
4
  import { ReactNode, memo } from 'react';
6
5
  import { useTranslation } from 'react-i18next';
7
6
 
7
+ import PageTitle from '@/components/PageTitle';
8
8
  import { useSwitchSideBarOnInit } from '@/store/global';
9
9
  import { SidebarTabKey } from '@/store/global/initialState';
10
10
  import { genSiteHeadTitle } from '@/utils/genSiteHeadTitle';
11
11
 
12
- import DesktopLayout from './layout.desktop';
13
- import MobileLayout from './layout.mobile';
12
+ import MobileLayout from '../layout.mobile';
13
+ import DesktopLayout from './Desktop';
14
14
 
15
15
  const Setting = memo<{ children: ReactNode }>(({ children }) => {
16
16
  const { mobile } = useResponsive();
@@ -23,9 +23,7 @@ const Setting = memo<{ children: ReactNode }>(({ children }) => {
23
23
 
24
24
  return (
25
25
  <>
26
- <Head>
27
- <title>{pageTitle}</title>
28
- </Head>
26
+ <PageTitle title={pageTitle} />
29
27
  <RenderLayout>{children}</RenderLayout>
30
28
  </>
31
29
  );
@@ -1,3 +1,5 @@
1
+ 'use client';
2
+
1
3
  import { ReactNode, memo } from 'react';
2
4
  import { Flexbox } from 'react-layout-kit';
3
5
 
@@ -0,0 +1,14 @@
1
+ import { PropsWithChildren } from 'react';
2
+
3
+ import { isMobileDevice } from '@/utils/responsive';
4
+
5
+ import Desktop from './layout.desktop';
6
+ import Mobile from './layout.mobile';
7
+
8
+ const Layout = ({ children }: PropsWithChildren) => {
9
+ const mobile = isMobileDevice();
10
+
11
+ return mobile ? <Mobile>{children}</Mobile> : <Desktop>{children}</Desktop>;
12
+ };
13
+
14
+ export default Layout;
@@ -5,16 +5,11 @@ import { memo } from 'react';
5
5
  import { useSwitchSideBarOnInit } from '@/store/global/hooks/useSwitchSettingsOnInit';
6
6
  import { SettingsTabs } from '@/store/global/initialState';
7
7
 
8
- import Layout from '../index';
9
8
  import LLM from './LLM';
10
9
 
11
10
  const LLMSetting = memo(() => {
12
11
  useSwitchSideBarOnInit(SettingsTabs.LLM);
13
- return (
14
- <Layout>
15
- <LLM />
16
- </Layout>
17
- );
12
+ return <LLM />;
18
13
  });
19
14
 
20
15
  export default LLMSetting;
@@ -1,188 +1,170 @@
1
1
  import { Form, ItemGroup, SelectWithImg, SliderWithInput } from '@lobehub/ui';
2
- import { ConfigProvider, Input, Select, Switch } from 'antd';
3
- import { useTheme, useThemeMode } from 'antd-style';
2
+ import { Form as AFrom, Input, Select, Switch } from 'antd';
3
+ import { useThemeMode } from 'antd-style';
4
4
  import isEqual from 'fast-deep-equal';
5
5
  import { debounce } from 'lodash-es';
6
6
  import { BrainCog, LayoutList, MessageSquare, MessagesSquare } from 'lucide-react';
7
- import { memo, useMemo } from 'react';
7
+ import { memo, useEffect } from 'react';
8
8
  import { useTranslation } from 'react-i18next';
9
9
 
10
10
  import { FORM_STYLE } from '@/const/layoutTokens';
11
11
  import { LanguageModel } from '@/types/llm';
12
- import { LobeAgentConfigKeys } from '@/types/session';
13
12
 
14
13
  import { useStore } from '../store';
15
14
 
16
- type SettingItemGroup = ItemGroup & {
17
- children: {
18
- name?: LobeAgentConfigKeys | string | string[];
19
- }[];
20
- };
21
-
22
15
  const AgentConfig = memo(() => {
23
16
  const { t } = useTranslation('setting');
24
17
  const updateConfig = useStore((s) => s.setAgentConfig);
18
+ const [form] = AFrom.useForm();
25
19
  const config = useStore((s) => s.config, isEqual);
26
- const theme = useTheme();
20
+
27
21
  const { isDarkMode } = useThemeMode();
28
22
 
29
- const chat: SettingItemGroup = useMemo(
30
- () => ({
31
- children: [
32
- {
33
- children: (
34
- <SelectWithImg
35
- height={86}
36
- onChange={(mode) => updateConfig({ displayMode: mode })}
37
- options={[
38
- {
39
- icon: MessagesSquare,
40
- img: `/images/chatmode_chat_${isDarkMode ? 'dark' : 'light'}.webp`,
41
- label: t('settingChat.chatStyleType.type.chat'),
42
- value: 'chat',
43
- },
44
- {
45
- icon: LayoutList,
46
- img: `/images/chatmode_docs_${isDarkMode ? 'dark' : 'light'}.webp`,
47
- label: t('settingChat.chatStyleType.type.docs'),
48
- value: 'docs',
49
- },
50
- ]}
51
- value={config.displayMode}
52
- width={144}
53
- />
54
- ),
55
- label: t('settingChat.chatStyleType.title'),
56
- minWidth: undefined,
57
- },
58
- {
59
- children: <Input placeholder={t('settingChat.inputTemplate.placeholder')} />,
60
- desc: t('settingChat.inputTemplate.desc'),
61
- label: t('settingChat.inputTemplate.title'),
62
- name: 'inputTemplate',
63
- },
64
- {
65
- children: <Switch />,
66
- label: t('settingChat.enableHistoryCount.title'),
67
- minWidth: undefined,
68
- name: 'enableHistoryCount',
69
- valuePropName: 'checked',
70
- },
71
- {
72
- children: <SliderWithInput max={32} min={0} />,
73
- desc: t('settingChat.historyCount.desc'),
74
- divider: false,
75
- hidden: !config.enableHistoryCount,
76
- label: t('settingChat.historyCount.title'),
77
- name: 'historyCount',
78
- },
79
- {
80
- children: <Switch />,
81
- label: t('settingChat.enableCompressThreshold.title'),
82
- minWidth: undefined,
83
- name: 'enableCompressThreshold',
84
- valuePropName: 'checked',
85
- },
86
- {
87
- children: <SliderWithInput max={32} min={0} />,
88
- desc: t('settingChat.compressThreshold.desc'),
89
- divider: false,
90
- hidden: !config.enableCompressThreshold,
91
- label: t('settingChat.compressThreshold.title'),
92
- name: 'compressThreshold',
93
- },
94
- ],
95
- icon: MessageSquare,
96
- title: t('settingChat.title'),
97
- }),
98
- [config],
99
- );
23
+ useEffect(() => {
24
+ form.setFieldsValue(config);
25
+ }, [config]);
100
26
 
101
- const model: SettingItemGroup = useMemo(
102
- () => ({
103
- children: [
104
- {
105
- children: (
106
- <Select
107
- options={Object.values(LanguageModel).map((value) => ({
108
- label: value,
109
- value,
110
- }))}
111
- />
112
- ),
113
- desc: t('settingModel.model.desc'),
114
- label: t('settingModel.model.title'),
115
- name: 'model',
116
- tag: 'model',
117
- },
118
- {
119
- children: <SliderWithInput max={1} min={0} step={0.1} />,
120
- desc: t('settingModel.temperature.desc'),
121
- label: t('settingModel.temperature.title'),
122
- name: ['params', 'temperature'],
123
- tag: 'temperature',
124
- },
125
- {
126
- children: <SliderWithInput max={1} min={0} step={0.1} />,
127
- desc: t('settingModel.topP.desc'),
128
- label: t('settingModel.topP.title'),
129
- name: ['params', 'top_p'],
130
- tag: 'top_p',
131
- },
132
- {
133
- children: <SliderWithInput max={2} min={-2} step={0.1} />,
134
- desc: t('settingModel.presencePenalty.desc'),
135
- label: t('settingModel.presencePenalty.title'),
136
- name: ['params', 'presence_penalty'],
137
- tag: 'presence_penalty',
138
- },
139
- {
140
- children: <SliderWithInput max={2} min={-2} step={0.1} />,
141
- desc: t('settingModel.frequencyPenalty.desc'),
142
- label: t('settingModel.frequencyPenalty.title'),
143
- name: ['params', 'frequency_penalty'],
144
- tag: 'frequency_penalty',
145
- },
146
- {
147
- children: <Switch />,
148
- label: t('settingModel.enableMaxTokens.title'),
149
- minWidth: undefined,
150
- name: 'enableMaxTokens',
151
- valuePropName: 'checked',
152
- },
153
- {
154
- children: <SliderWithInput max={32_000} min={0} step={100} />,
155
- desc: t('settingModel.maxTokens.desc'),
156
- divider: false,
157
- hidden: !config?.enableMaxTokens,
158
- label: t('settingModel.maxTokens.title'),
159
- name: ['params', 'max_tokens'],
160
- tag: 'max_tokens',
161
- },
162
- ],
163
- icon: BrainCog,
164
- title: t('settingModel.title'),
165
- }),
166
- [config],
167
- );
27
+ const chat: ItemGroup = {
28
+ children: [
29
+ {
30
+ children: (
31
+ <SelectWithImg
32
+ height={86}
33
+ onChange={(mode) => updateConfig({ displayMode: mode })}
34
+ options={[
35
+ {
36
+ icon: MessagesSquare,
37
+ img: `/images/chatmode_chat_${isDarkMode ? 'dark' : 'light'}.webp`,
38
+ label: t('settingChat.chatStyleType.type.chat'),
39
+ value: 'chat',
40
+ },
41
+ {
42
+ icon: LayoutList,
43
+ img: `/images/chatmode_docs_${isDarkMode ? 'dark' : 'light'}.webp`,
44
+ label: t('settingChat.chatStyleType.type.docs'),
45
+ value: 'docs',
46
+ },
47
+ ]}
48
+ value={config.displayMode}
49
+ width={144}
50
+ />
51
+ ),
52
+ label: t('settingChat.chatStyleType.title'),
53
+ minWidth: undefined,
54
+ },
55
+ {
56
+ children: <Input placeholder={t('settingChat.inputTemplate.placeholder')} />,
57
+ desc: t('settingChat.inputTemplate.desc'),
58
+ label: t('settingChat.inputTemplate.title'),
59
+ name: 'inputTemplate',
60
+ },
61
+ {
62
+ children: <Switch />,
63
+ label: t('settingChat.enableHistoryCount.title'),
64
+ minWidth: undefined,
65
+ name: 'enableHistoryCount',
66
+ valuePropName: 'checked',
67
+ },
68
+ {
69
+ children: <SliderWithInput max={32} min={0} />,
70
+ desc: t('settingChat.historyCount.desc'),
71
+ divider: false,
72
+ hidden: !config.enableHistoryCount,
73
+ label: t('settingChat.historyCount.title'),
74
+ name: 'historyCount',
75
+ },
76
+ {
77
+ children: <Switch />,
78
+ label: t('settingChat.enableCompressThreshold.title'),
79
+ minWidth: undefined,
80
+ name: 'enableCompressThreshold',
81
+ valuePropName: 'checked',
82
+ },
83
+ {
84
+ children: <SliderWithInput max={32} min={0} />,
85
+ desc: t('settingChat.compressThreshold.desc'),
86
+ divider: false,
87
+ hidden: !config.enableCompressThreshold,
88
+ label: t('settingChat.compressThreshold.title'),
89
+ name: 'compressThreshold',
90
+ },
91
+ ],
92
+ icon: MessageSquare,
93
+ title: t('settingChat.title'),
94
+ };
95
+
96
+ const model: ItemGroup = {
97
+ children: [
98
+ {
99
+ children: (
100
+ <Select
101
+ options={Object.values(LanguageModel).map((value) => ({
102
+ label: value,
103
+ value,
104
+ }))}
105
+ />
106
+ ),
107
+ desc: t('settingModel.model.desc'),
108
+ label: t('settingModel.model.title'),
109
+ name: 'model',
110
+ tag: 'model',
111
+ },
112
+ {
113
+ children: <SliderWithInput max={1} min={0} step={0.1} />,
114
+ desc: t('settingModel.temperature.desc'),
115
+ label: t('settingModel.temperature.title'),
116
+ name: ['params', 'temperature'],
117
+ tag: 'temperature',
118
+ },
119
+ {
120
+ children: <SliderWithInput max={1} min={0} step={0.1} />,
121
+ desc: t('settingModel.topP.desc'),
122
+ label: t('settingModel.topP.title'),
123
+ name: ['params', 'top_p'],
124
+ tag: 'top_p',
125
+ },
126
+ {
127
+ children: <SliderWithInput max={2} min={-2} step={0.1} />,
128
+ desc: t('settingModel.presencePenalty.desc'),
129
+ label: t('settingModel.presencePenalty.title'),
130
+ name: ['params', 'presence_penalty'],
131
+ tag: 'presence_penalty',
132
+ },
133
+ {
134
+ children: <SliderWithInput max={2} min={-2} step={0.1} />,
135
+ desc: t('settingModel.frequencyPenalty.desc'),
136
+ label: t('settingModel.frequencyPenalty.title'),
137
+ name: ['params', 'frequency_penalty'],
138
+ tag: 'frequency_penalty',
139
+ },
140
+ {
141
+ children: <Switch />,
142
+ label: t('settingModel.enableMaxTokens.title'),
143
+ minWidth: undefined,
144
+ name: 'enableMaxTokens',
145
+ valuePropName: 'checked',
146
+ },
147
+ {
148
+ children: <SliderWithInput max={32_000} min={0} step={100} />,
149
+ desc: t('settingModel.maxTokens.desc'),
150
+ divider: false,
151
+ hidden: !config?.enableMaxTokens,
152
+ label: t('settingModel.maxTokens.title'),
153
+ name: ['params', 'max_tokens'],
154
+ tag: 'max_tokens',
155
+ },
156
+ ],
157
+ icon: BrainCog,
158
+ title: t('settingModel.title'),
159
+ };
168
160
 
169
161
  return (
170
- <ConfigProvider
171
- theme={{
172
- components: {
173
- Segmented: {
174
- colorBgLayout: theme.isDarkMode ? '#111' : '#f1f1f1',
175
- },
176
- },
177
- }}
178
- >
179
- <Form
180
- initialValues={config}
181
- items={[chat, model]}
182
- onValuesChange={debounce(updateConfig, 100)}
183
- {...FORM_STYLE}
184
- />
185
- </ConfigProvider>
162
+ <Form
163
+ form={form}
164
+ items={[chat, model]}
165
+ onValuesChange={debounce(updateConfig, 100)}
166
+ {...FORM_STYLE}
167
+ />
186
168
  );
187
169
  });
188
170
 
@@ -1,26 +0,0 @@
1
- import isEqual from 'fast-deep-equal';
2
- import { memo } from 'react';
3
-
4
- import AgentSetting from '@/features/AgentSetting';
5
- import { settingsSelectors, useGlobalStore } from '@/store/global';
6
-
7
- const Agent = memo(() => {
8
- const config = useGlobalStore(settingsSelectors.defaultAgentConfig, isEqual);
9
- const meta = useGlobalStore(settingsSelectors.defaultAgentMeta, isEqual);
10
- const [updateAgent] = useGlobalStore((s) => [s.updateDefaultAgent]);
11
-
12
- return (
13
- <AgentSetting
14
- config={config}
15
- meta={meta}
16
- onConfigChange={(config) => {
17
- updateAgent({ config });
18
- }}
19
- onMetaChange={(meta) => {
20
- updateAgent({ meta });
21
- }}
22
- />
23
- );
24
- });
25
-
26
- export default Agent;