@lobehub/lobehub 2.0.0-next.220 → 2.0.0-next.221
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/.i18nrc.js +4 -2
- package/CHANGELOG.md +33 -0
- package/apps/desktop/src/main/core/browser/Browser.ts +48 -20
- package/apps/desktop/src/main/core/browser/__tests__/Browser.test.ts +1 -0
- package/changelog/v1.json +12 -0
- package/docs/glossary.md +11 -0
- package/locales/zh-CN/topic.json +5 -5
- package/package.json +1 -1
- package/src/server/routers/lambda/notebook.ts +4 -2
- package/src/services/notebook.ts +2 -0
- package/src/store/tool/slices/builtin/executors/lobe-web-browsing.ts +2 -0
- package/glossary.json +0 -8
package/.i18nrc.js
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
const { defineConfig } = require('@lobehub/i18n-cli');
|
|
2
|
+
const fs = require('fs');
|
|
3
|
+
const path = require('path');
|
|
2
4
|
|
|
3
5
|
module.exports = defineConfig({
|
|
4
6
|
entry: 'locales/en-US',
|
|
@@ -31,8 +33,8 @@ module.exports = defineConfig({
|
|
|
31
33
|
},
|
|
32
34
|
markdown: {
|
|
33
35
|
reference:
|
|
34
|
-
'你需要保持 mdx
|
|
35
|
-
|
|
36
|
+
'你需要保持 mdx 的组件格式,输出文本不需要在最外层包裹任何代码块语法。\n' +
|
|
37
|
+
fs.readFileSync(path.join(__dirname, 'docs/glossary.md'), 'utf-8'),
|
|
36
38
|
entry: ['./README.zh-CN.md', './contributing/**/*.zh-CN.md', './docs/**/*.zh-CN.mdx'],
|
|
37
39
|
entryLocale: 'zh-CN',
|
|
38
40
|
outputLocales: ['en-US'],
|
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,39 @@
|
|
|
2
2
|
|
|
3
3
|
# Changelog
|
|
4
4
|
|
|
5
|
+
## [Version 2.0.0-next.221](https://github.com/lobehub/lobe-chat/compare/v2.0.0-next.220...v2.0.0-next.221)
|
|
6
|
+
|
|
7
|
+
<sup>Released on **2026-01-05**</sup>
|
|
8
|
+
|
|
9
|
+
#### ♻ Code Refactoring
|
|
10
|
+
|
|
11
|
+
- **misc**: Convert glossary from JSON to Markdown table format.
|
|
12
|
+
|
|
13
|
+
#### 🐛 Bug Fixes
|
|
14
|
+
|
|
15
|
+
- **misc**: Resolve desktop upload CORS issue.
|
|
16
|
+
|
|
17
|
+
<br/>
|
|
18
|
+
|
|
19
|
+
<details>
|
|
20
|
+
<summary><kbd>Improvements and Fixes</kbd></summary>
|
|
21
|
+
|
|
22
|
+
#### Code refactoring
|
|
23
|
+
|
|
24
|
+
- **misc**: Convert glossary from JSON to Markdown table format, closes [#11237](https://github.com/lobehub/lobe-chat/issues/11237) ([46a58a8](https://github.com/lobehub/lobe-chat/commit/46a58a8))
|
|
25
|
+
|
|
26
|
+
#### What's fixed
|
|
27
|
+
|
|
28
|
+
- **misc**: Resolve desktop upload CORS issue, closes [#11255](https://github.com/lobehub/lobe-chat/issues/11255) ([49ec5ed](https://github.com/lobehub/lobe-chat/commit/49ec5ed))
|
|
29
|
+
|
|
30
|
+
</details>
|
|
31
|
+
|
|
32
|
+
<div align="right">
|
|
33
|
+
|
|
34
|
+
[](#readme-top)
|
|
35
|
+
|
|
36
|
+
</div>
|
|
37
|
+
|
|
5
38
|
## [Version 2.0.0-next.220](https://github.com/lobehub/lobe-chat/compare/v2.0.0-next.219...v2.0.0-next.220)
|
|
6
39
|
|
|
7
40
|
<sup>Released on **2026-01-05**</sup>
|
|
@@ -374,14 +374,10 @@ export default class Browser {
|
|
|
374
374
|
| undefined;
|
|
375
375
|
logger.info(`Creating new BrowserWindow instance: ${this.identifier}`);
|
|
376
376
|
logger.debug(`[${this.identifier}] Options for new window: ${JSON.stringify(this.options)}`);
|
|
377
|
-
logger.debug(
|
|
378
|
-
`[${this.identifier}] Saved window state: ${JSON.stringify(savedState)}`,
|
|
379
|
-
);
|
|
377
|
+
logger.debug(`[${this.identifier}] Saved window state: ${JSON.stringify(savedState)}`);
|
|
380
378
|
|
|
381
379
|
const resolvedState = this.resolveWindowState(savedState, { height, width });
|
|
382
|
-
logger.debug(
|
|
383
|
-
`[${this.identifier}] Resolved window state: ${JSON.stringify(resolvedState)}`,
|
|
384
|
-
);
|
|
380
|
+
logger.debug(`[${this.identifier}] Resolved window state: ${JSON.stringify(resolvedState)}`);
|
|
385
381
|
|
|
386
382
|
const browserWindow = new BrowserWindow({
|
|
387
383
|
...res,
|
|
@@ -569,33 +565,65 @@ export default class Browser {
|
|
|
569
565
|
}
|
|
570
566
|
|
|
571
567
|
/**
|
|
572
|
-
* Setup CORS bypass for
|
|
573
|
-
*
|
|
568
|
+
* Setup CORS bypass for ALL requests
|
|
569
|
+
* In production, the renderer uses app://next protocol which triggers CORS for all external requests
|
|
570
|
+
* This completely bypasses CORS by:
|
|
571
|
+
* 1. Removing Origin header from requests (prevents OPTIONS preflight)
|
|
572
|
+
* 2. Adding proper CORS response headers using the stored origin value
|
|
574
573
|
*/
|
|
575
574
|
private setupCORSBypass(browserWindow: BrowserWindow): void {
|
|
576
|
-
logger.debug(`[${this.identifier}] Setting up CORS bypass for
|
|
575
|
+
logger.debug(`[${this.identifier}] Setting up CORS bypass for all requests`);
|
|
577
576
|
|
|
578
577
|
const session = browserWindow.webContents.session;
|
|
579
578
|
|
|
580
|
-
//
|
|
579
|
+
// Store origin values for each request ID
|
|
580
|
+
const originMap = new Map<number, string>();
|
|
581
|
+
|
|
582
|
+
// Remove Origin header and store it for later use
|
|
583
|
+
session.webRequest.onBeforeSendHeaders((details, callback) => {
|
|
584
|
+
const requestHeaders = { ...details.requestHeaders };
|
|
585
|
+
|
|
586
|
+
// Store and remove Origin header to prevent CORS preflight
|
|
587
|
+
if (requestHeaders['Origin']) {
|
|
588
|
+
originMap.set(details.id, requestHeaders['Origin']);
|
|
589
|
+
delete requestHeaders['Origin'];
|
|
590
|
+
logger.debug(
|
|
591
|
+
`[${this.identifier}] Removed Origin header for: ${details.url} (stored: ${requestHeaders['Origin']})`,
|
|
592
|
+
);
|
|
593
|
+
}
|
|
594
|
+
|
|
595
|
+
callback({ requestHeaders });
|
|
596
|
+
});
|
|
597
|
+
|
|
598
|
+
// Add CORS headers to ALL responses using stored origin
|
|
581
599
|
session.webRequest.onHeadersReceived((details, callback) => {
|
|
582
|
-
const
|
|
600
|
+
const responseHeaders = details.responseHeaders || {};
|
|
601
|
+
|
|
602
|
+
// Get the original origin from our map, fallback to default
|
|
603
|
+
const origin = originMap.get(details.id) || '*';
|
|
583
604
|
|
|
584
|
-
//
|
|
585
|
-
|
|
586
|
-
|
|
605
|
+
// Cannot use '*' when Access-Control-Allow-Credentials is true
|
|
606
|
+
responseHeaders['Access-Control-Allow-Origin'] = [origin];
|
|
607
|
+
responseHeaders['Access-Control-Allow-Methods'] = ['GET, POST, PUT, DELETE, OPTIONS, PATCH'];
|
|
608
|
+
responseHeaders['Access-Control-Allow-Headers'] = ['*'];
|
|
609
|
+
responseHeaders['Access-Control-Allow-Credentials'] = ['true'];
|
|
587
610
|
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
611
|
+
// Clean up the stored origin after response
|
|
612
|
+
originMap.delete(details.id);
|
|
613
|
+
|
|
614
|
+
// For OPTIONS requests, add preflight cache and override status
|
|
615
|
+
if (details.method === 'OPTIONS') {
|
|
616
|
+
responseHeaders['Access-Control-Max-Age'] = ['86400']; // 24 hours
|
|
617
|
+
logger.debug(`[${this.identifier}] Adding CORS headers to OPTIONS response`);
|
|
592
618
|
|
|
593
619
|
callback({
|
|
594
620
|
responseHeaders,
|
|
621
|
+
statusLine: 'HTTP/1.1 200 OK',
|
|
595
622
|
});
|
|
596
|
-
|
|
597
|
-
callback({ responseHeaders: details.responseHeaders });
|
|
623
|
+
return;
|
|
598
624
|
}
|
|
625
|
+
|
|
626
|
+
callback({ responseHeaders });
|
|
599
627
|
});
|
|
600
628
|
|
|
601
629
|
logger.debug(`[${this.identifier}] CORS bypass setup completed`);
|
package/changelog/v1.json
CHANGED
|
@@ -1,4 +1,16 @@
|
|
|
1
1
|
[
|
|
2
|
+
{
|
|
3
|
+
"children": {
|
|
4
|
+
"improvements": [
|
|
5
|
+
"Convert glossary from JSON to Markdown table format."
|
|
6
|
+
],
|
|
7
|
+
"fixes": [
|
|
8
|
+
"Resolve desktop upload CORS issue."
|
|
9
|
+
]
|
|
10
|
+
},
|
|
11
|
+
"date": "2026-01-05",
|
|
12
|
+
"version": "2.0.0-next.221"
|
|
13
|
+
},
|
|
2
14
|
{
|
|
3
15
|
"children": {
|
|
4
16
|
"fixes": [
|
package/docs/glossary.md
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
# Glossary
|
|
2
|
+
|
|
3
|
+
以下是一些词汇的固定翻译:
|
|
4
|
+
|
|
5
|
+
| develop key | zh-CN(中文) | en-US(English) |
|
|
6
|
+
|-------------| ----------- | -------------- |
|
|
7
|
+
| agent | 助理 | Agent |
|
|
8
|
+
| agentGroup | 群组 | Group |
|
|
9
|
+
| page | 文稿 | Page |
|
|
10
|
+
| topic | 话题 | Topic |
|
|
11
|
+
| thread | 子话题 | Thread |
|
package/locales/zh-CN/topic.json
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"actions.addNewTopic": "开启新话题",
|
|
3
3
|
"actions.autoRename": "智能重命名",
|
|
4
|
-
"actions.confirmRemoveAll": "
|
|
5
|
-
"actions.confirmRemoveTopic": "
|
|
6
|
-
"actions.confirmRemoveUnstarred": "
|
|
4
|
+
"actions.confirmRemoveAll": "您即将删除所有话题,此操作无法撤销。",
|
|
5
|
+
"actions.confirmRemoveTopic": "您即将删除此话题,此操作无法撤销。",
|
|
6
|
+
"actions.confirmRemoveUnstarred": "您即将删除未加星标的话题,此操作无法撤销。",
|
|
7
7
|
"actions.duplicate": "复制",
|
|
8
|
-
"actions.export": "
|
|
8
|
+
"actions.export": "导出话题",
|
|
9
9
|
"actions.import": "导入对话",
|
|
10
10
|
"actions.openInNewWindow": "打开独立窗口",
|
|
11
11
|
"actions.removeAll": "删除全部话题",
|
|
@@ -24,7 +24,7 @@
|
|
|
24
24
|
"groupTitle.byTime.week": "本周",
|
|
25
25
|
"groupTitle.byTime.yesterday": "昨天",
|
|
26
26
|
"guide.desc": "点击发送左侧按钮可将当前会话保存为历史话题,并开启新一轮会话",
|
|
27
|
-
"guide.title": "
|
|
27
|
+
"guide.title": "话题列表",
|
|
28
28
|
"importError": "导入遇到了问题",
|
|
29
29
|
"importInvalidFormat": "文件格式不正确。请确认这是有效的 JSON 文件",
|
|
30
30
|
"importLoading": "正在导入对话…",
|
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.221",
|
|
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",
|
|
@@ -24,6 +24,8 @@ export const notebookRouter = router({
|
|
|
24
24
|
content: z.string(),
|
|
25
25
|
description: z.string(),
|
|
26
26
|
metadata: z.record(z.string(), z.any()).optional(),
|
|
27
|
+
source: z.string().optional().default('notebook'),
|
|
28
|
+
sourceType: z.enum(['file', 'web', 'api', 'topic']).optional().default('api'),
|
|
27
29
|
title: z.string(),
|
|
28
30
|
topicId: z.string(),
|
|
29
31
|
type: z
|
|
@@ -39,8 +41,8 @@ export const notebookRouter = router({
|
|
|
39
41
|
description: input.description,
|
|
40
42
|
fileType: input.type,
|
|
41
43
|
metadata: input.metadata,
|
|
42
|
-
source:
|
|
43
|
-
sourceType:
|
|
44
|
+
source: input.source,
|
|
45
|
+
sourceType: input.sourceType,
|
|
44
46
|
title: input.title,
|
|
45
47
|
totalCharCount: input.content.length,
|
|
46
48
|
totalLineCount: input.content.split('\n').length,
|
package/src/services/notebook.ts
CHANGED
|
@@ -130,6 +130,8 @@ class WebBrowsingExecutor extends BaseExecutor<typeof WebBrowsingApiName> {
|
|
|
130
130
|
const document = await notebookService.createDocument({
|
|
131
131
|
content: pageData.content,
|
|
132
132
|
description: pageData.description || `Crawled from ${pageData.url}`,
|
|
133
|
+
source: pageData.url,
|
|
134
|
+
sourceType: 'web',
|
|
133
135
|
title: pageData.title || pageData.url,
|
|
134
136
|
topicId: ctx.topicId!,
|
|
135
137
|
type: 'article',
|