@lobehub/chat 0.160.5 → 0.160.7

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 (60) hide show
  1. package/CHANGELOG.md +65 -0
  2. package/locales/ar/error.json +2 -0
  3. package/locales/bg-BG/error.json +2 -0
  4. package/locales/de-DE/error.json +2 -0
  5. package/locales/en-US/error.json +2 -0
  6. package/locales/es-ES/error.json +2 -0
  7. package/locales/fr-FR/error.json +2 -0
  8. package/locales/it-IT/error.json +2 -0
  9. package/locales/ja-JP/error.json +2 -0
  10. package/locales/ko-KR/error.json +2 -0
  11. package/locales/nl-NL/error.json +2 -0
  12. package/locales/pl-PL/error.json +2 -0
  13. package/locales/pt-BR/error.json +2 -0
  14. package/locales/ru-RU/error.json +2 -0
  15. package/locales/tr-TR/error.json +2 -0
  16. package/locales/vi-VN/error.json +2 -0
  17. package/locales/zh-CN/error.json +2 -0
  18. package/locales/zh-TW/error.json +2 -0
  19. package/package.json +2 -2
  20. package/src/app/(loading)/Redirect.tsx +8 -0
  21. package/src/app/(main)/chat/(workspace)/features/TelemetryNotification.tsx +42 -75
  22. package/src/app/(main)/market/_layout/Desktop/index.tsx +24 -20
  23. package/src/app/(main)/settings/llm/Azure/index.tsx +1 -0
  24. package/src/app/(main)/settings/llm/OpenAI/index.tsx +0 -1
  25. package/src/app/trpc/edge/[trpc]/route.ts +1 -1
  26. package/src/components/FetchErrorNotification/Description.tsx +48 -0
  27. package/src/components/FetchErrorNotification/index.tsx +15 -0
  28. package/src/components/ModelProviderIcon/index.tsx +6 -1
  29. package/src/components/Notification/index.tsx +95 -0
  30. package/src/config/server/provider.ts +1 -0
  31. package/src/database/client/models/__tests__/message.test.ts +2 -2
  32. package/src/database/client/models/message.ts +2 -2
  33. package/src/features/ModelSwitchPanel/index.tsx +6 -3
  34. package/src/features/User/UserAvatar.tsx +4 -3
  35. package/src/locales/default/error.ts +3 -1
  36. package/src/middleware.ts +10 -1
  37. package/src/server/globalConfig/index.ts +2 -0
  38. package/src/server/routers/edge/config/__snapshots__/index.test.ts.snap +1 -0
  39. package/src/services/file/type.ts +2 -3
  40. package/src/services/message/client.test.ts +151 -23
  41. package/src/services/message/client.ts +9 -5
  42. package/src/services/message/type.ts +10 -3
  43. package/src/services/upload.ts +4 -4
  44. package/src/services/user/client.ts +17 -1
  45. package/src/services/user/type.ts +14 -0
  46. package/src/store/agent/slices/chat/selectors.test.ts +2 -2
  47. package/src/store/agent/slices/chat/selectors.ts +1 -1
  48. package/src/store/chat/slices/enchance/action.test.ts +4 -3
  49. package/src/store/chat/slices/enchance/action.ts +3 -2
  50. package/src/store/chat/slices/plugin/action.test.ts +3 -5
  51. package/src/store/chat/slices/plugin/action.ts +1 -1
  52. package/src/store/market/action.ts +7 -0
  53. package/src/store/user/slices/auth/selectors.ts +1 -1
  54. package/src/store/user/slices/preference/action.test.ts +4 -9
  55. package/src/store/user/slices/preference/action.ts +17 -20
  56. package/src/store/user/slices/settings/selectors/modelConfig.test.ts +29 -1
  57. package/src/store/user/slices/settings/selectors/modelConfig.ts +1 -1
  58. package/src/tools/dalle/Render/Item/Error.tsx +1 -1
  59. package/src/types/files.ts +33 -0
  60. /package/src/types/{user.ts → user/index.ts} +0 -0
package/CHANGELOG.md CHANGED
@@ -2,6 +2,71 @@
2
2
 
3
3
  # Changelog
4
4
 
5
+ ### [Version 0.160.7](https://github.com/lobehub/lobe-chat/compare/v0.160.6...v0.160.7)
6
+
7
+ <sup>Released on **2024-05-21**</sup>
8
+
9
+ #### 🐛 Bug Fixes
10
+
11
+ - **misc**: Fix duplicate model panel key.
12
+
13
+ <br/>
14
+
15
+ <details>
16
+ <summary><kbd>Improvements and Fixes</kbd></summary>
17
+
18
+ #### What's fixed
19
+
20
+ - **misc**: Fix duplicate model panel key, closes [#2591](https://github.com/lobehub/lobe-chat/issues/2591) ([c733fcf](https://github.com/lobehub/lobe-chat/commit/c733fcf))
21
+
22
+ </details>
23
+
24
+ <div align="right">
25
+
26
+ [![](https://img.shields.io/badge/-BACK_TO_TOP-151515?style=flat-square)](#readme-top)
27
+
28
+ </div>
29
+
30
+ ### [Version 0.160.6](https://github.com/lobehub/lobe-chat/compare/v0.160.5...v0.160.6)
31
+
32
+ <sup>Released on **2024-05-21**</sup>
33
+
34
+ #### ♻ Code Refactoring
35
+
36
+ - **misc**: Refactor a Notification component, refactor code, refactor message action, refactor the type, refactor user preference.
37
+
38
+ #### 💄 Styles
39
+
40
+ - **misc**: Add ENABLED_OPENAI env, add fetch error notification, improve openai fetch client switch, improve redirect when login.
41
+
42
+ <br/>
43
+
44
+ <details>
45
+ <summary><kbd>Improvements and Fixes</kbd></summary>
46
+
47
+ #### Code refactoring
48
+
49
+ - **misc**: Refactor a Notification component ([28db3d5](https://github.com/lobehub/lobe-chat/commit/28db3d5))
50
+ - **misc**: Refactor code, closes [#2584](https://github.com/lobehub/lobe-chat/issues/2584) ([086244c](https://github.com/lobehub/lobe-chat/commit/086244c))
51
+ - **misc**: Refactor message action ([224bd67](https://github.com/lobehub/lobe-chat/commit/224bd67))
52
+ - **misc**: Refactor the type ([ddf1abf](https://github.com/lobehub/lobe-chat/commit/ddf1abf))
53
+ - **misc**: Refactor user preference ([1823b0d](https://github.com/lobehub/lobe-chat/commit/1823b0d))
54
+
55
+ #### Styles
56
+
57
+ - **misc**: Add ENABLED_OPENAI env ([35f6230](https://github.com/lobehub/lobe-chat/commit/35f6230))
58
+ - **misc**: Add fetch error notification ([0186b4b](https://github.com/lobehub/lobe-chat/commit/0186b4b))
59
+ - **misc**: Improve openai fetch client switch ([3cad470](https://github.com/lobehub/lobe-chat/commit/3cad470))
60
+ - **misc**: Improve redirect when login ([cb26655](https://github.com/lobehub/lobe-chat/commit/cb26655))
61
+
62
+ </details>
63
+
64
+ <div align="right">
65
+
66
+ [![](https://img.shields.io/badge/-BACK_TO_TOP-151515?style=flat-square)](#readme-top)
67
+
68
+ </div>
69
+
5
70
  ### [Version 0.160.5](https://github.com/lobehub/lobe-chat/compare/v0.160.4...v0.160.5)
6
71
 
7
72
  <sup>Released on **2024-05-20**</sup>
@@ -12,6 +12,8 @@
12
12
  "retry": "إعادة التحميل",
13
13
  "title": "واجهت الصفحة مشكلة ما.."
14
14
  },
15
+ "fetchError": "فشل الطلب",
16
+ "fetchErrorDetail": "تفاصيل الخطأ",
15
17
  "notFound": {
16
18
  "backHome": "العودة إلى الصفحة الرئيسية",
17
19
  "desc": "لم نتمكن من العثور على الصفحة التي تبحث عنها، يرجى التحقق مما إذا كان الرابط صحيحًا",
@@ -12,6 +12,8 @@
12
12
  "retry": "Опитай отново",
13
13
  "title": "Страницата се е сблъскала с проблем.."
14
14
  },
15
+ "fetchError": "Грешка при извличане",
16
+ "fetchErrorDetail": "Подробности за грешката",
15
17
  "notFound": {
16
18
  "backHome": "Върни се в началото",
17
19
  "desc": "Не можем да намерим страницата, която търсите. Моля, проверете дали връзката е правилна.",
@@ -12,6 +12,8 @@
12
12
  "retry": "Erneut laden",
13
13
  "title": "Ein Problem ist aufgetreten auf der Seite.."
14
14
  },
15
+ "fetchError": "Anforderung fehlgeschlagen",
16
+ "fetchErrorDetail": "Fehlerdetails",
15
17
  "notFound": {
16
18
  "backHome": "Zurück zur Startseite",
17
19
  "desc": "Die von Ihnen gesuchte Seite konnte nicht gefunden werden. Bitte überprüfen Sie, ob der Link korrekt ist.",
@@ -12,6 +12,8 @@
12
12
  "retry": "Reload",
13
13
  "title": "Oops, something went wrong.."
14
14
  },
15
+ "fetchError": "Request Failed",
16
+ "fetchErrorDetail": "Error Details",
15
17
  "notFound": {
16
18
  "backHome": "Back to Home",
17
19
  "desc": "We couldn't find the page you're looking for, please check if the link is correct",
@@ -12,6 +12,8 @@
12
12
  "retry": "Reintentar",
13
13
  "title": "Se ha producido un problema en la página.."
14
14
  },
15
+ "fetchError": "Error en la solicitud",
16
+ "fetchErrorDetail": "Detalles del error",
15
17
  "notFound": {
16
18
  "backHome": "Volver a la página de inicio",
17
19
  "desc": "No podemos encontrar la página que estás buscando, por favor verifica si el enlace es correcto",
@@ -12,6 +12,8 @@
12
12
  "retry": "Recharger",
13
13
  "title": "Un problème est survenu sur la page.."
14
14
  },
15
+ "fetchError": "Échec de la requête",
16
+ "fetchErrorDetail": "Détails de l'erreur",
15
17
  "notFound": {
16
18
  "backHome": "Retour à la page d'accueil",
17
19
  "desc": "La page que vous recherchez est introuvable. Veuillez vérifier si le lien est correct.",
@@ -12,6 +12,8 @@
12
12
  "retry": "Ricarica",
13
13
  "title": "La pagina ha riscontrato un problema.."
14
14
  },
15
+ "fetchError": "Errore di richiesta",
16
+ "fetchErrorDetail": "Dettagli dell'errore",
15
17
  "notFound": {
16
18
  "backHome": "Torna alla homepage",
17
19
  "desc": "Non riusciamo a trovare la pagina che stai cercando, controlla che il link sia corretto",
@@ -12,6 +12,8 @@
12
12
  "retry": "再読み込み",
13
13
  "title": "ページに問題が発生しました.."
14
14
  },
15
+ "fetchError": "リクエストが失敗しました",
16
+ "fetchErrorDetail": "エラーの詳細",
15
17
  "notFound": {
16
18
  "backHome": "ホームに戻る",
17
19
  "desc": "お探しのページが見つかりません。リンクが正しいかどうかをご確認ください",
@@ -12,6 +12,8 @@
12
12
  "retry": "다시 시도",
13
13
  "title": "페이지에서 문제가 발생했습니다."
14
14
  },
15
+ "fetchError": "요청 실패",
16
+ "fetchErrorDetail": "오류 상세",
15
17
  "notFound": {
16
18
  "backHome": "홈페이지로 돌아가기",
17
19
  "desc": "찾고 있는 페이지를 찾을 수 없습니다. 링크가 올바른지 확인해주세요.",
@@ -12,6 +12,8 @@
12
12
  "retry": "Opnieuw proberen",
13
13
  "title": "Er is een probleem opgetreden op de pagina.."
14
14
  },
15
+ "fetchError": "Verzoek mislukt",
16
+ "fetchErrorDetail": "Foutdetails",
15
17
  "notFound": {
16
18
  "backHome": "Terug naar startpagina",
17
19
  "desc": "We kunnen de pagina die je zoekt niet vinden, controleer of de link juist is",
@@ -12,6 +12,8 @@
12
12
  "retry": "Ponów próbę",
13
13
  "title": "Napotkano problem na stronie.."
14
14
  },
15
+ "fetchError": "Błąd żądania",
16
+ "fetchErrorDetail": "Szczegóły błędu",
15
17
  "notFound": {
16
18
  "backHome": "Powrót do strony głównej",
17
19
  "desc": "Nie możemy odnaleźć strony, której szukasz. Sprawdź, czy link jest poprawny.",
@@ -12,6 +12,8 @@
12
12
  "retry": "Tentar novamente",
13
13
  "title": "Ocorreu um problema na página.."
14
14
  },
15
+ "fetchError": "Falha na solicitação",
16
+ "fetchErrorDetail": "Detalhes do erro",
15
17
  "notFound": {
16
18
  "backHome": "Voltar para a página inicial",
17
19
  "desc": "Não conseguimos encontrar a página que você está procurando, por favor, verifique se o link está correto",
@@ -12,6 +12,8 @@
12
12
  "retry": "Повторить попытку",
13
13
  "title": "Произошла проблема на странице.."
14
14
  },
15
+ "fetchError": "Ошибка запроса",
16
+ "fetchErrorDetail": "Подробности ошибки",
15
17
  "notFound": {
16
18
  "backHome": "Вернуться на главную",
17
19
  "desc": "Мы не можем найти страницу, которую вы ищете. Пожалуйста, проверьте правильность ссылки",
@@ -12,6 +12,8 @@
12
12
  "retry": "Yeniden Yükle",
13
13
  "title": "Sayfa bir sorunla karşılaştı.."
14
14
  },
15
+ "fetchError": "İstek başarısız oldu",
16
+ "fetchErrorDetail": "Hata detayı",
15
17
  "notFound": {
16
18
  "backHome": "Ana Sayfaya Dön",
17
19
  "desc": "Aradığınız sayfayı bulamadık, lütfen bağlantının doğru olduğundan emin olun",
@@ -12,6 +12,8 @@
12
12
  "retry": "Thử lại",
13
13
  "title": "Trang gặp một chút vấn đề.."
14
14
  },
15
+ "fetchError": "Yêu cầu thất bại",
16
+ "fetchErrorDetail": "Chi tiết lỗi",
15
17
  "notFound": {
16
18
  "backHome": "Quay về Trang chủ",
17
19
  "desc": "Chúng tôi không thể tìm thấy trang bạn đang tìm, vui lòng kiểm tra xem liên kết có đúng không",
@@ -12,6 +12,8 @@
12
12
  "retry": "重新加载",
13
13
  "title": "页面遇到一点问题.."
14
14
  },
15
+ "fetchError": "请求失败",
16
+ "fetchErrorDetail": "错误详情",
15
17
  "notFound": {
16
18
  "backHome": "返回首页",
17
19
  "desc": "我们找不到你正在寻找的页面,请检查链接是否正确",
@@ -12,6 +12,8 @@
12
12
  "retry": "重新加載",
13
13
  "title": "頁面遇到一點問題.."
14
14
  },
15
+ "fetchError": "請求失敗",
16
+ "fetchErrorDetail": "錯誤詳情",
15
17
  "notFound": {
16
18
  "backHome": "返回首頁",
17
19
  "desc": "我們找不到您正在尋找的頁面,請檢查連結是否正確",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lobehub/chat",
3
- "version": "0.160.5",
3
+ "version": "0.160.7",
4
4
  "description": "Lobe Chat - an open-source, high-performance chatbot framework that supports speech synthesis, multimodal, and extensible Function Call plugin system. Supports one-click free deployment of your private ChatGPT/LLM web application.",
5
5
  "keywords": [
6
6
  "framework",
@@ -98,7 +98,7 @@
98
98
  "@lobehub/chat-plugins-gateway": "latest",
99
99
  "@lobehub/icons": "^1.21.0",
100
100
  "@lobehub/tts": "latest",
101
- "@lobehub/ui": "^1.138.24",
101
+ "@lobehub/ui": "^1.138.26",
102
102
  "@microsoft/fetch-event-source": "^2.0.1",
103
103
  "@next/third-parties": "^14.2.3",
104
104
  "@sentry/nextjs": "^7.114.0",
@@ -5,6 +5,8 @@ import { memo, useEffect } from 'react';
5
5
 
6
6
  import { messageService } from '@/services/message';
7
7
  import { sessionService } from '@/services/session';
8
+ import { useUserStore } from '@/store/user';
9
+ import { authSelectors } from '@/store/user/selectors';
8
10
 
9
11
  const checkHasConversation = async () => {
10
12
  const hasMessages = await messageService.hasMessages();
@@ -14,8 +16,14 @@ const checkHasConversation = async () => {
14
16
 
15
17
  const Redirect = memo(() => {
16
18
  const router = useRouter();
19
+ const isLogin = useUserStore(authSelectors.isLogin);
17
20
 
18
21
  useEffect(() => {
22
+ if (!isLogin) {
23
+ router.replace('/welcome');
24
+ return;
25
+ }
26
+
19
27
  checkHasConversation().then((hasData) => {
20
28
  if (hasData) {
21
29
  router.replace('/chat');
@@ -5,58 +5,29 @@ import { Button } from 'antd';
5
5
  import { createStyles } from 'antd-style';
6
6
  import { LucideArrowUpRightFromSquare, TelescopeIcon } from 'lucide-react';
7
7
  import Link from 'next/link';
8
- import { rgba } from 'polished';
9
8
  import { memo } from 'react';
10
9
  import { useTranslation } from 'react-i18next';
11
10
  import { Flexbox } from 'react-layout-kit';
12
11
 
12
+ import Notification from '@/components/Notification';
13
13
  import { PRIVACY_URL } from '@/const/url';
14
14
  import { useServerConfigStore } from '@/store/serverConfig';
15
15
  import { serverConfigSelectors } from '@/store/serverConfig/selectors';
16
16
  import { useUserStore } from '@/store/user';
17
17
  import { preferenceSelectors } from '@/store/user/selectors';
18
18
 
19
- const useStyles = createStyles(({ css, token, isDarkMode }) => ({
20
- container: css`
21
- position: absolute;
22
- z-index: 1100;
23
- bottom: 16px;
24
- inset-inline-end: 20px;
25
-
26
- overflow: hidden;
27
-
28
- width: 422px;
29
-
30
- background: ${token.colorBgContainer};
31
- border: 1px solid ${token.colorSplit};
32
- border-radius: 8px;
33
- box-shadow: ${token.boxShadowSecondary};
34
- `,
19
+ const useStyles = createStyles(({ css, token }) => ({
35
20
  desc: css`
36
21
  color: ${token.colorTextSecondary};
37
22
  `,
38
- mobileContainer: css`
39
- bottom: 8px;
40
- inset-inline-start: 8px;
41
- width: calc(100% - 16px);
42
- `,
43
23
  title: css`
44
24
  font-size: 18px;
45
25
  font-weight: bold;
46
26
  `,
47
- wrapper: css`
48
- padding: 20px 20px 16px;
49
- background: linear-gradient(
50
- 180deg,
51
- ${rgba(token.colorBgContainer, 0)},
52
- ${token.colorBgContainer} ${isDarkMode ? '80' : '140'}px
53
- ),
54
- url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24'%3E%3Cg fill='${token.colorFillTertiary}' %3E %3Cpolygon fill-rule='evenodd' points='8 4 12 6 8 8 6 12 4 8 0 6 4 4 6 0 8 4'/%3E%3C/g%3E%3C/svg%3E");
55
- `,
56
27
  }));
57
28
 
58
29
  const TelemetryNotification = memo<{ mobile?: boolean }>(({ mobile }) => {
59
- const { styles, theme, cx } = useStyles();
30
+ const { styles, theme } = useStyles();
60
31
 
61
32
  const { t } = useTranslation('common');
62
33
  const shouldCheck = useServerConfigStore(serverConfigSelectors.enabledTelemetryChat);
@@ -75,51 +46,47 @@ const TelemetryNotification = memo<{ mobile?: boolean }>(({ mobile }) => {
75
46
  };
76
47
 
77
48
  return (
78
- showModal && (
79
- <Flexbox className={cx(styles.container, mobile && styles.mobileContainer)}>
80
- <Flexbox className={styles.wrapper} gap={16} horizontal>
81
- <Flexbox>
82
- <Avatar
83
- avatar={<TelescopeIcon />}
84
- background={theme.geekblue1}
85
- style={{ color: theme.geekblue7 }}
86
- ></Avatar>
87
- </Flexbox>
88
- <Flexbox gap={16}>
89
- <Flexbox gap={12}>
90
- <Flexbox className={styles.title}>{t('telemetry.title')}</Flexbox>
91
- <div className={styles.desc}>
92
- {t('telemetry.desc')}
93
- <span>
94
- <Link href={PRIVACY_URL} target={'_blank'}>
95
- {t('telemetry.learnMore')}
96
- <Icon icon={LucideArrowUpRightFromSquare} style={{ marginInlineStart: 4 }} />
97
- </Link>
98
- </span>
99
- </div>
100
- </Flexbox>
101
- <Flexbox gap={8} horizontal>
102
- <Button
103
- onClick={() => {
104
- updateTelemetry(true);
105
- }}
106
- type={'primary'}
107
- >
108
- {t('telemetry.allow')}
109
- </Button>
110
- <Button
111
- onClick={() => {
112
- updateTelemetry(false);
113
- }}
114
- type={'text'}
115
- >
116
- {t('telemetry.deny')}
117
- </Button>
118
- </Flexbox>
119
- </Flexbox>
49
+ <Notification mobile={mobile} show={showModal} showCloseIcon={false}>
50
+ <Flexbox>
51
+ <Avatar
52
+ avatar={<TelescopeIcon />}
53
+ background={theme.geekblue1}
54
+ style={{ color: theme.geekblue7 }}
55
+ ></Avatar>
56
+ </Flexbox>
57
+ <Flexbox gap={16}>
58
+ <Flexbox gap={12}>
59
+ <Flexbox className={styles.title}>{t('telemetry.title')}</Flexbox>
60
+ <div className={styles.desc}>
61
+ {t('telemetry.desc')}
62
+ <span>
63
+ <Link href={PRIVACY_URL} target={'_blank'}>
64
+ {t('telemetry.learnMore')}
65
+ <Icon icon={LucideArrowUpRightFromSquare} style={{ marginInlineStart: 4 }} />
66
+ </Link>
67
+ </span>
68
+ </div>
69
+ </Flexbox>
70
+ <Flexbox gap={8} horizontal>
71
+ <Button
72
+ onClick={() => {
73
+ updateTelemetry(true);
74
+ }}
75
+ type={'primary'}
76
+ >
77
+ {t('telemetry.allow')}
78
+ </Button>
79
+ <Button
80
+ onClick={() => {
81
+ updateTelemetry(false);
82
+ }}
83
+ type={'text'}
84
+ >
85
+ {t('telemetry.deny')}
86
+ </Button>
120
87
  </Flexbox>
121
88
  </Flexbox>
122
- )
89
+ </Notification>
123
90
  );
124
91
  });
125
92
 
@@ -10,29 +10,33 @@ import Hero from './Hero';
10
10
 
11
11
  const Layout = ({ children, detail }: LayoutProps) => {
12
12
  return (
13
- <Flexbox
14
- height={'100%'}
15
- id={'lobe-market-container'}
16
- style={{ position: 'relative' }}
17
- width={'100%'}
18
- >
19
- <Header />
20
- <Flexbox height={'100%'} horizontal style={{ position: 'relative' }} width={'100%'}>
21
- <Flexbox
22
- align={'center'}
23
- flex={1}
24
- padding={16}
25
- style={{ overflowX: 'hidden', overflowY: 'scroll', position: 'relative' }}
26
- >
27
- <SafeSpacing />
28
- <Flexbox gap={16} style={{ maxWidth: MAX_WIDTH, position: 'relative', width: '100%' }}>
29
- <Hero />
30
- {children}
13
+ <>
14
+ <Flexbox
15
+ height={'100%'}
16
+ id={'lobe-market-container'}
17
+ style={{ position: 'relative' }}
18
+ width={'100%'}
19
+ >
20
+ <Header />
21
+ <Flexbox height={'100%'} horizontal style={{ position: 'relative' }} width={'100%'}>
22
+ <Flexbox
23
+ align={'center'}
24
+ flex={1}
25
+ padding={16}
26
+ style={{ overflowX: 'hidden', overflowY: 'scroll', position: 'relative' }}
27
+ >
28
+ <SafeSpacing />
29
+ <Flexbox gap={16} style={{ maxWidth: MAX_WIDTH, position: 'relative', width: '100%' }}>
30
+ <Hero />
31
+ {children}
32
+ </Flexbox>
31
33
  </Flexbox>
34
+ <DetailSidebar>{detail}</DetailSidebar>
32
35
  </Flexbox>
33
- <DetailSidebar>{detail}</DetailSidebar>
34
36
  </Flexbox>
35
- </Flexbox>
37
+ {/* ↓ cloud slot ↓ */}
38
+ {/* ↑ cloud slot ↑ */}
39
+ </>
36
40
  );
37
41
  };
38
42
 
@@ -95,6 +95,7 @@ const AzureOpenAIProvider = memo(() => {
95
95
  placeholder: t('azure.modelListPlaceholder'),
96
96
  }}
97
97
  provider={providerKey}
98
+ showBrowserRequest
98
99
  title={
99
100
  <Flexbox align={'center'} gap={8} horizontal>
100
101
  <Azure.Combine size={22} type={'color'}></Azure.Combine>
@@ -20,7 +20,6 @@ const OpenAIProvider = memo(() => {
20
20
  }
21
21
  }
22
22
  showApiKey={showOpenAIApiKey}
23
- showBrowserRequest
24
23
  title={<OpenAI.Combine size={24} />}
25
24
  />
26
25
  );
@@ -18,7 +18,7 @@ const handler = (req: NextRequest) =>
18
18
 
19
19
  onError: ({ error, path }) => {
20
20
  pino.info(`Error in tRPC handler (edge) on path: ${path}`);
21
- pino.error(error);
21
+ console.error(error);
22
22
  },
23
23
 
24
24
  req,
@@ -0,0 +1,48 @@
1
+ import { Icon } from '@lobehub/ui';
2
+ import { Skeleton } from 'antd';
3
+ import { css, cx } from 'antd-style';
4
+ import { ChevronDown, ChevronUp } from 'lucide-react';
5
+ import dynamic from 'next/dynamic';
6
+ import { memo, useState } from 'react';
7
+ import { useTranslation } from 'react-i18next';
8
+ import { Flexbox } from 'react-layout-kit';
9
+
10
+ const container = css`
11
+ pre.shiki {
12
+ padding: 8px !important;
13
+ }
14
+ `;
15
+
16
+ const Highlighter = dynamic(() => import('@lobehub/ui/es/Highlighter'), {
17
+ loading: () => <Skeleton avatar={false} title={false} />,
18
+ ssr: false,
19
+ });
20
+
21
+ const Description = memo<{ message: string; status: number }>(({ message, status }) => {
22
+ const { t } = useTranslation('error');
23
+ const [show, setShow] = useState(false);
24
+ return (
25
+ <Flexbox gap={8}>
26
+ {t(`response.${status}` as any)}
27
+ <Flexbox
28
+ gap={4}
29
+ horizontal
30
+ onClick={() => {
31
+ setShow(!show);
32
+ }}
33
+ style={{ cursor: 'pointer', fontSize: 12 }}
34
+ >
35
+ {t('fetchErrorDetail')} <Icon icon={show ? ChevronUp : ChevronDown} />
36
+ </Flexbox>
37
+ <Highlighter
38
+ className={cx(container)}
39
+ language={'text'}
40
+ style={{ display: show ? undefined : 'none', maxHeight: 80 }}
41
+ >
42
+ {message}
43
+ </Highlighter>
44
+ </Flexbox>
45
+ );
46
+ });
47
+
48
+ export default Description;
@@ -0,0 +1,15 @@
1
+ import { t } from 'i18next';
2
+
3
+ import { notification } from '@/components/AntdStaticMethods';
4
+
5
+ import Description from './Description';
6
+
7
+ export const fetchErrorNotification = {
8
+ error: ({ status, errorMessage }: { errorMessage: string; status: number }) => {
9
+ notification.error({
10
+ description: <Description message={errorMessage} status={status} />,
11
+ message: t('fetchError', { ns: 'error' }),
12
+ type: 'error',
13
+ });
14
+ },
15
+ };
@@ -16,6 +16,7 @@ import {
16
16
  ZeroOne,
17
17
  Zhipu,
18
18
  } from '@lobehub/icons';
19
+ import { Logo } from '@lobehub/ui';
19
20
  import { memo } from 'react';
20
21
  import { Center } from 'react-layout-kit';
21
22
 
@@ -27,6 +28,10 @@ interface ModelProviderIconProps {
27
28
 
28
29
  const ModelProviderIcon = memo<ModelProviderIconProps>(({ provider }) => {
29
30
  switch (provider) {
31
+ case 'lobehub': {
32
+ return <Logo size={20} />;
33
+ }
34
+
30
35
  case ModelProvider.ZhiPu: {
31
36
  return <Zhipu size={20} />;
32
37
  }
@@ -38,7 +43,7 @@ const ModelProviderIcon = memo<ModelProviderIconProps>(({ provider }) => {
38
43
  case ModelProvider.DeepSeek: {
39
44
  return <DeepSeek size={20} />;
40
45
  }
41
-
46
+
42
47
  case ModelProvider.Google: {
43
48
  return (
44
49
  <Center height={20} width={20}>