@lobehub/chat 0.127.0 → 0.127.2

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 (69) hide show
  1. package/CHANGELOG.md +50 -0
  2. package/README.md +8 -8
  3. package/README.zh-CN.md +8 -8
  4. package/package.json +1 -1
  5. package/src/app/chat/(desktop)/layout.desktop.tsx +1 -3
  6. package/src/app/chat/(mobile)/index.tsx +2 -5
  7. package/src/app/chat/features/ChatHeader/SettingButton.tsx +1 -2
  8. package/src/app/home/Redirect.tsx +0 -4
  9. package/src/app/market/(desktop)/layout.desktop.tsx +1 -4
  10. package/src/app/market/(mobile)/layout.mobile.tsx +1 -4
  11. package/src/app/market/features/AgentDetailContent/AgentInfo/Header.tsx +0 -4
  12. package/src/app/settings/(desktop)/features/Header.tsx +3 -4
  13. package/src/app/settings/(desktop)/features/SideBar.tsx +42 -0
  14. package/src/app/settings/(desktop)/index.tsx +4 -3
  15. package/src/app/settings/(desktop)/layout.desktop.tsx +14 -9
  16. package/src/app/settings/(desktop)/layout.responsive.tsx +4 -4
  17. package/src/app/settings/(mobile)/features/ExtraList.tsx +7 -5
  18. package/src/app/settings/(mobile)/features/Header/index.tsx +8 -5
  19. package/src/app/settings/(mobile)/index.tsx +1 -3
  20. package/src/app/settings/(mobile)/layout.mobile.tsx +8 -6
  21. package/src/app/settings/(mobile)/mobile/index.tsx +3 -5
  22. package/src/app/settings/agent/Agent.tsx +0 -4
  23. package/src/app/settings/agent/layout.tsx +9 -1
  24. package/src/app/settings/agent/page.tsx +17 -2
  25. package/src/app/settings/common/index.tsx +0 -3
  26. package/src/app/settings/common/layout.tsx +9 -1
  27. package/src/app/settings/features/SettingList/Item.tsx +50 -0
  28. package/src/app/settings/features/{SideBar/List.tsx → SettingList/index.tsx} +14 -15
  29. package/src/app/settings/layout.server.tsx +10 -3
  30. package/src/app/settings/llm/Azure/index.tsx +78 -106
  31. package/src/app/settings/llm/Bedrock/index.tsx +60 -89
  32. package/src/app/settings/llm/Google/index.tsx +26 -55
  33. package/src/app/settings/llm/Moonshot/index.tsx +29 -54
  34. package/src/app/settings/llm/Ollama/index.tsx +35 -61
  35. package/src/app/settings/llm/OpenAI/index.tsx +91 -107
  36. package/src/app/settings/llm/Zhipu/index.tsx +29 -54
  37. package/src/app/settings/llm/components/ProviderConfig/index.tsx +58 -0
  38. package/src/app/settings/llm/index.tsx +42 -0
  39. package/src/app/settings/llm/layout.tsx +9 -1
  40. package/src/app/settings/llm/page.tsx +6 -46
  41. package/src/app/settings/tts/layout.tsx +9 -1
  42. package/src/app/settings/tts/page.tsx +17 -2
  43. package/src/const/settings.ts +1 -0
  44. package/src/features/MobileTabBar/index.tsx +7 -14
  45. package/src/features/SideBar/BottomActions.tsx +3 -9
  46. package/src/features/SideBar/TopActions.tsx +2 -7
  47. package/src/features/SideBar/index.tsx +7 -5
  48. package/src/layout/AppLayout.desktop.tsx +8 -3
  49. package/src/layout/AppLayout.mobile.tsx +4 -2
  50. package/src/layout/ResponsiveLayout.client.tsx +7 -7
  51. package/src/layout/ResponsiveLayout.server.tsx +6 -6
  52. package/src/services/_auth.test.ts +132 -0
  53. package/src/services/_auth.ts +1 -1
  54. package/src/store/global/hooks/index.ts +1 -1
  55. package/src/store/global/slices/common/action.test.ts +0 -12
  56. package/src/store/global/slices/common/action.ts +1 -6
  57. package/src/store/global/slices/common/initialState.ts +0 -2
  58. package/src/store/global/slices/settings/action.test.ts +0 -13
  59. package/src/store/global/slices/settings/action.ts +0 -5
  60. package/src/store/global/slices/settings/selectors/modelProvider.ts +7 -0
  61. package/src/types/settings/modelProvider.ts +1 -0
  62. package/src/app/settings/agent/index.tsx +0 -21
  63. package/src/app/settings/features/SideBar/Item.tsx +0 -44
  64. package/src/app/settings/features/SideBar/index.tsx +0 -42
  65. package/src/app/settings/tts/index.tsx +0 -21
  66. package/src/store/global/hooks/useSwitchSettingsOnInit.ts +0 -12
  67. package/src/store/global/hooks/useSwitchSideBarOnInit.ts +0 -13
  68. /package/src/app/settings/llm/{Checker.tsx → components/Checker.tsx} +0 -0
  69. /package/src/app/settings/llm/{useSyncSettings.ts → components/ProviderConfig/useSyncSettings.ts} +0 -0
@@ -0,0 +1,50 @@
1
+ import { Icon, List } from '@lobehub/ui';
2
+ import { createStyles, useResponsive } from 'antd-style';
3
+ import { ChevronRight, type LucideIcon } from 'lucide-react';
4
+ import { CSSProperties, ReactNode, memo } from 'react';
5
+
6
+ const { Item } = List;
7
+
8
+ const useStyles = createStyles(({ css, token, responsive }) => ({
9
+ container: css`
10
+ position: relative;
11
+ padding-top: 16px;
12
+ padding-bottom: 16px;
13
+ border-radius: ${token.borderRadius}px;
14
+ ${responsive.mobile} {
15
+ border-radius: 0;
16
+ }
17
+ `,
18
+ noHover: css`
19
+ pointer-events: none;
20
+ `,
21
+ }));
22
+
23
+ export interface ItemProps {
24
+ active?: boolean;
25
+ className?: string;
26
+ hoverable?: boolean;
27
+ icon: LucideIcon;
28
+ label: ReactNode;
29
+ style?: CSSProperties;
30
+ }
31
+
32
+ const SettingItem = memo<ItemProps>(
33
+ ({ label, icon, hoverable = true, active = false, style, className }) => {
34
+ const { cx, styles } = useStyles();
35
+ const { mobile } = useResponsive();
36
+ return (
37
+ <Item
38
+ active={active}
39
+ avatar={<Icon icon={icon} size={{ fontSize: 20 }} />}
40
+ className={cx(styles.container, !hoverable && styles.noHover, className)}
41
+ style={style}
42
+ title={label as string}
43
+ >
44
+ {mobile && <Icon icon={ChevronRight} size={{ fontSize: 16 }} />}
45
+ </Item>
46
+ );
47
+ },
48
+ );
49
+
50
+ export default SettingItem;
@@ -1,18 +1,19 @@
1
- import { useResponsive } from 'antd-style';
2
1
  import { Bot, Mic2, Settings2, Webhook } from 'lucide-react';
3
2
  import Link from 'next/link';
4
3
  import { memo } from 'react';
5
4
  import { useTranslation } from 'react-i18next';
6
5
 
7
- import { useGlobalStore } from '@/store/global';
8
6
  import { SettingsTabs } from '@/store/global/initialState';
9
7
 
10
8
  import Item from './Item';
11
9
 
12
- const List = memo(() => {
10
+ export interface SettingListProps {
11
+ activeTab?: SettingsTabs;
12
+ mobile?: boolean;
13
+ }
14
+
15
+ const SettingList = memo<SettingListProps>(({ activeTab, mobile }) => {
13
16
  const { t } = useTranslation('setting');
14
- const [tab, switchSettingTabs] = useGlobalStore((s) => [s.settingsTab, s.switchSettingTabs]);
15
- const { mobile } = useResponsive();
16
17
 
17
18
  const items = [
18
19
  { icon: Settings2, label: t('tab.common'), value: SettingsTabs.Common },
@@ -22,17 +23,15 @@ const List = memo(() => {
22
23
  ];
23
24
 
24
25
  return items.map(({ value, icon, label }) => (
25
- <Link
26
- aria-label={label}
27
- href={`/settings/${value}`}
28
- key={value}
29
- onClick={() => {
30
- switchSettingTabs(value);
31
- }}
32
- >
33
- <Item active={mobile ? false : tab === value} icon={icon} label={label} />
26
+ <Link aria-label={label} href={`/settings/${value}`} key={value}>
27
+ <Item
28
+ active={mobile ? false : activeTab === value}
29
+ hoverable={!mobile}
30
+ icon={icon}
31
+ label={label}
32
+ />
34
33
  </Link>
35
34
  ));
36
35
  });
37
36
 
38
- export default List;
37
+ export default SettingList;
@@ -1,12 +1,19 @@
1
- import { PropsWithChildren, memo } from 'react';
1
+ import { PropsWithChildren, ReactNode, memo } from 'react';
2
2
 
3
3
  import ResponsiveLayout from '@/layout/ResponsiveLayout.server';
4
+ import { SettingsTabs } from '@/store/global/initialState';
4
5
 
5
6
  import DesktopLayout from './(desktop)/layout.responsive';
6
7
  import MobileLayout from './(mobile)/layout.mobile';
7
8
 
8
- export default memo(({ children }: PropsWithChildren) => (
9
- <ResponsiveLayout Desktop={DesktopLayout} Mobile={MobileLayout}>
9
+ export interface SettingLayoutProps {
10
+ activeTab: SettingsTabs;
11
+ children: ReactNode;
12
+ }
13
+ const SettingLayout = memo<SettingLayoutProps>(({ children, ...res }: PropsWithChildren) => (
14
+ <ResponsiveLayout Desktop={DesktopLayout} Mobile={MobileLayout} {...res}>
10
15
  {children}
11
16
  </ResponsiveLayout>
12
17
  ));
18
+
19
+ export default SettingLayout;
@@ -1,20 +1,16 @@
1
1
  import { Azure, OpenAI } from '@lobehub/icons';
2
- import { Form, type ItemGroup, Markdown } from '@lobehub/ui';
3
- import { Form as AntForm, AutoComplete, Divider, Input, Switch } from 'antd';
2
+ import { Markdown } from '@lobehub/ui';
3
+ import { AutoComplete, Divider, Input } from 'antd';
4
4
  import { createStyles } from 'antd-style';
5
- import { debounce } from 'lodash-es';
6
5
  import { memo } from 'react';
7
6
  import { useTranslation } from 'react-i18next';
8
7
  import { Flexbox } from 'react-layout-kit';
9
8
 
10
- import { FORM_STYLE } from '@/const/layoutTokens';
11
9
  import { ModelProvider } from '@/libs/agent-runtime';
12
- import { useGlobalStore } from '@/store/global';
13
- import { modelProviderSelectors } from '@/store/global/selectors';
14
10
 
15
- import Checker from '../Checker';
11
+ import Checker from '../components/Checker';
12
+ import ProviderConfig from '../components/ProviderConfig';
16
13
  import { LLMProviderApiTokenKey, LLMProviderBaseUrlKey, LLMProviderConfigKey } from '../const';
17
- import { useSyncSettings } from '../useSyncSettings';
18
14
 
19
15
  const useStyles = createStyles(({ css, token }) => ({
20
16
  markdown: css`
@@ -37,107 +33,83 @@ const providerKey = 'azure';
37
33
 
38
34
  const AzureOpenAIProvider = memo(() => {
39
35
  const { t } = useTranslation('setting');
40
- const [form] = AntForm.useForm();
41
- const { styles } = useStyles();
42
-
43
- const [toggleProviderEnabled, setSettings] = useGlobalStore((s) => [
44
- s.toggleProviderEnabled,
45
- s.setSettings,
46
- ]);
47
-
48
- const enabled = useGlobalStore(modelProviderSelectors.enableAzure);
49
-
50
- useSyncSettings(form);
51
36
 
52
- const openAI: ItemGroup = {
53
- children: [
54
- {
55
- children: (
56
- <Input.Password
57
- autoComplete={'new-password'}
58
- placeholder={t('llm.AzureOpenAI.token.placeholder')}
59
- />
60
- ),
61
- desc: t('llm.AzureOpenAI.token.desc'),
62
- label: t('llm.AzureOpenAI.token.title'),
63
- name: [LLMProviderConfigKey, providerKey, LLMProviderApiTokenKey],
64
- },
65
- {
66
- children: <Input allowClear placeholder={t('llm.AzureOpenAI.endpoint.placeholder')} />,
67
- desc: t('llm.AzureOpenAI.endpoint.desc'),
68
- label: t('llm.AzureOpenAI.endpoint.title'),
69
- name: [LLMProviderConfigKey, providerKey, LLMProviderBaseUrlKey],
70
- },
71
- {
72
- children: (
73
- <AutoComplete
74
- options={[
75
- '2023-12-01-preview',
76
- '2023-08-01-preview',
77
- '2023-07-01-preview',
78
- '2023-06-01-preview',
79
- '2023-03-15-preview',
80
- ].map((i) => ({
81
- label: i,
82
- value: i,
83
- }))}
84
- placeholder={'20XX-XX-XX'}
85
- />
86
- ),
87
- desc: (
88
- <Markdown className={styles.markdown}>
89
- {t('llm.AzureOpenAI.azureApiVersion.desc')}
90
- </Markdown>
91
- ),
92
- label: t('llm.AzureOpenAI.azureApiVersion.title'),
93
- name: [LLMProviderConfigKey, providerKey, 'apiVersion'],
94
- },
95
- {
96
- children: (
97
- <Input.TextArea
98
- allowClear
99
- placeholder={'gpt-35-16k,my-gpt=gpt-35-turbo'}
100
- style={{ height: 100 }}
101
- />
102
- ),
103
- desc: (
104
- <Markdown className={styles.markdown}>{t('llm.AzureOpenAI.deployments.desc')}</Markdown>
105
- ),
106
-
107
- label: t('llm.AzureOpenAI.deployments.title'),
108
- name: [LLMProviderConfigKey, providerKey, 'deployments'],
109
- },
110
- {
111
- children: <Checker model={'gpt-3.5-turbo'} provider={ModelProvider.Azure} />,
112
- desc: t('llm.checker.desc'),
113
- label: t('llm.checker.title'),
114
- minWidth: undefined,
115
- },
116
- ],
117
- defaultActive: enabled,
118
- extra: (
119
- <Switch
120
- onChange={(enabled) => {
121
- toggleProviderEnabled(providerKey, enabled);
122
- }}
123
- value={enabled}
124
- />
125
- ),
126
- title: (
127
- <Flexbox align={'center'} gap={8} horizontal>
128
- <Azure.Combine size={24} type={'color'}></Azure.Combine>
129
- <Divider style={{ margin: '0 4px' }} type={'vertical'} />
130
- <OpenAI.Combine size={24}></OpenAI.Combine>
131
- </Flexbox>
132
- ),
133
- };
37
+ const { styles } = useStyles();
134
38
 
135
39
  return (
136
- <Form
137
- form={form}
138
- items={[openAI]}
139
- onValuesChange={debounce(setSettings, 100)}
140
- {...FORM_STYLE}
40
+ <ProviderConfig
41
+ configItems={[
42
+ {
43
+ children: (
44
+ <Input.Password
45
+ autoComplete={'new-password'}
46
+ placeholder={t('llm.AzureOpenAI.token.placeholder')}
47
+ />
48
+ ),
49
+ desc: t('llm.AzureOpenAI.token.desc'),
50
+ label: t('llm.AzureOpenAI.token.title'),
51
+ name: [LLMProviderConfigKey, providerKey, LLMProviderApiTokenKey],
52
+ },
53
+ {
54
+ children: <Input allowClear placeholder={t('llm.AzureOpenAI.endpoint.placeholder')} />,
55
+ desc: t('llm.AzureOpenAI.endpoint.desc'),
56
+ label: t('llm.AzureOpenAI.endpoint.title'),
57
+ name: [LLMProviderConfigKey, providerKey, LLMProviderBaseUrlKey],
58
+ },
59
+ {
60
+ children: (
61
+ <AutoComplete
62
+ options={[
63
+ '2023-12-01-preview',
64
+ '2023-08-01-preview',
65
+ '2023-07-01-preview',
66
+ '2023-06-01-preview',
67
+ '2023-03-15-preview',
68
+ ].map((i) => ({
69
+ label: i,
70
+ value: i,
71
+ }))}
72
+ placeholder={'20XX-XX-XX'}
73
+ />
74
+ ),
75
+ desc: (
76
+ <Markdown className={styles.markdown}>
77
+ {t('llm.AzureOpenAI.azureApiVersion.desc')}
78
+ </Markdown>
79
+ ),
80
+ label: t('llm.AzureOpenAI.azureApiVersion.title'),
81
+ name: [LLMProviderConfigKey, providerKey, 'apiVersion'],
82
+ },
83
+ {
84
+ children: (
85
+ <Input.TextArea
86
+ allowClear
87
+ placeholder={'gpt-35-16k,my-gpt=gpt-35-turbo'}
88
+ style={{ height: 100 }}
89
+ />
90
+ ),
91
+ desc: (
92
+ <Markdown className={styles.markdown}>{t('llm.AzureOpenAI.deployments.desc')}</Markdown>
93
+ ),
94
+
95
+ label: t('llm.AzureOpenAI.deployments.title'),
96
+ name: [LLMProviderConfigKey, providerKey, 'deployments'],
97
+ },
98
+ {
99
+ children: <Checker model={'gpt-3.5-turbo'} provider={ModelProvider.Azure} />,
100
+ desc: t('llm.checker.desc'),
101
+ label: t('llm.checker.title'),
102
+ minWidth: undefined,
103
+ },
104
+ ]}
105
+ provider={providerKey}
106
+ title={
107
+ <Flexbox align={'center'} gap={8} horizontal>
108
+ <Azure.Combine size={24} type={'color'}></Azure.Combine>
109
+ <Divider style={{ margin: '0 4px' }} type={'vertical'} />
110
+ <OpenAI.Combine size={24}></OpenAI.Combine>
111
+ </Flexbox>
112
+ }
141
113
  />
142
114
  );
143
115
  });
@@ -1,108 +1,79 @@
1
1
  import { Aws, Bedrock } from '@lobehub/icons';
2
- import { Form, type ItemGroup } from '@lobehub/ui';
3
- import { Form as AntForm, Divider, Input, Select, Switch } from 'antd';
4
- import { debounce } from 'lodash-es';
2
+ import { Divider, Input, Select } from 'antd';
5
3
  import { memo } from 'react';
6
4
  import { useTranslation } from 'react-i18next';
7
5
  import { Flexbox } from 'react-layout-kit';
8
6
 
9
- import { FORM_STYLE } from '@/const/layoutTokens';
10
7
  import { ModelProvider } from '@/libs/agent-runtime';
11
- import { useGlobalStore } from '@/store/global';
12
- import { modelProviderSelectors } from '@/store/global/selectors';
13
8
  import { GlobalLLMProviderKey } from '@/types/settings';
14
9
 
15
- import Checker from '../Checker';
10
+ import Checker from '../components/Checker';
11
+ import ProviderConfig from '../components/ProviderConfig';
16
12
  import { LLMProviderConfigKey } from '../const';
17
- import { useSyncSettings } from '../useSyncSettings';
18
13
 
19
14
  const providerKey: GlobalLLMProviderKey = 'bedrock';
20
15
 
21
16
  const BedrockProvider = memo(() => {
22
17
  const { t } = useTranslation('setting');
23
- const [form] = AntForm.useForm();
24
- const [toggleProviderEnabled, setSettings] = useGlobalStore((s) => [
25
- s.toggleProviderEnabled,
26
- s.setSettings,
27
- ]);
28
- const enabled = useGlobalStore(modelProviderSelectors.enableBedrock);
29
-
30
- useSyncSettings(form);
31
-
32
- const model: ItemGroup = {
33
- children: [
34
- {
35
- children: (
36
- <Input.Password
37
- autoComplete={'new-password'}
38
- placeholder={t('llm.Bedrock.accessKeyId.placeholder')}
39
- />
40
- ),
41
- desc: t('llm.Bedrock.accessKeyId.desc'),
42
- label: t('llm.Bedrock.accessKeyId.title'),
43
- name: [LLMProviderConfigKey, providerKey, 'accessKeyId'],
44
- },
45
- {
46
- children: (
47
- <Input.Password
48
- autoComplete={'new-password'}
49
- placeholder={t('llm.Bedrock.secretAccessKey.placeholder')}
50
- />
51
- ),
52
- desc: t('llm.Bedrock.secretAccessKey.desc'),
53
- label: t('llm.Bedrock.secretAccessKey.title'),
54
- name: [LLMProviderConfigKey, providerKey, 'secretAccessKey'],
55
- },
56
- {
57
- children: (
58
- <Select
59
- allowClear
60
- options={['us-east-1', 'us-west-2', 'ap-southeast-1'].map((i) => ({
61
- label: i,
62
- value: i,
63
- }))}
64
- placeholder={'us-east-1'}
65
- />
66
- ),
67
- desc: t('llm.Bedrock.region.desc'),
68
- label: t('llm.Bedrock.region.title'),
69
- name: [LLMProviderConfigKey, providerKey, 'region'],
70
- },
71
- {
72
- children: (
73
- <Checker model={'anthropic.claude-instant-v1'} provider={ModelProvider.Bedrock} />
74
- ),
75
- desc: t('llm.Bedrock.checker.desc'),
76
- label: t('llm.checker.title'),
77
- minWidth: '100%',
78
- },
79
- ],
80
- defaultActive: enabled,
81
- extra: (
82
- <div
83
- onClick={(e) => {
84
- e.stopPropagation();
85
- }}
86
- >
87
- <Switch
88
- onChange={(enabled) => {
89
- toggleProviderEnabled(providerKey, enabled);
90
- }}
91
- value={enabled}
92
- />
93
- </div>
94
- ),
95
- title: (
96
- <Flexbox align={'center'} gap={8} horizontal>
97
- <Aws.Color size={32} />
98
- <Divider style={{ margin: '0 4px' }} type={'vertical'} />
99
- <Bedrock.Combine size={24} type={'color'} />
100
- </Flexbox>
101
- ),
102
- };
103
18
 
104
19
  return (
105
- <Form form={form} items={[model]} onValuesChange={debounce(setSettings, 100)} {...FORM_STYLE} />
20
+ <ProviderConfig
21
+ configItems={[
22
+ {
23
+ children: (
24
+ <Input.Password
25
+ autoComplete={'new-password'}
26
+ placeholder={t('llm.Bedrock.accessKeyId.placeholder')}
27
+ />
28
+ ),
29
+ desc: t('llm.Bedrock.accessKeyId.desc'),
30
+ label: t('llm.Bedrock.accessKeyId.title'),
31
+ name: [LLMProviderConfigKey, providerKey, 'accessKeyId'],
32
+ },
33
+ {
34
+ children: (
35
+ <Input.Password
36
+ autoComplete={'new-password'}
37
+ placeholder={t('llm.Bedrock.secretAccessKey.placeholder')}
38
+ />
39
+ ),
40
+ desc: t('llm.Bedrock.secretAccessKey.desc'),
41
+ label: t('llm.Bedrock.secretAccessKey.title'),
42
+ name: [LLMProviderConfigKey, providerKey, 'secretAccessKey'],
43
+ },
44
+ {
45
+ children: (
46
+ <Select
47
+ allowClear
48
+ options={['us-east-1', 'us-west-2', 'ap-southeast-1'].map((i) => ({
49
+ label: i,
50
+ value: i,
51
+ }))}
52
+ placeholder={'us-east-1'}
53
+ />
54
+ ),
55
+ desc: t('llm.Bedrock.region.desc'),
56
+ label: t('llm.Bedrock.region.title'),
57
+ name: [LLMProviderConfigKey, providerKey, 'region'],
58
+ },
59
+ {
60
+ children: (
61
+ <Checker model={'anthropic.claude-instant-v1'} provider={ModelProvider.Bedrock} />
62
+ ),
63
+ desc: t('llm.Bedrock.checker.desc'),
64
+ label: t('llm.checker.title'),
65
+ minWidth: '100%',
66
+ },
67
+ ]}
68
+ provider={providerKey}
69
+ title={
70
+ <Flexbox align={'center'} gap={8} horizontal>
71
+ <Aws.Color size={32} />
72
+ <Divider style={{ margin: '0 4px' }} type={'vertical'} />
73
+ <Bedrock.Combine size={24} type={'color'} />
74
+ </Flexbox>
75
+ }
76
+ />
106
77
  );
107
78
  });
108
79
 
@@ -1,73 +1,44 @@
1
1
  import { Google } from '@lobehub/icons';
2
- import { Form, type ItemGroup } from '@lobehub/ui';
3
- import { Form as AntForm, Input, Switch } from 'antd';
4
- import { debounce } from 'lodash-es';
2
+ import { Input } from 'antd';
5
3
  import { memo } from 'react';
6
4
  import { useTranslation } from 'react-i18next';
7
- import { Flexbox } from 'react-layout-kit';
8
5
 
9
- import { FORM_STYLE } from '@/const/layoutTokens';
10
6
  import { ModelProvider } from '@/libs/agent-runtime';
11
- import { useGlobalStore } from '@/store/global';
12
- import { modelProviderSelectors } from '@/store/global/selectors';
13
7
  import { GlobalLLMProviderKey } from '@/types/settings';
14
8
 
15
- import Checker from '../Checker';
9
+ import Checker from '../components/Checker';
10
+ import ProviderConfig from '../components/ProviderConfig';
16
11
  import { LLMProviderApiTokenKey, LLMProviderConfigKey } from '../const';
17
- import { useSyncSettings } from '../useSyncSettings';
18
12
 
19
13
  const providerKey: GlobalLLMProviderKey = 'google';
20
14
 
21
15
  const GoogleProvider = memo(() => {
22
16
  const { t } = useTranslation('setting');
23
- const [form] = AntForm.useForm();
24
- useSyncSettings(form);
25
-
26
- const [toggleProviderEnabled, setSettings] = useGlobalStore((s) => [
27
- s.toggleProviderEnabled,
28
- s.setSettings,
29
- ]);
30
-
31
- const enabled = useGlobalStore(modelProviderSelectors.enableGoogle);
32
-
33
- const model: ItemGroup = {
34
- children: [
35
- {
36
- children: (
37
- <Input.Password
38
- autoComplete={'new-password'}
39
- placeholder={t('llm.Google.token.placeholder')}
40
- />
41
- ),
42
- desc: t('llm.Google.token.desc'),
43
- label: t('llm.Google.token.title'),
44
- name: [LLMProviderConfigKey, providerKey, LLMProviderApiTokenKey],
45
- },
46
- {
47
- children: <Checker model={'gemini-pro'} provider={ModelProvider.Google} />,
48
- desc: t('llm.checker.desc'),
49
- label: t('llm.checker.title'),
50
- minWidth: '100%',
51
- },
52
- ],
53
- defaultActive: enabled,
54
- extra: (
55
- <Switch
56
- onChange={(enabled) => {
57
- toggleProviderEnabled(providerKey, enabled);
58
- }}
59
- value={enabled}
60
- />
61
- ),
62
- title: (
63
- <Flexbox align={'center'} gap={8} horizontal>
64
- <Google.BrandColor size={28} />
65
- </Flexbox>
66
- ),
67
- };
68
17
 
69
18
  return (
70
- <Form form={form} items={[model]} onValuesChange={debounce(setSettings, 100)} {...FORM_STYLE} />
19
+ <ProviderConfig
20
+ configItems={[
21
+ {
22
+ children: (
23
+ <Input.Password
24
+ autoComplete={'new-password'}
25
+ placeholder={t('llm.Google.token.placeholder')}
26
+ />
27
+ ),
28
+ desc: t('llm.Google.token.desc'),
29
+ label: t('llm.Google.token.title'),
30
+ name: [LLMProviderConfigKey, providerKey, LLMProviderApiTokenKey],
31
+ },
32
+ {
33
+ children: <Checker model={'gemini-pro'} provider={ModelProvider.Google} />,
34
+ desc: t('llm.checker.desc'),
35
+ label: t('llm.checker.title'),
36
+ minWidth: '100%',
37
+ },
38
+ ]}
39
+ provider={providerKey}
40
+ title={<Google.BrandColor size={28} />}
41
+ />
71
42
  );
72
43
  });
73
44