@lobehub/lobehub 2.0.0-next.312 → 2.0.0-next.314
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/apps/desktop/src/main/appBrowsers.ts +4 -1
- package/apps/desktop/src/main/controllers/AuthCtr.ts +75 -7
- package/apps/desktop/src/main/controllers/BrowserWindowsCtr.ts +15 -3
- package/apps/desktop/src/main/core/browser/Browser.ts +14 -4
- package/apps/desktop/src/main/core/browser/BrowserManager.ts +7 -2
- package/changelog/v1.json +18 -0
- package/docs/usage/providers/internlm.mdx +2 -2
- package/docs/usage/providers/internlm.zh-CN.mdx +3 -3
- package/e2e/src/steps/community/detail-pages.steps.ts +2 -2
- package/e2e/src/steps/community/interactions.steps.ts +6 -6
- package/e2e/src/steps/hooks.ts +19 -3
- package/locales/en-US/error.json +10 -1
- package/locales/en-US/subscription.json +1 -1
- package/locales/zh-CN/desktop-onboarding.json +5 -0
- package/locales/zh-CN/error.json +10 -1
- package/locales/zh-CN/subscription.json +1 -1
- package/package.json +1 -1
- package/packages/agent-runtime/src/agents/GeneralChatAgent.ts +14 -2
- package/packages/agent-runtime/src/agents/__tests__/GeneralChatAgent.test.ts +275 -1
- package/packages/builtin-tool-cloud-sandbox/package.json +1 -0
- package/packages/builtin-tool-cloud-sandbox/src/ExecutionRuntime/index.ts +105 -134
- package/packages/builtin-tool-cloud-sandbox/src/executor/index.ts +254 -0
- package/packages/builtin-tool-cloud-sandbox/src/index.ts +1 -0
- package/packages/builtin-tool-cloud-sandbox/src/types/api.ts +22 -0
- package/packages/builtin-tool-cloud-sandbox/src/types/index.ts +4 -0
- package/packages/builtin-tool-cloud-sandbox/src/types/params.ts +85 -0
- package/packages/builtin-tool-cloud-sandbox/src/types/service.ts +48 -0
- package/packages/builtin-tool-cloud-sandbox/src/{types.ts → types/state.ts} +0 -23
- package/packages/builtin-tool-memory/src/manifest.ts +5 -5
- package/packages/desktop-bridge/src/index.ts +5 -0
- package/packages/editor-runtime/src/__tests__/EditorRuntime.real.test.ts +1 -1
- package/packages/editor-runtime/src/__tests__/EditorRuntime.test.ts +1 -1
- package/packages/electron-client-ipc/src/events/index.ts +5 -1
- package/packages/electron-client-ipc/src/events/remoteServer.ts +23 -0
- package/packages/electron-client-ipc/src/types/window.ts +3 -2
- package/packages/memory-user-memory/src/schemas/index.ts +0 -1
- package/packages/model-bank/src/modelProviders/internlm.ts +1 -1
- package/packages/model-runtime/src/core/RouterRuntime/createRuntime.ts +5 -15
- package/packages/model-runtime/src/providers/internlm/index.test.ts +15 -15
- package/packages/model-runtime/src/providers/internlm/index.ts +1 -1
- package/packages/types/src/tool/intervention.ts +4 -2
- package/packages/types/src/user/preference.ts +1 -0
- package/src/app/[variants]/(desktop)/desktop-onboarding/_layout/index.tsx +6 -3
- package/src/app/[variants]/(desktop)/desktop-onboarding/components/OnboardingFooterActions.tsx +38 -0
- package/src/app/[variants]/(desktop)/desktop-onboarding/features/DataModeStep.tsx +19 -14
- package/src/app/[variants]/(desktop)/desktop-onboarding/features/LoginStep.tsx +121 -29
- package/src/app/[variants]/(desktop)/desktop-onboarding/features/PermissionsStep.tsx +19 -14
- package/src/app/[variants]/(desktop)/desktop-onboarding/index.tsx +8 -7
- package/src/app/[variants]/(main)/_layout/DesktopAutoOidcOnFirstOpen.tsx +4 -0
- package/src/app/manifest.ts +1 -1
- package/src/business/server/user.ts +4 -0
- package/src/features/Conversation/Messages/Task/Actions/index.tsx +0 -2
- package/src/features/Conversation/Messages/Task/index.tsx +1 -1
- package/src/features/Conversation/Messages/Tasks/shared/ProcessingState.tsx +0 -2
- package/src/features/Electron/titlebar/NavigationBar.tsx +1 -2
- package/src/features/NavPanel/components/NavPanelDraggable.tsx +0 -14
- package/src/features/ResourceManager/components/Explorer/ItemDropdown/useFileItemDropdown.tsx +4 -3
- package/src/features/SharePopover/index.tsx +5 -3
- package/src/hooks/useAppOrigin.ts +16 -0
- package/src/layout/GlobalProvider/useUserStateRedirect.ts +37 -24
- package/src/libs/trusted-client/index.ts +2 -5
- package/src/locales/default/desktop-onboarding.ts +5 -0
- package/src/locales/default/error.ts +11 -0
- package/src/locales/default/subscription.ts +1 -1
- package/src/server/manifest.ts +2 -2
- package/src/server/modules/AgentRuntime/RuntimeExecutors.ts +2 -0
- package/src/server/routers/lambda/user.ts +24 -10
- package/src/server/services/agentRuntime/AgentRuntimeService.test.ts +3 -0
- package/src/server/services/agentRuntime/AgentRuntimeService.ts +8 -5
- package/src/server/services/agentRuntime/types.ts +7 -0
- package/src/server/services/aiAgent/__tests__/execGroupSubAgentTask.test.ts +3 -0
- package/src/server/services/aiAgent/index.ts +10 -4
- package/src/server/services/market/index.ts +20 -0
- package/src/server/services/sandbox/index.ts +186 -0
- package/src/server/services/toolExecution/builtin.ts +12 -18
- package/src/server/services/toolExecution/index.ts +1 -1
- package/src/server/services/toolExecution/serverRuntimes/cloudSandbox.ts +38 -0
- package/src/server/services/toolExecution/serverRuntimes/index.ts +55 -0
- package/src/server/services/toolExecution/serverRuntimes/types.ts +14 -0
- package/src/server/services/toolExecution/serverRuntimes/webBrowsing.ts +20 -0
- package/src/server/services/toolExecution/types.ts +2 -0
- package/src/services/{codeInterpreter.ts → cloudSandbox.ts} +3 -3
- package/src/services/electron/remoteServer.ts +8 -0
- package/src/services/electron/system.ts +5 -5
- package/src/store/chat/agents/GroupOrchestration/__tests__/batch-exec-async-tasks.test.ts +626 -0
- package/src/store/chat/agents/GroupOrchestration/createGroupOrchestrationExecutors.ts +294 -0
- package/src/store/chat/slices/plugin/action.test.ts +0 -48
- package/src/store/chat/slices/plugin/actions/pluginTypes.ts +0 -131
- package/src/store/tool/slices/builtin/executors/index.ts +2 -0
- package/src/store/user/slices/settings/selectors/toolIntervention.test.ts +143 -0
- package/src/store/user/slices/settings/selectors/toolIntervention.ts +11 -2
- package/packages/memory-user-memory/src/schemas/jsonSchemas.ts +0 -37
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,57 @@
|
|
|
2
2
|
|
|
3
3
|
# Changelog
|
|
4
4
|
|
|
5
|
+
## [Version 2.0.0-next.314](https://github.com/lobehub/lobe-chat/compare/v2.0.0-next.313...v2.0.0-next.314)
|
|
6
|
+
|
|
7
|
+
<sup>Released on **2026-01-19**</sup>
|
|
8
|
+
|
|
9
|
+
#### ✨ Features
|
|
10
|
+
|
|
11
|
+
- **misc**: Improve desktop onboarding window management and footer actions.
|
|
12
|
+
|
|
13
|
+
<br/>
|
|
14
|
+
|
|
15
|
+
<details>
|
|
16
|
+
<summary><kbd>Improvements and Fixes</kbd></summary>
|
|
17
|
+
|
|
18
|
+
#### What's improved
|
|
19
|
+
|
|
20
|
+
- **misc**: Improve desktop onboarding window management and footer actions, closes [#11619](https://github.com/lobehub/lobe-chat/issues/11619) ([6ed280e](https://github.com/lobehub/lobe-chat/commit/6ed280e))
|
|
21
|
+
|
|
22
|
+
</details>
|
|
23
|
+
|
|
24
|
+
<div align="right">
|
|
25
|
+
|
|
26
|
+
[](#readme-top)
|
|
27
|
+
|
|
28
|
+
</div>
|
|
29
|
+
|
|
30
|
+
## [Version 2.0.0-next.313](https://github.com/lobehub/lobe-chat/compare/v2.0.0-next.312...v2.0.0-next.313)
|
|
31
|
+
|
|
32
|
+
<sup>Released on **2026-01-19**</sup>
|
|
33
|
+
|
|
34
|
+
#### 🐛 Bug Fixes
|
|
35
|
+
|
|
36
|
+
- **misc**: Fix server agent task run with headless, internlm provider base url and homepage.
|
|
37
|
+
|
|
38
|
+
<br/>
|
|
39
|
+
|
|
40
|
+
<details>
|
|
41
|
+
<summary><kbd>Improvements and Fixes</kbd></summary>
|
|
42
|
+
|
|
43
|
+
#### What's fixed
|
|
44
|
+
|
|
45
|
+
- **misc**: Fix server agent task run with headless, closes [#11600](https://github.com/lobehub/lobe-chat/issues/11600) ([435eede](https://github.com/lobehub/lobe-chat/commit/435eede))
|
|
46
|
+
- **misc**: Internlm provider base url and homepage, closes [#11612](https://github.com/lobehub/lobe-chat/issues/11612) ([38725da](https://github.com/lobehub/lobe-chat/commit/38725da))
|
|
47
|
+
|
|
48
|
+
</details>
|
|
49
|
+
|
|
50
|
+
<div align="right">
|
|
51
|
+
|
|
52
|
+
[](#readme-top)
|
|
53
|
+
|
|
54
|
+
</div>
|
|
55
|
+
|
|
5
56
|
## [Version 2.0.0-next.312](https://github.com/lobehub/lobe-chat/compare/v2.0.0-next.311...v2.0.0-next.312)
|
|
6
57
|
|
|
7
58
|
<sup>Released on **2026-01-19**</sup>
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { APP_WINDOW_MIN_SIZE } from '@lobechat/desktop-bridge';
|
|
2
|
+
|
|
1
3
|
import type { BrowserWindowOpts } from './core/browser/Browser';
|
|
2
4
|
|
|
3
5
|
export const BrowsersIdentifiers = {
|
|
@@ -11,7 +13,8 @@ export const appBrowsers = {
|
|
|
11
13
|
height: 800,
|
|
12
14
|
identifier: 'app',
|
|
13
15
|
keepAlive: true,
|
|
14
|
-
|
|
16
|
+
minHeight: APP_WINDOW_MIN_SIZE.height,
|
|
17
|
+
minWidth: APP_WINDOW_MIN_SIZE.width,
|
|
15
18
|
path: '/',
|
|
16
19
|
showOnInit: true,
|
|
17
20
|
titleBarStyle: 'hidden',
|
|
@@ -1,4 +1,9 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
AuthorizationPhase,
|
|
3
|
+
AuthorizationProgress,
|
|
4
|
+
DataSyncConfig,
|
|
5
|
+
MarketAuthorizationParams,
|
|
6
|
+
} from '@lobechat/electron-client-ipc';
|
|
2
7
|
import { BrowserWindow, shell } from 'electron';
|
|
3
8
|
import crypto from 'node:crypto';
|
|
4
9
|
import querystring from 'node:querystring';
|
|
@@ -9,9 +14,11 @@ import { createLogger } from '@/utils/logger';
|
|
|
9
14
|
import RemoteServerConfigCtr from './RemoteServerConfigCtr';
|
|
10
15
|
import { ControllerModule, IpcMethod } from './index';
|
|
11
16
|
|
|
12
|
-
// Create logger
|
|
13
17
|
const logger = createLogger('controllers:AuthCtr');
|
|
14
18
|
|
|
19
|
+
const MAX_POLL_TIME = 2 * 60 * 1000; // 2 minutes (reduced from 5 minutes for better UX)
|
|
20
|
+
const POLL_INTERVAL = 3000; // 3 seconds
|
|
21
|
+
|
|
15
22
|
/**
|
|
16
23
|
* Authentication Controller
|
|
17
24
|
* Implements OAuth authorization flow using intermediate page + polling mechanism
|
|
@@ -107,6 +114,12 @@ export default class AuthCtr extends ControllerModule {
|
|
|
107
114
|
await shell.openExternal(authUrl.toString());
|
|
108
115
|
logger.debug('Opening authorization URL in default browser');
|
|
109
116
|
|
|
117
|
+
this.broadcastAuthorizationProgress({
|
|
118
|
+
elapsed: 0,
|
|
119
|
+
maxPollTime: MAX_POLL_TIME,
|
|
120
|
+
phase: 'browser_opened',
|
|
121
|
+
});
|
|
122
|
+
|
|
110
123
|
// Start polling for credentials
|
|
111
124
|
this.startPolling();
|
|
112
125
|
|
|
@@ -117,6 +130,24 @@ export default class AuthCtr extends ControllerModule {
|
|
|
117
130
|
}
|
|
118
131
|
}
|
|
119
132
|
|
|
133
|
+
/**
|
|
134
|
+
* Cancel current authorization process
|
|
135
|
+
*/
|
|
136
|
+
@IpcMethod()
|
|
137
|
+
async cancelAuthorization() {
|
|
138
|
+
if (this.authRequestState) {
|
|
139
|
+
logger.info('User cancelled authorization');
|
|
140
|
+
this.clearAuthorizationState();
|
|
141
|
+
this.broadcastAuthorizationProgress({
|
|
142
|
+
elapsed: 0,
|
|
143
|
+
maxPollTime: MAX_POLL_TIME,
|
|
144
|
+
phase: 'cancelled',
|
|
145
|
+
});
|
|
146
|
+
return { success: true };
|
|
147
|
+
}
|
|
148
|
+
return { error: 'No active authorization', success: false };
|
|
149
|
+
}
|
|
150
|
+
|
|
120
151
|
/**
|
|
121
152
|
* Request Market OAuth authorization (desktop)
|
|
122
153
|
*/
|
|
@@ -152,14 +183,29 @@ export default class AuthCtr extends ControllerModule {
|
|
|
152
183
|
}
|
|
153
184
|
|
|
154
185
|
logger.info('Starting credential polling');
|
|
155
|
-
|
|
156
|
-
const maxPollTime = 5 * 60 * 1000; // 5 minutes
|
|
186
|
+
|
|
157
187
|
const startTime = Date.now();
|
|
158
188
|
|
|
189
|
+
// Broadcast initial state
|
|
190
|
+
this.broadcastAuthorizationProgress({
|
|
191
|
+
elapsed: 0,
|
|
192
|
+
maxPollTime: MAX_POLL_TIME,
|
|
193
|
+
phase: 'waiting_for_auth',
|
|
194
|
+
});
|
|
195
|
+
|
|
159
196
|
this.pollingInterval = setInterval(async () => {
|
|
197
|
+
const elapsed = Date.now() - startTime;
|
|
198
|
+
|
|
199
|
+
// Broadcast progress on every tick
|
|
200
|
+
this.broadcastAuthorizationProgress({
|
|
201
|
+
elapsed,
|
|
202
|
+
maxPollTime: MAX_POLL_TIME,
|
|
203
|
+
phase: 'waiting_for_auth',
|
|
204
|
+
});
|
|
205
|
+
|
|
160
206
|
try {
|
|
161
207
|
// Check if polling has timed out
|
|
162
|
-
if (
|
|
208
|
+
if (elapsed > MAX_POLL_TIME) {
|
|
163
209
|
logger.warn('Credential polling timed out');
|
|
164
210
|
this.clearAuthorizationState();
|
|
165
211
|
this.broadcastAuthorizationFailed('Authorization timed out');
|
|
@@ -173,6 +219,13 @@ export default class AuthCtr extends ControllerModule {
|
|
|
173
219
|
logger.info('Successfully received credentials from polling');
|
|
174
220
|
this.stopPolling();
|
|
175
221
|
|
|
222
|
+
// Broadcast verifying state
|
|
223
|
+
this.broadcastAuthorizationProgress({
|
|
224
|
+
elapsed,
|
|
225
|
+
maxPollTime: MAX_POLL_TIME,
|
|
226
|
+
phase: 'verifying',
|
|
227
|
+
});
|
|
228
|
+
|
|
176
229
|
// Validate state parameter
|
|
177
230
|
if (result.state !== this.authRequestState) {
|
|
178
231
|
logger.error(
|
|
@@ -198,7 +251,7 @@ export default class AuthCtr extends ControllerModule {
|
|
|
198
251
|
this.clearAuthorizationState();
|
|
199
252
|
this.broadcastAuthorizationFailed('Polling error: ' + error.message);
|
|
200
253
|
}
|
|
201
|
-
},
|
|
254
|
+
}, POLL_INTERVAL);
|
|
202
255
|
}
|
|
203
256
|
|
|
204
257
|
/**
|
|
@@ -511,6 +564,21 @@ export default class AuthCtr extends ControllerModule {
|
|
|
511
564
|
}
|
|
512
565
|
}
|
|
513
566
|
|
|
567
|
+
/**
|
|
568
|
+
* Broadcast authorization progress event
|
|
569
|
+
*/
|
|
570
|
+
private broadcastAuthorizationProgress(progress: AuthorizationProgress) {
|
|
571
|
+
// Avoid logging too frequently
|
|
572
|
+
// logger.debug('Broadcasting authorizationProgress event');
|
|
573
|
+
const allWindows = BrowserWindow.getAllWindows();
|
|
574
|
+
|
|
575
|
+
for (const win of allWindows) {
|
|
576
|
+
if (!win.isDestroyed()) {
|
|
577
|
+
win.webContents.send('authorizationProgress', progress);
|
|
578
|
+
}
|
|
579
|
+
}
|
|
580
|
+
}
|
|
581
|
+
|
|
514
582
|
/**
|
|
515
583
|
* Broadcast authorization failed event
|
|
516
584
|
*/
|
|
@@ -563,7 +631,7 @@ export default class AuthCtr extends ControllerModule {
|
|
|
563
631
|
// Hash codeVerifier using SHA-256
|
|
564
632
|
const encoder = new TextEncoder();
|
|
565
633
|
const data = encoder.encode(codeVerifier);
|
|
566
|
-
const digest = await crypto.subtle.digest('SHA-256', data
|
|
634
|
+
const digest = await crypto.subtle.digest('SHA-256', data.buffer);
|
|
567
635
|
|
|
568
636
|
// Convert hash result to base64url encoding
|
|
569
637
|
const challenge = Buffer.from(digest)
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type {
|
|
2
2
|
InterceptRouteParams,
|
|
3
3
|
OpenSettingsWindowOptions,
|
|
4
|
-
|
|
4
|
+
WindowMinimumSizeParams,
|
|
5
5
|
WindowSizeParams,
|
|
6
6
|
} from '@lobechat/electron-client-ipc';
|
|
7
7
|
import { findMatchingRoute } from '~common/routes';
|
|
@@ -81,9 +81,21 @@ export default class BrowserWindowsCtr extends ControllerModule {
|
|
|
81
81
|
}
|
|
82
82
|
|
|
83
83
|
@IpcMethod()
|
|
84
|
-
|
|
84
|
+
setWindowMinimumSize(params: WindowMinimumSizeParams) {
|
|
85
85
|
this.withSenderIdentifier((identifier) => {
|
|
86
|
-
this.app.browserManager.
|
|
86
|
+
const currentSize = this.app.browserManager.getWindowSize(identifier);
|
|
87
|
+
const nextWindowSize = {
|
|
88
|
+
...currentSize,
|
|
89
|
+
};
|
|
90
|
+
if (params.height) {
|
|
91
|
+
nextWindowSize.height = Math.max(currentSize.height, params.height);
|
|
92
|
+
}
|
|
93
|
+
if (params.width) {
|
|
94
|
+
nextWindowSize.width = Math.max(currentSize.width, params.width);
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
this.app.browserManager.setWindowSize(identifier, nextWindowSize);
|
|
98
|
+
this.app.browserManager.setWindowMinimumSize(identifier, params);
|
|
87
99
|
});
|
|
88
100
|
}
|
|
89
101
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { TITLE_BAR_HEIGHT } from '@lobechat/desktop-bridge';
|
|
1
|
+
import { APP_WINDOW_MIN_SIZE, TITLE_BAR_HEIGHT } from '@lobechat/desktop-bridge';
|
|
2
2
|
import { MainBroadcastEventKey, MainBroadcastParams } from '@lobechat/electron-client-ipc';
|
|
3
3
|
import {
|
|
4
4
|
BrowserWindow,
|
|
@@ -291,9 +291,19 @@ export default class Browser {
|
|
|
291
291
|
});
|
|
292
292
|
}
|
|
293
293
|
|
|
294
|
-
|
|
295
|
-
logger.debug(`[${this.identifier}] Setting window
|
|
296
|
-
|
|
294
|
+
setWindowMinimumSize(size: { height?: number; width?: number }): void {
|
|
295
|
+
logger.debug(`[${this.identifier}] Setting window minimum size: ${JSON.stringify(size)}`);
|
|
296
|
+
|
|
297
|
+
const currentMinimumSize = this._browserWindow?.getMinimumSize?.() ?? [0, 0];
|
|
298
|
+
const rawWidth = size.width ?? currentMinimumSize[0];
|
|
299
|
+
const rawHeight = size.height ?? currentMinimumSize[1];
|
|
300
|
+
|
|
301
|
+
// Electron doesn't "reset" minimum size with 0x0 reliably.
|
|
302
|
+
// Treat 0 / negative as fallback to app-level default preset.
|
|
303
|
+
const width = rawWidth > 0 ? rawWidth : APP_WINDOW_MIN_SIZE.width;
|
|
304
|
+
const height = rawHeight > 0 ? rawHeight : APP_WINDOW_MIN_SIZE.height;
|
|
305
|
+
|
|
306
|
+
this._browserWindow?.setMinimumSize?.(width, height);
|
|
297
307
|
}
|
|
298
308
|
|
|
299
309
|
// ==================== Window Position ====================
|
|
@@ -250,9 +250,14 @@ export class BrowserManager {
|
|
|
250
250
|
browser?.setWindowSize(size);
|
|
251
251
|
}
|
|
252
252
|
|
|
253
|
-
|
|
253
|
+
getWindowSize(identifier: string) {
|
|
254
254
|
const browser = this.browsers.get(identifier);
|
|
255
|
-
browser?.
|
|
255
|
+
return browser?.browserWindow.getBounds();
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
setWindowMinimumSize(identifier: string, size: { height?: number; width?: number }) {
|
|
259
|
+
const browser = this.browsers.get(identifier);
|
|
260
|
+
browser?.setWindowMinimumSize(size);
|
|
256
261
|
}
|
|
257
262
|
|
|
258
263
|
getIdentifierByWebContents(webContents: WebContents): string | null {
|
package/changelog/v1.json
CHANGED
|
@@ -1,4 +1,22 @@
|
|
|
1
1
|
[
|
|
2
|
+
{
|
|
3
|
+
"children": {
|
|
4
|
+
"features": [
|
|
5
|
+
"Improve desktop onboarding window management and footer actions."
|
|
6
|
+
]
|
|
7
|
+
},
|
|
8
|
+
"date": "2026-01-19",
|
|
9
|
+
"version": "2.0.0-next.314"
|
|
10
|
+
},
|
|
11
|
+
{
|
|
12
|
+
"children": {
|
|
13
|
+
"fixes": [
|
|
14
|
+
"Fix server agent task run with headless, internlm provider base url and homepage."
|
|
15
|
+
]
|
|
16
|
+
},
|
|
17
|
+
"date": "2026-01-19",
|
|
18
|
+
"version": "2.0.0-next.313"
|
|
19
|
+
},
|
|
2
20
|
{
|
|
3
21
|
"children": {
|
|
4
22
|
"improvements": [
|
|
@@ -14,7 +14,7 @@ tags:
|
|
|
14
14
|
|
|
15
15
|
<Image cover src={'https://github.com/user-attachments/assets/be7dcd49-0165-4f7b-bf90-0739cc9dd212'} />
|
|
16
16
|
|
|
17
|
-
[InternLM](https://
|
|
17
|
+
[InternLM](https://internlm.intern-ai.org.cn/) is a large pre-trained language model jointly launched by the Shanghai Artificial Intelligence Laboratory and Shusheng Group. This model focuses on natural language processing, aimed at understanding and generating human language, boasting powerful semantic comprehension and text generation capabilities.
|
|
18
18
|
|
|
19
19
|
This article will guide you on how to use InternLM in LobeChat.
|
|
20
20
|
|
|
@@ -39,7 +39,7 @@ This article will guide you on how to use InternLM in LobeChat.
|
|
|
39
39
|
|
|
40
40
|
<Image alt={'Enter API Key'} inStep src={'https://github.com/user-attachments/assets/8ec7656e-1e3d-41e0-95a0-f6883135c2fc'} />
|
|
41
41
|
|
|
42
|
-
- Enter the obtained
|
|
42
|
+
- Enter the obtained API Key
|
|
43
43
|
- Choose a InternLM model for your AI assistant to start a conversation
|
|
44
44
|
|
|
45
45
|
<Image alt={'Select InternLM Model and Start Conversation'} inStep src={'https://github.com/user-attachments/assets/76ad163e-ee19-4f95-a712-85bea764d3ec'} />
|
|
@@ -12,7 +12,7 @@ tags:
|
|
|
12
12
|
|
|
13
13
|
<Image cover src={'https://github.com/user-attachments/assets/be7dcd49-0165-4f7b-bf90-0739cc9dd212'} />
|
|
14
14
|
|
|
15
|
-
[书生浦语(InternLM)](https://
|
|
15
|
+
[书生浦语(InternLM)](https://internlm.intern-ai.org.cn/) 是由上海人工智能实验室与书生集团联合推出的一款大型预训练语言模型。该模型专注于自然语言处理,旨在理解和生成自然语言,具备强大的语义理解和文本生成能力。
|
|
16
16
|
|
|
17
17
|
本文将指导你如何在 LobeChat 中使用书生浦语。
|
|
18
18
|
|
|
@@ -32,11 +32,11 @@ tags:
|
|
|
32
32
|
### 步骤二:在 LobeChat 中配置书生浦语
|
|
33
33
|
|
|
34
34
|
- 访问 LobeChat 的`设置`界面
|
|
35
|
-
- 在`AI 服务商`下找到
|
|
35
|
+
- 在`AI 服务商`下找到 `书生` 的设置项
|
|
36
36
|
|
|
37
37
|
<Image alt={'填入 API 密钥'} inStep src={'https://github.com/user-attachments/assets/8ec7656e-1e3d-41e0-95a0-f6883135c2fc'} />
|
|
38
38
|
|
|
39
|
-
- 填入获得的
|
|
39
|
+
- 填入获得的 API Key
|
|
40
40
|
- 为你的 AI 助手选择一个书生浦语的模型即可开始对话
|
|
41
41
|
|
|
42
42
|
<Image alt={'选择书生浦语模型并开始对话'} inStep src={'https://github.com/user-attachments/assets/76ad163e-ee19-4f95-a712-85bea764d3ec'} />
|
|
@@ -68,7 +68,7 @@ Then('I should be on an assistant detail page', async function (this: CustomWorl
|
|
|
68
68
|
|
|
69
69
|
const currentUrl = this.page.url();
|
|
70
70
|
// Check if URL matches assistant detail page pattern
|
|
71
|
-
const hasAssistantDetail = /\/community\/
|
|
71
|
+
const hasAssistantDetail = /\/community\/agent\/[^#?]+/.test(currentUrl);
|
|
72
72
|
expect(
|
|
73
73
|
hasAssistantDetail,
|
|
74
74
|
`Expected URL to match assistant detail page pattern, but got: ${currentUrl}`,
|
|
@@ -138,7 +138,7 @@ Then('I should be on the assistant list page', async function (this: CustomWorld
|
|
|
138
138
|
// After back navigation, URL should be /community/agent or /community
|
|
139
139
|
const isListPage =
|
|
140
140
|
(currentUrl.includes('/community/agent') &&
|
|
141
|
-
!/\/community\/
|
|
141
|
+
!/\/community\/agent\/[\dA-Za-z-]+$/.test(currentUrl)) ||
|
|
142
142
|
currentUrl.endsWith('/community') ||
|
|
143
143
|
currentUrl.includes('/community#');
|
|
144
144
|
|
|
@@ -230,10 +230,10 @@ When('I click on the sort dropdown', async function (this: CustomWorld) {
|
|
|
230
230
|
});
|
|
231
231
|
|
|
232
232
|
When('I select a sort option', async function (this: CustomWorld) {
|
|
233
|
-
await this.page.waitForTimeout(
|
|
233
|
+
await this.page.waitForTimeout(1000);
|
|
234
234
|
|
|
235
|
-
//
|
|
236
|
-
const sortOptions = this.page.locator('[role="
|
|
235
|
+
// The sort dropdown uses checkbox items with role="menuitemcheckbox"
|
|
236
|
+
const sortOptions = this.page.locator('[role="menuitemcheckbox"]');
|
|
237
237
|
|
|
238
238
|
// Wait for options to appear
|
|
239
239
|
await sortOptions.first().waitFor({ state: 'visible', timeout: 30_000 });
|
|
@@ -381,7 +381,7 @@ Then('the URL should contain the category parameter', async function (this: Cust
|
|
|
381
381
|
currentUrl.includes('category=') ||
|
|
382
382
|
currentUrl.includes('tag=') ||
|
|
383
383
|
// For path-based routing like /community/agent/category-name
|
|
384
|
-
/\/community\/
|
|
384
|
+
/\/community\/agent\/[^/?]+/.test(currentUrl);
|
|
385
385
|
|
|
386
386
|
expect(
|
|
387
387
|
hasCategory,
|
|
@@ -433,8 +433,8 @@ Then('I should be navigated to the assistant detail page', async function (this:
|
|
|
433
433
|
await this.page.waitForLoadState('networkidle', { timeout: 30_000 });
|
|
434
434
|
|
|
435
435
|
const currentUrl = this.page.url();
|
|
436
|
-
// Verify that URL changed and contains /
|
|
437
|
-
const hasAssistantDetail = /\/community\/
|
|
436
|
+
// Verify that URL changed and contains /agent/ followed by an identifier
|
|
437
|
+
const hasAssistantDetail = /\/community\/agent\/[^#?]+/.test(currentUrl);
|
|
438
438
|
const urlChanged = currentUrl !== this.testContext.previousUrl;
|
|
439
439
|
|
|
440
440
|
expect(
|
package/e2e/src/steps/hooks.ts
CHANGED
|
@@ -45,10 +45,24 @@ BeforeAll({ timeout: 600_000 }, async function () {
|
|
|
45
45
|
// Navigate to signin page
|
|
46
46
|
await page.goto(`${baseUrl}/signin`, { waitUntil: 'networkidle' });
|
|
47
47
|
|
|
48
|
+
// Wait for the page to fully hydrate
|
|
49
|
+
await page.waitForTimeout(2000);
|
|
50
|
+
|
|
51
|
+
// Check if we can find the email input
|
|
52
|
+
const emailInput = page
|
|
53
|
+
.locator('input[id="email"], input[name="email"], input[type="text"]')
|
|
54
|
+
.first();
|
|
55
|
+
const emailInputVisible = await emailInput.isVisible().catch(() => false);
|
|
56
|
+
|
|
57
|
+
if (!emailInputVisible) {
|
|
58
|
+
console.log(
|
|
59
|
+
'⚠️ Login form not available, skipping authentication (tests requiring auth may fail)',
|
|
60
|
+
);
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
63
|
+
|
|
48
64
|
// Step 1: Enter email
|
|
49
65
|
console.log(' Step 1: Entering email...');
|
|
50
|
-
const emailInput = page.locator('input[id="email"]').first();
|
|
51
|
-
await emailInput.waitFor({ state: 'visible', timeout: 30_000 });
|
|
52
66
|
await emailInput.fill(TEST_USER.email);
|
|
53
67
|
|
|
54
68
|
// Click the next button
|
|
@@ -57,7 +71,9 @@ BeforeAll({ timeout: 600_000 }, async function () {
|
|
|
57
71
|
|
|
58
72
|
// Step 2: Wait for password step and enter password
|
|
59
73
|
console.log(' Step 2: Entering password...');
|
|
60
|
-
const passwordInput = page
|
|
74
|
+
const passwordInput = page
|
|
75
|
+
.locator('input[id="password"], input[name="password"], input[type="password"]')
|
|
76
|
+
.first();
|
|
61
77
|
await passwordInput.waitFor({ state: 'visible', timeout: 30_000 });
|
|
62
78
|
await passwordInput.fill(TEST_USER.password);
|
|
63
79
|
|
package/locales/en-US/error.json
CHANGED
|
@@ -12,6 +12,11 @@
|
|
|
12
12
|
"import.importConfigFile.title": "Import Failed",
|
|
13
13
|
"import.incompatible.description": "This file was exported from a higher version. Please try upgrading to the latest version and then re-importing.",
|
|
14
14
|
"import.incompatible.title": "Current application does not support importing this file",
|
|
15
|
+
"inviteCode.currentEmail": "Current account: {{email}}",
|
|
16
|
+
"inviteCode.desc": "An invite code is required to access LobeHub. Please enter a valid invite code to continue.",
|
|
17
|
+
"inviteCode.friends": "Friends",
|
|
18
|
+
"inviteCode.getCodeHint": "Get an invite code from:",
|
|
19
|
+
"inviteCode.title": "Invite Code Required",
|
|
15
20
|
"loginRequired.desc": "You will be redirected to the login page shortly",
|
|
16
21
|
"loginRequired.title": "Please log in to use this feature",
|
|
17
22
|
"notFound.backHome": "Back to Home",
|
|
@@ -144,5 +149,9 @@
|
|
|
144
149
|
"upload.networkError": "Please check your network connection and ensure that the file storage service's cross-origin configuration is correct.",
|
|
145
150
|
"upload.title": "File upload failed. Please check your network connection or try again later",
|
|
146
151
|
"upload.unknownError": "Error reason: {{reason}}",
|
|
147
|
-
"upload.uploadFailed": "File upload failed."
|
|
152
|
+
"upload.uploadFailed": "File upload failed.",
|
|
153
|
+
"waitlist.currentEmail": "Current account: {{email}}",
|
|
154
|
+
"waitlist.desc": "Your account is not on the whitelist. Please contact the administrator to request access.",
|
|
155
|
+
"waitlist.switchAccount": "Switch Account",
|
|
156
|
+
"waitlist.title": "Access Restricted"
|
|
148
157
|
}
|
|
@@ -288,7 +288,7 @@
|
|
|
288
288
|
"referral.rules.backfill.description": "Forgot to enter invite code? You can backfill within 3 days of registration",
|
|
289
289
|
"referral.rules.backfill.expiredTip": "Backfill period has expired. Cannot backfill after 3 days of registration",
|
|
290
290
|
"referral.rules.backfill.link": "Backfill Invite Code",
|
|
291
|
-
"referral.rules.backfill.placeholder": "Enter invite code",
|
|
291
|
+
"referral.rules.backfill.placeholder": "Enter invite code or link",
|
|
292
292
|
"referral.rules.backfill.submit": "Confirm Binding",
|
|
293
293
|
"referral.rules.backfill.success": "Invite code bound successfully",
|
|
294
294
|
"referral.rules.backfill.title": "Backfill Invite Code",
|
|
@@ -58,6 +58,7 @@
|
|
|
58
58
|
"screen4.title": "您希望如何共享数据?",
|
|
59
59
|
"screen4.title2": "您的选择将帮助我们改进",
|
|
60
60
|
"screen4.title3": "您可以随时在设置中更改",
|
|
61
|
+
"screen5.actions.cancel": "取消",
|
|
61
62
|
"screen5.actions.connectToServer": "连接服务器",
|
|
62
63
|
"screen5.actions.connecting": "正在连接…",
|
|
63
64
|
"screen5.actions.signInCloud": "登录 LobeHub Cloud",
|
|
@@ -65,6 +66,10 @@
|
|
|
65
66
|
"screen5.actions.signingIn": "正在登录…",
|
|
66
67
|
"screen5.actions.signingOut": "正在退出…",
|
|
67
68
|
"screen5.actions.tryAgain": "重试",
|
|
69
|
+
"screen5.auth.phase.browserOpened": "浏览器已打开,请前往登录…",
|
|
70
|
+
"screen5.auth.phase.verifying": "正在验证凭证…",
|
|
71
|
+
"screen5.auth.phase.waitingForAuth": "等待授权完成…",
|
|
72
|
+
"screen5.auth.remaining": "剩余时间:{{time}}秒",
|
|
68
73
|
"screen5.badge": "登录",
|
|
69
74
|
"screen5.description": "登录以在所有设备间同步代理、群组、设置和上下文。",
|
|
70
75
|
"screen5.errors.desktopOnlyOidc": "OIDC 授权仅在桌面端运行时可用。",
|
package/locales/zh-CN/error.json
CHANGED
|
@@ -12,6 +12,11 @@
|
|
|
12
12
|
"import.importConfigFile.title": "导入遇到了问题",
|
|
13
13
|
"import.incompatible.description": "该文件由更高版本导出。请升级到最新版后再导入",
|
|
14
14
|
"import.incompatible.title": "版本不兼容",
|
|
15
|
+
"inviteCode.currentEmail": "当前账号:{{email}}",
|
|
16
|
+
"inviteCode.desc": "需要邀请码才能访问 LobeHub。请输入有效的邀请码以继续。",
|
|
17
|
+
"inviteCode.friends": "好友",
|
|
18
|
+
"inviteCode.getCodeHint": "获取邀请码:",
|
|
19
|
+
"inviteCode.title": "需要邀请码",
|
|
15
20
|
"loginRequired.desc": "将为你跳转到登录页。登录后即可继续",
|
|
16
21
|
"loginRequired.title": "需要登录后继续",
|
|
17
22
|
"notFound.backHome": "返回首页",
|
|
@@ -144,5 +149,9 @@
|
|
|
144
149
|
"upload.networkError": "网络异常或跨域配置不正确。请检查文件存储服务的 CORS 设置后重试",
|
|
145
150
|
"upload.title": "上传未能完成",
|
|
146
151
|
"upload.unknownError": "原因:{{reason}}",
|
|
147
|
-
"upload.uploadFailed": "上传未能完成"
|
|
152
|
+
"upload.uploadFailed": "上传未能完成",
|
|
153
|
+
"waitlist.currentEmail": "当前账号:{{email}}",
|
|
154
|
+
"waitlist.desc": "你的账号不在白名单中。请联系管理员申请访问权限。",
|
|
155
|
+
"waitlist.switchAccount": "切换账号",
|
|
156
|
+
"waitlist.title": "访问受限"
|
|
148
157
|
}
|
|
@@ -288,7 +288,7 @@
|
|
|
288
288
|
"referral.rules.backfill.description": "忘记填写邀请码?注册三天内可以补填",
|
|
289
289
|
"referral.rules.backfill.expiredTip": "补填期限已过,注册超过三天后无法补填",
|
|
290
290
|
"referral.rules.backfill.link": "补填邀请码",
|
|
291
|
-
"referral.rules.backfill.placeholder": "
|
|
291
|
+
"referral.rules.backfill.placeholder": "请输入邀请码或链接",
|
|
292
292
|
"referral.rules.backfill.submit": "确认绑定",
|
|
293
293
|
"referral.rules.backfill.success": "邀请码绑定成功",
|
|
294
294
|
"referral.rules.backfill.title": "补填邀请码",
|
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.314",
|
|
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",
|
|
@@ -88,10 +88,22 @@ export class GeneralChatAgent implements Agent {
|
|
|
88
88
|
}
|
|
89
89
|
|
|
90
90
|
// Priority 0: CRITICAL - Check security blacklist FIRST
|
|
91
|
-
// This overrides ALL other settings, including auto-run mode
|
|
92
91
|
const securityCheck = InterventionChecker.checkSecurityBlacklist(securityBlacklist, toolArgs);
|
|
92
|
+
|
|
93
|
+
// Priority 0.5: Headless mode - fully automated for async tasks
|
|
94
|
+
// In headless mode: blacklisted tools are skipped, all other tools execute directly
|
|
95
|
+
if (approvalMode === 'headless') {
|
|
96
|
+
if (securityCheck.blocked) {
|
|
97
|
+
// Skip blacklisted tools entirely (don't execute, don't wait for approval)
|
|
98
|
+
continue;
|
|
99
|
+
}
|
|
100
|
+
// All other tools execute directly
|
|
101
|
+
toolsToExecute.push(toolCalling);
|
|
102
|
+
continue;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
// For non-headless modes: security blacklist requires intervention
|
|
93
106
|
if (securityCheck.blocked) {
|
|
94
|
-
// Security blacklist always requires intervention
|
|
95
107
|
toolsNeedingIntervention.push(toolCalling);
|
|
96
108
|
continue;
|
|
97
109
|
}
|