@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 +51 -0
- package/README.zh-CN.md +2 -2
- package/apps/desktop/src/main/controllers/SystemCtr.ts +47 -1
- package/changelog/v1.json +18 -0
- package/package.json +1 -1
- package/packages/electron-client-ipc/src/events/system.ts +3 -0
- package/packages/electron-client-ipc/src/types/system.ts +2 -1
- package/src/app/[variants]/(main)/settings/system-agent/features/createForm.tsx +1 -1
- package/src/config/aiModels/xai.ts +25 -1
- package/src/features/ElectronTitlebar/hooks/useWatchThemeUpdate.ts +16 -3
- package/src/libs/model-runtime/xai/index.ts +7 -2
- package/src/store/electron/actions/app.ts +9 -7
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
|
+
[](#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
|
+
[](#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
|
-
|
601
|
+
我们提供了一个用于在您自己的私有设备上部署 LobeChat 服务的 Docker 镜像。请使用以下命令启动 LobeChat 服务:
|
602
602
|
|
603
|
-
1.
|
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
|
+
"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
|
}
|
@@ -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
|
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
|
-
|
20
|
-
|
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:
|
23
|
+
frequency_penalty: GrokReasoningModels.has(model) ? undefined : frequency_penalty,
|
19
24
|
model,
|
20
|
-
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',
|