@lobehub/chat 0.13.1 → 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 (51) hide show
  1. package/CHANGELOG.md +51 -0
  2. package/README.md +3 -3
  3. package/locales/en_US/common.json +19 -27
  4. package/locales/en_US/plugin.json +10 -0
  5. package/locales/en_US/setting.json +42 -6
  6. package/locales/zh_CN/common.json +8 -17
  7. package/locales/zh_CN/plugin.json +10 -0
  8. package/locales/zh_CN/setting.json +36 -0
  9. package/package.json +1 -1
  10. package/src/components/HeaderSpacing/index.tsx +3 -1
  11. package/src/components/HeaderTitle/index.tsx +42 -0
  12. package/src/const/layoutTokens.ts +6 -1
  13. package/src/const/meta.ts +3 -0
  14. package/src/locales/default/common.ts +31 -49
  15. package/src/locales/default/plugin.ts +10 -0
  16. package/src/locales/default/setting.ts +46 -1
  17. package/src/locales/resources/en_US.ts +2 -0
  18. package/src/locales/resources/zh_CN.ts +2 -0
  19. package/src/pages/chat/SessionList/List/SessionItem.tsx +1 -2
  20. package/src/pages/chat/[id]/Config/Header.tsx +26 -0
  21. package/src/pages/chat/[id]/Config/SideBar.tsx +86 -0
  22. package/src/pages/chat/[id]/Config/index.tsx +5 -45
  23. package/src/pages/chat/[id]/Conversation/FunctionMessage.tsx +1 -1
  24. package/src/pages/chat/[id]/Conversation/Input/Action.tsx +13 -5
  25. package/src/pages/chat/[id]/Conversation/Input/index.tsx +11 -3
  26. package/src/pages/chat/[id]/Conversation/MessageExtra.tsx +1 -1
  27. package/src/pages/chat/[id]/Header.tsx +34 -43
  28. package/src/pages/chat/[id]/edit/AgentConfig/index.tsx +154 -95
  29. package/src/pages/chat/[id]/edit/AgentMeta/AutoGenerateInput.tsx +39 -0
  30. package/src/pages/chat/[id]/edit/AgentMeta/BackgroundSwatches.tsx +31 -0
  31. package/src/pages/chat/[id]/edit/AgentMeta/EmojiPicker.tsx +7 -3
  32. package/src/pages/chat/[id]/edit/AgentMeta/index.tsx +68 -75
  33. package/src/pages/chat/[id]/edit/AgentPlugin/index.tsx +44 -0
  34. package/src/pages/chat/[id]/edit/AgentPrompt/index.tsx +48 -0
  35. package/src/pages/chat/[id]/edit/Header.tsx +31 -0
  36. package/src/pages/chat/[id]/edit/index.page.tsx +12 -40
  37. package/src/pages/chat/[id]/index.page.tsx +2 -1
  38. package/src/pages/setting/Header.tsx +4 -11
  39. package/src/pages/setting/SettingForm.tsx +9 -9
  40. package/src/pages/setting/index.page.tsx +2 -1
  41. package/src/plugins/index.ts +2 -1
  42. package/src/plugins/webCrawler/index.ts +20 -0
  43. package/src/plugins/webCrawler/runner.ts +75 -0
  44. package/src/store/session/slices/agentConfig/initialState.ts +1 -5
  45. package/src/store/session/slices/agentConfig/selectors.ts +15 -5
  46. package/src/store/session/slices/chat/selectors/chat.ts +2 -2
  47. package/src/store/session/slices/session/selectors/chat.ts +1 -1
  48. package/src/utils/genSiteHeadTitle.ts +1 -0
  49. package/src/pages/chat/[id]/Config/ReadMode.tsx +0 -64
  50. package/src/pages/chat/[id]/edit/AgentConfig/Plugin.tsx +0 -46
  51. package/src/pages/chat/[id]/edit/AgentConfig/Prompt.tsx +0 -69
@@ -1,43 +1,23 @@
1
- import { ActionIcon, ChatHeader } from '@lobehub/ui';
2
- import { createStyles } from 'antd-style';
3
- import { Download, Share2 } from 'lucide-react';
4
1
  import Head from 'next/head';
5
- import Router from 'next/router';
6
2
  import { memo } from 'react';
7
3
  import { useTranslation } from 'react-i18next';
8
4
  import { Flexbox } from 'react-layout-kit';
9
5
 
10
6
  import HeaderSpacing from '@/components/HeaderSpacing';
7
+ import { HEADER_HEIGHT } from '@/const/layoutTokens';
8
+ import { genSiteHeadTitle } from '@/utils/genSiteHeadTitle';
11
9
 
12
10
  import ChatLayout from '../../layout';
13
11
  import AgentConfig from './AgentConfig';
14
12
  import AgentMeta from './AgentMeta';
15
-
16
- const useStyles = createStyles(({ css, token }) => ({
17
- footer: css`
18
- position: sticky;
19
- bottom: 0;
20
- border-top: 1px solid ${token.colorBorder};
21
- `,
22
- form: css`
23
- overflow-y: auto;
24
- `,
25
- header: css`
26
- background: ${token.colorBgContainer};
27
- border-bottom: 1px solid ${token.colorSplit};
28
- `,
29
- title: css`
30
- font-size: 16px;
31
- font-weight: 500;
32
- `,
33
- }));
13
+ import AgentPlugin from './AgentPlugin';
14
+ import AgentPrompt from './AgentPrompt';
15
+ import Header from './Header';
34
16
 
35
17
  const EditPage = memo(() => {
36
- const { t } = useTranslation('common');
37
-
38
- const { styles } = useStyles();
18
+ const { t } = useTranslation('setting');
39
19
 
40
- const pageTitle = t('editAgentProfile');
20
+ const pageTitle = genSiteHeadTitle(t('header.session'));
41
21
 
42
22
  return (
43
23
  <>
@@ -45,21 +25,13 @@ const EditPage = memo(() => {
45
25
  <title>{pageTitle}</title>
46
26
  </Head>
47
27
  <ChatLayout>
48
- <ChatHeader
49
- left={<div className={styles.title}>{t('editAgentProfile')}</div>}
50
- onBackClick={() => Router.back()}
51
- right={
52
- <>
53
- <ActionIcon icon={Share2} size={{ fontSize: 24 }} title={t('share')} />
54
- <ActionIcon icon={Download} size={{ fontSize: 24 }} title={t('export')} />
55
- </>
56
- }
57
- showBackButton
58
- />
59
- <Flexbox className={styles.form} flex={1} gap={10} padding={24}>
60
- <HeaderSpacing />
28
+ <Header />
29
+ <Flexbox align={'center'} flex={1} gap={16} padding={24} style={{ overflow: 'auto' }}>
30
+ <HeaderSpacing height={HEADER_HEIGHT - 16} />
31
+ <AgentPrompt />
61
32
  <AgentMeta />
62
33
  <AgentConfig />
34
+ <AgentPlugin />
63
35
  </Flexbox>
64
36
  </ChatLayout>
65
37
  </>
@@ -4,6 +4,7 @@ import { memo } from 'react';
4
4
  import { Flexbox } from 'react-layout-kit';
5
5
 
6
6
  import { sessionSelectors, useSessionStore } from '@/store/session';
7
+ import { genSiteHeadTitle } from '@/utils/genSiteHeadTitle';
7
8
 
8
9
  import Layout from '../layout';
9
10
  import Config from './Config';
@@ -16,7 +17,7 @@ const Chat = memo(() => {
16
17
  return [context?.meta.title];
17
18
  }, isEqual);
18
19
 
19
- const pageTitle = title ? `${title} - LobeChat` : 'LobeChat';
20
+ const pageTitle = genSiteHeadTitle(title);
20
21
 
21
22
  return (
22
23
  <>
@@ -1,23 +1,16 @@
1
1
  import { ChatHeader } from '@lobehub/ui';
2
- import { createStyles } from 'antd-style';
3
- import { useTranslation } from 'react-i18next';
4
2
  import Router from 'next/router';
5
3
  import { memo } from 'react';
4
+ import { useTranslation } from 'react-i18next';
5
+
6
+ import HeaderTitle from '@/components/HeaderTitle';
6
7
 
7
- const useStyles = createStyles(({ css, token }) => ({
8
- title: css`
9
- font-size: 16px;
10
- font-weight: bold;
11
- color: ${token.colorText};
12
- `,
13
- }));
14
8
  const Header = memo(() => {
15
9
  const { t } = useTranslation('setting');
16
10
 
17
- const { styles } = useStyles();
18
11
  return (
19
12
  <ChatHeader
20
- left={<div className={styles.title}>{t('header')}</div>}
13
+ left={<HeaderTitle title={t('header.global')} />}
21
14
  onBackClick={() => Router.back()}
22
15
  showBackButton
23
16
  />
@@ -2,11 +2,12 @@ import { Form, type ItemGroup, ThemeSwitch } from '@lobehub/ui';
2
2
  import { Form as AntForm, Button, Input, Popconfirm, Select, Switch } from 'antd';
3
3
  import isEqual from 'fast-deep-equal';
4
4
  import { debounce } from 'lodash-es';
5
- import { AppWindow, Bot, MessagesSquare, Palette, Webhook } from 'lucide-react';
5
+ import { AppWindow, BrainCog, MessagesSquare, Palette, Webhook } from 'lucide-react';
6
6
  import { memo, useCallback, useMemo } from 'react';
7
7
  import { useTranslation } from 'react-i18next';
8
8
  import { shallow } from 'zustand/shallow';
9
9
 
10
+ import { FORM_STYLE } from '@/const/layoutTokens';
10
11
  import AvatarWithUpload from '@/features/AvatarWithUpload';
11
12
  import SliderWithInput from '@/features/SliderWithInput';
12
13
  import { options } from '@/locales/options';
@@ -99,7 +100,7 @@ const SettingForm = memo(() => {
99
100
  [settings],
100
101
  );
101
102
 
102
- const OpenAI: SettingItemGroup = useMemo(
103
+ const openAI: SettingItemGroup = useMemo(
103
104
  () => ({
104
105
  children: [
105
106
  {
@@ -123,7 +124,7 @@ const SettingForm = memo(() => {
123
124
  [settings],
124
125
  );
125
126
 
126
- const Chat: SettingItemGroup = useMemo(
127
+ const chat: SettingItemGroup = useMemo(
127
128
  () => ({
128
129
  children: [
129
130
  {
@@ -161,7 +162,7 @@ const SettingForm = memo(() => {
161
162
  [settings],
162
163
  );
163
164
 
164
- const Model: SettingItemGroup = useMemo(
165
+ const model: SettingItemGroup = useMemo(
165
166
  () => ({
166
167
  children: [
167
168
  {
@@ -222,13 +223,13 @@ const SettingForm = memo(() => {
222
223
  tag: 'max_tokens',
223
224
  },
224
225
  ],
225
- icon: Bot,
226
+ icon: BrainCog,
226
227
  title: t('settingModel.title'),
227
228
  }),
228
229
  [settings],
229
230
  );
230
231
 
231
- const System: SettingItemGroup = useMemo(
232
+ const system: SettingItemGroup = useMemo(
232
233
  () => ({
233
234
  children: [
234
235
  {
@@ -282,16 +283,15 @@ const SettingForm = memo(() => {
282
283
  [settings],
283
284
  );
284
285
 
285
- const items = useMemo(() => [theme, OpenAI, Chat, Model, System], [settings]);
286
+ const items = useMemo(() => [theme, openAI, chat, model, system], [settings]);
286
287
 
287
288
  return (
288
289
  <Form
289
290
  form={form}
290
291
  initialValues={settings}
291
- itemMinWidth="max(30%,240px)"
292
292
  items={items}
293
293
  onValuesChange={debounce(setSettings, 100)}
294
- style={{ maxWidth: 1024, width: '100%' }}
294
+ {...FORM_STYLE}
295
295
  />
296
296
  );
297
297
  });
@@ -6,6 +6,7 @@ import { Flexbox } from 'react-layout-kit';
6
6
  import HeaderSpacing from '@/components/HeaderSpacing';
7
7
  import { createI18nNext } from '@/locales/create';
8
8
  import ChatLayout from '@/pages/chat/layout';
9
+ import { genSiteHeadTitle } from '@/utils/genSiteHeadTitle';
9
10
 
10
11
  import Header from './Header';
11
12
  import SettingForm from './SettingForm';
@@ -14,7 +15,7 @@ const initI18n = createI18nNext('setting');
14
15
 
15
16
  const SettingLayout = memo(() => {
16
17
  const { t } = useTranslation('setting');
17
- const pageTitle = `${t('header')} - LobeChat`;
18
+ const pageTitle = genSiteHeadTitle(t('header.global'));
18
19
 
19
20
  useEffect(() => {
20
21
  initI18n.finally();
@@ -1,6 +1,7 @@
1
1
  import searchEngine from './searchEngine';
2
2
  import getWeather from './weather';
3
+ import webCrawler from './webCrawler';
3
4
 
4
- const pluginList = [getWeather, searchEngine];
5
+ const pluginList = [getWeather, searchEngine, webCrawler];
5
6
 
6
7
  export default pluginList;
@@ -0,0 +1,20 @@
1
+ import runner from './runner';
2
+
3
+ const schema = {
4
+ description: '提取网页内容并总结',
5
+ name: 'websiteCrawler',
6
+ parameters: {
7
+ properties: {
8
+ url: {
9
+ description: '网页内容',
10
+ type: 'string',
11
+ },
12
+ },
13
+ required: ['url'],
14
+ type: 'object',
15
+ },
16
+ };
17
+
18
+ const getWeather = { avatar: '🕸', name: 'websiteCrawler', runner, schema };
19
+
20
+ export default getWeather;
@@ -0,0 +1,75 @@
1
+ export type DataResults = DataItem[];
2
+
3
+ export interface DataItem {
4
+ crawl: Crawl;
5
+ markdown: string;
6
+ metadata: Metadata;
7
+ screenshotUrl: any;
8
+ text: string;
9
+ url: string;
10
+ }
11
+
12
+ export interface Crawl {
13
+ depth: number;
14
+ httpStatusCode: number;
15
+ loadedTime: string;
16
+ loadedUrl: string;
17
+ referrerUrl: string;
18
+ }
19
+
20
+ export interface Metadata {
21
+ author: any;
22
+ canonicalUrl: string;
23
+ description: string;
24
+ keywords: string;
25
+ languageCode: string;
26
+ title: string;
27
+ }
28
+
29
+ const BASE_URL =
30
+ 'https://api.apify.com/v2/acts/apify~website-content-crawler/run-sync-get-dataset-items';
31
+ const token = process.env.APIFY_API_KEY;
32
+
33
+ const runner = async ({ url }: { url: string }) => {
34
+ // Prepare Actor input
35
+ const input = {
36
+ aggressivePrune: false,
37
+ clickElementsCssSelector: '[aria-expanded="false"]',
38
+ debugMode: false,
39
+ dynamicContentWaitSecs: 3,
40
+ proxyConfiguration: {
41
+ useApifyProxy: true,
42
+ },
43
+ removeCookieWarnings: true,
44
+ removeElementsCssSelector:
45
+ 'nav, footer, script, style, noscript, svg,\n[role="alert"],\n[role="banner"],\n[role="dialog"],\n[role="alertdialog"],\n[role="region"][aria-label*="skip" i],\n[aria-modal="true"]',
46
+ saveFiles: false,
47
+ saveHtml: false,
48
+ saveMarkdown: true,
49
+ saveScreenshots: false,
50
+ startUrls: [{ url }],
51
+ };
52
+
53
+ try {
54
+ const data = await fetch(`${BASE_URL}?token=${token}`, {
55
+ body: JSON.stringify(input),
56
+ headers: {
57
+ 'Content-Type': 'application/json',
58
+ },
59
+ method: 'POST',
60
+ });
61
+ const result = (await data.json()) as DataResults;
62
+
63
+ const item = result[0];
64
+ return {
65
+ content: item.markdown,
66
+ title: item.metadata.title,
67
+ url: item.url,
68
+ };
69
+ } catch (error) {
70
+ console.error(error);
71
+ return { content: '抓取失败', errorMessage: (error as any).message };
72
+ }
73
+ };
74
+
75
+ export default runner;
@@ -16,10 +16,6 @@ export const initialLobeAgentConfig: LobeAgentConfig = {
16
16
  systemRole: '',
17
17
  };
18
18
 
19
- export const DEFAULT_AVATAR = 'https://npm.elemecdn.com/@lobehub/assets-logo/assets/logo-3d.webp';
20
-
21
- export const DEFAULT_TITLE = 'DefaultSession';
22
-
23
19
  export const initialAgentConfigState: AgentConfigState = {
24
20
  // // loading 中间态
25
21
  autocompleteLoading: {
@@ -30,5 +26,5 @@ export const initialAgentConfigState: AgentConfigState = {
30
26
  title: false,
31
27
  },
32
28
 
33
- showAgentSettings: false,
29
+ showAgentSettings: true,
34
30
  };
@@ -1,30 +1,34 @@
1
+ import { DEFAULT_AVATAR, DEFAULT_BACKGROUND_COLOR } from '@/const/meta';
1
2
  import { SessionStore } from '@/store/session';
2
3
  import { LanguageModel } from '@/types/llm';
3
4
  import { MetaData } from '@/types/meta';
4
5
  import { LobeAgentConfig } from '@/types/session';
5
6
 
6
7
  import { sessionSelectors } from '../session';
7
- import { DEFAULT_AVATAR, initialLobeAgentConfig } from './initialState';
8
+ import { initialLobeAgentConfig } from './initialState';
8
9
 
9
10
  const currentAgentMeta = (s: SessionStore): MetaData => {
10
11
  const session = sessionSelectors.currentSession(s);
11
12
 
12
- return session?.meta || {};
13
+ return { avatar: DEFAULT_AVATAR, backgroundColor: DEFAULT_BACKGROUND_COLOR, ...session?.meta };
13
14
  };
14
15
 
15
16
  const currentAgentTitle = (s: SessionStore) => currentAgentMeta(s)?.title;
16
17
 
17
- const currentAgentAvatar = (s: SessionStore) => {
18
+ const currentAgentBackgroundColor = (s: SessionStore) => {
18
19
  const session = sessionSelectors.currentSession(s);
20
+ if (!session) return DEFAULT_BACKGROUND_COLOR;
21
+ return session.meta.backgroundColor || DEFAULT_BACKGROUND_COLOR;
22
+ };
19
23
 
24
+ const currentAgentAvatar = (s: SessionStore) => {
25
+ const session = sessionSelectors.currentSession(s);
20
26
  if (!session) return DEFAULT_AVATAR;
21
-
22
27
  return session.meta.avatar || DEFAULT_AVATAR;
23
28
  };
24
29
 
25
30
  const currentAgentConfig = (s: SessionStore) => {
26
31
  const session = sessionSelectors.currentSession(s);
27
-
28
32
  return session?.config;
29
33
  };
30
34
 
@@ -32,6 +36,10 @@ const currentAgentConfigSafe = (s: SessionStore): LobeAgentConfig => {
32
36
  return currentAgentConfig(s) || initialLobeAgentConfig;
33
37
  };
34
38
 
39
+ const currentAgentSystemRole = (s: SessionStore) => {
40
+ return currentAgentConfigSafe(s).systemRole;
41
+ };
42
+
35
43
  const currentAgentModel = (s: SessionStore): LanguageModel => {
36
44
  const config = currentAgentConfig(s);
37
45
 
@@ -45,10 +53,12 @@ const hasSystemRole = (s: SessionStore) => {
45
53
  };
46
54
  export const agentSelectors = {
47
55
  currentAgentAvatar,
56
+ currentAgentBackgroundColor,
48
57
  currentAgentConfig,
49
58
  currentAgentConfigSafe,
50
59
  currentAgentMeta,
51
60
  currentAgentModel,
61
+ currentAgentSystemRole,
52
62
  currentAgentTitle,
53
63
  hasSystemRole,
54
64
  };
@@ -1,9 +1,9 @@
1
+ import { DEFAULT_USER_AVATAR } from '@/const/meta';
1
2
  import { agentSelectors } from '@/store/session';
2
3
  import { useSettings } from '@/store/settings';
3
4
  import { ChatMessage } from '@/types/chatMessage';
4
5
 
5
6
  import type { SessionStore } from '../../../store';
6
- import { DEFAULT_AVATAR } from '../../agentConfig';
7
7
  import { sessionSelectors } from '../../session';
8
8
  import { organizeChats } from './utils';
9
9
 
@@ -14,7 +14,7 @@ export const currentChats = (s: SessionStore): ChatMessage[] => {
14
14
 
15
15
  return organizeChats(session, {
16
16
  assistant: agentSelectors.currentAgentAvatar(s),
17
- user: useSettings.getState().settings.avatar || DEFAULT_AVATAR,
17
+ user: useSettings.getState().settings.avatar || DEFAULT_USER_AVATAR,
18
18
  });
19
19
  };
20
20
 
@@ -1,4 +1,4 @@
1
- import { DEFAULT_AVATAR } from '@/store/session/slices/agentConfig';
1
+ import { DEFAULT_AVATAR } from '@/const/meta';
2
2
  import { MetaData } from '@/types/meta';
3
3
 
4
4
  export const getAgentAvatar = (s: MetaData) => s.avatar || DEFAULT_AVATAR;
@@ -0,0 +1 @@
1
+ export const genSiteHeadTitle = (title?: string) => (title ? `${title} - LobeChat` : 'LobeChat');
@@ -1,64 +0,0 @@
1
- import { Avatar } from '@lobehub/ui';
2
- import { createStyles } from 'antd-style';
3
- import isEqual from 'fast-deep-equal';
4
- import { LucideBrain, LucideThermometer, WholeWord } from 'lucide-react';
5
- import { memo } from 'react';
6
- import { useTranslation } from 'react-i18next';
7
- import { Center, Flexbox } from 'react-layout-kit';
8
- import { shallow } from 'zustand/shallow';
9
-
10
- import { agentSelectors, sessionSelectors, useSessionStore } from '@/store/session';
11
- import { DEFAULT_TITLE } from '@/store/session/slices/agentConfig';
12
-
13
- import { ConfigCell, ConfigCellGroup } from './ConfigCell';
14
-
15
- const useStyles = createStyles(({ css, token }) => ({
16
- desc: css`
17
- color: ${token.colorText};
18
- `,
19
- model: css`
20
- color: ${token.colorTextTertiary};
21
- `,
22
- title: css`
23
- font-size: ${token.fontSizeHeading4}px;
24
- font-weight: bold;
25
- `,
26
- }));
27
-
28
- const ReadMode = memo(() => {
29
- const { styles } = useStyles();
30
- const session = useSessionStore(sessionSelectors.currentSessionSafe, isEqual);
31
- const avatar = useSessionStore(agentSelectors.currentAgentAvatar, shallow);
32
- const title = useSessionStore(agentSelectors.currentAgentTitle, shallow);
33
- const model = useSessionStore(agentSelectors.currentAgentModel, shallow);
34
-
35
- const { t } = useTranslation('common');
36
- return (
37
- <Center gap={12} paddingBlock={16} style={{ marginTop: 8 }}>
38
- <Avatar avatar={avatar} size={100} />
39
- <Flexbox className={styles.title}>{title || DEFAULT_TITLE}</Flexbox>
40
- <Flexbox className={styles.model}>{model}</Flexbox>
41
- <Flexbox className={styles.desc}>{session.meta.description}</Flexbox>
42
-
43
- <Flexbox flex={1} gap={12} width={'100%'}>
44
- <ConfigCell icon={LucideBrain} label={t('agentPrompt')} />
45
- <ConfigCellGroup
46
- items={[
47
- {
48
- icon: LucideThermometer,
49
- label: t('modelTemperature'),
50
- value: session.config.params.temperature,
51
- },
52
- {
53
- icon: WholeWord,
54
- label: t('agentMaxToken'),
55
- value: session.config.params.max_tokens,
56
- },
57
- ]}
58
- />
59
- </Flexbox>
60
- </Center>
61
- );
62
- });
63
-
64
- export default ReadMode;
@@ -1,46 +0,0 @@
1
- import { Avatar } from '@lobehub/ui';
2
- import { List, Switch, Tag } from 'antd';
3
- import isEqual from 'fast-deep-equal';
4
- import { useTranslation } from 'react-i18next';
5
- import { Flexbox } from 'react-layout-kit';
6
- import { shallow } from 'zustand/shallow';
7
-
8
- import pluginList from '@/plugins';
9
- import { agentSelectors, useSessionStore } from '@/store/session';
10
-
11
- const PluginList = () => {
12
- const { t } = useTranslation('common');
13
-
14
- const config = useSessionStore(agentSelectors.currentAgentConfigSafe, isEqual);
15
-
16
- const [toggleAgentPlugin] = useSessionStore((s) => [s.toggleAgentPlugin], shallow);
17
-
18
- return (
19
- <List
20
- bordered
21
- dataSource={pluginList}
22
- renderItem={(item) => (
23
- <List.Item>
24
- <List.Item.Meta
25
- avatar={<Avatar avatar={item.avatar} />}
26
- description={item.schema.description}
27
- title={
28
- <Flexbox align={'center'} gap={8} horizontal>
29
- {t(`plugin-${item.name}` as any)} <Tag>{item.name}</Tag>
30
- </Flexbox>
31
- }
32
- />
33
- <Switch
34
- checked={!config.plugins ? false : config.plugins.includes(item.name)}
35
- onChange={() => {
36
- toggleAgentPlugin(item.name);
37
- }}
38
- />
39
- </List.Item>
40
- )}
41
- size={'large'}
42
- />
43
- );
44
- };
45
-
46
- export default PluginList;
@@ -1,69 +0,0 @@
1
- import { EditableMessage } from '@lobehub/ui';
2
- import { Button } from 'antd';
3
- import { createStyles } from 'antd-style';
4
- import { 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 { FormItem } from '../FormItem';
12
-
13
- export const useStyles = createStyles(({ css, token }) => ({
14
- input: css`
15
- padding: 12px;
16
- background: ${token.colorFillTertiary};
17
- border: 1px solid ${token.colorPrimaryBorder};
18
- border-radius: 8px;
19
- `,
20
- markdown: css`
21
- padding: 12px;
22
- background: ${token.colorFillTertiary};
23
- `,
24
- }));
25
-
26
- const Prompt = () => {
27
- const { t } = useTranslation('common');
28
-
29
- const [editing, setEditing] = useState(false);
30
- const { styles } = useStyles();
31
-
32
- const systemRole = useSessionStore((s) => {
33
- const config = agentSelectors.currentAgentConfigSafe(s);
34
- return config.systemRole;
35
- }, shallow);
36
-
37
- const [updateAgentConfig] = useSessionStore((s) => [s.updateAgentConfig], shallow);
38
-
39
- return (
40
- <FormItem label={t('agentPrompt')}>
41
- <Flexbox gap={16}>
42
- <EditableMessage
43
- classNames={styles}
44
- editing={editing}
45
- onChange={(e) => {
46
- updateAgentConfig({ systemRole: e });
47
- }}
48
- onEditingChange={setEditing}
49
- showEditWhenEmpty
50
- value={systemRole}
51
- />
52
- {!editing && !!systemRole && (
53
- <Flexbox direction={'horizontal-reverse'}>
54
- <Button
55
- onClick={() => {
56
- setEditing(true);
57
- }}
58
- type={'primary'}
59
- >
60
- {t('edit')}
61
- </Button>
62
- </Flexbox>
63
- )}
64
- </Flexbox>
65
- </FormItem>
66
- );
67
- };
68
-
69
- export default Prompt;