@lobehub/chat 1.52.0 → 1.52.1

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 CHANGED
@@ -2,6 +2,31 @@
2
2
 
3
3
  # Changelog
4
4
 
5
+ ### [Version 1.52.1](https://github.com/lobehub/lobe-chat/compare/v1.52.0...v1.52.1)
6
+
7
+ <sup>Released on **2025-02-08**</sup>
8
+
9
+ #### 🐛 Bug Fixes
10
+
11
+ - **misc**: Fix static relative issues.
12
+
13
+ <br/>
14
+
15
+ <details>
16
+ <summary><kbd>Improvements and Fixes</kbd></summary>
17
+
18
+ #### What's fixed
19
+
20
+ - **misc**: Fix static relative issues, closes [#5874](https://github.com/lobehub/lobe-chat/issues/5874) ([419977b](https://github.com/lobehub/lobe-chat/commit/419977b))
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
+
5
30
  ## [Version 1.52.0](https://github.com/lobehub/lobe-chat/compare/v1.51.16...v1.52.0)
6
31
 
7
32
  <sup>Released on **2025-02-08**</sup>
package/changelog/v1.json CHANGED
@@ -1,4 +1,13 @@
1
1
  [
2
+ {
3
+ "children": {
4
+ "fixes": [
5
+ "Fix static relative issues."
6
+ ]
7
+ },
8
+ "date": "2025-02-08",
9
+ "version": "1.52.1"
10
+ },
2
11
  {
3
12
  "children": {
4
13
  "features": [
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lobehub/chat",
3
- "version": "1.52.0",
3
+ "version": "1.52.1",
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",
@@ -1,7 +1,7 @@
1
1
  import { act, renderHook } from '@testing-library/react';
2
2
  import { describe, expect, it, vi } from 'vitest';
3
3
 
4
- import { ServerConfigStoreProvider } from '@/store/serverConfig';
4
+ import { ServerConfigStoreProvider } from '@/store/serverConfig/Provider';
5
5
  import { useUserStore } from '@/store/user';
6
6
 
7
7
  import { useCategory } from '../features/useCategory';
@@ -37,5 +37,3 @@ const Page = async (props: DynamicLayoutProps) => {
37
37
  Page.displayName = 'Me';
38
38
 
39
39
  export default Page;
40
-
41
- export const dynamic = 'force-static';
@@ -27,5 +27,3 @@ const Page = async (props: DynamicLayoutProps) => {
27
27
  Page.displayName = 'MeProfile';
28
28
 
29
29
  export default Page;
30
-
31
- export const dynamic = 'force-static';
@@ -27,5 +27,3 @@ const Page = async (props: DynamicLayoutProps) => {
27
27
  Page.displayName = 'MeSettings';
28
28
 
29
29
  export default Page;
30
-
31
- export const dynamic = 'force-static';
@@ -71,5 +71,3 @@ const Page = async (props: Props) => {
71
71
  Page.DisplayName = 'DiscoverSearch';
72
72
 
73
73
  export default Page;
74
-
75
- export const dynamic = 'force-static';
@@ -8,5 +8,3 @@ const MainLayout = ServerLayout({ Desktop, Mobile });
8
8
  MainLayout.displayName = 'MainLayout';
9
9
 
10
10
  export default MainLayout;
11
-
12
- export const dynamic = 'force-dynamic';
@@ -9,5 +9,3 @@ const SettingsLayout = ServerLayout<LayoutProps>({ Desktop, Mobile });
9
9
  SettingsLayout.displayName = 'SettingsLayout';
10
10
 
11
11
  export default SettingsLayout;
12
-
13
- export const dynamic = 'force-static';
@@ -1,7 +1,7 @@
1
1
  import { act, renderHook } from '@testing-library/react';
2
2
  import { describe, expect, it, vi } from 'vitest';
3
3
 
4
- import { ServerConfigStoreProvider } from '@/store/serverConfig';
4
+ import { ServerConfigStoreProvider } from '@/store/serverConfig/Provider';
5
5
  import { useUserStore } from '@/store/user';
6
6
 
7
7
  import { useMenu } from '../UserPanel/useMenu';
@@ -38,6 +38,10 @@ const StoreInitialization = memo(() => {
38
38
  // init the system preference
39
39
  useInitSystemStatus();
40
40
 
41
+ // fetch server config
42
+ const useFetchServerConfig = useServerConfigStore((s) => s.useInitServerConfig);
43
+ useFetchServerConfig();
44
+
41
45
  // Update NextAuth status
42
46
  const useUserStoreUpdater = createStoreUpdater(useUserStore);
43
47
  const oAuthSSOProviders = useServerConfigStore(serverConfigSelectors.oAuthSSOProviders);
@@ -4,7 +4,7 @@ import { appEnv } from '@/config/app';
4
4
  import { getServerFeatureFlagsValue } from '@/config/featureFlags';
5
5
  import DevPanel from '@/features/DevPanel';
6
6
  import { getServerGlobalConfig } from '@/server/globalConfig';
7
- import { ServerConfigStoreProvider } from '@/store/serverConfig';
7
+ import { ServerConfigStoreProvider } from '@/store/serverConfig/Provider';
8
8
  import { getAntdLocale } from '@/utils/locale';
9
9
 
10
10
  import AntdV5MonkeyPatch from './AntdV5MonkeyPatch';
@@ -37,7 +37,7 @@ const GlobalLayout = async ({
37
37
 
38
38
  // get default feature flags to use with ssr
39
39
  const serverFeatureFlags = getServerFeatureFlagsValue();
40
- const serverConfig = getServerGlobalConfig();
40
+ const serverConfig = await getServerGlobalConfig();
41
41
  return (
42
42
  <StyleRegistry>
43
43
  <Locale antdLocale={antdLocale} defaultLang={userLocale}>
@@ -37,7 +37,7 @@ describe('configRouter', () => {
37
37
  const response = await router.getGlobalConfig();
38
38
 
39
39
  // Assert
40
- const result = response.languageModel?.openai;
40
+ const result = response.serverConfig.languageModel?.openai;
41
41
 
42
42
  expect(result).toMatchSnapshot();
43
43
  process.env.OPENAI_MODEL_LIST = '';
@@ -49,7 +49,7 @@ describe('configRouter', () => {
49
49
 
50
50
  const response = await router.getGlobalConfig();
51
51
 
52
- const result = response.languageModel?.openai?.serverModelCards;
52
+ const result = response.serverConfig.languageModel?.openai?.serverModelCards;
53
53
 
54
54
  expect(result).toMatchSnapshot();
55
55
 
@@ -62,7 +62,7 @@ describe('configRouter', () => {
62
62
 
63
63
  const response = await router.getGlobalConfig();
64
64
 
65
- const result = response.languageModel?.openai?.serverModelCards;
65
+ const result = response.serverConfig.languageModel?.openai?.serverModelCards;
66
66
 
67
67
  expect(result?.find((s) => s.id === 'gpt-4-0125-preview')?.displayName).toEqual(
68
68
  'gpt-4-32k',
@@ -76,7 +76,7 @@ describe('configRouter', () => {
76
76
 
77
77
  const response = await router.getGlobalConfig();
78
78
 
79
- const result = response.languageModel?.openai?.serverModelCards;
79
+ const result = response.serverConfig.languageModel?.openai?.serverModelCards;
80
80
 
81
81
  expect(result?.find((r) => r.id === 'gpt-4')).toBeUndefined();
82
82
 
@@ -88,7 +88,7 @@ describe('configRouter', () => {
88
88
 
89
89
  const response = await router.getGlobalConfig();
90
90
 
91
- const result = response.languageModel?.openai?.serverModelCards;
91
+ const result = response.serverConfig.languageModel?.openai?.serverModelCards;
92
92
 
93
93
  const model = result?.find((o) => o.id === 'gpt-4-1106-preview');
94
94
 
@@ -102,7 +102,7 @@ describe('configRouter', () => {
102
102
 
103
103
  const response = await router.getGlobalConfig();
104
104
 
105
- const result = response.languageModel?.openai?.serverModelCards;
105
+ const result = response.serverConfig.languageModel?.openai?.serverModelCards;
106
106
 
107
107
  expect(result).toContainEqual({
108
108
  displayName: 'model1',
@@ -137,7 +137,7 @@ describe('configRouter', () => {
137
137
  const response = await router.getGlobalConfig();
138
138
 
139
139
  // Assert
140
- const result = response.languageModel?.openrouter;
140
+ const result = response.serverConfig.languageModel?.openrouter;
141
141
 
142
142
  expect(result).toMatchSnapshot();
143
143
 
@@ -1,12 +1,17 @@
1
+ import { getServerFeatureFlagsValue } from '@/config/featureFlags';
1
2
  import { publicProcedure, router } from '@/libs/trpc';
2
3
  import { getServerDefaultAgentConfig, getServerGlobalConfig } from '@/server/globalConfig';
4
+ import { GlobalRuntimeConfig } from '@/types/serverConfig';
3
5
 
4
6
  export const configRouter = router({
5
7
  getDefaultAgentConfig: publicProcedure.query(async () => {
6
8
  return getServerDefaultAgentConfig();
7
9
  }),
8
10
 
9
- getGlobalConfig: publicProcedure.query(async () => {
10
- return getServerGlobalConfig();
11
+ getGlobalConfig: publicProcedure.query(async (): Promise<GlobalRuntimeConfig> => {
12
+ const serverConfig = await getServerGlobalConfig();
13
+ const serverFeatureFlags = getServerFeatureFlagsValue();
14
+
15
+ return { serverConfig, serverFeatureFlags };
11
16
  }),
12
17
  });
@@ -1,7 +1,7 @@
1
1
  import { Mock, beforeEach, describe, expect, it, vi } from 'vitest';
2
2
 
3
3
  import { edgeClient } from '@/libs/trpc/client';
4
- import { GlobalServerConfig } from '@/types/serverConfig';
4
+ import { GlobalRuntimeConfig } from '@/types/serverConfig';
5
5
 
6
6
  import { globalService } from '../global';
7
7
 
@@ -77,14 +77,17 @@ describe('GlobalService', () => {
77
77
  describe('ServerConfig', () => {
78
78
  it('should return the serverConfig when fetch is successful', async () => {
79
79
  // Arrange
80
- const mockConfig = { enabledOAuthSSO: true } as GlobalServerConfig;
80
+ const mockConfig = {
81
+ serverConfig: { enabledOAuthSSO: true },
82
+ serverFeatureFlags: {},
83
+ } as GlobalRuntimeConfig;
81
84
  vi.spyOn(edgeClient.config.getGlobalConfig, 'query').mockResolvedValue(mockConfig);
82
85
 
83
86
  // Act
84
87
  const config = await globalService.getGlobalConfig();
85
88
 
86
89
  // Assert
87
- expect(config).toEqual({ enabledOAuthSSO: true });
90
+ expect(config).toEqual(mockConfig);
88
91
  });
89
92
 
90
93
  it('should return the defaultAgentConfig when fetch is successful', async () => {
@@ -2,7 +2,7 @@ import { DeepPartial } from 'utility-types';
2
2
 
3
3
  import { edgeClient } from '@/libs/trpc/client';
4
4
  import { LobeAgentConfig } from '@/types/agent';
5
- import { GlobalServerConfig } from '@/types/serverConfig';
5
+ import { GlobalRuntimeConfig } from '@/types/serverConfig';
6
6
 
7
7
  const VERSION_URL = 'https://registry.npmmirror.com/@lobehub/chat/latest';
8
8
 
@@ -17,7 +17,7 @@ class GlobalService {
17
17
  return data['version'];
18
18
  };
19
19
 
20
- getGlobalConfig = async (): Promise<GlobalServerConfig> => {
20
+ getGlobalConfig = async (): Promise<GlobalRuntimeConfig> => {
21
21
  return edgeClient.config.getGlobalConfig.query();
22
22
  };
23
23
 
@@ -0,0 +1,36 @@
1
+ import { SWRResponse } from 'swr';
2
+ import { StateCreator } from 'zustand/vanilla';
3
+
4
+ import { useOnlyFetchOnceSWR } from '@/libs/swr';
5
+ import { globalService } from '@/services/global';
6
+ import { GlobalRuntimeConfig } from '@/types/serverConfig';
7
+
8
+ import type { ServerConfigStore } from './store';
9
+
10
+ const FETCH_SERVER_CONFIG_KEY = 'FETCH_SERVER_CONFIG';
11
+ export interface ServerConfigAction {
12
+ useInitServerConfig: () => SWRResponse<GlobalRuntimeConfig>;
13
+ }
14
+
15
+ export const createServerConfigSlice: StateCreator<
16
+ ServerConfigStore,
17
+ [['zustand/devtools', never]],
18
+ [],
19
+ ServerConfigAction
20
+ > = (set) => ({
21
+ useInitServerConfig: () => {
22
+ return useOnlyFetchOnceSWR<GlobalRuntimeConfig>(
23
+ FETCH_SERVER_CONFIG_KEY,
24
+ () => globalService.getGlobalConfig(),
25
+ {
26
+ onSuccess: (data) => {
27
+ set(
28
+ { featureFlags: data.serverFeatureFlags, serverConfig: data.serverConfig },
29
+ false,
30
+ 'initServerConfig',
31
+ );
32
+ },
33
+ },
34
+ );
35
+ },
36
+ });
@@ -1,3 +1,2 @@
1
- export { ServerConfigStoreProvider } from './Provider';
2
1
  export { featureFlagsSelectors } from './selectors';
3
2
  export { useServerConfigStore } from './store';
@@ -21,7 +21,7 @@ describe('createServerConfigStore', () => {
21
21
  it('should initialize store with default state', () => {
22
22
  const store = createServerConfigStore();
23
23
 
24
- expect(store.getState()).toEqual({
24
+ expect(store.getState()).toMatchObject({
25
25
  featureFlags: DEFAULT_FEATURE_FLAGS,
26
26
  serverConfig: { telemetry: {}, aiProvider: {} },
27
27
  });
@@ -10,26 +10,33 @@ import { GlobalServerConfig } from '@/types/serverConfig';
10
10
  import { merge } from '@/utils/merge';
11
11
  import { StoreApiWithSelector } from '@/utils/zustand';
12
12
 
13
- const initialState: ServerConfigStore = {
13
+ import { ServerConfigAction, createServerConfigSlice } from './action';
14
+
15
+ interface ServerConfigState {
16
+ featureFlags: IFeatureFlags;
17
+ isMobile?: boolean;
18
+ serverConfig: GlobalServerConfig;
19
+ }
20
+
21
+ const initialState: ServerConfigState = {
14
22
  featureFlags: DEFAULT_FEATURE_FLAGS,
15
23
  serverConfig: { aiProvider: {}, telemetry: {} },
16
24
  };
17
25
 
18
26
  // =============== 聚合 createStoreFn ============ //
19
27
 
20
- export interface ServerConfigStore {
21
- featureFlags: IFeatureFlags;
22
- isMobile?: boolean;
23
- serverConfig: GlobalServerConfig;
24
- }
28
+ export interface ServerConfigStore extends ServerConfigState, ServerConfigAction {}
25
29
 
26
30
  type CreateStore = (
27
31
  initState: Partial<ServerConfigStore>,
28
32
  ) => StateCreator<ServerConfigStore, [['zustand/devtools', never]]>;
29
33
 
30
- const createStore: CreateStore = (runtimeState) => () => ({
31
- ...merge(initialState, runtimeState),
32
- });
34
+ const createStore: CreateStore =
35
+ (runtimeState) =>
36
+ (...params) => ({
37
+ ...merge(initialState, runtimeState),
38
+ ...createServerConfigSlice(...params),
39
+ });
33
40
 
34
41
  // =============== 实装 useStore ============ //
35
42
 
@@ -1,5 +1,6 @@
1
1
  import { DeepPartial } from 'utility-types';
2
2
 
3
+ import { IFeatureFlags } from '@/config/featureFlags';
3
4
  import { ChatModelCard } from '@/types/llm';
4
5
  import {
5
6
  GlobalLLMProviderKey,
@@ -38,3 +39,8 @@ export interface GlobalServerConfig {
38
39
  langfuse?: boolean;
39
40
  };
40
41
  }
42
+
43
+ export interface GlobalRuntimeConfig {
44
+ serverConfig: GlobalServerConfig;
45
+ serverFeatureFlags: IFeatureFlags;
46
+ }