@lobehub/chat 0.76.1 → 0.77.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 (52) hide show
  1. package/.bunfig.toml +3 -0
  2. package/.github/workflows/release.yml +6 -13
  3. package/.github/workflows/sync.yml +1 -1
  4. package/.github/workflows/test.yml +5 -12
  5. package/CHANGELOG.md +50 -0
  6. package/README.md +51 -28
  7. package/README.zh-CN.md +55 -28
  8. package/bun.lockb +0 -0
  9. package/docs/Deploy-with-Azure-OpenAI.md +49 -0
  10. package/docs/{deploy-with-azure-openai.zh-CN.md → Deploy-with-Azure-OpenAI.zh-CN.md} +8 -0
  11. package/docs/Home.md +38 -13
  12. package/docs/{Plugin-Development.en-US.md → Plugin-Development.md} +45 -13
  13. package/docs/Plugin-Development.zh-CN.md +67 -35
  14. package/docs/{Upstream-Sync.en-US.md → Upstream-Sync.md} +4 -3
  15. package/docs/Upstream-Sync.zh-CN.md +4 -3
  16. package/docs/_Sidebar.md +20 -13
  17. package/locales/en_US/common.json +17 -17
  18. package/locales/en_US/market.json +9 -5
  19. package/locales/en_US/setting.json +8 -7
  20. package/locales/en_US/welcome.json +3 -3
  21. package/locales/ru_RU/market.json +6 -2
  22. package/locales/ru_RU/setting.json +2 -1
  23. package/locales/zh_CN/common.json +1 -1
  24. package/locales/zh_CN/empty.json +1 -1
  25. package/locales/zh_CN/error.json +1 -1
  26. package/locales/zh_CN/market.json +6 -2
  27. package/locales/zh_CN/plugin.json +1 -1
  28. package/locales/zh_CN/setting.json +2 -1
  29. package/locales/zh_CN/welcome.json +1 -1
  30. package/next.config.mjs +0 -3
  31. package/package.json +1 -1
  32. package/renovate.json +13 -0
  33. package/src/config/server.ts +2 -0
  34. package/src/const/settings.ts +0 -2
  35. package/src/features/AgentSetting/AgentConfig/index.tsx +2 -10
  36. package/src/locales/default/market.ts +4 -0
  37. package/src/locales/resources/en_US.ts +1 -1
  38. package/src/locales/resources/index.ts +6 -6
  39. package/src/locales/resources/ru_RU.ts +1 -1
  40. package/src/locales/resources/zh_CN.ts +1 -1
  41. package/src/pages/api/openai/chat.api.ts +2 -2
  42. package/src/pages/chat/features/Conversation/ChatList/index.tsx +4 -4
  43. package/src/pages/market/features/AgentCard/index.tsx +24 -5
  44. package/src/pages/market/features/AgentCard/style.ts +8 -1
  45. package/src/pages/market/features/SideBar/Mobile.tsx +1 -1
  46. package/src/pages/market/layout.mobile.tsx +3 -0
  47. package/src/pages/market/layout.tsx +4 -0
  48. package/src/pages/settings/features/Settings/LLM/index.tsx +1 -2
  49. package/src/pages/settings/index.page.tsx +1 -8
  50. package/vercel.json +2 -2
  51. package/.github/workflows/contributor-help.yml +0 -27
  52. package/src/config/client.ts +0 -14
@@ -73,7 +73,8 @@
73
73
  "useAzure": {
74
74
  "desc": "Использование служб OpenAI из Azure",
75
75
  "fetch": "Получить список",
76
- "title": "Azure OpenAI"
76
+ "title": "Azure OpenAI",
77
+ "serverConfig": "Администратор настроил сервер для использования Azure OpenAI. Переключение запрещено."
77
78
  }
78
79
  },
79
80
  "waitingForMore": "<1>Планируется доступ к другим моделям</1>, так что следите за обновлениями ✨"
@@ -82,4 +82,4 @@
82
82
  "updateAgent": "更新助理信息",
83
83
  "updatePrompt": "更新提示词",
84
84
  "warp": "换行"
85
- }
85
+ }
@@ -3,4 +3,4 @@
3
3
  "desc": "点击发送左侧按钮可将当前会话保存为历史话题,并开启新一轮会话",
4
4
  "title": "话题列表"
5
5
  }
6
- }
6
+ }
@@ -38,4 +38,4 @@
38
38
  "title": "输入密码解锁应用"
39
39
  }
40
40
  }
41
- }
41
+ }
@@ -8,5 +8,9 @@
8
8
  "prompt": "提示词",
9
9
  "title": "助手详情"
10
10
  },
11
- "submitAgent": "提交助手"
12
- }
11
+ "submitAgent": "提交助手",
12
+ "title": {
13
+ "recentSubmits": "最近新增",
14
+ "allAgents": "全部助手"
15
+ }
16
+ }
@@ -103,4 +103,4 @@
103
103
  "modalDesc": "配置插件市场的地址后,可以使用自定义的插件市场",
104
104
  "title": "设置插件市场"
105
105
  }
106
- }
106
+ }
@@ -73,6 +73,7 @@
73
73
  "useAzure": {
74
74
  "desc": "使用 Azure 提供的 OpenAI 服务",
75
75
  "fetch": "获取列表",
76
+ "serverConfig": "管理员在服务端配置开启了 Azure OpenAI,禁止切换",
76
77
  "title": "Azure OpenAI"
77
78
  }
78
79
  },
@@ -220,4 +221,4 @@
220
221
  "common": "通用设置",
221
222
  "llm": "语言模型"
222
223
  }
223
- }
224
+ }
@@ -11,4 +11,4 @@
11
11
  "desc2": "创建你的第一个助手,让我们开始吧~",
12
12
  "title": "给自己一个更聪明的大脑"
13
13
  }
14
- }
14
+ }
package/next.config.mjs CHANGED
@@ -14,9 +14,6 @@ const nextConfig = {
14
14
  reactStrictMode: true,
15
15
  pageExtensions: ['page.tsx', 'api.ts'],
16
16
  transpilePackages: ['@lobehub/ui'],
17
- env: {
18
- USE_AZURE_OPENAI: process.env.USE_AZURE_OPENAI === '1',
19
- },
20
17
  webpack(config) {
21
18
  config.experiments = {
22
19
  asyncWebAssembly: true,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lobehub/chat",
3
- "version": "0.76.1",
3
+ "version": "0.77.0",
4
4
  "description": "Lobe Chat is an open-source chatbot client using Vercel AI SDK, Typescript and Next.js",
5
5
  "keywords": [
6
6
  "chatbot",
package/renovate.json ADDED
@@ -0,0 +1,13 @@
1
+ {
2
+ "$schema": "https://docs.renovatebot.com/renovate-schema.json",
3
+ "automerge": false,
4
+ "dependencyDashboard": true,
5
+ "ignoreDeps": [],
6
+ "labels": ["dependencies"],
7
+ "postUpdateOptions": ["yarnDedupeHighest"],
8
+ "prConcurrentLimit": 30,
9
+ "prHourlyLimit": 0,
10
+ "rebaseWhen": "conflicted",
11
+ "schedule": "on sunday before 6:00am",
12
+ "timezone": "UTC"
13
+ }
@@ -7,6 +7,7 @@ declare global {
7
7
  AZURE_API_VERSION?: string;
8
8
  OPENAI_API_KEY?: string;
9
9
  OPENAI_PROXY_URL?: string;
10
+ USE_AZURE_OPENAI?: string;
10
11
  }
11
12
  }
12
13
  }
@@ -25,5 +26,6 @@ export const getServerConfig = () => {
25
26
 
26
27
  OPENAI_API_KEY: process.env.OPENAI_API_KEY,
27
28
  OPENAI_PROXY_URL: process.env.OPENAI_PROXY_URL,
29
+ USE_AZURE_OPENAI: process.env.USE_AZURE_OPENAI === '1',
28
30
  };
29
31
  };
@@ -1,4 +1,3 @@
1
- import { getClientConfig } from '@/config/client';
2
1
  import { DEFAULT_OPENAI_MODEL_LIST } from '@/const/llm';
3
2
  import { DEFAULT_AGENT_META } from '@/const/meta';
4
3
  import { LanguageModel } from '@/types/llm';
@@ -38,7 +37,6 @@ export const DEFAULT_LLM_CONFIG: GlobalLLMConfig = {
38
37
  openAI: {
39
38
  OPENAI_API_KEY: '',
40
39
  models: DEFAULT_OPENAI_MODEL_LIST,
41
- useAzure: getClientConfig().USE_AZURE_OPENAI,
42
40
  },
43
41
  };
44
42
 
@@ -33,6 +33,7 @@ const AgentConfig = memo(() => {
33
33
  children: (
34
34
  <SelectWithImg
35
35
  height={86}
36
+ onChange={(mode) => updateConfig({ displayMode: mode })}
36
37
  options={[
37
38
  {
38
39
  icon: MessagesSquare,
@@ -47,21 +48,12 @@ const AgentConfig = memo(() => {
47
48
  value: 'docs',
48
49
  },
49
50
  ]}
50
- styles={{
51
- img: {
52
- background: `linear-gradient(
53
- to bottom,
54
- ${isDarkMode ? theme.colorBgElevated : theme.colorBgLayout},
55
- ${theme.colorBgContainer}
56
- )`,
57
- },
58
- }}
51
+ value={config.displayMode}
59
52
  width={144}
60
53
  />
61
54
  ),
62
55
  label: t('settingChat.chatStyleType.title'),
63
56
  minWidth: undefined,
64
- name: 'displayMode',
65
57
  },
66
58
  {
67
59
  children: <Input placeholder={t('settingChat.inputTemplate.placeholder')} />,
@@ -9,4 +9,8 @@ export default {
9
9
  title: '助手详情',
10
10
  },
11
11
  submitAgent: '提交助手',
12
+ title: {
13
+ allAgents: '全部助手',
14
+ recentSubmits: '最近新增',
15
+ },
12
16
  };
@@ -13,7 +13,7 @@ const resources = {
13
13
  market,
14
14
  plugin,
15
15
  setting,
16
- welcome,
16
+ welcome
17
17
  } as const;
18
18
 
19
19
  export default resources;
@@ -1,11 +1,11 @@
1
- import en_US from './en_US';
2
- import ru_RU from './ru_RU';
3
- import zh_CN from './zh_CN';
1
+ import zh_CN from "./zh_CN";
2
+ import en_US from "./en_US";
3
+ import ru_RU from "./ru_RU";
4
4
 
5
5
  const resources = {
6
- 'en-US': en_US,
7
- 'ru-RU': ru_RU,
8
- 'zh-CN': zh_CN,
6
+ "en-US": en_US,
7
+ "ru-RU": ru_RU,
8
+ "zh-CN": zh_CN,
9
9
  } as const;
10
10
  export default resources;
11
11
  export const defaultResources = zh_CN;
@@ -13,7 +13,7 @@ const resources = {
13
13
  market,
14
14
  plugin,
15
15
  setting,
16
- welcome,
16
+ welcome
17
17
  } as const;
18
18
 
19
19
  export default resources;
@@ -13,7 +13,7 @@ const resources = {
13
13
  market,
14
14
  plugin,
15
15
  setting,
16
- welcome,
16
+ welcome
17
17
  } as const;
18
18
 
19
19
  export default resources;
@@ -1,6 +1,6 @@
1
1
  import OpenAI from 'openai';
2
2
 
3
- import { getClientConfig } from '@/config/client';
3
+ import { getServerConfig } from '@/config/server';
4
4
  import { getOpenAIAuthFromRequest } from '@/const/fetch';
5
5
  import { ErrorType } from '@/types/fetch';
6
6
  import { OpenAIStreamPayload } from '@/types/openai';
@@ -26,7 +26,7 @@ export default async function handler(req: Request) {
26
26
 
27
27
  let openai: OpenAI;
28
28
 
29
- const { USE_AZURE_OPENAI } = getClientConfig();
29
+ const { USE_AZURE_OPENAI } = getServerConfig();
30
30
  const useAzureOpenAI = useAzure || USE_AZURE_OPENAI;
31
31
 
32
32
  if (useAzureOpenAI) {
@@ -67,9 +67,9 @@ const List = () => {
67
67
  [chatLoadingId],
68
68
  );
69
69
 
70
- return !init ? (
71
- <SkeletonList />
72
- ) : (
70
+ if (!init) return <SkeletonList />;
71
+
72
+ return (
73
73
  <ChatList
74
74
  data={data}
75
75
  loadingId={chatLoadingId}
@@ -102,7 +102,7 @@ const List = () => {
102
102
  edit: t('edit'),
103
103
  regenerate: t('regenerate'),
104
104
  }}
105
- type={displayMode}
105
+ type={displayMode || 'chat'}
106
106
  />
107
107
  );
108
108
  };
@@ -1,22 +1,28 @@
1
1
  import { SpotlightCard } from '@lobehub/ui';
2
+ import { useResponsive } from 'antd-style';
3
+ import { shuffle } from 'lodash-es';
2
4
  import { memo, useMemo } from 'react';
5
+ import { useTranslation } from 'react-i18next';
6
+ import { Flexbox } from 'react-layout-kit';
3
7
 
4
8
  import { agentMarketSelectors, useMarketStore } from '@/store/market';
5
9
 
6
10
  import TagList from '../TagList';
7
11
  import AgentCardItem from './AgentCardItem';
8
12
  import Loading from './Loading';
13
+ import { useStyles } from './style';
9
14
 
10
15
  const gridRender = (item: any) => <AgentCardItem {...item} />;
11
16
 
12
17
  const AgentCard = memo(() => {
18
+ const { mobile } = useResponsive();
13
19
  const agentList = useMarketStore(agentMarketSelectors.getAgentList);
14
-
20
+ const { t } = useTranslation('market');
15
21
  const [useFetchAgentList, keywords] = useMarketStore((s) => [
16
22
  s.useFetchAgentList,
17
23
  s.searchKeywords,
18
24
  ]);
19
-
25
+ const { styles } = useStyles();
20
26
  const { isLoading } = useFetchAgentList();
21
27
 
22
28
  const agentListData = useMemo(() => {
@@ -27,10 +33,23 @@ const AgentCard = memo(() => {
27
33
  if (isLoading || !agentList) return <Loading />;
28
34
 
29
35
  return (
30
- <>
36
+ <Flexbox gap={mobile ? 16 : 24}>
31
37
  <TagList />
32
- <SpotlightCard items={agentListData} renderItem={gridRender} />
33
- </>
38
+ {keywords ? (
39
+ <SpotlightCard items={agentListData} renderItem={gridRender} spotlight={false} />
40
+ ) : (
41
+ <>
42
+ <div className={styles.subTitle}>{t('title.recentSubmits')}</div>
43
+ <SpotlightCard items={agentListData.slice(0, 3)} renderItem={gridRender} />
44
+ <div className={styles.subTitle}>{t('title.allAgents')}</div>
45
+ <SpotlightCard
46
+ items={shuffle(agentListData.slice(3))}
47
+ renderItem={gridRender}
48
+ spotlight={false}
49
+ />
50
+ </>
51
+ )}
52
+ </Flexbox>
34
53
  );
35
54
  });
36
55
 
@@ -1,6 +1,6 @@
1
1
  import { createStyles } from 'antd-style';
2
2
 
3
- export const useStyles = createStyles(({ css, token }) => ({
3
+ export const useStyles = createStyles(({ css, token, responsive }) => ({
4
4
  avatar: css``,
5
5
 
6
6
  container: css`
@@ -14,6 +14,13 @@ export const useStyles = createStyles(({ css, token }) => ({
14
14
  inner: css`
15
15
  padding: 16px;
16
16
  `,
17
+ subTitle: css`
18
+ font-size: 24px;
19
+ font-weight: 600;
20
+ ${responsive.mobile} {
21
+ font-size: 20px;
22
+ }
23
+ `,
17
24
  title: css`
18
25
  margin-bottom: 0 !important;
19
26
  font-size: 16px;
@@ -20,7 +20,7 @@ const Mobile = memo<PropsWithChildren>(({ children }) => {
20
20
  <Drawer
21
21
  bodyStyle={{ padding: 0 }}
22
22
  closeIcon={<ActionIcon icon={X} size={{ blockSize: 32, fontSize: 20 }} />}
23
- drawerStyle={{ background: theme.colorBgContainer }}
23
+ drawerStyle={{ background: theme.colorBgLayout }}
24
24
  headerStyle={{ padding: '8px 4px' }}
25
25
  height={'75vh'}
26
26
  onClose={deactivateAgent}
@@ -3,10 +3,13 @@ import { Flexbox } from 'react-layout-kit';
3
3
 
4
4
  import AppMobileLayout from '@/layout/AppMobileLayout';
5
5
  import SideBar from '@/pages/market/features/SideBar';
6
+ import { useSwitchSideBarOnInit } from '@/store/global';
6
7
 
7
8
  import Header from './features/Header';
8
9
 
9
10
  const MarketLayout = memo<{ children: ReactNode }>(({ children }) => {
11
+ useSwitchSideBarOnInit('market');
12
+
10
13
  return (
11
14
  <AppMobileLayout navBar={<Header />} showTabBar>
12
15
  <Flexbox flex={1} gap={16} style={{ padding: 16 }}>
@@ -5,6 +5,7 @@ import { Center, Flexbox } from 'react-layout-kit';
5
5
 
6
6
  import SafeSpacing from '@/components/SafeSpacing';
7
7
  import { MAX_WIDTH } from '@/const/layoutTokens';
8
+ import { useSwitchSideBarOnInit } from '@/store/global';
8
9
 
9
10
  import AppLayout from '../../layout/AppLayout';
10
11
  import Header from './features/Header';
@@ -25,6 +26,9 @@ const useStyles = createStyles(({ css }) => ({
25
26
 
26
27
  const MarketLayout = memo<PropsWithChildren>(({ children }) => {
27
28
  const { theme, styles } = useStyles();
29
+
30
+ useSwitchSideBarOnInit('market');
31
+
28
32
  return (
29
33
  <AppLayout>
30
34
  <Flexbox
@@ -8,7 +8,6 @@ import { memo } from 'react';
8
8
  import { Trans, useTranslation } from 'react-i18next';
9
9
  import { Flexbox } from 'react-layout-kit';
10
10
 
11
- import { getClientConfig } from '@/config/client';
12
11
  import { FORM_STYLE } from '@/const/layoutTokens';
13
12
  import { globalSelectors, useEffectAfterGlobalHydrated, useGlobalStore } from '@/store/global';
14
13
 
@@ -83,7 +82,7 @@ const LLM = memo(() => {
83
82
  },
84
83
  {
85
84
  children: (
86
- <Switch disabled={getClientConfig().USE_AZURE_OPENAI} />
85
+ <Switch />
87
86
  // <Flexbox gap={4}>
88
87
  // <div>
89
88
  //
@@ -3,16 +3,13 @@ import Head from 'next/head';
3
3
  import { memo } from 'react';
4
4
  import { useTranslation } from 'react-i18next';
5
5
 
6
- import { createI18nNext } from '@/locales/create';
7
- import { useOnFinishHydrationGlobal, useSwitchSideBarOnInit } from '@/store/global';
6
+ import { useSwitchSideBarOnInit } from '@/store/global';
8
7
  import { genSiteHeadTitle } from '@/utils/genSiteHeadTitle';
9
8
 
10
9
  import Settings from './features/Settings';
11
10
  import DesktopLayout from './layout';
12
11
  import MobileLayout from './layout.mobile';
13
12
 
14
- const initI18n = createI18nNext({ namespace: 'setting' });
15
-
16
13
  const Setting = memo(() => {
17
14
  const { mobile } = useResponsive();
18
15
  const { t } = useTranslation('setting');
@@ -22,10 +19,6 @@ const Setting = memo(() => {
22
19
 
23
20
  useSwitchSideBarOnInit('settings');
24
21
 
25
- useOnFinishHydrationGlobal(() => {
26
- initI18n.then(() => {});
27
- });
28
-
29
22
  return (
30
23
  <>
31
24
  <Head>
package/vercel.json CHANGED
@@ -1,3 +1,3 @@
1
1
  {
2
- "installCommand": "pnpm i"
3
- }
2
+ "installCommand": "/bun1/bun install"
3
+ }
@@ -1,27 +0,0 @@
1
- name: Contributor Helper
2
-
3
- on:
4
- schedule: [{ cron: '0 18 * * *' }]
5
- workflow_dispatch:
6
- jobs:
7
- contributor:
8
- runs-on: ubuntu-latest
9
- steps:
10
- - uses: actions/checkout@master
11
-
12
- - uses: actions-cool/contributor-helper@v1
13
- with:
14
- token: ${{ secrets.GH_TOKEN }}
15
- style: 'simple'
16
- update-files: 'README.md, README.zh-CN.md'
17
- update-places: '<!-- CONTRIBUTION GROUP -->/<!-- CONTRIBUTION END -->, <!-- CONTRIBUTION GROUP -->/<!-- CONTRIBUTION END -->'
18
-
19
- - name: Commit and push if changed
20
- run: |-
21
- git diff
22
- git config --global user.name "lobehubbot"
23
- git config --global user.email "i@lobehub.com"
24
- git pull
25
- git add -A
26
- git commit -m "🤖 docs: Auto update contributors" || exit 0
27
- git push
@@ -1,14 +0,0 @@
1
- declare global {
2
- // eslint-disable-next-line @typescript-eslint/no-namespace
3
- namespace NodeJS {
4
- interface ProcessEnv {
5
- USE_AZURE_OPENAI?: boolean;
6
- }
7
- }
8
- }
9
-
10
- export const getClientConfig = () => {
11
- return {
12
- USE_AZURE_OPENAI: process.env.USE_AZURE_OPENAI,
13
- };
14
- };