@lobehub/lobehub 2.0.0-next.21 → 2.0.0-next.23
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 +42 -0
- package/apps/desktop/src/main/controllers/AuthCtr.ts +3 -3
- package/apps/desktop/src/main/controllers/MenuCtr.ts +5 -5
- package/apps/desktop/src/main/controllers/NotificationCtr.ts +29 -29
- package/apps/desktop/src/main/controllers/RemoteServerConfigCtr.ts +16 -16
- package/apps/desktop/src/main/controllers/ShortcutCtr.ts +2 -2
- package/apps/desktop/src/main/controllers/TrayMenuCtr.ts +18 -18
- package/apps/desktop/src/main/controllers/UpdaterCtr.ts +4 -4
- package/apps/desktop/src/main/controllers/__tests__/TrayMenuCtr.test.ts +5 -5
- package/apps/desktop/src/main/controllers/index.ts +4 -4
- package/changelog/v1.json +14 -0
- package/docs/development/database-schema.dbml +2 -1
- package/package.json +2 -2
- package/packages/database/migrations/0042_improve_agent_index.sql +1 -0
- package/packages/database/migrations/meta/0042_snapshot.json +7800 -0
- package/packages/database/migrations/meta/_journal.json +7 -0
- package/packages/database/src/core/migrations.json +8 -0
- package/packages/database/src/models/agent.ts +16 -13
- package/packages/database/src/models/session.ts +20 -9
- package/packages/database/src/models/user.ts +2 -1
- package/packages/database/src/schemas/agent.ts +4 -1
- package/packages/memory-extract/package.json +1 -1
- package/packages/types/src/message/ui/params.ts +4 -4
- package/renovate.json +49 -13
- package/src/server/routers/lambda/message.ts +0 -2
- package/src/server/routers/lambda/user.ts +8 -6
- package/src/server/services/mcp/deps/MCPSystemDepsCheckService.test.ts +541 -0
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,48 @@
|
|
|
2
2
|
|
|
3
3
|
# Changelog
|
|
4
4
|
|
|
5
|
+
## [Version 2.0.0-next.23](https://github.com/lobehub/lobe-chat/compare/v2.0.0-next.22...v2.0.0-next.23)
|
|
6
|
+
|
|
7
|
+
<sup>Released on **2025-11-04**</sup>
|
|
8
|
+
|
|
9
|
+
#### 🐛 Bug Fixes
|
|
10
|
+
|
|
11
|
+
- **misc**: Fix send message.
|
|
12
|
+
|
|
13
|
+
<br/>
|
|
14
|
+
|
|
15
|
+
<details>
|
|
16
|
+
<summary><kbd>Improvements and Fixes</kbd></summary>
|
|
17
|
+
|
|
18
|
+
#### What's fixed
|
|
19
|
+
|
|
20
|
+
- **misc**: Fix send message, closes [#10041](https://github.com/lobehub/lobe-chat/issues/10041) [#9984](https://github.com/lobehub/lobe-chat/issues/9984) ([7cca60f](https://github.com/lobehub/lobe-chat/commit/7cca60f))
|
|
21
|
+
|
|
22
|
+
</details>
|
|
23
|
+
|
|
24
|
+
<div align="right">
|
|
25
|
+
|
|
26
|
+
[](#readme-top)
|
|
27
|
+
|
|
28
|
+
</div>
|
|
29
|
+
|
|
30
|
+
## [Version 2.0.0-next.22](https://github.com/lobehub/lobe-chat/compare/v2.0.0-next.21...v2.0.0-next.22)
|
|
31
|
+
|
|
32
|
+
<sup>Released on **2025-11-04**</sup>
|
|
33
|
+
|
|
34
|
+
<br/>
|
|
35
|
+
|
|
36
|
+
<details>
|
|
37
|
+
<summary><kbd>Improvements and Fixes</kbd></summary>
|
|
38
|
+
|
|
39
|
+
</details>
|
|
40
|
+
|
|
41
|
+
<div align="right">
|
|
42
|
+
|
|
43
|
+
[](#readme-top)
|
|
44
|
+
|
|
45
|
+
</div>
|
|
46
|
+
|
|
5
47
|
## [Version 2.0.0-next.21](https://github.com/lobehub/lobe-chat/compare/v2.0.0-next.20...v2.0.0-next.21)
|
|
6
48
|
|
|
7
49
|
<sup>Released on **2025-11-04**</sup>
|
|
@@ -58,7 +58,7 @@ export default class AuthCtr extends ControllerModule {
|
|
|
58
58
|
*/
|
|
59
59
|
@ipcClientEvent('requestAuthorization')
|
|
60
60
|
async requestAuthorization(config: DataSyncConfig) {
|
|
61
|
-
//
|
|
61
|
+
// Clear any old authorization state
|
|
62
62
|
this.clearAuthorizationState();
|
|
63
63
|
|
|
64
64
|
const remoteUrl = await this.remoteServerConfigCtr.getRemoteServerUrl(config);
|
|
@@ -186,8 +186,8 @@ export default class AuthCtr extends ControllerModule {
|
|
|
186
186
|
}
|
|
187
187
|
|
|
188
188
|
/**
|
|
189
|
-
*
|
|
190
|
-
*
|
|
189
|
+
* Clear authorization state
|
|
190
|
+
* Called before starting a new authorization flow or after authorization failure/timeout
|
|
191
191
|
*/
|
|
192
192
|
private clearAuthorizationState() {
|
|
193
193
|
logger.debug('Clearing authorization state');
|
|
@@ -2,16 +2,16 @@ import { ControllerModule, ipcClientEvent } from './index';
|
|
|
2
2
|
|
|
3
3
|
export default class MenuController extends ControllerModule {
|
|
4
4
|
/**
|
|
5
|
-
*
|
|
5
|
+
* Refresh menu
|
|
6
6
|
*/
|
|
7
7
|
@ipcClientEvent('refreshAppMenu')
|
|
8
8
|
refreshAppMenu() {
|
|
9
|
-
//
|
|
9
|
+
// Note: May need to decide whether to allow renderer process to refresh all menus based on specific circumstances
|
|
10
10
|
return this.app.menuManager.refreshMenus();
|
|
11
11
|
}
|
|
12
12
|
|
|
13
13
|
/**
|
|
14
|
-
*
|
|
14
|
+
* Show context menu
|
|
15
15
|
*/
|
|
16
16
|
@ipcClientEvent('showContextMenu')
|
|
17
17
|
showContextMenu(params: { data?: any; type: string }) {
|
|
@@ -19,11 +19,11 @@ export default class MenuController extends ControllerModule {
|
|
|
19
19
|
}
|
|
20
20
|
|
|
21
21
|
/**
|
|
22
|
-
*
|
|
22
|
+
* Set development menu visibility
|
|
23
23
|
*/
|
|
24
24
|
@ipcClientEvent('setDevMenuVisibility')
|
|
25
25
|
setDevMenuVisibility(visible: boolean) {
|
|
26
|
-
//
|
|
26
|
+
// Call MenuManager method to rebuild application menu
|
|
27
27
|
return this.app.menuManager.rebuildAppMenu({ showDevItems: visible });
|
|
28
28
|
}
|
|
29
29
|
}
|
|
@@ -13,31 +13,31 @@ const logger = createLogger('controllers:NotificationCtr');
|
|
|
13
13
|
|
|
14
14
|
export default class NotificationCtr extends ControllerModule {
|
|
15
15
|
/**
|
|
16
|
-
*
|
|
16
|
+
* Set up desktop notifications after the application is ready
|
|
17
17
|
*/
|
|
18
18
|
afterAppReady() {
|
|
19
19
|
this.setupNotifications();
|
|
20
20
|
}
|
|
21
21
|
|
|
22
22
|
/**
|
|
23
|
-
*
|
|
23
|
+
* Set up desktop notification permissions and configuration
|
|
24
24
|
*/
|
|
25
25
|
private setupNotifications() {
|
|
26
26
|
logger.debug('Setting up desktop notifications');
|
|
27
27
|
|
|
28
28
|
try {
|
|
29
|
-
//
|
|
29
|
+
// Check notification support
|
|
30
30
|
if (!Notification.isSupported()) {
|
|
31
31
|
logger.warn('Desktop notifications are not supported on this platform');
|
|
32
32
|
return;
|
|
33
33
|
}
|
|
34
34
|
|
|
35
|
-
//
|
|
35
|
+
// On macOS, we may need to explicitly request notification permissions
|
|
36
36
|
if (macOS()) {
|
|
37
37
|
logger.debug('macOS detected, notification permissions should be handled by system');
|
|
38
38
|
}
|
|
39
39
|
|
|
40
|
-
//
|
|
40
|
+
// Set app user model ID on Windows
|
|
41
41
|
if (windows()) {
|
|
42
42
|
app.setAppUserModelId('com.lobehub.chat');
|
|
43
43
|
logger.debug('Set Windows App User Model ID for notifications');
|
|
@@ -49,34 +49,34 @@ export default class NotificationCtr extends ControllerModule {
|
|
|
49
49
|
}
|
|
50
50
|
}
|
|
51
51
|
/**
|
|
52
|
-
*
|
|
52
|
+
* Show system desktop notification (only when window is hidden)
|
|
53
53
|
*/
|
|
54
54
|
@ipcClientEvent('showDesktopNotification')
|
|
55
55
|
async showDesktopNotification(
|
|
56
56
|
params: ShowDesktopNotificationParams,
|
|
57
57
|
): Promise<DesktopNotificationResult> {
|
|
58
|
-
logger.debug('
|
|
58
|
+
logger.debug('Received desktop notification request:', params);
|
|
59
59
|
|
|
60
60
|
try {
|
|
61
|
-
//
|
|
61
|
+
// Check notification support
|
|
62
62
|
if (!Notification.isSupported()) {
|
|
63
|
-
logger.warn('
|
|
63
|
+
logger.warn('System does not support desktop notifications');
|
|
64
64
|
return { error: 'Desktop notifications not supported', success: false };
|
|
65
65
|
}
|
|
66
66
|
|
|
67
|
-
//
|
|
67
|
+
// Check if window is hidden
|
|
68
68
|
const isWindowHidden = this.isMainWindowHidden();
|
|
69
69
|
|
|
70
70
|
if (!isWindowHidden) {
|
|
71
|
-
logger.debug('
|
|
71
|
+
logger.debug('Main window is visible, skipping desktop notification');
|
|
72
72
|
return { reason: 'Window is visible', skipped: true, success: true };
|
|
73
73
|
}
|
|
74
74
|
|
|
75
|
-
logger.info('
|
|
75
|
+
logger.info('Window is hidden, showing desktop notification:', params.title);
|
|
76
76
|
|
|
77
77
|
const notification = new Notification({
|
|
78
78
|
body: params.body,
|
|
79
|
-
//
|
|
79
|
+
// Add more configuration to ensure notifications display properly
|
|
80
80
|
hasReply: false,
|
|
81
81
|
silent: params.silent || false,
|
|
82
82
|
timeoutType: 'default',
|
|
@@ -84,38 +84,38 @@ export default class NotificationCtr extends ControllerModule {
|
|
|
84
84
|
urgency: 'normal',
|
|
85
85
|
});
|
|
86
86
|
|
|
87
|
-
//
|
|
87
|
+
// Add more event listeners for debugging
|
|
88
88
|
notification.on('show', () => {
|
|
89
|
-
logger.info('
|
|
89
|
+
logger.info('Notification shown');
|
|
90
90
|
});
|
|
91
91
|
|
|
92
92
|
notification.on('click', () => {
|
|
93
|
-
logger.debug('
|
|
93
|
+
logger.debug('User clicked notification, showing main window');
|
|
94
94
|
const mainWindow = this.app.browserManager.getMainWindow();
|
|
95
95
|
mainWindow.show();
|
|
96
96
|
mainWindow.browserWindow.focus();
|
|
97
97
|
});
|
|
98
98
|
|
|
99
99
|
notification.on('close', () => {
|
|
100
|
-
logger.debug('
|
|
100
|
+
logger.debug('Notification closed');
|
|
101
101
|
});
|
|
102
102
|
|
|
103
103
|
notification.on('failed', (error) => {
|
|
104
|
-
logger.error('
|
|
104
|
+
logger.error('Notification display failed:', error);
|
|
105
105
|
});
|
|
106
106
|
|
|
107
|
-
//
|
|
107
|
+
// Use Promise to ensure notification is shown
|
|
108
108
|
return new Promise((resolve) => {
|
|
109
109
|
notification.show();
|
|
110
110
|
|
|
111
|
-
//
|
|
111
|
+
// Give the notification some time to display, then check the result
|
|
112
112
|
setTimeout(() => {
|
|
113
|
-
logger.info('
|
|
113
|
+
logger.info('Notification display call completed');
|
|
114
114
|
resolve({ success: true });
|
|
115
115
|
}, 100);
|
|
116
116
|
});
|
|
117
117
|
} catch (error) {
|
|
118
|
-
logger.error('
|
|
118
|
+
logger.error('Failed to show desktop notification:', error);
|
|
119
119
|
return {
|
|
120
120
|
error: error instanceof Error ? error.message : 'Unknown error',
|
|
121
121
|
success: false,
|
|
@@ -124,7 +124,7 @@ export default class NotificationCtr extends ControllerModule {
|
|
|
124
124
|
}
|
|
125
125
|
|
|
126
126
|
/**
|
|
127
|
-
*
|
|
127
|
+
* Check if the main window is hidden
|
|
128
128
|
*/
|
|
129
129
|
@ipcClientEvent('isMainWindowHidden')
|
|
130
130
|
isMainWindowHidden(): boolean {
|
|
@@ -132,23 +132,23 @@ export default class NotificationCtr extends ControllerModule {
|
|
|
132
132
|
const mainWindow = this.app.browserManager.getMainWindow();
|
|
133
133
|
const browserWindow = mainWindow.browserWindow;
|
|
134
134
|
|
|
135
|
-
//
|
|
135
|
+
// If window is destroyed, consider it hidden
|
|
136
136
|
if (browserWindow.isDestroyed()) {
|
|
137
137
|
return true;
|
|
138
138
|
}
|
|
139
139
|
|
|
140
|
-
//
|
|
140
|
+
// Check if window is visible and focused
|
|
141
141
|
const isVisible = browserWindow.isVisible();
|
|
142
142
|
const isFocused = browserWindow.isFocused();
|
|
143
143
|
const isMinimized = browserWindow.isMinimized();
|
|
144
144
|
|
|
145
|
-
logger.debug('
|
|
145
|
+
logger.debug('Window state check:', { isFocused, isMinimized, isVisible });
|
|
146
146
|
|
|
147
|
-
//
|
|
147
|
+
// Window is hidden if: not visible, minimized, or not focused
|
|
148
148
|
return !isVisible || isMinimized || !isFocused;
|
|
149
149
|
} catch (error) {
|
|
150
|
-
logger.error('
|
|
151
|
-
return true; //
|
|
150
|
+
logger.error('Failed to check window state:', error);
|
|
151
|
+
return true; // Consider window hidden on error to ensure notifications can be shown
|
|
152
152
|
}
|
|
153
153
|
}
|
|
154
154
|
}
|
|
@@ -246,8 +246,8 @@ export default class RemoteServerConfigCtr extends ControllerModule {
|
|
|
246
246
|
}
|
|
247
247
|
|
|
248
248
|
/**
|
|
249
|
-
*
|
|
250
|
-
*
|
|
249
|
+
* Refresh access token
|
|
250
|
+
* Use stored refresh token to obtain a new access token
|
|
251
251
|
* Handles concurrent requests by returning the existing refresh promise if one is in progress.
|
|
252
252
|
*/
|
|
253
253
|
async refreshAccessToken(): Promise<{ error?: string; success: boolean }> {
|
|
@@ -271,27 +271,27 @@ export default class RemoteServerConfigCtr extends ControllerModule {
|
|
|
271
271
|
*/
|
|
272
272
|
private async performTokenRefresh(): Promise<{ error?: string; success: boolean }> {
|
|
273
273
|
try {
|
|
274
|
-
//
|
|
274
|
+
// Get configuration information
|
|
275
275
|
const config = await this.getRemoteServerConfig();
|
|
276
276
|
|
|
277
277
|
if (!config.remoteServerUrl || !config.active) {
|
|
278
278
|
logger.warn('Remote server not active or configured, skipping refresh.');
|
|
279
|
-
return { error: '
|
|
279
|
+
return { error: 'Remote server is not active or configured', success: false };
|
|
280
280
|
}
|
|
281
281
|
|
|
282
|
-
//
|
|
282
|
+
// Get refresh token
|
|
283
283
|
const refreshToken = await this.getRefreshToken();
|
|
284
284
|
if (!refreshToken) {
|
|
285
285
|
logger.error('No refresh token available for refresh operation.');
|
|
286
|
-
return { error: '
|
|
286
|
+
return { error: 'No refresh token available', success: false };
|
|
287
287
|
}
|
|
288
288
|
|
|
289
|
-
//
|
|
289
|
+
// Construct refresh request
|
|
290
290
|
const remoteUrl = await this.getRemoteServerUrl(config);
|
|
291
291
|
|
|
292
292
|
const tokenUrl = new URL('/oidc/token', remoteUrl);
|
|
293
293
|
|
|
294
|
-
//
|
|
294
|
+
// Construct request body
|
|
295
295
|
const body = querystring.stringify({
|
|
296
296
|
client_id: 'lobehub-desktop',
|
|
297
297
|
grant_type: 'refresh_token',
|
|
@@ -300,7 +300,7 @@ export default class RemoteServerConfigCtr extends ControllerModule {
|
|
|
300
300
|
|
|
301
301
|
logger.debug(`Sending token refresh request to ${tokenUrl.toString()}`);
|
|
302
302
|
|
|
303
|
-
//
|
|
303
|
+
// Send request
|
|
304
304
|
const response = await fetch(tokenUrl.toString(), {
|
|
305
305
|
body,
|
|
306
306
|
headers: {
|
|
@@ -310,25 +310,25 @@ export default class RemoteServerConfigCtr extends ControllerModule {
|
|
|
310
310
|
});
|
|
311
311
|
|
|
312
312
|
if (!response.ok) {
|
|
313
|
-
//
|
|
313
|
+
// Try to parse error response
|
|
314
314
|
const errorData = await response.json().catch(() => ({}));
|
|
315
|
-
const errorMessage =
|
|
315
|
+
const errorMessage = `Token refresh failed: ${response.status} ${response.statusText} ${
|
|
316
316
|
errorData.error_description || errorData.error || ''
|
|
317
317
|
}`.trim();
|
|
318
318
|
logger.error(errorMessage, errorData);
|
|
319
319
|
return { error: errorMessage, success: false };
|
|
320
320
|
}
|
|
321
321
|
|
|
322
|
-
//
|
|
322
|
+
// Parse response
|
|
323
323
|
const data = await response.json();
|
|
324
324
|
|
|
325
|
-
//
|
|
325
|
+
// Check if response contains necessary tokens
|
|
326
326
|
if (!data.access_token || !data.refresh_token) {
|
|
327
327
|
logger.error('Refresh response missing access_token or refresh_token', data);
|
|
328
|
-
return { error: '
|
|
328
|
+
return { error: 'Missing tokens in refresh response', success: false };
|
|
329
329
|
}
|
|
330
330
|
|
|
331
|
-
//
|
|
331
|
+
// Save new tokens
|
|
332
332
|
logger.info('Token refresh successful, saving new tokens.');
|
|
333
333
|
await this.saveTokens(data.access_token, data.refresh_token, data.expires_in);
|
|
334
334
|
|
|
@@ -336,7 +336,7 @@ export default class RemoteServerConfigCtr extends ControllerModule {
|
|
|
336
336
|
} catch (error) {
|
|
337
337
|
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
338
338
|
logger.error('Exception during token refresh operation:', errorMessage, error);
|
|
339
|
-
return { error:
|
|
339
|
+
return { error: `Exception occurred during token refresh: ${errorMessage}`, success: false };
|
|
340
340
|
} finally {
|
|
341
341
|
// Ensure the promise reference is cleared once the operation completes
|
|
342
342
|
logger.debug('Clearing the refresh promise reference.');
|
|
@@ -4,7 +4,7 @@ import { ControllerModule, ipcClientEvent } from '.';
|
|
|
4
4
|
|
|
5
5
|
export default class ShortcutController extends ControllerModule {
|
|
6
6
|
/**
|
|
7
|
-
*
|
|
7
|
+
* Get all shortcut configurations
|
|
8
8
|
*/
|
|
9
9
|
@ipcClientEvent('getShortcutsConfig')
|
|
10
10
|
getShortcutsConfig() {
|
|
@@ -12,7 +12,7 @@ export default class ShortcutController extends ControllerModule {
|
|
|
12
12
|
}
|
|
13
13
|
|
|
14
14
|
/**
|
|
15
|
-
*
|
|
15
|
+
* Update a single shortcut configuration
|
|
16
16
|
*/
|
|
17
17
|
@ipcClientEvent('updateShortcutConfig')
|
|
18
18
|
updateShortcutConfig({
|
|
@@ -8,24 +8,24 @@ import { createLogger } from '@/utils/logger';
|
|
|
8
8
|
|
|
9
9
|
import { ControllerModule, ipcClientEvent } from './index';
|
|
10
10
|
|
|
11
|
-
//
|
|
11
|
+
// Create logger
|
|
12
12
|
const logger = createLogger('controllers:TrayMenuCtr');
|
|
13
13
|
|
|
14
14
|
export default class TrayMenuCtr extends ControllerModule {
|
|
15
15
|
async toggleMainWindow() {
|
|
16
|
-
logger.debug('
|
|
16
|
+
logger.debug('Toggle main window visibility via shortcut');
|
|
17
17
|
const mainWindow = this.app.browserManager.getMainWindow();
|
|
18
18
|
mainWindow.toggleVisible();
|
|
19
19
|
}
|
|
20
20
|
|
|
21
21
|
/**
|
|
22
|
-
*
|
|
23
|
-
* @param options
|
|
24
|
-
* @returns
|
|
22
|
+
* Show tray balloon notification
|
|
23
|
+
* @param options Balloon options
|
|
24
|
+
* @returns Operation result
|
|
25
25
|
*/
|
|
26
26
|
@ipcClientEvent('showTrayNotification')
|
|
27
27
|
async showNotification(options: ShowTrayNotificationParams) {
|
|
28
|
-
logger.debug('
|
|
28
|
+
logger.debug('Show tray balloon notification');
|
|
29
29
|
|
|
30
30
|
if (process.platform === 'win32') {
|
|
31
31
|
const mainTray = this.app.trayManager.getMainTray();
|
|
@@ -42,19 +42,19 @@ export default class TrayMenuCtr extends ControllerModule {
|
|
|
42
42
|
}
|
|
43
43
|
|
|
44
44
|
return {
|
|
45
|
-
error: '
|
|
45
|
+
error: 'Tray notifications are only supported on Windows platform',
|
|
46
46
|
success: false,
|
|
47
47
|
};
|
|
48
48
|
}
|
|
49
49
|
|
|
50
50
|
/**
|
|
51
|
-
*
|
|
52
|
-
* @param options
|
|
53
|
-
* @returns
|
|
51
|
+
* Update tray icon
|
|
52
|
+
* @param options Icon options
|
|
53
|
+
* @returns Operation result
|
|
54
54
|
*/
|
|
55
55
|
@ipcClientEvent('updateTrayIcon')
|
|
56
56
|
async updateTrayIcon(options: UpdateTrayIconParams) {
|
|
57
|
-
logger.debug('
|
|
57
|
+
logger.debug('Update tray icon');
|
|
58
58
|
|
|
59
59
|
if (process.platform === 'win32') {
|
|
60
60
|
const mainTray = this.app.trayManager.getMainTray();
|
|
@@ -64,7 +64,7 @@ export default class TrayMenuCtr extends ControllerModule {
|
|
|
64
64
|
mainTray.updateIcon(options.iconPath);
|
|
65
65
|
return { success: true };
|
|
66
66
|
} catch (error) {
|
|
67
|
-
logger.error('
|
|
67
|
+
logger.error('Failed to update tray icon:', error);
|
|
68
68
|
return {
|
|
69
69
|
error: String(error),
|
|
70
70
|
success: false,
|
|
@@ -74,19 +74,19 @@ export default class TrayMenuCtr extends ControllerModule {
|
|
|
74
74
|
}
|
|
75
75
|
|
|
76
76
|
return {
|
|
77
|
-
error: '
|
|
77
|
+
error: 'Tray functionality is only supported on Windows platform',
|
|
78
78
|
success: false,
|
|
79
79
|
};
|
|
80
80
|
}
|
|
81
81
|
|
|
82
82
|
/**
|
|
83
|
-
*
|
|
84
|
-
* @param options
|
|
85
|
-
* @returns
|
|
83
|
+
* Update tray tooltip text
|
|
84
|
+
* @param options Tooltip text options
|
|
85
|
+
* @returns Operation result
|
|
86
86
|
*/
|
|
87
87
|
@ipcClientEvent('updateTrayTooltip')
|
|
88
88
|
async updateTrayTooltip(options: UpdateTrayTooltipParams) {
|
|
89
|
-
logger.debug('
|
|
89
|
+
logger.debug('Update tray tooltip text');
|
|
90
90
|
|
|
91
91
|
if (process.platform === 'win32') {
|
|
92
92
|
const mainTray = this.app.trayManager.getMainTray();
|
|
@@ -98,7 +98,7 @@ export default class TrayMenuCtr extends ControllerModule {
|
|
|
98
98
|
}
|
|
99
99
|
|
|
100
100
|
return {
|
|
101
|
-
error: '
|
|
101
|
+
error: 'Tray functionality is only supported on Windows platform',
|
|
102
102
|
success: false,
|
|
103
103
|
};
|
|
104
104
|
}
|
|
@@ -6,7 +6,7 @@ const logger = createLogger('controllers:UpdaterCtr');
|
|
|
6
6
|
|
|
7
7
|
export default class UpdaterCtr extends ControllerModule {
|
|
8
8
|
/**
|
|
9
|
-
*
|
|
9
|
+
* Check for updates
|
|
10
10
|
*/
|
|
11
11
|
@ipcClientEvent('checkUpdate')
|
|
12
12
|
async checkForUpdates() {
|
|
@@ -15,7 +15,7 @@ export default class UpdaterCtr extends ControllerModule {
|
|
|
15
15
|
}
|
|
16
16
|
|
|
17
17
|
/**
|
|
18
|
-
*
|
|
18
|
+
* Download update
|
|
19
19
|
*/
|
|
20
20
|
@ipcClientEvent('downloadUpdate')
|
|
21
21
|
async downloadUpdate() {
|
|
@@ -24,7 +24,7 @@ export default class UpdaterCtr extends ControllerModule {
|
|
|
24
24
|
}
|
|
25
25
|
|
|
26
26
|
/**
|
|
27
|
-
*
|
|
27
|
+
* Quit application and install update
|
|
28
28
|
*/
|
|
29
29
|
@ipcClientEvent('installNow')
|
|
30
30
|
quitAndInstallUpdate() {
|
|
@@ -33,7 +33,7 @@ export default class UpdaterCtr extends ControllerModule {
|
|
|
33
33
|
}
|
|
34
34
|
|
|
35
35
|
/**
|
|
36
|
-
*
|
|
36
|
+
* Install update on next startup
|
|
37
37
|
*/
|
|
38
38
|
@ipcClientEvent('installLater')
|
|
39
39
|
installLater() {
|
|
@@ -106,7 +106,7 @@ describe('TrayMenuCtr', () => {
|
|
|
106
106
|
expect(mockGetMainTray).not.toHaveBeenCalled();
|
|
107
107
|
expect(mockDisplayBalloon).not.toHaveBeenCalled();
|
|
108
108
|
expect(result).toEqual({
|
|
109
|
-
error: '
|
|
109
|
+
error: 'Tray notifications are only supported on Windows platform',
|
|
110
110
|
success: false,
|
|
111
111
|
});
|
|
112
112
|
});
|
|
@@ -126,7 +126,7 @@ describe('TrayMenuCtr', () => {
|
|
|
126
126
|
expect(mockGetMainTray).toHaveBeenCalled();
|
|
127
127
|
expect(mockDisplayBalloon).not.toHaveBeenCalled();
|
|
128
128
|
expect(result).toEqual({
|
|
129
|
-
error: '
|
|
129
|
+
error: 'Tray notifications are only supported on Windows platform',
|
|
130
130
|
success: false
|
|
131
131
|
});
|
|
132
132
|
});
|
|
@@ -188,7 +188,7 @@ describe('TrayMenuCtr', () => {
|
|
|
188
188
|
const result = await trayMenuCtr.updateTrayIcon(options);
|
|
189
189
|
|
|
190
190
|
expect(result).toEqual({
|
|
191
|
-
error: '
|
|
191
|
+
error: 'Tray functionality is only supported on Windows platform',
|
|
192
192
|
success: false,
|
|
193
193
|
});
|
|
194
194
|
});
|
|
@@ -226,7 +226,7 @@ describe('TrayMenuCtr', () => {
|
|
|
226
226
|
const result = await trayMenuCtr.updateTrayTooltip(options);
|
|
227
227
|
|
|
228
228
|
expect(result).toEqual({
|
|
229
|
-
error: '
|
|
229
|
+
error: 'Tray functionality is only supported on Windows platform',
|
|
230
230
|
success: false,
|
|
231
231
|
});
|
|
232
232
|
});
|
|
@@ -248,7 +248,7 @@ describe('TrayMenuCtr', () => {
|
|
|
248
248
|
|
|
249
249
|
expect(mockUpdateTooltip).not.toHaveBeenCalled();
|
|
250
250
|
expect(result).toEqual({
|
|
251
|
-
error: '
|
|
251
|
+
error: 'Tray functionality is only supported on Windows platform',
|
|
252
252
|
success: false,
|
|
253
253
|
});
|
|
254
254
|
});
|
|
@@ -19,13 +19,13 @@ const ipcDecorator =
|
|
|
19
19
|
};
|
|
20
20
|
|
|
21
21
|
/**
|
|
22
|
-
*
|
|
22
|
+
* IPC client event decorator for controllers
|
|
23
23
|
*/
|
|
24
24
|
export const ipcClientEvent = (method: keyof ClientDispatchEvents) =>
|
|
25
25
|
ipcDecorator(method, 'client');
|
|
26
26
|
|
|
27
27
|
/**
|
|
28
|
-
*
|
|
28
|
+
* IPC server event decorator for controllers
|
|
29
29
|
*/
|
|
30
30
|
export const ipcServerEvent = (method: keyof ServerDispatchEvents) =>
|
|
31
31
|
ipcDecorator(method, 'server');
|
|
@@ -56,8 +56,8 @@ const protocolDecorator =
|
|
|
56
56
|
|
|
57
57
|
/**
|
|
58
58
|
* Protocol handler decorator
|
|
59
|
-
* @param urlType
|
|
60
|
-
* @param action
|
|
59
|
+
* @param urlType Protocol URL type (e.g., 'plugin')
|
|
60
|
+
* @param action Action type (e.g., 'install')
|
|
61
61
|
*/
|
|
62
62
|
export const createProtocolHandler = (urlType: string) => (action: string) =>
|
|
63
63
|
protocolDecorator(urlType, action);
|
package/changelog/v1.json
CHANGED
|
@@ -1,4 +1,18 @@
|
|
|
1
1
|
[
|
|
2
|
+
{
|
|
3
|
+
"children": {
|
|
4
|
+
"fixes": [
|
|
5
|
+
"Fix send message."
|
|
6
|
+
]
|
|
7
|
+
},
|
|
8
|
+
"date": "2025-11-04",
|
|
9
|
+
"version": "2.0.0-next.23"
|
|
10
|
+
},
|
|
11
|
+
{
|
|
12
|
+
"children": {},
|
|
13
|
+
"date": "2025-11-04",
|
|
14
|
+
"version": "2.0.0-next.22"
|
|
15
|
+
},
|
|
2
16
|
{
|
|
3
17
|
"children": {
|
|
4
18
|
"fixes": [
|
|
@@ -56,6 +56,7 @@ table agents_knowledge_bases {
|
|
|
56
56
|
|
|
57
57
|
indexes {
|
|
58
58
|
(agent_id, knowledge_base_id) [pk]
|
|
59
|
+
agent_id [name: 'agents_knowledge_bases_agent_id_idx']
|
|
59
60
|
}
|
|
60
61
|
}
|
|
61
62
|
|
|
@@ -1176,4 +1177,4 @@ ref: topic_documents.document_id > documents.id
|
|
|
1176
1177
|
|
|
1177
1178
|
ref: topic_documents.topic_id > topics.id
|
|
1178
1179
|
|
|
1179
|
-
ref: topics.session_id - sessions.id
|
|
1180
|
+
ref: topics.session_id - sessions.id
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lobehub/lobehub",
|
|
3
|
-
"version": "2.0.0-next.
|
|
3
|
+
"version": "2.0.0-next.23",
|
|
4
4
|
"description": "LobeHub - an open-source,comprehensive AI Agent 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",
|
|
@@ -250,7 +250,7 @@
|
|
|
250
250
|
"pdfjs-dist": "4.8.69",
|
|
251
251
|
"pdfkit": "^0.17.2",
|
|
252
252
|
"pg": "^8.16.3",
|
|
253
|
-
"pino": "^
|
|
253
|
+
"pino": "^10.1.0",
|
|
254
254
|
"plaiceholder": "^3.0.0",
|
|
255
255
|
"polished": "^4.3.1",
|
|
256
256
|
"posthog-js": "~1.278.0",
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
CREATE INDEX IF NOT EXISTS "agents_knowledge_bases_agent_id_idx" ON "agents_knowledge_bases" USING btree ("agent_id");
|