@lobehub/chat 1.97.3 → 1.97.5

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,57 @@
2
2
 
3
3
  # Changelog
4
4
 
5
+ ### [Version 1.97.5](https://github.com/lobehub/lobe-chat/compare/v1.97.4...v1.97.5)
6
+
7
+ <sup>Released on **2025-07-10**</sup>
8
+
9
+ #### 💄 Styles
10
+
11
+ - **misc**: Fix: solve the loading was strange spin when switch show.
12
+
13
+ <br/>
14
+
15
+ <details>
16
+ <summary><kbd>Improvements and Fixes</kbd></summary>
17
+
18
+ #### Styles
19
+
20
+ - **misc**: Fix: solve the loading was strange spin when switch show, closes [#8333](https://github.com/lobehub/lobe-chat/issues/8333) ([07197e7](https://github.com/lobehub/lobe-chat/commit/07197e7))
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.97.4](https://github.com/lobehub/lobe-chat/compare/v1.97.3...v1.97.4)
31
+
32
+ <sup>Released on **2025-07-10**</sup>
33
+
34
+ #### 💄 Styles
35
+
36
+ - **misc**: Add `grok-4-0709` model from xAI, fix theme issue in desktop.
37
+
38
+ <br/>
39
+
40
+ <details>
41
+ <summary><kbd>Improvements and Fixes</kbd></summary>
42
+
43
+ #### Styles
44
+
45
+ - **misc**: Add `grok-4-0709` model from xAI, closes [#8379](https://github.com/lobehub/lobe-chat/issues/8379) ([b7ca447](https://github.com/lobehub/lobe-chat/commit/b7ca447))
46
+ - **misc**: Fix theme issue in desktop, closes [#8380](https://github.com/lobehub/lobe-chat/issues/8380) ([c7ae78b](https://github.com/lobehub/lobe-chat/commit/c7ae78b))
47
+
48
+ </details>
49
+
50
+ <div align="right">
51
+
52
+ [![](https://img.shields.io/badge/-BACK_TO_TOP-151515?style=flat-square)](#readme-top)
53
+
54
+ </div>
55
+
5
56
  ### [Version 1.97.3](https://github.com/lobehub/lobe-chat/compare/v1.97.2...v1.97.3)
6
57
 
7
58
  <sup>Released on **2025-07-10**</sup>
package/README.zh-CN.md CHANGED
@@ -598,9 +598,9 @@ LobeChat 提供了 Vercel 的 自托管版本 和 [Docker 镜像][docker-release
598
598
  [![][docker-size-shield]][docker-size-link]
599
599
  [![][docker-pulls-shield]][docker-pulls-link]
600
600
 
601
- We provide a Docker image for deploying the LobeChat service on your own private device. Use the following command to start the LobeChat service:
601
+ 我们提供了一个用于在您自己的私有设备上部署 LobeChat 服务的 Docker 镜像。请使用以下命令启动 LobeChat 服务:
602
602
 
603
- 1. create a folder to for storage files
603
+ 1. 创建一个用于存储文件的文件夹
604
604
 
605
605
  ```fish
606
606
  $ mkdir lobe-chat-db && cd lobe-chat-db
@@ -1,15 +1,27 @@
1
1
  import { ElectronAppState, ThemeMode } from '@lobechat/electron-client-ipc';
2
- import { app, shell, systemPreferences } from 'electron';
2
+ import { app, nativeTheme, shell, systemPreferences } from 'electron';
3
3
  import { macOS } from 'electron-is';
4
4
  import { readFileSync, writeFileSync } from 'node:fs';
5
5
  import { join } from 'node:path';
6
6
  import process from 'node:process';
7
7
 
8
8
  import { DB_SCHEMA_HASH_FILENAME, LOCAL_DATABASE_DIR, userDataDir } from '@/const/dir';
9
+ import { createLogger } from '@/utils/logger';
9
10
 
10
11
  import { ControllerModule, ipcClientEvent, ipcServerEvent } from './index';
11
12
 
13
+ const logger = createLogger('controllers:SystemCtr');
14
+
12
15
  export default class SystemController extends ControllerModule {
16
+ private systemThemeListenerInitialized = false;
17
+
18
+ /**
19
+ * Initialize system theme listener when app is ready
20
+ */
21
+ afterAppReady() {
22
+ this.initializeSystemThemeListener();
23
+ }
24
+
13
25
  /**
14
26
  * Handles the 'getDesktopAppState' IPC request.
15
27
  * Gathers essential application and system information.
@@ -26,6 +38,7 @@ export default class SystemController extends ControllerModule {
26
38
  isMac: platform === 'darwin',
27
39
  isWindows: platform === 'win32',
28
40
  platform: platform as 'darwin' | 'win32' | 'linux',
41
+ systemAppearance: nativeTheme.shouldUseDarkColors ? 'dark' : 'light',
29
42
  userPath: {
30
43
  // User Paths (ensure keys match UserPathData / DesktopAppState interface)
31
44
  desktop: app.getPath('desktop'),
@@ -100,4 +113,37 @@ export default class SystemController extends ControllerModule {
100
113
  private get DB_SCHEMA_HASH_PATH() {
101
114
  return join(this.app.appStoragePath, DB_SCHEMA_HASH_FILENAME);
102
115
  }
116
+
117
+ /**
118
+ * Initialize system theme listener to monitor OS theme changes
119
+ */
120
+ private initializeSystemThemeListener() {
121
+ if (this.systemThemeListenerInitialized) {
122
+ logger.debug('System theme listener already initialized');
123
+ return;
124
+ }
125
+
126
+ logger.info('Initializing system theme listener');
127
+
128
+ // Get initial system theme
129
+ const initialDarkMode = nativeTheme.shouldUseDarkColors;
130
+ const initialSystemTheme: ThemeMode = initialDarkMode ? 'dark' : 'light';
131
+ logger.info(`Initial system theme: ${initialSystemTheme}`);
132
+
133
+ // Listen for system theme changes
134
+ nativeTheme.on('updated', () => {
135
+ const isDarkMode = nativeTheme.shouldUseDarkColors;
136
+ const systemTheme: ThemeMode = isDarkMode ? 'dark' : 'light';
137
+
138
+ logger.info(`System theme changed to: ${systemTheme}`);
139
+
140
+ // Broadcast system theme change to all renderer processes
141
+ this.app.browserManager.broadcastToAllWindows('systemThemeChanged', {
142
+ themeMode: systemTheme,
143
+ });
144
+ });
145
+
146
+ this.systemThemeListenerInitialized = true;
147
+ logger.info('System theme listener initialized successfully');
148
+ }
103
149
  }
package/changelog/v1.json CHANGED
@@ -1,4 +1,22 @@
1
1
  [
2
+ {
3
+ "children": {
4
+ "improvements": [
5
+ "Fix: solve the loading was strange spin when switch show."
6
+ ]
7
+ },
8
+ "date": "2025-07-10",
9
+ "version": "1.97.5"
10
+ },
11
+ {
12
+ "children": {
13
+ "improvements": [
14
+ "Add grok-4-0709 model from xAI, fix theme issue in desktop."
15
+ ]
16
+ },
17
+ "date": "2025-07-10",
18
+ "version": "1.97.4"
19
+ },
2
20
  {
3
21
  "children": {},
4
22
  "date": "2025-07-10",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lobehub/chat",
3
- "version": "1.97.3",
3
+ "version": "1.97.5",
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,3 +1,5 @@
1
+ import { ThemeAppearance } from 'antd-style';
2
+
1
3
  import { ElectronAppState, ThemeMode } from '../types';
2
4
 
3
5
  export interface SystemDispatchEvents {
@@ -16,5 +18,6 @@ export interface SystemDispatchEvents {
16
18
  }
17
19
 
18
20
  export interface SystemBroadcastEvents {
21
+ systemThemeChanged: (data: { themeMode: ThemeAppearance }) => void;
19
22
  themeChanged: (data: { themeMode: ThemeMode }) => void;
20
23
  }
@@ -3,7 +3,8 @@ export interface ElectronAppState {
3
3
  isLinux?: boolean;
4
4
  isMac?: boolean;
5
5
  isWindows?: boolean;
6
- platform?: 'darwin' | 'win32' | 'linux'; // , etc.
6
+ platform?: 'darwin' | 'win32' | 'linux';
7
+ systemAppearance?: string;
7
8
  userPath?: UserPathData;
8
9
  }
9
10
 
@@ -86,7 +86,7 @@ const SystemAgentForm = memo(
86
86
  }) as FormItemProps,
87
87
  ].filter(Boolean),
88
88
  extra: (
89
- <Flexbox>
89
+ <Flexbox direction="horizontal" gap={8}>
90
90
  {loading && <Icon icon={Loader2Icon} size={16} spin style={{ opacity: 0.5 }} />}
91
91
  {allowDisable && (
92
92
  <Switch
@@ -2,6 +2,31 @@ import { AIChatModelCard } from '@/types/aiModel';
2
2
 
3
3
  // https://docs.x.ai/docs/models
4
4
  const xaiChatModels: AIChatModelCard[] = [
5
+ {
6
+ abilities: {
7
+ functionCall: true,
8
+ reasoning: true,
9
+ search: true,
10
+ },
11
+ contextWindowTokens: 256_000,
12
+ description:
13
+ '我们最新最强大的旗舰模型,在自然语言处理、数学计算和推理方面表现卓越 —— 是一款完美的全能型选手。',
14
+ displayName: 'Grok 4 0709',
15
+ enabled: true,
16
+ id: 'grok-4-0709',
17
+ pricing: {
18
+ cachedInput: 0.75,
19
+ input: 3,
20
+ output: 15,
21
+ },
22
+ releasedAt: '2025-07-09',
23
+ settings: {
24
+ // reasoning_effort is not supported by grok-4. Specifying reasoning_effort parameter will get an error response.
25
+ // extendParams: ['reasoningEffort'],
26
+ searchImpl: 'params',
27
+ },
28
+ type: 'chat',
29
+ },
5
30
  {
6
31
  abilities: {
7
32
  functionCall: true,
@@ -11,7 +36,6 @@ const xaiChatModels: AIChatModelCard[] = [
11
36
  description:
12
37
  '旗舰级模型,擅长数据提取、编程和文本摘要等企业级应用,拥有金融、医疗、法律和科学等领域的深厚知识。',
13
38
  displayName: 'Grok 3',
14
- enabled: true,
15
39
  id: 'grok-3',
16
40
  pricing: {
17
41
  cachedInput: 0.75,
@@ -3,19 +3,32 @@ import { useTheme } from 'antd-style';
3
3
  import { rgba } from 'polished';
4
4
  import { useEffect } from 'react';
5
5
 
6
+ import { useElectronStore } from '@/store/electron';
6
7
  import { useGlobalStore } from '@/store/global';
7
8
 
8
9
  export const useWatchThemeUpdate = () => {
10
+ const [systemAppearance, updateElectronAppState] = useElectronStore((s) => [
11
+ s.appState.systemAppearance,
12
+ s.updateElectronAppState,
13
+ ]);
9
14
  const switchThemeMode = useGlobalStore((s) => s.switchThemeMode);
10
15
 
11
- const token = useTheme();
16
+ const theme = useTheme();
12
17
 
13
18
  useWatchBroadcast('themeChanged', ({ themeMode }) => {
14
19
  switchThemeMode(themeMode, { skipBroadcast: true });
15
20
  });
16
21
 
22
+ useWatchBroadcast('systemThemeChanged', ({ themeMode }) => {
23
+ updateElectronAppState({ systemAppearance: themeMode });
24
+ });
25
+
17
26
  useEffect(() => {
18
27
  document.documentElement.style.background = 'none';
19
- document.body.style.background = rgba(token.colorBgLayout, 0.66);
20
- }, [token]);
28
+
29
+ // https://x.com/alanblogsooo/status/1939208908993896684
30
+ const isNotSameTheme = !systemAppearance ? true : theme.appearance !== systemAppearance;
31
+
32
+ document.body.style.background = rgba(theme.colorBgLayout, isNotSameTheme ? 0.95 : 0.66);
33
+ }, [theme, systemAppearance]);
21
34
  };
@@ -7,6 +7,11 @@ export interface XAIModelCard {
7
7
  id: string;
8
8
  }
9
9
 
10
+ export const GrokReasoningModels = new Set([
11
+ 'grok-3-mini',
12
+ 'grok-4-0709',
13
+ ]);
14
+
10
15
  export const LobeXAI = createOpenAICompatibleRuntime({
11
16
  baseURL: 'https://api.x.ai/v1',
12
17
  chatCompletion: {
@@ -15,9 +20,9 @@ export const LobeXAI = createOpenAICompatibleRuntime({
15
20
 
16
21
  return {
17
22
  ...rest,
18
- frequency_penalty: model.includes('grok-3-mini') ? undefined : frequency_penalty,
23
+ frequency_penalty: GrokReasoningModels.has(model) ? undefined : frequency_penalty,
19
24
  model,
20
- presence_penalty: model.includes('grok-3-mini') ? undefined : presence_penalty,
25
+ presence_penalty: GrokReasoningModels.has(model) ? undefined : presence_penalty,
21
26
  stream: true,
22
27
  ...(enabledSearch && {
23
28
  search_parameters: {
@@ -6,18 +6,15 @@ import { useOnlyFetchOnceSWR } from '@/libs/swr';
6
6
  // Import for type usage
7
7
  import { electronSystemService } from '@/services/electron/system';
8
8
  import { globalAgentContextManager } from '@/utils/client/GlobalAgentContextManager';
9
+ import { merge } from '@/utils/merge';
9
10
 
10
11
  import { ElectronStore } from '../store';
11
12
 
12
- // Import the new service
13
-
14
- // ======== State ======== //
15
-
16
- // Note: Actual state is defined in initialState.ts and ElectronState interface
17
-
18
13
  // ======== Action Interface ======== //
19
14
 
20
15
  export interface ElectronAppAction {
16
+ updateElectronAppState: (state: ElectronAppState) => void;
17
+
21
18
  /**
22
19
  * Initializes the basic Electron application state, including system info and special paths.
23
20
  * Should be called once when the application starts.
@@ -32,7 +29,12 @@ export const createElectronAppSlice: StateCreator<
32
29
  [['zustand/devtools', never]],
33
30
  [],
34
31
  ElectronAppAction
35
- > = (set) => ({
32
+ > = (set, get) => ({
33
+ updateElectronAppState: (state: ElectronAppState) => {
34
+ const prevState = get().appState;
35
+ set({ appState: merge(prevState, state) });
36
+ },
37
+
36
38
  useInitElectronAppState: () =>
37
39
  useOnlyFetchOnceSWR<ElectronAppState>(
38
40
  'initElectronAppState',