@lobehub/chat 0.14.0 → 0.15.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.
Files changed (46) hide show
  1. package/CHANGELOG.md +26 -0
  2. package/locales/en_US/common.json +19 -27
  3. package/locales/en_US/plugin.json +10 -0
  4. package/locales/en_US/setting.json +42 -6
  5. package/locales/zh_CN/common.json +8 -17
  6. package/locales/zh_CN/plugin.json +10 -0
  7. package/locales/zh_CN/setting.json +36 -0
  8. package/package.json +1 -1
  9. package/src/components/HeaderSpacing/index.tsx +3 -1
  10. package/src/components/HeaderTitle/index.tsx +42 -0
  11. package/src/const/layoutTokens.ts +6 -1
  12. package/src/const/meta.ts +3 -0
  13. package/src/locales/default/common.ts +31 -51
  14. package/src/locales/default/plugin.ts +10 -0
  15. package/src/locales/default/setting.ts +46 -1
  16. package/src/locales/resources/en_US.ts +2 -0
  17. package/src/locales/resources/zh_CN.ts +2 -0
  18. package/src/pages/chat/SessionList/List/SessionItem.tsx +1 -2
  19. package/src/pages/chat/[id]/Config/Header.tsx +26 -0
  20. package/src/pages/chat/[id]/Config/SideBar.tsx +86 -0
  21. package/src/pages/chat/[id]/Config/index.tsx +5 -45
  22. package/src/pages/chat/[id]/Conversation/FunctionMessage.tsx +1 -1
  23. package/src/pages/chat/[id]/Conversation/Input/Action.tsx +13 -5
  24. package/src/pages/chat/[id]/Conversation/Input/index.tsx +11 -3
  25. package/src/pages/chat/[id]/Header.tsx +34 -43
  26. package/src/pages/chat/[id]/edit/AgentConfig/index.tsx +154 -95
  27. package/src/pages/chat/[id]/edit/AgentMeta/AutoGenerateInput.tsx +39 -0
  28. package/src/pages/chat/[id]/edit/AgentMeta/BackgroundSwatches.tsx +31 -0
  29. package/src/pages/chat/[id]/edit/AgentMeta/EmojiPicker.tsx +7 -3
  30. package/src/pages/chat/[id]/edit/AgentMeta/index.tsx +68 -75
  31. package/src/pages/chat/[id]/edit/AgentPlugin/index.tsx +44 -0
  32. package/src/pages/chat/[id]/edit/AgentPrompt/index.tsx +48 -0
  33. package/src/pages/chat/[id]/edit/Header.tsx +31 -0
  34. package/src/pages/chat/[id]/edit/index.page.tsx +12 -40
  35. package/src/pages/chat/[id]/index.page.tsx +2 -1
  36. package/src/pages/setting/Header.tsx +4 -11
  37. package/src/pages/setting/SettingForm.tsx +9 -9
  38. package/src/pages/setting/index.page.tsx +2 -1
  39. package/src/store/session/slices/agentConfig/initialState.ts +1 -5
  40. package/src/store/session/slices/agentConfig/selectors.ts +15 -5
  41. package/src/store/session/slices/chat/selectors/chat.ts +2 -2
  42. package/src/store/session/slices/session/selectors/chat.ts +1 -1
  43. package/src/utils/genSiteHeadTitle.ts +1 -0
  44. package/src/pages/chat/[id]/Config/ReadMode.tsx +0 -64
  45. package/src/pages/chat/[id]/edit/AgentConfig/Plugin.tsx +0 -46
  46. package/src/pages/chat/[id]/edit/AgentConfig/Prompt.tsx +0 -69
@@ -0,0 +1,86 @@
1
+ import { ActionIcon, DraggablePanelBody, EditableMessage, SearchBar } from '@lobehub/ui';
2
+ import { createStyles } from 'antd-style';
3
+ import { ChevronRight } from 'lucide-react';
4
+ import { memo, useState } from 'react';
5
+ import { useTranslation } from 'react-i18next';
6
+ import { Flexbox } from 'react-layout-kit';
7
+ import { shallow } from 'zustand/shallow';
8
+
9
+ import { agentSelectors, useSessionStore } from '@/store/session';
10
+
11
+ import Header from './Header';
12
+
13
+ const useStyles = createStyles(({ css, token }) => ({
14
+ desc: css`
15
+ color: ${token.colorText};
16
+ `,
17
+ model: css`
18
+ color: ${token.colorTextTertiary};
19
+ `,
20
+ prompt: css`
21
+ overflow-x: hidden;
22
+ overflow-y: auto;
23
+
24
+ height: 200px;
25
+ padding: 0 16px 16px;
26
+
27
+ opacity: 0.75;
28
+ border-bottom: 1px solid ${token.colorBorder};
29
+
30
+ transition: 200ms ${token.motionEaseOut};
31
+
32
+ &:hover {
33
+ opacity: 1;
34
+ }
35
+ `,
36
+ title: css`
37
+ font-size: ${token.fontSizeHeading4}px;
38
+ font-weight: bold;
39
+ `,
40
+ }));
41
+
42
+ const SideBar = memo(() => {
43
+ const [openModal, setOpenModal] = useState(false);
44
+ const { styles } = useStyles();
45
+ const [updateAgentConfig] = useSessionStore((s) => [s.updateAgentConfig], shallow);
46
+ const systemRole = useSessionStore(agentSelectors.currentAgentSystemRole, shallow);
47
+
48
+ const { t } = useTranslation('common');
49
+ return (
50
+ <DraggablePanelBody style={{ padding: 0 }}>
51
+ <Header
52
+ actions={
53
+ <ActionIcon
54
+ icon={ChevronRight}
55
+ onClick={() => setOpenModal(true)}
56
+ size="small"
57
+ title={t('edit')}
58
+ />
59
+ }
60
+ title={t('settingAgent.prompt.title', { ns: 'setting' })}
61
+ />
62
+ <EditableMessage
63
+ classNames={{ markdown: styles.prompt }}
64
+ onChange={(e) => {
65
+ updateAgentConfig({ systemRole: e });
66
+ }}
67
+ onOpenChange={setOpenModal}
68
+ openModal={openModal}
69
+ placeholder={`${t('settingAgent.prompt.placeholder', { ns: 'setting' })}...`}
70
+ styles={{ markdown: systemRole ? {} : { opacity: 0.5 } }}
71
+ text={{
72
+ cancel: t('cancel'),
73
+ confirm: t('ok'),
74
+ edit: t('edit'),
75
+ title: t('settingAgent.prompt.title', { ns: 'setting' }),
76
+ }}
77
+ value={systemRole}
78
+ />
79
+ <Flexbox style={{ padding: 16 }}>
80
+ <SearchBar placeholder={t('archiveSearchPlaceholder')} />
81
+ </Flexbox>
82
+ </DraggablePanelBody>
83
+ );
84
+ });
85
+
86
+ export default SideBar;
@@ -1,22 +1,13 @@
1
- import {
2
- ActionIcon,
3
- DraggablePanel,
4
- DraggablePanelBody,
5
- DraggablePanelContainer,
6
- } from '@lobehub/ui';
1
+ import { DraggablePanel, DraggablePanelContainer } from '@lobehub/ui';
7
2
  import { createStyles } from 'antd-style';
8
- import { LucideEdit, LucideX } from 'lucide-react';
9
- import Router from 'next/router';
10
3
  import { rgba } from 'polished';
11
- import { useTranslation } from 'react-i18next';
12
- import { Flexbox } from 'react-layout-kit';
13
4
  import { shallow } from 'zustand/shallow';
14
5
 
15
6
  import HeaderSpacing from '@/components/HeaderSpacing';
16
7
  import { CHAT_SIDEBAR_WIDTH } from '@/const/layoutTokens';
17
8
  import { useSessionStore } from '@/store/session';
18
9
 
19
- import ReadMode from './ReadMode';
10
+ import SideBar from './SideBar';
20
11
 
21
12
  const useStyles = createStyles(({ cx, css, token, stylish }) => ({
22
13
  drawer: cx(
@@ -31,10 +22,9 @@ const useStyles = createStyles(({ cx, css, token, stylish }) => ({
31
22
  }));
32
23
 
33
24
  const Config = () => {
34
- const { t } = useTranslation('common');
35
25
  const { styles } = useStyles();
36
- const [showAgentSettings, toggleConfig, id] = useSessionStore(
37
- (s) => [s.showAgentSettings, s.toggleConfig, s.activeId],
26
+ const [showAgentSettings, toggleConfig] = useSessionStore(
27
+ (s) => [s.showAgentSettings, s.toggleConfig],
38
28
  shallow,
39
29
  );
40
30
 
@@ -50,37 +40,7 @@ const Config = () => {
50
40
  >
51
41
  <HeaderSpacing />
52
42
  <DraggablePanelContainer style={{ flex: 'none', minWidth: CHAT_SIDEBAR_WIDTH }}>
53
- <Flexbox
54
- align={'center'}
55
- className={styles.header}
56
- distribution={'space-between'}
57
- horizontal
58
- padding={12}
59
- paddingInline={16}
60
- >
61
- <Flexbox>{t('agentProfile')}</Flexbox>
62
- <Flexbox gap={4} horizontal>
63
- <ActionIcon
64
- icon={LucideEdit}
65
- onClick={() => {
66
- Router.push(`/chat/${id}/edit`);
67
- }}
68
- size={{ blockSize: 32, fontSize: 20 }}
69
- title={t('edit')}
70
- />
71
- <ActionIcon
72
- icon={LucideX}
73
- onClick={() => {
74
- toggleConfig(false);
75
- }}
76
- size={{ blockSize: 32, fontSize: 20 }}
77
- title={t('close')}
78
- />
79
- </Flexbox>
80
- </Flexbox>
81
- <DraggablePanelBody>
82
- <ReadMode />
83
- </DraggablePanelBody>
43
+ <SideBar />
84
44
  </DraggablePanelContainer>
85
45
  </DraggablePanel>
86
46
  );
@@ -16,7 +16,7 @@ const useStyles = createStyles(({ css, token }) => ({
16
16
  `,
17
17
  }));
18
18
  const FunctionMessage = memo(() => {
19
- const { t } = useTranslation();
19
+ const { t } = useTranslation('plugin');
20
20
  const { styles } = useStyles();
21
21
  return (
22
22
  <Flexbox className={styles.container} gap={8} horizontal>
@@ -1,6 +1,6 @@
1
1
  import { ActionIcon } from '@lobehub/ui';
2
2
  import { Popconfirm } from 'antd';
3
- import { Eraser, Languages } from 'lucide-react';
3
+ import { BrainCog, Eraser, Thermometer, Timer } from 'lucide-react';
4
4
  import { memo } from 'react';
5
5
  import { useTranslation } from 'react-i18next';
6
6
  import { shallow } from 'zustand/shallow';
@@ -8,14 +8,22 @@ import { shallow } from 'zustand/shallow';
8
8
  import { useSessionStore } from '@/store/session';
9
9
 
10
10
  const InputActions = memo(() => {
11
- const { t } = useTranslation();
11
+ const { t } = useTranslation('setting');
12
12
  const [clearMessage] = useSessionStore((s) => [s.clearMessage], shallow);
13
13
 
14
14
  return (
15
15
  <>
16
- <ActionIcon icon={Languages} />
17
- <Popconfirm onConfirm={() => clearMessage()} title={t('confirmClearCurrentMessages')}>
18
- <ActionIcon icon={Eraser} title={t('clearCurrentMessages')} />
16
+ <ActionIcon icon={BrainCog} title={t('settingModel.model.title')} />
17
+ <ActionIcon icon={Thermometer} title={t('settingModel.temperature.title')} />
18
+ <ActionIcon icon={Timer} title={t('settingChat.historyCount.title')} />
19
+ <Popconfirm
20
+ cancelText={t('cancel', { ns: 'common' })}
21
+ okButtonProps={{ danger: true }}
22
+ okText={t('ok', { ns: 'common' })}
23
+ onConfirm={() => clearMessage()}
24
+ title={t('confirmClearCurrentMessages', { ns: 'common' })}
25
+ >
26
+ <ActionIcon icon={Eraser} title={t('clearCurrentMessages', { ns: 'common' })} />
19
27
  </Popconfirm>
20
28
  </>
21
29
  );
@@ -1,4 +1,4 @@
1
- import { ChatInputArea, DraggablePanel, Icon } from '@lobehub/ui';
1
+ import { ChatInputArea, DraggablePanel, Icon, Tooltip } from '@lobehub/ui';
2
2
  import { Button } from 'antd';
3
3
  import { Archive } from 'lucide-react';
4
4
  import { memo, useMemo, useState } from 'react';
@@ -13,7 +13,7 @@ import InputActions from './Action';
13
13
  import Token from './Token';
14
14
 
15
15
  const ChatInput = () => {
16
- const { t } = useTranslation();
16
+ const { t } = useTranslation('common');
17
17
  const [expand, setExpand] = useState<boolean>(false);
18
18
  const [text, setText] = useState('');
19
19
 
@@ -21,7 +21,11 @@ const ChatInput = () => {
21
21
  const [sendMessage] = useSessionStore((s) => [s.createOrSendMsg], shallow);
22
22
 
23
23
  const footer = useMemo(
24
- () => <Button icon={<Icon icon={Archive} title={t('archiveCurrentMessages')} />} />,
24
+ () => (
25
+ <Tooltip title={t('archiveCurrentMessages')}>
26
+ <Button icon={<Icon icon={Archive} />} />
27
+ </Tooltip>
28
+ ),
25
29
  [],
26
30
  );
27
31
 
@@ -54,6 +58,10 @@ const ChatInput = () => {
54
58
  onExpandChange={setExpand}
55
59
  onInputChange={setText}
56
60
  onSend={sendMessage}
61
+ placeholder={t('sendPlaceholder')}
62
+ text={{
63
+ send: t('send'),
64
+ }}
57
65
  />
58
66
  </DraggablePanel>
59
67
  );
@@ -1,61 +1,45 @@
1
1
  import { ActionIcon, Avatar, ChatHeader } from '@lobehub/ui';
2
2
  import { Tag } from 'antd';
3
- import { createStyles } from 'antd-style';
4
- import { ArchiveIcon, MoreVerticalIcon, Share2 } from 'lucide-react';
3
+ import { PanelRightClose, PanelRightOpen, Settings, Share2 } from 'lucide-react';
4
+ import Router from 'next/router';
5
5
  import { memo } from 'react';
6
6
  import { useTranslation } from 'react-i18next';
7
- import { Flexbox } from 'react-layout-kit';
8
7
  import { shallow } from 'zustand/shallow';
9
8
 
10
- import { agentSelectors, sessionSelectors, useSessionStore } from '@/store/session';
11
-
12
- const useStyles = createStyles(({ css, token }) => ({
13
- desc: css`
14
- font-size: 12px;
15
- color: ${token.colorTextTertiary};
16
- `,
17
- title: css`
18
- font-weight: bold;
19
- color: ${token.colorText};
20
- `,
21
- }));
9
+ import HeaderTitle from '@/components/HeaderTitle';
10
+ import { agentSelectors, useSessionStore } from '@/store/session';
22
11
 
23
12
  const Header = memo(() => {
24
13
  const { t } = useTranslation('common');
25
- const [avatar, model] = useSessionStore(
26
- (s) => [agentSelectors.currentAgentAvatar(s), agentSelectors.currentAgentModel(s)],
14
+
15
+ const [meta, id, modle] = useSessionStore(
16
+ (s) => [agentSelectors.currentAgentMeta(s), s.activeId, agentSelectors.currentAgentModel(s)],
27
17
  shallow,
28
18
  );
29
- const [meta, id] = useSessionStore((s) => {
30
- const chat = sessionSelectors.currentSession(s);
31
- return [chat?.meta, s.activeId];
32
- }, shallow);
33
-
34
- const [
35
- // genShareUrl,
36
-
37
- toggleConfig,
38
- ] = useSessionStore(
39
- (s) => [
40
- // s.genShareUrl,
41
- s.toggleConfig,
42
- ],
19
+ const [showAgentSettings, toggleConfig] = useSessionStore(
20
+ (s) => [s.showAgentSettings, s.toggleConfig],
43
21
  shallow,
44
22
  );
45
23
 
46
- const { styles } = useStyles();
47
24
  return (
48
25
  <ChatHeader
49
26
  left={
50
27
  <>
51
- <Avatar avatar={avatar} size={40} title={meta?.title} />
52
- <Flexbox>
53
- <Flexbox align={'center'} className={styles.title} gap={8} horizontal>
54
- {meta?.title || t('defaultAgent')}
55
- <Tag bordered={false}>{model}</Tag>
56
- </Flexbox>
57
- <Flexbox className={styles.desc}>{meta?.description || t('noDescription')}</Flexbox>
58
- </Flexbox>
28
+ <Avatar
29
+ avatar={meta?.avatar}
30
+ background={meta?.backgroundColor}
31
+ onClick={() => {
32
+ Router.push(`/chat/${id}/edit`);
33
+ }}
34
+ size={40}
35
+ style={{ cursor: 'pointer' }}
36
+ title={meta?.title}
37
+ />
38
+ <HeaderTitle
39
+ desc={meta?.description || t('noDescription')}
40
+ tag={<Tag>{modle}</Tag>}
41
+ title={meta?.title || t('defaultAgent')}
42
+ />
59
43
  </>
60
44
  }
61
45
  right={
@@ -69,12 +53,19 @@ const Header = memo(() => {
69
53
  size={{ fontSize: 24 }}
70
54
  title={t('share')}
71
55
  />
72
- <ActionIcon icon={ArchiveIcon} size={{ fontSize: 24 }} title={t('archive')} />
73
56
  <ActionIcon
74
- icon={MoreVerticalIcon}
57
+ icon={showAgentSettings ? PanelRightClose : PanelRightOpen}
75
58
  onClick={() => toggleConfig()}
76
59
  size={{ fontSize: 24 }}
77
- title={t('sessionSetting')}
60
+ title={t('roleAndArchive')}
61
+ />
62
+ <ActionIcon
63
+ icon={Settings}
64
+ onClick={() => {
65
+ Router.push(`/chat/${id}/edit`);
66
+ }}
67
+ size={{ fontSize: 24 }}
68
+ title={t('header.session', { ns: 'setting' })}
78
69
  />
79
70
  </>
80
71
  )
@@ -1,113 +1,172 @@
1
- import { Collapse, ConfigProvider, InputNumber, Segmented, Slider } from 'antd';
1
+ import { Form, ItemGroup } from '@lobehub/ui';
2
+ import { Input, Segmented, Select, Switch } from 'antd';
2
3
  import isEqual from 'fast-deep-equal';
4
+ import { debounce } from 'lodash-es';
5
+ import { BrainCog, MessagesSquare } from 'lucide-react';
6
+ import { useMemo } from 'react';
3
7
  import { useTranslation } from 'react-i18next';
4
- import { Flexbox } from 'react-layout-kit';
5
8
  import { shallow } from 'zustand/shallow';
6
9
 
10
+ import { FORM_STYLE } from '@/const/layoutTokens';
11
+ import SliderWithInput from '@/features/SliderWithInput';
7
12
  import { agentSelectors, useSessionStore } from '@/store/session';
8
13
  import { LanguageModel } from '@/types/llm';
14
+ import type { LobeAgentConfig } from '@/types/session';
9
15
 
10
- import { FormItem } from '../FormItem';
11
- import { useStyles } from '../style';
12
- import Plugin from './Plugin';
13
- import Prompt from './Prompt';
16
+ type SettingItemGroup = ItemGroup & {
17
+ children: {
18
+ name?: keyof LobeAgentConfig;
19
+ }[];
20
+ };
14
21
 
15
22
  const AgentConfig = () => {
16
- const { t } = useTranslation('common');
17
-
18
- const { styles, theme } = useStyles();
23
+ const { t } = useTranslation('setting');
19
24
 
20
25
  const config = useSessionStore(agentSelectors.currentAgentConfigSafe, isEqual);
21
26
 
22
27
  const [updateAgentConfig] = useSessionStore((s) => [s.updateAgentConfig], shallow);
23
28
 
24
- return (
25
- <ConfigProvider
26
- theme={{
27
- components: {
28
- Segmented: {
29
- colorBgLayout: theme.isDarkMode ? '#111' : '#f1f1f1',
30
- },
29
+ // TODO: setting 结构嵌套,现在是扁平的 params: { temperature: 0.6 }
30
+ // @ts-ignore
31
+ const chat: SettingItemGroup = useMemo(
32
+ () => ({
33
+ children: [
34
+ {
35
+ children: (
36
+ <Segmented
37
+ options={[
38
+ { label: t('settingChat.chatStyleType.type.bubble'), value: 'chat' },
39
+ { label: t('settingChat.chatStyleType.type.docs'), value: 'docs' },
40
+ ]}
41
+ />
42
+ ),
43
+ label: t('settingChat.chatStyleType.title'),
44
+ minWidth: undefined,
45
+ name: 'chatStyleType',
46
+ },
47
+ {
48
+ children: <Input placeholder={t('settingChat.inputTemplate.placeholder')} />,
49
+ desc: t('settingChat.inputTemplate.desc'),
50
+ label: t('settingChat.inputTemplate.title'),
51
+ name: 'enableHistoryCount',
52
+ },
53
+ {
54
+ children: <Switch />,
55
+ label: t('settingChat.enableHistoryCount.title'),
56
+ minWidth: undefined,
57
+ name: 'enableHistoryCount',
58
+ valuePropName: 'checked',
59
+ },
60
+ {
61
+ children: <SliderWithInput max={32} min={0} />,
62
+ desc: t('settingChat.historyCount.desc'),
63
+ // @ts-ignore
64
+ hidden: !config.params.enableHistoryCount,
65
+ label: t('settingChat.historyCount.title'),
66
+ name: 'historyCount',
67
+ },
68
+ {
69
+ children: <Switch />,
70
+ label: t('settingChat.enableCompressThreshold.title'),
71
+ minWidth: undefined,
72
+ name: 'enableCompressThreshold',
73
+ valuePropName: 'checked',
74
+ },
75
+ {
76
+ children: <SliderWithInput max={32} min={0} />,
77
+ desc: t('settingChat.compressThreshold.desc'),
78
+ // @ts-ignore
79
+ hidden: !config.params.enableCompressThreshold,
80
+ label: t('settingChat.compressThreshold.title'),
81
+ name: 'compressThreshold',
82
+ },
83
+ ],
84
+ icon: MessagesSquare,
85
+ title: t('settingChat.title'),
86
+ }),
87
+ [config],
88
+ );
89
+
90
+ // TODO: setting 结构嵌套,现在是扁平的 params: { temperature: 0.6 }
91
+ // @ts-ignore
92
+ const model: SettingItemGroup = useMemo(
93
+ () => ({
94
+ children: [
95
+ {
96
+ children: (
97
+ <Select
98
+ options={Object.values(LanguageModel).map((value) => ({
99
+ label: value,
100
+ value,
101
+ }))}
102
+ />
103
+ ),
104
+ desc: t('settingModel.model.desc'),
105
+ label: t('settingModel.model.title'),
106
+ name: 'model',
107
+ tag: 'model',
31
108
  },
32
- }}
33
- >
34
- <Flexbox
35
- align={'center'}
36
- distribution={'space-between'}
37
- horizontal
38
- paddingBlock={12}
39
- style={{
40
- borderBottom: `1px solid ${theme.colorBorder}`,
41
- }}
42
- >
43
- <Flexbox className={styles.profile}> {t('modelConfig')}</Flexbox>
44
- </Flexbox>
45
- <Flexbox gap={24}>
46
- <FormItem label={t('agentModel')}>
47
- <Segmented
48
- block
49
- onChange={(value) => {
50
- updateAgentConfig({ model: value as LanguageModel });
51
- }}
52
- options={Object.values(LanguageModel).map((value) => ({
53
- label: t(value),
54
- value,
55
- }))}
56
- size={'large'}
57
- value={config.model}
58
- />
59
- </FormItem>
60
- <Prompt />
61
- <Collapse
62
- className={styles.title}
63
- expandIconPosition={'end'}
64
- items={[
65
- {
66
- children: (
67
- <Flexbox paddingBlock={16}>
68
- <FormItem label={t('modelTemperature')}>
69
- <Flexbox gap={16} horizontal>
70
- <Slider
71
- max={1}
72
- min={0}
73
- onChange={(value) => {
74
- updateAgentConfig({ params: { temperature: value } });
75
- }}
76
- step={0.1}
77
- style={{ flex: 1 }}
78
- value={Number(config.params.temperature)}
79
- />
80
- <InputNumber
81
- max={1}
82
- min={0}
83
- onChange={(value) => {
84
- if (value) updateAgentConfig({ params: { temperature: value } });
85
- }}
86
- value={config.params.temperature}
87
- />
88
- </Flexbox>
89
- </FormItem>
90
- </Flexbox>
91
- ),
92
- key: 'advanceSettings',
93
- label: t('advanceSettings'),
94
- },
95
- ]}
96
- />
97
- <Flexbox
98
- align={'center'}
99
- distribution={'space-between'}
100
- horizontal
101
- paddingBlock={12}
102
- style={{
103
- borderBottom: `1px solid ${theme.colorBorder}`,
104
- }}
105
- >
106
- <Flexbox className={styles.profile}> {t('pluginList')}</Flexbox>
107
- </Flexbox>
108
- <Plugin />
109
- </Flexbox>
110
- </ConfigProvider>
109
+ {
110
+ children: <SliderWithInput max={1} min={0} step={0.1} />,
111
+ desc: t('settingModel.temperature.desc'),
112
+ label: t('settingModel.temperature.title'),
113
+ name: 'temperature',
114
+ tag: 'temperature',
115
+ },
116
+ {
117
+ children: <SliderWithInput max={1} min={0} step={0.1} />,
118
+ desc: t('settingModel.topP.desc'),
119
+ label: t('settingModel.topP.title'),
120
+ name: 'topP',
121
+ tag: 'top_p',
122
+ },
123
+ {
124
+ children: <SliderWithInput max={2} min={-2} step={0.1} />,
125
+ desc: t('settingModel.presencePenalty.desc'),
126
+ label: t('settingModel.presencePenalty.title'),
127
+ name: 'presencePenalty',
128
+ tag: 'presence_penalty',
129
+ },
130
+ {
131
+ children: <SliderWithInput max={2} min={-2} step={0.1} />,
132
+ desc: t('settingModel.frequencyPenalty.desc'),
133
+ label: t('settingModel.frequencyPenalty.title'),
134
+ name: 'frequencyPenalty',
135
+ tag: 'frequency_penalty',
136
+ },
137
+ {
138
+ children: <Switch />,
139
+ label: t('settingModel.enableMaxTokens.title'),
140
+ minWidth: undefined,
141
+ name: 'enableMaxTokens',
142
+ valuePropName: 'checked',
143
+ },
144
+ {
145
+ children: <SliderWithInput max={32_000} min={0} step={100} />,
146
+ desc: t('settingModel.maxTokens.desc'),
147
+ // TODO
148
+ // @ts-ignore
149
+ hidden: !config?.params?.enableMaxTokens,
150
+ label: t('settingModel.maxTokens.title'),
151
+ name: 'params.maxTokens',
152
+ tag: 'max_tokens',
153
+ },
154
+ ],
155
+ icon: BrainCog,
156
+ title: t('settingModel.title'),
157
+ }),
158
+ [config],
159
+ );
160
+
161
+ const items = useMemo(() => [chat, model], [config]);
162
+
163
+ return (
164
+ <Form
165
+ initialValues={config}
166
+ items={items}
167
+ onValuesChange={debounce(updateAgentConfig, 100)}
168
+ {...FORM_STYLE}
169
+ />
111
170
  );
112
171
  };
113
172
 
@@ -0,0 +1,39 @@
1
+ import { ActionIcon } from '@lobehub/ui';
2
+ import { Input, InputProps } from 'antd';
3
+ import { useTheme } from 'antd-style';
4
+ import { Wand2 } from 'lucide-react';
5
+ import { memo } from 'react';
6
+ import { useTranslation } from 'react-i18next';
7
+
8
+ export interface AutoGenerateInputProps extends InputProps {
9
+ loading: boolean;
10
+ onGenerate: () => void;
11
+ }
12
+
13
+ const AutoGenerateInput = memo<AutoGenerateInputProps>(({ loading, onGenerate, ...props }) => {
14
+ const { t } = useTranslation('common');
15
+ const theme = useTheme();
16
+
17
+ return (
18
+ <Input
19
+ suffix={
20
+ <ActionIcon
21
+ active
22
+ icon={Wand2}
23
+ loading={loading}
24
+ onClick={onGenerate}
25
+ size={'small'}
26
+ style={{
27
+ color: theme.colorInfo,
28
+ marginRight: -4,
29
+ }}
30
+ title={t('autoGenerate')}
31
+ />
32
+ }
33
+ type={'block'}
34
+ {...props}
35
+ />
36
+ );
37
+ });
38
+
39
+ export default AutoGenerateInput;