@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.
- package/CHANGELOG.md +51 -0
- package/README.md +3 -3
- package/locales/en_US/common.json +19 -27
- package/locales/en_US/plugin.json +10 -0
- package/locales/en_US/setting.json +42 -6
- package/locales/zh_CN/common.json +8 -17
- package/locales/zh_CN/plugin.json +10 -0
- package/locales/zh_CN/setting.json +36 -0
- package/package.json +1 -1
- package/src/components/HeaderSpacing/index.tsx +3 -1
- package/src/components/HeaderTitle/index.tsx +42 -0
- package/src/const/layoutTokens.ts +6 -1
- package/src/const/meta.ts +3 -0
- package/src/locales/default/common.ts +31 -49
- package/src/locales/default/plugin.ts +10 -0
- package/src/locales/default/setting.ts +46 -1
- package/src/locales/resources/en_US.ts +2 -0
- package/src/locales/resources/zh_CN.ts +2 -0
- package/src/pages/chat/SessionList/List/SessionItem.tsx +1 -2
- package/src/pages/chat/[id]/Config/Header.tsx +26 -0
- package/src/pages/chat/[id]/Config/SideBar.tsx +86 -0
- package/src/pages/chat/[id]/Config/index.tsx +5 -45
- package/src/pages/chat/[id]/Conversation/FunctionMessage.tsx +1 -1
- package/src/pages/chat/[id]/Conversation/Input/Action.tsx +13 -5
- package/src/pages/chat/[id]/Conversation/Input/index.tsx +11 -3
- package/src/pages/chat/[id]/Conversation/MessageExtra.tsx +1 -1
- package/src/pages/chat/[id]/Header.tsx +34 -43
- package/src/pages/chat/[id]/edit/AgentConfig/index.tsx +154 -95
- package/src/pages/chat/[id]/edit/AgentMeta/AutoGenerateInput.tsx +39 -0
- package/src/pages/chat/[id]/edit/AgentMeta/BackgroundSwatches.tsx +31 -0
- package/src/pages/chat/[id]/edit/AgentMeta/EmojiPicker.tsx +7 -3
- package/src/pages/chat/[id]/edit/AgentMeta/index.tsx +68 -75
- package/src/pages/chat/[id]/edit/AgentPlugin/index.tsx +44 -0
- package/src/pages/chat/[id]/edit/AgentPrompt/index.tsx +48 -0
- package/src/pages/chat/[id]/edit/Header.tsx +31 -0
- package/src/pages/chat/[id]/edit/index.page.tsx +12 -40
- package/src/pages/chat/[id]/index.page.tsx +2 -1
- package/src/pages/setting/Header.tsx +4 -11
- package/src/pages/setting/SettingForm.tsx +9 -9
- package/src/pages/setting/index.page.tsx +2 -1
- package/src/plugins/index.ts +2 -1
- package/src/plugins/webCrawler/index.ts +20 -0
- package/src/plugins/webCrawler/runner.ts +75 -0
- package/src/store/session/slices/agentConfig/initialState.ts +1 -5
- package/src/store/session/slices/agentConfig/selectors.ts +15 -5
- package/src/store/session/slices/chat/selectors/chat.ts +2 -2
- package/src/store/session/slices/session/selectors/chat.ts +1 -1
- package/src/utils/genSiteHeadTitle.ts +1 -0
- package/src/pages/chat/[id]/Config/ReadMode.tsx +0 -64
- package/src/pages/chat/[id]/edit/AgentConfig/Plugin.tsx +0 -46
- 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
|
-
|
|
17
|
-
|
|
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('
|
|
37
|
-
|
|
38
|
-
const { styles } = useStyles();
|
|
18
|
+
const { t } = useTranslation('setting');
|
|
39
19
|
|
|
40
|
-
const pageTitle = t('
|
|
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
|
-
<
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
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
|
|
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={<
|
|
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,
|
|
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
|
|
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
|
|
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
|
|
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:
|
|
226
|
+
icon: BrainCog,
|
|
226
227
|
title: t('settingModel.title'),
|
|
227
228
|
}),
|
|
228
229
|
[settings],
|
|
229
230
|
);
|
|
230
231
|
|
|
231
|
-
const
|
|
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,
|
|
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
|
-
|
|
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 =
|
|
18
|
+
const pageTitle = genSiteHeadTitle(t('header.global'));
|
|
18
19
|
|
|
19
20
|
useEffect(() => {
|
|
20
21
|
initI18n.finally();
|
package/src/plugins/index.ts
CHANGED
|
@@ -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:
|
|
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 {
|
|
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
|
|
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 ||
|
|
17
|
+
user: useSettings.getState().settings.avatar || DEFAULT_USER_AVATAR,
|
|
18
18
|
});
|
|
19
19
|
};
|
|
20
20
|
|
|
@@ -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;
|