@lobehub/chat 0.56.0 → 0.58.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 (63) hide show
  1. package/CHANGELOG.md +71 -0
  2. package/package.json +2 -2
  3. package/src/components/SafeSpacing/index.tsx +27 -0
  4. package/src/const/fetch.ts +2 -0
  5. package/src/const/layoutTokens.ts +2 -0
  6. package/src/features/AgentSetting/AgentPlugin/index.tsx +107 -60
  7. package/src/features/AvatarWithUpload/index.tsx +4 -3
  8. package/src/features/MobileTabBar/index.tsx +60 -0
  9. package/src/features/PluginSettings/PluginSettingRender.tsx +65 -0
  10. package/src/features/PluginSettings/index.tsx +65 -0
  11. package/src/features/SideBar/TopActions.tsx +1 -1
  12. package/src/layout/AppMobileLayout.tsx +76 -0
  13. package/src/locales/default/common.ts +3 -1
  14. package/src/locales/default/error.ts +30 -2
  15. package/src/locales/default/setting.ts +1 -0
  16. package/src/pages/api/auth.ts +2 -2
  17. package/src/pages/api/error.ts +3 -3
  18. package/src/pages/api/openai.ts +3 -3
  19. package/src/pages/chat/SessionList/Header.tsx +26 -2
  20. package/src/pages/chat/SessionList/List/Item/index.tsx +2 -2
  21. package/src/pages/chat/SessionList/index.tsx +10 -1
  22. package/src/pages/chat/[id]/index.page.tsx +19 -7
  23. package/src/pages/chat/[id]/mobile.tsx +31 -0
  24. package/src/pages/chat/[id]/setting/Header.tsx +25 -2
  25. package/src/pages/chat/[id]/setting/index.page.tsx +33 -16
  26. package/src/pages/chat/[id]/setting/mobile.tsx +11 -0
  27. package/src/pages/chat/features/Conversation/ChatList/Error/Plugin/PluginError.tsx +28 -0
  28. package/src/pages/chat/features/Conversation/ChatList/Error/Plugin/PluginSettings.tsx +61 -0
  29. package/src/pages/chat/features/Conversation/ChatList/Error/index.tsx +42 -0
  30. package/src/pages/chat/features/Conversation/ChatList/index.tsx +2 -15
  31. package/src/pages/chat/features/Conversation/index.tsx +5 -5
  32. package/src/pages/chat/features/Header/Mobile.tsx +47 -0
  33. package/src/pages/chat/features/Header/PC.tsx +101 -0
  34. package/src/pages/chat/features/Header/index.tsx +7 -93
  35. package/src/pages/chat/features/Sidebar/Header.tsx +6 -4
  36. package/src/pages/chat/features/Sidebar/Mobile.tsx +36 -0
  37. package/src/pages/chat/features/Sidebar/SystemRole.tsx +2 -2
  38. package/src/pages/chat/features/Sidebar/index.tsx +33 -15
  39. package/src/pages/chat/index.page.tsx +14 -8
  40. package/src/pages/chat/layout.tsx +12 -8
  41. package/src/pages/chat/mobile.tsx +25 -0
  42. package/src/pages/settings/index.page.tsx +40 -8
  43. package/src/pages/settings/layout.tsx +5 -27
  44. package/src/pages/settings/mobile.tsx +20 -0
  45. package/src/pages/welcome/Banner/Hero.tsx +3 -5
  46. package/src/pages/welcome/Banner/index.tsx +5 -5
  47. package/src/pages/welcome/index.page.tsx +13 -4
  48. package/src/pages/welcome/mobile.tsx +20 -0
  49. package/src/pages/welcome/style.ts +2 -2
  50. package/src/services/plugin.ts +11 -14
  51. package/src/services/pluginMarket.ts +10 -0
  52. package/src/store/global/initialState.ts +2 -0
  53. package/src/store/global/selectors.ts +2 -2
  54. package/src/store/global/slices/common.ts +7 -0
  55. package/src/store/global/store.ts +7 -0
  56. package/src/store/plugin/action.ts +13 -2
  57. package/src/store/plugin/initialState.ts +3 -0
  58. package/src/store/plugin/selectors.ts +4 -0
  59. package/src/store/plugin/store.ts +2 -1
  60. package/src/store/session/slices/chat/actions/message.ts +11 -2
  61. package/src/types/fetch.ts +18 -14
  62. package/src/utils/fetch.ts +24 -18
  63. package/src/components/HeaderSpacing/index.tsx +0 -9
@@ -21,12 +21,10 @@ const Hero = memo<{ width: number }>(({ width }) => {
21
21
 
22
22
  return (
23
23
  <>
24
- <LogoThree
25
- size={size.logo}
26
- style={{ marginBottom: -size.logo / 40, marginTop: -size.logo / 5 }}
27
- />
24
+ <LogoThree size={size.logo} style={{ marginTop: -size.logo / 5 }} />
28
25
  <div className={styles.title} style={{ fontSize: size.title }}>
29
- LobeChat{mobile ? <br /> : ' '}
26
+ <span style={mobile ? { fontSize: '1.2em' } : {}}>LobeChat</span>
27
+ {mobile ? <br /> : ' '}
30
28
  {t('slogan.title')}
31
29
  </div>
32
30
  <div className={styles.desc} style={{ fontSize: size.desc }}>
@@ -13,7 +13,7 @@ import { useImportConfig } from '@/hooks/useImportConfig';
13
13
  import { useStyles } from '../style';
14
14
  import Hero from './Hero';
15
15
 
16
- const Banner = memo(() => {
16
+ const Banner = memo<{ mobile?: boolean }>(() => {
17
17
  const { importConfig } = useImportConfig();
18
18
  const ref = useRef(null);
19
19
  const domSize = useSize(ref);
@@ -28,12 +28,15 @@ const Banner = memo(() => {
28
28
  }, []);
29
29
 
30
30
  return (
31
- <Flexbox height={'80vh'} style={{ marginTop: '10vh' }}>
31
+ <Flexbox height={'80vh'} style={{ paddingTop: '10vh' }}>
32
32
  <GridShowcase>
33
33
  <div className={styles.container} ref={ref}>
34
34
  <Hero width={width} />
35
35
  </div>
36
36
  <Flexbox gap={16} horizontal style={{ marginTop: 16 }}>
37
+ <Upload maxCount={1} onChange={handleImport} showUploadList={false}>
38
+ <Button size={'large'}>{t('button.import')}</Button>
39
+ </Upload>
37
40
  <Link href={'/chat'}>
38
41
  <Button size={'large'} type={'primary'}>
39
42
  <Flexbox align={'center'} gap={4} horizontal>
@@ -42,9 +45,6 @@ const Banner = memo(() => {
42
45
  </Flexbox>
43
46
  </Button>
44
47
  </Link>
45
- <Upload maxCount={1} onChange={handleImport} showUploadList={false}>
46
- <Button size={'large'}>{t('button.import')}</Button>
47
- </Upload>
48
48
  </Flexbox>
49
49
  </GridShowcase>
50
50
  {/*TODO:暂时隐藏,待模板完成后再补回*/}
@@ -1,3 +1,4 @@
1
+ import { useResponsive } from 'antd-style';
1
2
  import Head from 'next/head';
2
3
  import { memo } from 'react';
3
4
  import { useTranslation } from 'react-i18next';
@@ -7,8 +8,10 @@ import { genSiteHeadTitle } from '@/utils/genSiteHeadTitle';
7
8
  import Banner from './Banner';
8
9
  import Footer from './Footer';
9
10
  import Layout from './layout';
11
+ import Mobile from './mobile';
10
12
 
11
13
  const Welcome = memo(() => {
14
+ const { mobile } = useResponsive();
12
15
  const { t } = useTranslation('welcome');
13
16
  const pageTitle = genSiteHeadTitle(t('header'));
14
17
 
@@ -17,10 +20,16 @@ const Welcome = memo(() => {
17
20
  <Head>
18
21
  <title>{pageTitle}</title>
19
22
  </Head>
20
- <Layout>
21
- <Banner />
22
- <Footer />
23
- </Layout>
23
+ {mobile ? (
24
+ <Mobile>
25
+ <Banner />
26
+ </Mobile>
27
+ ) : (
28
+ <Layout>
29
+ <Banner />
30
+ <Footer />
31
+ </Layout>
32
+ )}
24
33
  </>
25
34
  );
26
35
  });
@@ -0,0 +1,20 @@
1
+ import { Logo, MobileNavBar } from '@lobehub/ui';
2
+ import { useTheme } from 'antd-style';
3
+ import { PropsWithChildren, memo } from 'react';
4
+
5
+ import AppMobileLayout from '../../layout/AppMobileLayout';
6
+
7
+ const WelcomeLayout = memo<PropsWithChildren>(({ children }) => {
8
+ const theme = useTheme();
9
+ return (
10
+ <AppMobileLayout
11
+ navBar={<MobileNavBar center={<Logo type={'text'} />} />}
12
+ showTabBar
13
+ style={{ background: theme.colorBgContainer }}
14
+ >
15
+ {children}
16
+ </AppMobileLayout>
17
+ );
18
+ });
19
+
20
+ export default WelcomeLayout;
@@ -41,9 +41,9 @@ export const useStyles = createStyles(({ css, token, stylish, cx }) => {
41
41
  padding: 16px;
42
42
  `,
43
43
  title: css`
44
- margin-bottom: 0.2em;
44
+ margin-bottom: 0.25em;
45
45
  font-weight: 800;
46
- line-height: 1.2;
46
+ line-height: 1.4;
47
47
  text-align: center;
48
48
  `,
49
49
  view: cx(
@@ -1,8 +1,8 @@
1
1
  import { PluginRequestPayload } from '@lobehub/chat-plugin-sdk';
2
2
 
3
- import { LOBE_CHAT_ACCESS_CODE } from '@/const/fetch';
4
- import { PLUGINS_INDEX_URL } from '@/const/url';
5
- import { useGlobalStore } from '@/store/global';
3
+ import { LOBE_PLUGIN_SETTINGS } from '@/const/fetch';
4
+ import { usePluginStore } from '@/store/plugin';
5
+ import { getMessageError } from '@/utils/fetch';
6
6
 
7
7
  import { URLS } from './url';
8
8
 
@@ -12,30 +12,27 @@ interface FetchChatModelOptions {
12
12
  }
13
13
 
14
14
  /**
15
- * 请求插件结果
15
+ * 请求插件结果´
16
16
  */
17
17
  export const fetchPlugin = async (
18
18
  params: PluginRequestPayload,
19
19
  options?: FetchChatModelOptions,
20
20
  ) => {
21
+ const settings = usePluginStore.getState().pluginsSettings?.[params.identifier];
22
+
21
23
  const res = await fetch(URLS.plugins, {
22
24
  body: JSON.stringify(params),
23
25
  headers: {
24
26
  'Content-Type': 'application/json',
25
- [LOBE_CHAT_ACCESS_CODE]: useGlobalStore.getState().settings.password || '',
27
+ [LOBE_PLUGIN_SETTINGS]: JSON.stringify(settings) || '',
26
28
  },
27
29
  method: 'POST',
28
30
  signal: options?.signal,
29
31
  });
30
32
 
31
- return await res.text();
32
- };
33
+ if (!res.ok) {
34
+ throw await getMessageError(res);
35
+ }
33
36
 
34
- /**
35
- * 请求插件列表
36
- */
37
- export const getPluginList = async () => {
38
- const res = await fetch(PLUGINS_INDEX_URL);
39
-
40
- return res.json();
37
+ return await res.text();
41
38
  };
@@ -0,0 +1,10 @@
1
+ import { PLUGINS_INDEX_URL } from '@/const/url';
2
+
3
+ /**
4
+ * 请求插件列表
5
+ */
6
+ export const getPluginList = async () => {
7
+ const res = await fetch(PLUGINS_INDEX_URL);
8
+
9
+ return res.json();
10
+ };
@@ -25,6 +25,7 @@ export interface GlobalState {
25
25
  export interface GlobalPreference {
26
26
  guide?: Guide;
27
27
  inputHeight: number;
28
+ mobileShowTopic?: boolean;
28
29
  sessionsWidth: number;
29
30
  showChatSideBar?: boolean;
30
31
  showSessionPanel?: boolean;
@@ -34,6 +35,7 @@ export const initialState: GlobalState = {
34
35
  preference: {
35
36
  guide: {},
36
37
  inputHeight: 200,
38
+ mobileShowTopic: false,
37
39
  sessionsWidth: 320,
38
40
  showChatSideBar: true,
39
41
  showSessionPanel: true,
@@ -11,10 +11,10 @@ const currentSettings = (s: GlobalStore) => merge({}, DEFAULT_SETTINGS, s.settin
11
11
  const currentDefaultAgent = (s: GlobalStore) => merge({}, DEFAULT_AGENT, s.settings.defaultAgent);
12
12
 
13
13
  const currentAgentConfig = (s: GlobalStore) =>
14
- merge({}, DEFAULT_AGENT_CONFIG, s.settings.defaultAgent.config);
14
+ merge({}, DEFAULT_AGENT_CONFIG, currentDefaultAgent(s).config);
15
15
 
16
16
  const currentAgentMeta = (s: GlobalStore) =>
17
- merge({}, DEFAULT_AGENT_META, s.settings.defaultAgent.meta);
17
+ merge({}, DEFAULT_AGENT_META, currentDefaultAgent(s).meta);
18
18
 
19
19
  export const exportSettings = (s: GlobalStore) => {
20
20
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
@@ -19,6 +19,7 @@ export interface CommonAction {
19
19
  */
20
20
  switchSideBar: (key: SidebarTabKey) => void;
21
21
  toggleChatSideBar: (visible?: boolean) => void;
22
+ toggleMobileTopic: (visible?: boolean) => void;
22
23
  updateGuideState: (guide: Partial<Guide>) => void;
23
24
  updatePreference: (preference: Partial<GlobalPreference>, action?: string) => void;
24
25
  }
@@ -38,6 +39,12 @@ export const createCommonSlice: StateCreator<
38
39
 
39
40
  get().updatePreference({ showChatSideBar }, t('toggleAgentPanel', newValue) as string);
40
41
  },
42
+ toggleMobileTopic: (newValue) => {
43
+ const mobileShowTopic =
44
+ typeof newValue === 'boolean' ? newValue : !get().preference.mobileShowTopic;
45
+
46
+ get().updatePreference({ mobileShowTopic }, t('toggleMobileTopic', newValue) as string);
47
+ },
41
48
  updateGuideState: (guide) => {
42
49
  const { updatePreference } = get();
43
50
  const nextGuide = merge({}, get().preference.guide, guide);
@@ -3,6 +3,7 @@ import { shallow } from 'zustand/shallow';
3
3
  import { createWithEqualityFn } from 'zustand/traditional';
4
4
  import { StateCreator } from 'zustand/vanilla';
5
5
 
6
+ import { DEFAULT_AGENT } from '@/const/settings';
6
7
  import { isDev } from '@/utils/env';
7
8
 
8
9
  import { type GlobalState, initialState } from './initialState';
@@ -25,6 +26,12 @@ const createStore: StateCreator<GlobalStore, [['zustand/devtools', never]]> = (.
25
26
  type GlobalPersist = Pick<GlobalStore, 'preference' | 'settings'>;
26
27
 
27
28
  const persistOptions: PersistOptions<GlobalStore, GlobalPersist> = {
29
+ merge: (persistedState, currentState) => {
30
+ if (!(persistedState as GlobalPersist).settings.defaultAgent) {
31
+ currentState.settings.defaultAgent = DEFAULT_AGENT;
32
+ }
33
+ return currentState;
34
+ },
28
35
  name: 'LOBE_SETTINGS',
29
36
  partialize: (s) => ({
30
37
  preference: s.preference,
@@ -5,11 +5,11 @@ import {
5
5
  } from '@lobehub/chat-plugin-sdk';
6
6
  import { message } from 'antd';
7
7
  import { produce } from 'immer';
8
- import { uniq } from 'lodash-es';
8
+ import { merge, uniq } from 'lodash-es';
9
9
  import useSWR, { SWRResponse } from 'swr';
10
10
  import { StateCreator } from 'zustand/vanilla';
11
11
 
12
- import { getPluginList } from '@/services/plugin';
12
+ import { getPluginList } from '@/services/pluginMarket';
13
13
  import { pluginSelectors } from '@/store/plugin/selectors';
14
14
  import { LobeSessions } from '@/types/session';
15
15
  import { setNamespace } from '@/utils/storeDebug';
@@ -27,6 +27,7 @@ export interface PluginAction {
27
27
  dispatchPluginManifest: (payload: PluginDispatch) => void;
28
28
  fetchPluginManifest: (name: string) => Promise<void>;
29
29
  updateManifestLoadingState: (key: string, value: boolean | undefined) => void;
30
+ updatePluginSettings: <T>(id: string, settings: Partial<T>) => void;
30
31
  useFetchPluginList: () => SWRResponse<LobeChatPluginsMarketIndex>;
31
32
  }
32
33
 
@@ -112,6 +113,16 @@ export const createPluginSlice: StateCreator<
112
113
  t('updateManifestLoadingState'),
113
114
  );
114
115
  },
116
+
117
+ updatePluginSettings: (id, settings) => {
118
+ set(
119
+ produce((draft) => {
120
+ draft.pluginsSettings[id] = merge({}, draft.pluginsSettings[id], settings);
121
+ }),
122
+ false,
123
+ t('updatePluginSettings'),
124
+ );
125
+ },
115
126
  useFetchPluginList: () =>
116
127
  useSWR<LobeChatPluginsMarketIndex>('fetchPluginList', getPluginList, {
117
128
  onSuccess: (pluginMarketIndex) => {
@@ -3,12 +3,14 @@ import { LobeChatPluginMeta } from '@lobehub/chat-plugin-sdk';
3
3
  import { PluginManifestMap } from '@/types/plugin';
4
4
 
5
5
  export type PluginManifestLoadingState = Record<string, boolean>;
6
+ export type PluginsSettings = Record<string, any>;
6
7
 
7
8
  export interface PluginStoreState {
8
9
  manifestPrepared: boolean;
9
10
  pluginList: LobeChatPluginMeta[];
10
11
  pluginManifestLoading: PluginManifestLoadingState;
11
12
  pluginManifestMap: PluginManifestMap;
13
+ pluginsSettings: PluginsSettings;
12
14
  }
13
15
 
14
16
  export const initialState: PluginStoreState = {
@@ -16,4 +18,5 @@ export const initialState: PluginStoreState = {
16
18
  pluginList: [],
17
19
  pluginManifestLoading: {},
18
20
  pluginManifestMap: {},
21
+ pluginsSettings: {},
19
22
  };
@@ -25,7 +25,11 @@ const enabledSchema =
25
25
  const getPluginMetaById = (id: string) => (s: PluginStoreState) =>
26
26
  s.pluginList?.find((p) => p.identifier === id);
27
27
 
28
+ const getPluginManifestSettingsById = (id: string) => (s: PluginStoreState) =>
29
+ s.pluginManifestMap[id];
30
+
28
31
  export const pluginSelectors = {
29
32
  enabledSchema,
33
+ getPluginManifestSettingsById,
30
34
  getPluginMetaById,
31
35
  };
@@ -19,7 +19,7 @@ const createStore: StateCreator<PluginStore, [['zustand/devtools', never]]> = (.
19
19
 
20
20
  // =============== persist 本地缓存中间件配置 ============ //
21
21
 
22
- type SessionPersist = Pick<PluginStore, 'pluginList' | 'pluginManifestMap'>;
22
+ type SessionPersist = Pick<PluginStore, 'pluginList' | 'pluginManifestMap' | 'pluginsSettings'>;
23
23
 
24
24
  const storeName = 'LOBE_PLUGIN';
25
25
 
@@ -29,6 +29,7 @@ const persistOptions: PersistOptions<PluginStore, SessionPersist> = {
29
29
  partialize: (s) => ({
30
30
  pluginList: s.pluginList,
31
31
  pluginManifestMap: s.pluginManifestMap,
32
+ pluginsSettings: s.pluginsSettings,
32
33
  }),
33
34
 
34
35
  // 手动控制 Hydration ,避免 ssr 报错
@@ -346,9 +346,18 @@ export const chatMessage: StateCreator<
346
346
  dispatchMessage({ id, key: 'name', type: 'updateMessage', value: payload.identifier });
347
347
  dispatchMessage({ id, key: 'plugin', type: 'updateMessage', value: payload });
348
348
 
349
- const abortController = toggleChatLoading(true, id);
350
- const data = await fetchPlugin(payload, { signal: abortController?.signal });
349
+ let data: string;
350
+ try {
351
+ const abortController = toggleChatLoading(true, id);
352
+ data = await fetchPlugin(payload, { signal: abortController?.signal });
353
+ } catch (error) {
354
+ dispatchMessage({ id, key: 'error', type: 'updateMessage', value: error });
355
+
356
+ data = '';
357
+ }
351
358
  toggleChatLoading(false);
359
+ // 如果报错则结束了
360
+ if (!data) return;
352
361
 
353
362
  dispatchMessage({ id, key: 'content', type: 'updateMessage', value: data });
354
363
 
@@ -1,25 +1,29 @@
1
- export enum ErrorType {
1
+ /* eslint-disable sort-keys-fix/sort-keys-fix */
2
+ export const ChatErrorType = {
2
3
  // ******* 业务错误语义 ******* //
3
4
 
4
5
  // 密码无效
5
- InvalidAccessCode = 'InvalidAccessCode',
6
+ InvalidAccessCode: 'InvalidAccessCode',
6
7
  // OpenAI 返回的业务错误
7
- OpenAIBizError = 'OpenAIBizError',
8
+ OpenAIBizError: 'OpenAIBizError',
8
9
 
9
10
  // ******* 客户端错误 ******* //
10
- BadRequest = 400,
11
- Unauthorized = 401,
12
- Forbidden = 403,
13
- ContentNotFound = 404, // 没找到接口
14
- MethodNotAllowed = 405, // 不支持
15
- TooManyRequests = 429,
11
+ BadRequest: 400,
12
+ Unauthorized: 401,
13
+ Forbidden: 403,
14
+ ContentNotFound: 404, // 没找到接口
15
+ MethodNotAllowed: 405, // 不支持
16
+ TooManyRequests: 429,
16
17
 
17
18
  // ******* 服务端错误 ******* //
18
- InternalServerError = 500,
19
- BadGateway = 502,
20
- ServiceUnavailable = 503,
21
- GatewayTimeout = 504,
22
- }
19
+ InternalServerError: 500,
20
+ BadGateway: 502,
21
+ ServiceUnavailable: 503,
22
+ GatewayTimeout: 504,
23
+ } as const;
24
+ /* eslint-enable */
25
+
26
+ export type ErrorType = (typeof ChatErrorType)[keyof typeof ChatErrorType];
23
27
 
24
28
  export interface ErrorResponse {
25
29
  body: any;
@@ -2,7 +2,29 @@ import { t } from 'i18next';
2
2
 
3
3
  import { fetchChatModel } from '@/services/chatModel';
4
4
  import { ChatMessageError } from '@/types/chatMessage';
5
- import { ErrorResponse } from '@/types/fetch';
5
+ import { ErrorResponse, ErrorType } from '@/types/fetch';
6
+
7
+ export const getMessageError = async (response: Response) => {
8
+ let chatMessageError: ChatMessageError;
9
+
10
+ // 尝试取一波业务错误语义
11
+ try {
12
+ const data = (await response.json()) as ErrorResponse;
13
+ chatMessageError = {
14
+ body: data.body,
15
+ message: t(`response.${data.errorType}`),
16
+ type: data.errorType,
17
+ };
18
+ } catch {
19
+ // 如果无法正常返回,说明是常规报错
20
+ chatMessageError = {
21
+ message: t(`response.${response.status}`),
22
+ type: response.status as ErrorType,
23
+ };
24
+ }
25
+
26
+ return chatMessageError;
27
+ };
6
28
 
7
29
  export interface FetchSSEOptions {
8
30
  onErrorHandle?: (error: ChatMessageError) => void;
@@ -19,23 +41,7 @@ export const fetchSSE = async (fetchFn: () => Promise<Response>, options: FetchS
19
41
 
20
42
  // 如果不 ok 说明有请求错误
21
43
  if (!response.ok) {
22
- let chatMessageError: ChatMessageError;
23
-
24
- // 尝试取一波业务错误语义
25
- try {
26
- const data = (await response.json()) as ErrorResponse;
27
- chatMessageError = {
28
- body: data.body,
29
- message: t(`response.${data.errorType}`),
30
- type: data.errorType,
31
- };
32
- } catch {
33
- // 如果无法正常返回,说明是常规报错
34
- chatMessageError = {
35
- message: t(`response.${response.status}`),
36
- type: response.status,
37
- };
38
- }
44
+ const chatMessageError = await getMessageError(response);
39
45
 
40
46
  options.onErrorHandle?.(chatMessageError);
41
47
  return;
@@ -1,9 +0,0 @@
1
- import { memo } from 'react';
2
-
3
- import { HEADER_HEIGHT } from '@/const/layoutTokens';
4
-
5
- const HeaderSpacing = memo<{ height?: number }>(({ height = HEADER_HEIGHT }) => (
6
- <div style={{ flex: 'none', height }} />
7
- ));
8
-
9
- export default HeaderSpacing;