@lobehub/chat 0.74.0 → 0.76.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 +86 -0
- package/README.md +26 -5
- package/README.zh-CN.md +25 -4
- package/docs/deploy-with-azure-openai.zh-CN.md +45 -0
- package/locales/en_US/market.json +12 -0
- package/locales/en_US/plugin.json +11 -2
- package/locales/en_US/setting.json +3 -1
- package/locales/ru_RU/market.json +12 -0
- package/locales/ru_RU/plugin.json +44 -49
- package/locales/ru_RU/setting.json +3 -1
- package/locales/zh_CN/common.json +1 -1
- package/locales/zh_CN/market.json +12 -0
- package/locales/zh_CN/plugin.json +19 -5
- package/locales/zh_CN/setting.json +62 -14
- package/next.config.mjs +3 -1
- package/package.json +5 -5
- package/scripts/i18nWorkflow/const.ts +19 -0
- package/scripts/i18nWorkflow/genDefaultLocale.ts +19 -0
- package/scripts/i18nWorkflow/genDiff.ts +50 -0
- package/scripts/i18nWorkflow/genResources.ts +26 -0
- package/scripts/i18nWorkflow/index.ts +15 -0
- package/scripts/i18nWorkflow/utils.ts +85 -0
- package/src/config/client.ts +14 -0
- package/src/config/server.ts +5 -0
- package/src/const/layoutTokens.ts +3 -1
- package/src/const/market.ts +15 -0
- package/src/const/settings.ts +2 -1
- package/src/const/url.ts +29 -4
- package/src/features/AgentSetting/AgentConfig/index.tsx +1 -2
- package/src/features/AgentSetting/AgentPlugin/MarketSettingModal.tsx +1 -1
- package/src/features/AgentSetting/store/initialState.ts +1 -1
- package/src/features/MobileTabBar/index.tsx +2 -2
- package/src/features/SideBar/TopActions.tsx +2 -2
- package/src/locales/default/market.ts +12 -0
- package/src/locales/default/setting.ts +1 -0
- package/src/locales/resources/en_US.ts +2 -0
- package/src/locales/resources/ru_RU.ts +2 -0
- package/src/locales/resources/zh_CN.ts +2 -0
- package/src/pages/api/openai/chat.api.ts +6 -10
- package/src/pages/api/openai/createAzureOpenai.ts +13 -9
- package/src/pages/chat/features/Conversation/Input/{Action.tsx → ActionBar/ActionLeft.tsx} +2 -2
- package/src/pages/chat/features/Conversation/Input/ActionBar/ActionRight.tsx +36 -0
- package/src/pages/chat/features/Conversation/Input/Desktop.tsx +40 -0
- package/src/pages/chat/features/Conversation/Input/Footer/SaveTopic.tsx +27 -0
- package/src/pages/chat/features/Conversation/Input/Footer/index.tsx +35 -0
- package/src/pages/chat/features/Conversation/Input/Mobile.tsx +12 -0
- package/src/pages/chat/features/Conversation/Input/index.tsx +20 -38
- package/src/pages/chat/features/SessionList/Header/Desktop.tsx +6 -13
- package/src/pages/chat/features/SessionList/Header/Mobile.tsx +1 -1
- package/src/pages/chat/features/SessionList/List/AddButton.tsx +1 -1
- package/src/pages/chat/features/SessionList/List/Item/index.tsx +4 -3
- package/src/pages/chat/features/SessionList/List/index.tsx +1 -3
- package/src/pages/chat/features/SessionList/Mobile.tsx +2 -12
- package/src/pages/chat/features/SessionSearchBar/index.tsx +26 -0
- package/src/pages/chat/features/Sidebar/Topic/index.tsx +18 -6
- package/src/pages/chat/features/Sidebar/TopicSearchBar/index.tsx +24 -0
- package/src/pages/chat/features/Sidebar/index.tsx +2 -9
- package/src/pages/market/features/AgentCard/AgentCardBanner.tsx +64 -0
- package/src/pages/market/features/AgentCard/AgentCardItem.tsx +57 -0
- package/src/pages/market/features/AgentCard/Loading.tsx +13 -0
- package/src/pages/market/features/AgentCard/index.tsx +37 -0
- package/src/pages/market/features/AgentCard/style.ts +22 -0
- package/src/pages/market/features/AgentSearchBar/index.tsx +26 -0
- package/src/pages/market/features/Header/Desktop.tsx +15 -4
- package/src/pages/market/features/Header/Mobile.tsx +7 -24
- package/src/pages/market/features/SideBar/AgentInfo/Comment.tsx +16 -0
- package/src/pages/market/features/SideBar/AgentInfo/Header.tsx +68 -0
- package/src/pages/market/features/SideBar/AgentInfo/Loading.tsx +61 -0
- package/src/pages/market/features/SideBar/AgentInfo/TokenTag.tsx +25 -0
- package/src/pages/market/features/SideBar/AgentInfo/index.tsx +68 -0
- package/src/pages/market/features/SideBar/AgentInfo/style.ts +46 -0
- package/src/pages/market/features/SideBar/Desktop.tsx +70 -0
- package/src/pages/market/features/SideBar/Mobile.tsx +36 -0
- package/src/pages/market/features/SideBar/index.tsx +23 -0
- package/src/pages/market/features/TagList/index.tsx +29 -0
- package/src/pages/market/index.page.tsx +11 -2
- package/src/pages/market/layout.mobile.tsx +8 -7
- package/src/pages/market/layout.tsx +39 -1
- package/src/pages/settings/features/Header/Desktop.tsx +2 -4
- package/src/pages/settings/features/Header/Mobile.tsx +1 -1
- package/src/pages/settings/features/Settings/Common.tsx +1 -2
- package/src/pages/settings/features/Settings/LLM/index.tsx +12 -1
- package/src/pages/settings/features/Settings/index.tsx +17 -4
- package/src/services/_header.ts +1 -1
- package/src/services/agentMarket.ts +21 -0
- package/src/store/global/initialState.ts +1 -2
- package/src/store/global/selectors.test.ts +0 -1
- package/src/store/market/action.ts +57 -0
- package/src/store/market/index.ts +3 -0
- package/src/store/market/initialState.ts +17 -0
- package/src/store/market/selectors.ts +36 -0
- package/src/store/market/store.ts +51 -0
- package/src/store/session/slices/session/action.ts +5 -3
- package/src/store/session/slices/session/initialState.ts +2 -0
- package/src/store/session/slices/session/reducers/session.test.ts +4 -4
- package/src/types/market.ts +19 -0
- package/src/types/meta.ts +1 -1
- package/src/utils/filter.ts +1 -1
- package/src/utils/findDuplicates.ts +22 -0
- package/scripts/genDefaultLocale.ts +0 -18
- package/scripts/genResources.ts +0 -51
- package/scripts/toc.ts +0 -7
- package/src/components/Empty/index.tsx +0 -63
- package/src/components/Empty/style.ts +0 -31
- package/src/components/SelectWithImg/index.tsx +0 -97
- package/src/components/SelectWithImg/styles.ts +0 -43
- package/src/pages/chat/features/Conversation/Input/ActionRight.tsx +0 -31
- package/src/pages/chat/features/Conversation/Input/Footer.tsx +0 -49
- /package/src/components/{ManifestPreviewer.tsx → ManifestPreviewer/index.tsx} +0 -0
- /package/src/pages/chat/features/Conversation/Input/{Token.tsx → ActionBar/Token.tsx} +0 -0
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { Avatar, DivProps } from '@lobehub/ui';
|
|
2
|
+
import { createStyles } from 'antd-style';
|
|
3
|
+
import { memo } from 'react';
|
|
4
|
+
import { Flexbox } from 'react-layout-kit';
|
|
5
|
+
|
|
6
|
+
import { MetaData } from '@/types/meta';
|
|
7
|
+
|
|
8
|
+
export const useStyles = createStyles(({ css, token }, maskColor: string) => ({
|
|
9
|
+
banner: css`
|
|
10
|
+
position: relative;
|
|
11
|
+
|
|
12
|
+
overflow: hidden;
|
|
13
|
+
|
|
14
|
+
height: 64px;
|
|
15
|
+
margin-bottom: -56px;
|
|
16
|
+
|
|
17
|
+
background: ${token.colorFill};
|
|
18
|
+
`,
|
|
19
|
+
bannerImg: css`
|
|
20
|
+
filter: blur(6px) saturate(1.6);
|
|
21
|
+
`,
|
|
22
|
+
bannerMask: css`
|
|
23
|
+
position: absolute;
|
|
24
|
+
bottom: 0;
|
|
25
|
+
left: 0;
|
|
26
|
+
|
|
27
|
+
width: 100%;
|
|
28
|
+
height: 100%;
|
|
29
|
+
|
|
30
|
+
background: linear-gradient(to bottom, transparent, ${maskColor || token.colorBgLayout});
|
|
31
|
+
`,
|
|
32
|
+
}));
|
|
33
|
+
|
|
34
|
+
interface AgentCardBannerProps extends DivProps {
|
|
35
|
+
mask?: boolean;
|
|
36
|
+
maskColor?: string;
|
|
37
|
+
meta: MetaData;
|
|
38
|
+
size?: number;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
const AgentCardBanner = memo<AgentCardBannerProps>(
|
|
42
|
+
({ meta, className, mask, size = 8, maskColor, ...props }) => {
|
|
43
|
+
const { styles, theme, cx } = useStyles(maskColor);
|
|
44
|
+
|
|
45
|
+
return (
|
|
46
|
+
<Flexbox
|
|
47
|
+
align={'center'}
|
|
48
|
+
className={cx(styles.banner, className)}
|
|
49
|
+
justify={'center'}
|
|
50
|
+
{...props}
|
|
51
|
+
>
|
|
52
|
+
<Avatar
|
|
53
|
+
avatar={meta.avatar}
|
|
54
|
+
background={meta.backgroundColor || theme.colorBgContainer}
|
|
55
|
+
className={styles.bannerImg}
|
|
56
|
+
style={{ transform: `scale(${size})` }}
|
|
57
|
+
/>
|
|
58
|
+
{mask && <div className={styles.bannerMask} />}
|
|
59
|
+
</Flexbox>
|
|
60
|
+
);
|
|
61
|
+
},
|
|
62
|
+
);
|
|
63
|
+
|
|
64
|
+
export default AgentCardBanner;
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { Avatar, Tag } from '@lobehub/ui';
|
|
2
|
+
import { useHover } from 'ahooks';
|
|
3
|
+
import { Typography } from 'antd';
|
|
4
|
+
import { useThemeMode } from 'antd-style';
|
|
5
|
+
import { startCase } from 'lodash-es';
|
|
6
|
+
import { memo, useRef } from 'react';
|
|
7
|
+
import { Flexbox } from 'react-layout-kit';
|
|
8
|
+
|
|
9
|
+
import { useMarketStore } from '@/store/market';
|
|
10
|
+
import { AgentsMarketIndexItem } from '@/types/market';
|
|
11
|
+
|
|
12
|
+
import AgentCardBanner from './AgentCardBanner';
|
|
13
|
+
import { useStyles } from './style';
|
|
14
|
+
|
|
15
|
+
const { Paragraph } = Typography;
|
|
16
|
+
const AgentCardItem = memo<AgentsMarketIndexItem>(({ meta, identifier }) => {
|
|
17
|
+
const ref = useRef(null);
|
|
18
|
+
const isHovering = useHover(ref);
|
|
19
|
+
const onAgentCardClick = useMarketStore((s) => s.activateAgent);
|
|
20
|
+
const { avatar, title, description, tags, backgroundColor } = meta;
|
|
21
|
+
const { styles, theme } = useStyles();
|
|
22
|
+
const { isDarkMode } = useThemeMode();
|
|
23
|
+
return (
|
|
24
|
+
<Flexbox className={styles.container} onClick={() => onAgentCardClick(identifier)}>
|
|
25
|
+
<AgentCardBanner
|
|
26
|
+
mask
|
|
27
|
+
maskColor={theme.colorBgContainer}
|
|
28
|
+
meta={meta}
|
|
29
|
+
style={{ opacity: isDarkMode ? 0.9 : 0.4 }}
|
|
30
|
+
/>
|
|
31
|
+
<Flexbox className={styles.inner} gap={8} ref={ref}>
|
|
32
|
+
<Avatar
|
|
33
|
+
animation={isHovering}
|
|
34
|
+
avatar={avatar}
|
|
35
|
+
background={backgroundColor || theme.colorFillTertiary}
|
|
36
|
+
className={styles.avatar}
|
|
37
|
+
size={56}
|
|
38
|
+
/>
|
|
39
|
+
<Paragraph className={styles.title} ellipsis={{ rows: 1, tooltip: title }}>
|
|
40
|
+
{title}
|
|
41
|
+
</Paragraph>
|
|
42
|
+
<Paragraph className={styles.desc} ellipsis={{ rows: 2, tooltip: description }}>
|
|
43
|
+
{description}
|
|
44
|
+
</Paragraph>
|
|
45
|
+
<Flexbox gap={6} horizontal style={{ flexWrap: 'wrap' }}>
|
|
46
|
+
{(tags as string[]).map((tag: string, index) => (
|
|
47
|
+
<Tag key={index} style={{ margin: 0 }}>
|
|
48
|
+
{startCase(tag).trim()}
|
|
49
|
+
</Tag>
|
|
50
|
+
))}
|
|
51
|
+
</Flexbox>
|
|
52
|
+
</Flexbox>
|
|
53
|
+
</Flexbox>
|
|
54
|
+
);
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
export default AgentCardItem;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { Skeleton } from 'antd';
|
|
2
|
+
import { memo } from 'react';
|
|
3
|
+
import { Flexbox } from 'react-layout-kit';
|
|
4
|
+
|
|
5
|
+
const Loading = memo(() => {
|
|
6
|
+
return (
|
|
7
|
+
<Flexbox>
|
|
8
|
+
<Skeleton paragraph={{ rows: 8 }} />
|
|
9
|
+
</Flexbox>
|
|
10
|
+
);
|
|
11
|
+
});
|
|
12
|
+
|
|
13
|
+
export default Loading;
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { SpotlightCard } from '@lobehub/ui';
|
|
2
|
+
import { memo, useMemo } from 'react';
|
|
3
|
+
|
|
4
|
+
import { agentMarketSelectors, useMarketStore } from '@/store/market';
|
|
5
|
+
|
|
6
|
+
import TagList from '../TagList';
|
|
7
|
+
import AgentCardItem from './AgentCardItem';
|
|
8
|
+
import Loading from './Loading';
|
|
9
|
+
|
|
10
|
+
const gridRender = (item: any) => <AgentCardItem {...item} />;
|
|
11
|
+
|
|
12
|
+
const AgentCard = memo(() => {
|
|
13
|
+
const agentList = useMarketStore(agentMarketSelectors.getAgentList);
|
|
14
|
+
|
|
15
|
+
const [useFetchAgentList, keywords] = useMarketStore((s) => [
|
|
16
|
+
s.useFetchAgentList,
|
|
17
|
+
s.searchKeywords,
|
|
18
|
+
]);
|
|
19
|
+
|
|
20
|
+
const { isLoading } = useFetchAgentList();
|
|
21
|
+
|
|
22
|
+
const agentListData = useMemo(() => {
|
|
23
|
+
if (!keywords) return agentList;
|
|
24
|
+
return agentList.filter(({ meta }) => JSON.stringify(meta).toLowerCase().includes(keywords));
|
|
25
|
+
}, [agentList, keywords]);
|
|
26
|
+
|
|
27
|
+
if (isLoading || !agentList) return <Loading />;
|
|
28
|
+
|
|
29
|
+
return (
|
|
30
|
+
<>
|
|
31
|
+
<TagList />
|
|
32
|
+
<SpotlightCard items={agentListData} renderItem={gridRender} />
|
|
33
|
+
</>
|
|
34
|
+
);
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
export default AgentCard;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { createStyles } from 'antd-style';
|
|
2
|
+
|
|
3
|
+
export const useStyles = createStyles(({ css, token }) => ({
|
|
4
|
+
avatar: css``,
|
|
5
|
+
|
|
6
|
+
container: css`
|
|
7
|
+
position: relative;
|
|
8
|
+
overflow: hidden;
|
|
9
|
+
border-radius: 11px;
|
|
10
|
+
`,
|
|
11
|
+
desc: css`
|
|
12
|
+
color: ${token.colorTextDescription};
|
|
13
|
+
`,
|
|
14
|
+
inner: css`
|
|
15
|
+
padding: 16px;
|
|
16
|
+
`,
|
|
17
|
+
title: css`
|
|
18
|
+
margin-bottom: 0 !important;
|
|
19
|
+
font-size: 16px;
|
|
20
|
+
font-weight: 600;
|
|
21
|
+
`,
|
|
22
|
+
}));
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { SearchBar } from '@lobehub/ui';
|
|
2
|
+
import { useResponsive } from 'antd-style';
|
|
3
|
+
import { memo } from 'react';
|
|
4
|
+
import { useTranslation } from 'react-i18next';
|
|
5
|
+
|
|
6
|
+
import { useMarketStore } from '@/store/market';
|
|
7
|
+
|
|
8
|
+
const AgentSearchBar = memo(() => {
|
|
9
|
+
const { t } = useTranslation('market');
|
|
10
|
+
const keywords = useMarketStore((s) => s.searchKeywords);
|
|
11
|
+
const { mobile } = useResponsive();
|
|
12
|
+
return (
|
|
13
|
+
<SearchBar
|
|
14
|
+
allowClear
|
|
15
|
+
enableShortKey={!mobile}
|
|
16
|
+
onChange={(e) => useMarketStore.setState({ searchKeywords: e.target.value })}
|
|
17
|
+
placeholder={t('search.placeholder')}
|
|
18
|
+
shortKey={'k'}
|
|
19
|
+
spotlight={!mobile}
|
|
20
|
+
type={mobile ? 'block' : 'ghost'}
|
|
21
|
+
value={keywords}
|
|
22
|
+
/>
|
|
23
|
+
);
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
export default AgentSearchBar;
|
|
@@ -1,9 +1,13 @@
|
|
|
1
|
-
import { ChatHeader,
|
|
1
|
+
import { ChatHeader, Icon, Logo } from '@lobehub/ui';
|
|
2
|
+
import { Button } from 'antd';
|
|
2
3
|
import { createStyles } from 'antd-style';
|
|
4
|
+
import { Bot } from 'lucide-react';
|
|
3
5
|
import Link from 'next/link';
|
|
4
6
|
import { memo } from 'react';
|
|
5
7
|
import { useTranslation } from 'react-i18next';
|
|
6
8
|
|
|
9
|
+
import { AGENTS_INDEX_GITHUB } from '@/const/url';
|
|
10
|
+
|
|
7
11
|
export const useStyles = createStyles(({ css, token }) => ({
|
|
8
12
|
logo: css`
|
|
9
13
|
color: ${token.colorText};
|
|
@@ -13,16 +17,23 @@ export const useStyles = createStyles(({ css, token }) => ({
|
|
|
13
17
|
|
|
14
18
|
const Header = memo(() => {
|
|
15
19
|
const { styles } = useStyles();
|
|
16
|
-
const { t } = useTranslation('
|
|
20
|
+
const { t } = useTranslation('market');
|
|
17
21
|
|
|
18
22
|
return (
|
|
19
23
|
<ChatHeader
|
|
20
24
|
left={
|
|
21
25
|
<Link href={'/'}>
|
|
22
|
-
<Logo className={styles.logo} extra={
|
|
26
|
+
<Logo className={styles.logo} extra={'Discover'} size={36} type={'text'} />
|
|
23
27
|
</Link>
|
|
24
28
|
}
|
|
25
|
-
right={
|
|
29
|
+
right={
|
|
30
|
+
<Button
|
|
31
|
+
icon={<Icon icon={Bot} />}
|
|
32
|
+
onClick={() => window.open(AGENTS_INDEX_GITHUB, '__blank')}
|
|
33
|
+
>
|
|
34
|
+
{t('submitAgent')}
|
|
35
|
+
</Button>
|
|
36
|
+
}
|
|
26
37
|
/>
|
|
27
38
|
);
|
|
28
39
|
});
|
|
@@ -1,39 +1,22 @@
|
|
|
1
1
|
import { ActionIcon, Logo, MobileNavBar } from '@lobehub/ui';
|
|
2
|
-
import {
|
|
3
|
-
import { MessageSquarePlus, Settings2 } from 'lucide-react';
|
|
2
|
+
import { Settings2 } from 'lucide-react';
|
|
4
3
|
import Router from 'next/router';
|
|
5
4
|
import { memo } from 'react';
|
|
6
5
|
|
|
7
6
|
import AvatarWithUpload from '@/features/AvatarWithUpload';
|
|
8
|
-
import { useSessionStore } from '@/store/session';
|
|
9
|
-
|
|
10
|
-
export const useStyles = createStyles(({ css, token }) => ({
|
|
11
|
-
logo: css`
|
|
12
|
-
fill: ${token.colorText};
|
|
13
|
-
`,
|
|
14
|
-
top: css`
|
|
15
|
-
position: sticky;
|
|
16
|
-
top: 0;
|
|
17
|
-
`,
|
|
18
|
-
}));
|
|
19
7
|
|
|
20
8
|
const Header = memo(() => {
|
|
21
|
-
const [createSession] = useSessionStore((s) => [s.createSession]);
|
|
22
|
-
|
|
23
9
|
return (
|
|
24
10
|
<MobileNavBar
|
|
25
11
|
center={<Logo type={'text'} />}
|
|
26
12
|
left={<AvatarWithUpload size={28} style={{ marginLeft: 8 }} />}
|
|
27
13
|
right={
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
}}
|
|
35
|
-
/>
|
|
36
|
-
</>
|
|
14
|
+
<ActionIcon
|
|
15
|
+
icon={Settings2}
|
|
16
|
+
onClick={() => {
|
|
17
|
+
Router.push({ pathname: `/settings` });
|
|
18
|
+
}}
|
|
19
|
+
/>
|
|
37
20
|
}
|
|
38
21
|
/>
|
|
39
22
|
);
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { Giscus } from '@lobehub/ui';
|
|
2
|
+
import { memo } from 'react';
|
|
3
|
+
|
|
4
|
+
const Comment = memo<{ identifier: string }>(({ identifier }) => (
|
|
5
|
+
<Giscus
|
|
6
|
+
category="General"
|
|
7
|
+
categoryId="DIC_kwDOKON5YM4CZNRJ"
|
|
8
|
+
id="lobehub"
|
|
9
|
+
mapping="specific"
|
|
10
|
+
repo="lobehub/lobe-chat-agents"
|
|
11
|
+
repoId="R_kgDOKON5YA"
|
|
12
|
+
term={identifier}
|
|
13
|
+
/>
|
|
14
|
+
));
|
|
15
|
+
|
|
16
|
+
export default Comment;
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { Avatar, Tag } from '@lobehub/ui';
|
|
2
|
+
import { Button, Typography } from 'antd';
|
|
3
|
+
import { startCase } from 'lodash-es';
|
|
4
|
+
import { memo } from 'react';
|
|
5
|
+
import { useTranslation } from 'react-i18next';
|
|
6
|
+
import { Center } from 'react-layout-kit';
|
|
7
|
+
|
|
8
|
+
import { useGlobalStore } from '@/store/global';
|
|
9
|
+
import { agentMarketSelectors, useMarketStore } from '@/store/market';
|
|
10
|
+
import { useSessionStore } from '@/store/session';
|
|
11
|
+
|
|
12
|
+
import { useStyles } from './style';
|
|
13
|
+
|
|
14
|
+
const { Link } = Typography;
|
|
15
|
+
|
|
16
|
+
const Header = memo(() => {
|
|
17
|
+
const { t } = useTranslation('market');
|
|
18
|
+
const { styles, theme } = useStyles();
|
|
19
|
+
|
|
20
|
+
const createSession = useSessionStore((s) => s.createSession);
|
|
21
|
+
const switchSideBar = useGlobalStore((s) => s.switchSideBar);
|
|
22
|
+
const agentItem = useMarketStore(agentMarketSelectors.currentAgentItem);
|
|
23
|
+
|
|
24
|
+
const { meta, createAt, author, homepage, config } = agentItem;
|
|
25
|
+
const { avatar, title, description, tags, backgroundColor } = meta;
|
|
26
|
+
|
|
27
|
+
return (
|
|
28
|
+
<Center className={styles.container} gap={16}>
|
|
29
|
+
<Avatar
|
|
30
|
+
avatar={avatar}
|
|
31
|
+
background={backgroundColor || theme.colorFillTertiary}
|
|
32
|
+
className={styles.avatar}
|
|
33
|
+
size={100}
|
|
34
|
+
/>
|
|
35
|
+
<div className={styles.title}>{title}</div>
|
|
36
|
+
<Center gap={6} horizontal style={{ flexWrap: 'wrap' }}>
|
|
37
|
+
{(tags as string[]).map((tag: string, index) => (
|
|
38
|
+
<Tag
|
|
39
|
+
key={index}
|
|
40
|
+
onClick={() => useMarketStore.setState({ searchKeywords: tag })}
|
|
41
|
+
style={{ margin: 0 }}
|
|
42
|
+
>
|
|
43
|
+
{startCase(tag).trim()}
|
|
44
|
+
</Tag>
|
|
45
|
+
))}
|
|
46
|
+
</Center>
|
|
47
|
+
<div className={styles.desc}>{description}</div>
|
|
48
|
+
<Link className={styles.author} href={homepage} target={'_blank'}>
|
|
49
|
+
@{author}
|
|
50
|
+
</Link>
|
|
51
|
+
<Button
|
|
52
|
+
block
|
|
53
|
+
onClick={() => {
|
|
54
|
+
if (!agentItem) return;
|
|
55
|
+
|
|
56
|
+
createSession({ config, meta });
|
|
57
|
+
switchSideBar('chat');
|
|
58
|
+
}}
|
|
59
|
+
type={'primary'}
|
|
60
|
+
>
|
|
61
|
+
{t('addAgent')}
|
|
62
|
+
</Button>
|
|
63
|
+
<div className={styles.date}>{createAt}</div>
|
|
64
|
+
</Center>
|
|
65
|
+
);
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
export default Header;
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { Skeleton } from 'antd';
|
|
2
|
+
import { memo } from 'react';
|
|
3
|
+
import { Center, Flexbox } from 'react-layout-kit';
|
|
4
|
+
|
|
5
|
+
import { useStyles } from './style';
|
|
6
|
+
|
|
7
|
+
const Loading = memo(() => {
|
|
8
|
+
const { styles } = useStyles();
|
|
9
|
+
return (
|
|
10
|
+
<>
|
|
11
|
+
<Center className={styles.container} gap={16} style={{ paddingTop: 80 }}>
|
|
12
|
+
<Skeleton.Avatar active shape={'circle'} size={100} />
|
|
13
|
+
<Skeleton
|
|
14
|
+
active
|
|
15
|
+
className={styles.loading}
|
|
16
|
+
paragraph={{
|
|
17
|
+
rows: 3,
|
|
18
|
+
style: {
|
|
19
|
+
alignItems: 'center',
|
|
20
|
+
display: 'flex',
|
|
21
|
+
flexDirection: 'column',
|
|
22
|
+
},
|
|
23
|
+
width: ['60%', '80%', '20%'],
|
|
24
|
+
}}
|
|
25
|
+
title={{
|
|
26
|
+
style: {
|
|
27
|
+
alignSelf: 'center',
|
|
28
|
+
marginBottom: 0,
|
|
29
|
+
},
|
|
30
|
+
width: '50%',
|
|
31
|
+
}}
|
|
32
|
+
/>
|
|
33
|
+
<Skeleton.Button active block />
|
|
34
|
+
<Skeleton
|
|
35
|
+
active
|
|
36
|
+
className={styles.loading}
|
|
37
|
+
paragraph={{
|
|
38
|
+
rows: 1,
|
|
39
|
+
style: {
|
|
40
|
+
alignItems: 'center',
|
|
41
|
+
display: 'flex',
|
|
42
|
+
flexDirection: 'column',
|
|
43
|
+
marginBottom: 0,
|
|
44
|
+
},
|
|
45
|
+
width: ['20%'],
|
|
46
|
+
}}
|
|
47
|
+
title={false}
|
|
48
|
+
/>
|
|
49
|
+
</Center>
|
|
50
|
+
<Center gap={16} style={{ padding: 16 }}>
|
|
51
|
+
<Flexbox gap={16} horizontal>
|
|
52
|
+
<Skeleton.Button active size={'small'} />
|
|
53
|
+
<Skeleton.Button active size={'small'} />
|
|
54
|
+
</Flexbox>
|
|
55
|
+
<Skeleton active paragraph={{ rows: 6 }} title={false} />
|
|
56
|
+
</Center>
|
|
57
|
+
</>
|
|
58
|
+
);
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
export default Loading;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { createStyles } from 'antd-style';
|
|
2
|
+
import { encode } from 'gpt-tokenizer';
|
|
3
|
+
import { memo, useMemo } from 'react';
|
|
4
|
+
|
|
5
|
+
const useStyles = createStyles(
|
|
6
|
+
({ css, token }) => css`
|
|
7
|
+
padding: 2px 5px;
|
|
8
|
+
|
|
9
|
+
font-size: 12px;
|
|
10
|
+
line-height: 1;
|
|
11
|
+
color: ${token.colorBgLayout};
|
|
12
|
+
|
|
13
|
+
background: ${token.colorText};
|
|
14
|
+
border-radius: 12px;
|
|
15
|
+
`,
|
|
16
|
+
);
|
|
17
|
+
|
|
18
|
+
const TokenTag = memo<{ systemRole: string }>(({ systemRole }) => {
|
|
19
|
+
const { styles } = useStyles();
|
|
20
|
+
const value = useMemo(() => encode(systemRole).length, [systemRole]);
|
|
21
|
+
|
|
22
|
+
return <div className={styles}>{value}</div>;
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
export default TokenTag;
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { Markdown, TabsNav } from '@lobehub/ui';
|
|
2
|
+
import { memo, useState } from 'react';
|
|
3
|
+
import { useTranslation } from 'react-i18next';
|
|
4
|
+
import { Flexbox } from 'react-layout-kit';
|
|
5
|
+
|
|
6
|
+
import TokenTag from '@/pages/market/features/SideBar/AgentInfo/TokenTag';
|
|
7
|
+
import { useMarketStore } from '@/store/market';
|
|
8
|
+
|
|
9
|
+
import AgentCardBanner from '../../AgentCard/AgentCardBanner';
|
|
10
|
+
import Comment from './Comment';
|
|
11
|
+
import Header from './Header';
|
|
12
|
+
import Loading from './Loading';
|
|
13
|
+
import { useStyles } from './style';
|
|
14
|
+
|
|
15
|
+
enum InfoTabs {
|
|
16
|
+
comment = 'comment',
|
|
17
|
+
prompt = 'prompt',
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
const AgentModalInner = memo(() => {
|
|
21
|
+
const [useFetchAgent, currentIdentifier] = useMarketStore((s) => [
|
|
22
|
+
s.useFetchAgent,
|
|
23
|
+
s.currentIdentifier,
|
|
24
|
+
]);
|
|
25
|
+
const { styles } = useStyles();
|
|
26
|
+
const { data, isLoading } = useFetchAgent(currentIdentifier);
|
|
27
|
+
const { t } = useTranslation('market');
|
|
28
|
+
const [tab, setTab] = useState<string>(InfoTabs.prompt);
|
|
29
|
+
|
|
30
|
+
if (isLoading || !data?.meta) return <Loading />;
|
|
31
|
+
|
|
32
|
+
const { config, meta, identifier } = data;
|
|
33
|
+
const { systemRole } = config;
|
|
34
|
+
|
|
35
|
+
return (
|
|
36
|
+
<>
|
|
37
|
+
<AgentCardBanner mask meta={meta} size={10} style={{ height: 120, marginBottom: -60 }} />
|
|
38
|
+
<Header />
|
|
39
|
+
<Flexbox align={'center'}>
|
|
40
|
+
<TabsNav
|
|
41
|
+
activeKey={tab}
|
|
42
|
+
className={styles.nav}
|
|
43
|
+
items={[
|
|
44
|
+
{
|
|
45
|
+
key: InfoTabs.prompt,
|
|
46
|
+
label: (
|
|
47
|
+
<Flexbox align={'center'} gap={8} horizontal>
|
|
48
|
+
{t('sidebar.prompt')} <TokenTag systemRole={systemRole} />
|
|
49
|
+
</Flexbox>
|
|
50
|
+
),
|
|
51
|
+
},
|
|
52
|
+
{
|
|
53
|
+
key: InfoTabs.comment,
|
|
54
|
+
label: t('sidebar.comment'),
|
|
55
|
+
},
|
|
56
|
+
]}
|
|
57
|
+
onChange={setTab}
|
|
58
|
+
/>
|
|
59
|
+
</Flexbox>
|
|
60
|
+
<Flexbox style={{ padding: 16 }}>
|
|
61
|
+
{tab === InfoTabs.prompt && <Markdown fullFeaturedCodeBlock>{systemRole}</Markdown>}
|
|
62
|
+
{tab === InfoTabs.comment && <Comment identifier={identifier} />}
|
|
63
|
+
</Flexbox>
|
|
64
|
+
</>
|
|
65
|
+
);
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
export default AgentModalInner;
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { createStyles } from 'antd-style';
|
|
2
|
+
|
|
3
|
+
export const useStyles = createStyles(({ css, token }) => ({
|
|
4
|
+
author: css`
|
|
5
|
+
font-size: 12px;
|
|
6
|
+
`,
|
|
7
|
+
|
|
8
|
+
avatar: css`
|
|
9
|
+
flex: none;
|
|
10
|
+
`,
|
|
11
|
+
container: css`
|
|
12
|
+
position: relative;
|
|
13
|
+
padding: 16px 16px 24px;
|
|
14
|
+
border-bottom: 1px solid ${token.colorBorderSecondary};
|
|
15
|
+
`,
|
|
16
|
+
date: css`
|
|
17
|
+
font-size: 12px;
|
|
18
|
+
color: ${token.colorTextDescription};
|
|
19
|
+
`,
|
|
20
|
+
desc: css`
|
|
21
|
+
color: ${token.colorTextDescription};
|
|
22
|
+
text-align: center;
|
|
23
|
+
`,
|
|
24
|
+
loading: css`
|
|
25
|
+
.ant-skeleton-content {
|
|
26
|
+
display: flex;
|
|
27
|
+
flex-direction: column;
|
|
28
|
+
}
|
|
29
|
+
`,
|
|
30
|
+
nav: css`
|
|
31
|
+
padding-top: 4px;
|
|
32
|
+
|
|
33
|
+
.ant-tabs-tab {
|
|
34
|
+
margin: 4px !important;
|
|
35
|
+
|
|
36
|
+
+ .ant-tabs-tab {
|
|
37
|
+
margin: 4px !important;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
`,
|
|
41
|
+
title: css`
|
|
42
|
+
font-size: 20px;
|
|
43
|
+
font-weight: 600;
|
|
44
|
+
text-align: center;
|
|
45
|
+
`,
|
|
46
|
+
}));
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import { DraggablePanel, DraggablePanelBody, DraggablePanelContainer } from '@lobehub/ui';
|
|
2
|
+
import { createStyles } from 'antd-style';
|
|
3
|
+
import { ReactNode, memo, useState } from 'react';
|
|
4
|
+
|
|
5
|
+
import SafeSpacing from '@/components/SafeSpacing';
|
|
6
|
+
import { MARKET_SIDEBAR_WIDTH } from '@/const/layoutTokens';
|
|
7
|
+
import { agentMarketSelectors, useMarketStore } from '@/store/market';
|
|
8
|
+
|
|
9
|
+
const useStyles = createStyles(({ css, token, stylish }) => ({
|
|
10
|
+
content: css`
|
|
11
|
+
display: flex;
|
|
12
|
+
flex-direction: column;
|
|
13
|
+
`,
|
|
14
|
+
drawer: css`
|
|
15
|
+
background: ${token.colorBgLayout};
|
|
16
|
+
`,
|
|
17
|
+
header: css`
|
|
18
|
+
border-bottom: 1px solid ${token.colorBorder};
|
|
19
|
+
`,
|
|
20
|
+
noScrollbar: stylish.noScrollbar,
|
|
21
|
+
}));
|
|
22
|
+
|
|
23
|
+
const SideBar = memo<{ children: ReactNode }>(({ children }) => {
|
|
24
|
+
const { styles } = useStyles();
|
|
25
|
+
const [tempId, setTempId] = useState<string>('');
|
|
26
|
+
const [showAgentSidebar, deactivateAgent, activateAgent] = useMarketStore((s) => [
|
|
27
|
+
agentMarketSelectors.showSideBar(s),
|
|
28
|
+
s.deactivateAgent,
|
|
29
|
+
s.activateAgent,
|
|
30
|
+
]);
|
|
31
|
+
|
|
32
|
+
return (
|
|
33
|
+
<DraggablePanel
|
|
34
|
+
className={styles.drawer}
|
|
35
|
+
classNames={{
|
|
36
|
+
content: styles.content,
|
|
37
|
+
}}
|
|
38
|
+
expand={showAgentSidebar}
|
|
39
|
+
minWidth={MARKET_SIDEBAR_WIDTH}
|
|
40
|
+
mode={'fixed'}
|
|
41
|
+
onExpandChange={(show) => {
|
|
42
|
+
if (!show) {
|
|
43
|
+
setTempId(useMarketStore.getState().currentIdentifier);
|
|
44
|
+
deactivateAgent();
|
|
45
|
+
} else if (tempId) {
|
|
46
|
+
activateAgent(tempId);
|
|
47
|
+
}
|
|
48
|
+
}}
|
|
49
|
+
placement={'right'}
|
|
50
|
+
>
|
|
51
|
+
<DraggablePanelContainer
|
|
52
|
+
style={{
|
|
53
|
+
flex: 'none',
|
|
54
|
+
height: '100vh',
|
|
55
|
+
minWidth: MARKET_SIDEBAR_WIDTH,
|
|
56
|
+
}}
|
|
57
|
+
>
|
|
58
|
+
<SafeSpacing />
|
|
59
|
+
<DraggablePanelBody
|
|
60
|
+
className={styles.noScrollbar}
|
|
61
|
+
style={{ padding: 0, position: 'relative' }}
|
|
62
|
+
>
|
|
63
|
+
{children}
|
|
64
|
+
</DraggablePanelBody>
|
|
65
|
+
</DraggablePanelContainer>
|
|
66
|
+
</DraggablePanel>
|
|
67
|
+
);
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
export default SideBar;
|