@lobehub/chat 1.47.1 → 1.47.3

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,56 @@
2
2
 
3
3
  # Changelog
4
4
 
5
+ ### [Version 1.47.3](https://github.com/lobehub/lobe-chat/compare/v1.47.2...v1.47.3)
6
+
7
+ <sup>Released on **2025-01-18**</sup>
8
+
9
+ #### 🐛 Bug Fixes
10
+
11
+ - **misc**: Fix hydration error.
12
+
13
+ <br/>
14
+
15
+ <details>
16
+ <summary><kbd>Improvements and Fixes</kbd></summary>
17
+
18
+ #### What's fixed
19
+
20
+ - **misc**: Fix hydration error, closes [#5502](https://github.com/lobehub/lobe-chat/issues/5502) ([cbe469a](https://github.com/lobehub/lobe-chat/commit/cbe469a))
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 1.47.2](https://github.com/lobehub/lobe-chat/compare/v1.47.1...v1.47.2)
31
+
32
+ <sup>Released on **2025-01-17**</sup>
33
+
34
+ #### 🐛 Bug Fixes
35
+
36
+ - **misc**: Fix api key in api key form.
37
+
38
+ <br/>
39
+
40
+ <details>
41
+ <summary><kbd>Improvements and Fixes</kbd></summary>
42
+
43
+ #### What's fixed
44
+
45
+ - **misc**: Fix api key in api key form, closes [#5498](https://github.com/lobehub/lobe-chat/issues/5498) ([b4a160b](https://github.com/lobehub/lobe-chat/commit/b4a160b))
46
+
47
+ </details>
48
+
49
+ <div align="right">
50
+
51
+ [![](https://img.shields.io/badge/-BACK_TO_TOP-151515?style=flat-square)](#readme-top)
52
+
53
+ </div>
54
+
5
55
  ### [Version 1.47.1](https://github.com/lobehub/lobe-chat/compare/v1.47.0...v1.47.1)
6
56
 
7
57
  <sup>Released on **2025-01-17**</sup>
package/changelog/v1.json CHANGED
@@ -1,4 +1,22 @@
1
1
  [
2
+ {
3
+ "children": {
4
+ "fixes": [
5
+ "Fix hydration error."
6
+ ]
7
+ },
8
+ "date": "2025-01-18",
9
+ "version": "1.47.3"
10
+ },
11
+ {
12
+ "children": {
13
+ "fixes": [
14
+ "Fix api key in api key form."
15
+ ]
16
+ },
17
+ "date": "2025-01-17",
18
+ "version": "1.47.2"
19
+ },
2
20
  {
3
21
  "children": {},
4
22
  "date": "2025-01-17",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lobehub/chat",
3
- "version": "1.47.1",
3
+ "version": "1.47.3",
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",
@@ -39,7 +39,7 @@
39
39
  "db:push-test": "NODE_ENV=test drizzle-kit push",
40
40
  "db:studio": "drizzle-kit studio",
41
41
  "db:z-pull": "drizzle-kit introspect",
42
- "dev": "next dev --turbo -p 3010",
42
+ "dev": "next dev --turbopack -p 3010",
43
43
  "docs:i18n": "lobe-i18n md && npm run lint:md && npm run lint:mdx",
44
44
  "docs:seo": "lobe-seo && npm run lint:mdx",
45
45
  "i18n": "npm run workflow:i18n && lobe-i18n",
@@ -6,11 +6,10 @@ import { useTranslation } from 'react-i18next';
6
6
 
7
7
  import { useProviderName } from '@/hooks/useProviderName';
8
8
  import { featureFlagsSelectors, useServerConfigStore } from '@/store/serverConfig';
9
- import { useUserStore } from '@/store/user';
10
- import { keyVaultsConfigSelectors } from '@/store/user/selectors';
11
9
  import { GlobalLLMProviderKey } from '@/types/user/settings';
12
10
 
13
11
  import { FormAction } from '../style';
12
+ import { useApiKey } from './useApiKey';
14
13
 
15
14
  interface ProviderApiKeyFormProps {
16
15
  apiKeyPlaceholder?: string;
@@ -25,11 +24,7 @@ const ProviderApiKeyForm = memo<ProviderApiKeyFormProps>(
25
24
  const { t: errorT } = useTranslation('error');
26
25
  const [showProxy, setShow] = useState(false);
27
26
 
28
- const [apiKey, proxyUrl, setConfig] = useUserStore((s) => [
29
- keyVaultsConfigSelectors.getVaultByProvider(provider)(s)?.apiKey,
30
- keyVaultsConfigSelectors.getVaultByProvider(provider)(s)?.baseURL,
31
- s.updateKeyVaultConfig,
32
- ]);
27
+ const { apiKey, baseURL, setConfig } = useApiKey(provider);
33
28
  const { showOpenAIProxyUrl } = useServerConfigStore(featureFlagsSelectors);
34
29
  const providerName = useProviderName(provider);
35
30
 
@@ -58,7 +53,7 @@ const ProviderApiKeyForm = memo<ProviderApiKeyFormProps>(
58
53
  }}
59
54
  placeholder={'https://api.openai.com/v1'}
60
55
  type={'block'}
61
- value={proxyUrl}
56
+ value={baseURL}
62
57
  />
63
58
  ) : (
64
59
  <Button
@@ -0,0 +1,34 @@
1
+ import isEqual from 'fast-deep-equal';
2
+
3
+ import { isDeprecatedEdition } from '@/const/version';
4
+ import { aiProviderSelectors, useAiInfraStore } from '@/store/aiInfra';
5
+ import { useUserStore } from '@/store/user';
6
+ import { keyVaultsConfigSelectors } from '@/store/user/selectors';
7
+
8
+ export const useApiKey = (provider: string) => {
9
+ const [apiKey, baseURL, setConfig] = useUserStore((s) => [
10
+ keyVaultsConfigSelectors.getVaultByProvider(provider as any)(s)?.apiKey,
11
+ keyVaultsConfigSelectors.getVaultByProvider(provider as any)(s)?.baseURL,
12
+ s.updateKeyVaultConfig,
13
+ ]);
14
+
15
+ const updateAiProviderConfig = useAiInfraStore((s) => s.updateAiProviderConfig);
16
+ const data = useAiInfraStore(aiProviderSelectors.providerConfigById(provider), isEqual);
17
+
18
+ // TODO: remove this in V2
19
+ if (isDeprecatedEdition) return { apiKey, baseURL, setConfig };
20
+ //
21
+
22
+ return {
23
+ apiKey: data?.keyVaults.apiKey,
24
+ baseURL: data?.keyVaults?.baseURL,
25
+ setConfig: async (id: string, params: Record<string, string>) => {
26
+ await updateAiProviderConfig(id, {
27
+ keyVaults: {
28
+ ...data?.keyVaults,
29
+ ...params,
30
+ },
31
+ });
32
+ },
33
+ };
34
+ };
@@ -4,8 +4,7 @@ import urlJoin from 'url-join';
4
4
  import { INBOX_SESSION_ID } from '@/const/session';
5
5
  import { useIsMobile } from '@/hooks/useIsMobile';
6
6
  import { useQueryRoute } from '@/hooks/useQueryRoute';
7
- import { useGlobalStore } from '@/store/global';
8
- import { ChatSettingsTabs, SettingsTabs, SidebarTabKey } from '@/store/global/initialState';
7
+ import { ChatSettingsTabs, SettingsTabs } from '@/store/global/initialState';
9
8
  import { useSessionStore } from '@/store/session';
10
9
 
11
10
  export const useOpenChatSettings = (tab: ChatSettingsTabs = ChatSettingsTabs.Meta) => {
@@ -15,9 +14,6 @@ export const useOpenChatSettings = (tab: ChatSettingsTabs = ChatSettingsTabs.Met
15
14
 
16
15
  return useMemo(() => {
17
16
  if (activeId === INBOX_SESSION_ID) {
18
- useGlobalStore.setState({
19
- sidebarKey: SidebarTabKey.Setting,
20
- });
21
17
  return () => router.push(urlJoin('/settings', SettingsTabs.Agent));
22
18
  }
23
19
  if (mobile) {
@@ -2,8 +2,6 @@ import { createTRPCClient, httpBatchLink } from '@trpc/client';
2
2
  import { createTRPCReact } from '@trpc/react-query';
3
3
  import superjson from 'superjson';
4
4
 
5
- import { fetchErrorNotification } from '@/components/Error/fetchErrorNotification';
6
- import { loginRequired } from '@/components/Error/loginRequiredNotification';
7
5
  import { ModelProvider } from '@/libs/agent-runtime';
8
6
  import type { LambdaRouter } from '@/server/routers/lambda';
9
7
 
@@ -17,6 +15,9 @@ const links = [
17
15
 
18
16
  const errorRes: ErrorResponse = await response.clone().json();
19
17
 
18
+ const { loginRequired } = await import('@/components/Error/loginRequiredNotification');
19
+ const { fetchErrorNotification } = await import('@/components/Error/fetchErrorNotification');
20
+
20
21
  errorRes.forEach((item) => {
21
22
  const errorData = item.error.json;
22
23
 
@@ -37,6 +37,17 @@ const isActiveProviderApiKeyNotEmpty = (s: AIProviderStoreState) => {
37
37
  return !!vault?.apiKey || !!vault?.accessKeyId || !!vault?.secretAccessKey;
38
38
  };
39
39
 
40
+ const providerConfigById =
41
+ (id: string) =>
42
+ (s: AIProviderStoreState): AiProviderRuntimeConfig | undefined => {
43
+ if (!id) return undefined;
44
+
45
+ return s.aiProviderRuntimeConfig?.[id];
46
+ };
47
+
48
+ const isProviderConfigUpdating = (id: string) => (s: AIProviderStoreState) =>
49
+ s.aiProviderConfigUpdatingIds.includes(id);
50
+
40
51
  /**
41
52
  * @description The conditions to enable client fetch
42
53
  * 1. If no baseUrl and apikey input, force on Server.
@@ -46,7 +57,7 @@ const isActiveProviderApiKeyNotEmpty = (s: AIProviderStoreState) => {
46
57
  */
47
58
  const isProviderFetchOnClient =
48
59
  (provider: GlobalLLMProviderKey | string) => (s: AIProviderStoreState) => {
49
- const config = activeProviderConfig(s);
60
+ const config = providerConfigById(provider)(s);
50
61
 
51
62
  // If the provider already disable broswer request in model config, force on Server.
52
63
  if (isProviderDisableBroswerRequest(provider)) return false;
@@ -56,8 +67,8 @@ const isProviderFetchOnClient =
56
67
  return config?.fetchOnClient;
57
68
 
58
69
  // 1. If no baseUrl and apikey input, force on Server.
59
- const isProviderEndpointNotEmpty = isActiveProviderEndpointNotEmpty(s);
60
- const isProviderApiKeyNotEmpty = isActiveProviderApiKeyNotEmpty(s);
70
+ const isProviderEndpointNotEmpty = !!config?.keyVaults.baseURL;
71
+ const isProviderApiKeyNotEmpty = !!config?.keyVaults.apiKey;
61
72
  if (!isProviderEndpointNotEmpty && !isProviderApiKeyNotEmpty) return false;
62
73
 
63
74
  // 2. If only contains baseUrl, force on Client
@@ -76,17 +87,6 @@ const providerKeyVaults = (provider: string | undefined) => (s: AIProviderStoreS
76
87
  return s.aiProviderRuntimeConfig?.[provider]?.keyVaults;
77
88
  };
78
89
 
79
- const providerConfigById =
80
- (id: string) =>
81
- (s: AIProviderStoreState): AiProviderRuntimeConfig | undefined => {
82
- if (!id) return undefined;
83
-
84
- return s.aiProviderRuntimeConfig?.[id];
85
- };
86
-
87
- const isProviderConfigUpdating = (id: string) => (s: AIProviderStoreState) =>
88
- s.aiProviderConfigUpdatingIds.includes(id);
89
-
90
90
  export const aiProviderSelectors = {
91
91
  activeProviderConfig,
92
92
  disabledAiProviderList,
@@ -201,7 +201,7 @@ export interface EnabledAiModel {
201
201
 
202
202
  export interface AiProviderRuntimeConfig {
203
203
  fetchOnClient?: boolean;
204
- keyVaults: Record<string, object>;
204
+ keyVaults: Record<string, string>;
205
205
  settings: AiProviderSettings;
206
206
  }
207
207