@lobehub/lobehub 2.0.0-next.98 → 2.0.0-next.99
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 +25 -0
- package/apps/desktop/src/main/services/__tests__/fileSrv.test.ts +603 -0
- package/changelog/v1.json +9 -0
- package/codecov.yml +1 -0
- package/locales/ar/plugin.json +34 -22
- package/locales/ar/tool.json +8 -0
- package/locales/bg-BG/plugin.json +34 -22
- package/locales/bg-BG/tool.json +8 -0
- package/locales/de-DE/plugin.json +34 -22
- package/locales/de-DE/tool.json +8 -0
- package/locales/en-US/plugin.json +34 -22
- package/locales/en-US/tool.json +8 -0
- package/locales/es-ES/plugin.json +34 -22
- package/locales/es-ES/tool.json +8 -0
- package/locales/fa-IR/plugin.json +34 -22
- package/locales/fa-IR/tool.json +8 -0
- package/locales/fr-FR/plugin.json +34 -22
- package/locales/fr-FR/tool.json +8 -0
- package/locales/it-IT/plugin.json +34 -22
- package/locales/it-IT/tool.json +8 -0
- package/locales/ja-JP/plugin.json +34 -22
- package/locales/ja-JP/tool.json +8 -0
- package/locales/ko-KR/plugin.json +34 -22
- package/locales/ko-KR/tool.json +8 -0
- package/locales/nl-NL/plugin.json +34 -22
- package/locales/nl-NL/tool.json +8 -0
- package/locales/pl-PL/plugin.json +34 -22
- package/locales/pl-PL/tool.json +8 -0
- package/locales/pt-BR/plugin.json +34 -22
- package/locales/pt-BR/tool.json +8 -0
- package/locales/ru-RU/plugin.json +34 -22
- package/locales/ru-RU/tool.json +8 -0
- package/locales/tr-TR/plugin.json +34 -22
- package/locales/tr-TR/tool.json +8 -0
- package/locales/vi-VN/plugin.json +34 -22
- package/locales/vi-VN/tool.json +8 -0
- package/locales/zh-CN/plugin.json +34 -22
- package/locales/zh-CN/tool.json +8 -0
- package/locales/zh-TW/plugin.json +34 -22
- package/locales/zh-TW/tool.json +8 -0
- package/package.json +1 -1
- package/packages/database/src/models/__tests__/document.test.ts +149 -0
- package/packages/database/src/models/chunk.ts +3 -1
- package/packages/database/src/models/document.ts +8 -2
- package/packages/prompts/src/prompts/knowledgeBaseQA/__snapshots__/formatFileContents.test.ts.snap +75 -0
- package/packages/prompts/src/prompts/knowledgeBaseQA/__snapshots__/formatNoSearchResults.test.ts.snap +45 -0
- package/packages/prompts/src/prompts/knowledgeBaseQA/__snapshots__/formatSearchResults.test.ts.snap +82 -0
- package/packages/prompts/src/prompts/knowledgeBaseQA/formatFileContents.test.ts +118 -0
- package/packages/prompts/src/prompts/knowledgeBaseQA/formatFileContents.ts +31 -0
- package/packages/prompts/src/prompts/knowledgeBaseQA/formatNoSearchResults.test.ts +25 -0
- package/packages/prompts/src/prompts/knowledgeBaseQA/formatNoSearchResults.ts +13 -0
- package/packages/prompts/src/prompts/knowledgeBaseQA/formatSearchResults.test.ts +191 -0
- package/packages/prompts/src/prompts/knowledgeBaseQA/formatSearchResults.ts +50 -0
- package/packages/prompts/src/prompts/knowledgeBaseQA/index.ts +6 -0
- package/packages/types/src/rag.ts +13 -4
- package/src/features/ChatInput/ActionBar/Token/TokenTag.tsx +2 -2
- package/src/features/ChatInput/ActionBar/Token/TokenTagForGroupChat.tsx +2 -2
- package/src/features/ChatList/Messages/Group/Tool/Inspector/ToolTitle.tsx +5 -23
- package/src/features/ChatList/Messages/Tool/Inspector/ToolTitle.tsx +5 -25
- package/src/features/PluginsUI/Render/BuiltinType/index.tsx +1 -1
- package/src/helpers/toolEngineering/index.test.ts +3 -3
- package/src/helpers/toolEngineering/index.ts +17 -4
- package/src/libs/trpc/client/lambda.ts +0 -6
- package/src/locales/default/plugin.ts +34 -22
- package/src/locales/default/tool.ts +13 -5
- package/src/server/routers/lambda/chunk.ts +168 -41
- package/src/services/chat/chat.test.ts +3 -3
- package/src/services/chat/index.ts +2 -2
- package/src/services/rag.ts +6 -2
- package/src/store/chat/slices/aiChat/actions/__tests__/conversationLifecycle.test.ts +11 -0
- package/src/store/chat/slices/aiChat/actions/__tests__/rag.test.ts +0 -87
- package/src/store/chat/slices/aiChat/actions/__tests__/streamingExecutor.test.ts +2 -69
- package/src/store/chat/slices/aiChat/actions/conversationLifecycle.ts +0 -2
- package/src/store/chat/slices/aiChat/actions/rag.ts +0 -47
- package/src/store/chat/slices/aiChat/actions/streamingExecutor.ts +8 -69
- package/src/store/chat/slices/builtinTool/actions/index.ts +4 -1
- package/src/store/chat/slices/builtinTool/actions/knowledgeBase.ts +174 -0
- package/src/store/chat/slices/operation/types.ts +1 -0
- package/src/store/chat/slices/thread/action.test.ts +0 -1
- package/src/store/chat/slices/thread/action.ts +0 -1
- package/src/tools/executionRuntimes.ts +3 -0
- package/src/tools/identifiers.ts +13 -0
- package/src/tools/index.ts +7 -0
- package/src/tools/knowledge-base/ExecutionRuntime/index.ts +96 -0
- package/src/tools/knowledge-base/Render/ReadKnowledge/FileCard.tsx +135 -0
- package/src/tools/knowledge-base/Render/ReadKnowledge/index.tsx +27 -0
- package/src/tools/knowledge-base/Render/SearchKnowledgeBase/Item/index.tsx +54 -0
- package/src/tools/knowledge-base/Render/SearchKnowledgeBase/Item/style.ts +51 -0
- package/src/tools/knowledge-base/Render/SearchKnowledgeBase/index.tsx +23 -0
- package/src/tools/knowledge-base/Render/index.ts +7 -0
- package/src/tools/knowledge-base/index.ts +64 -0
- package/src/tools/knowledge-base/systemRole.ts +102 -0
- package/src/tools/knowledge-base/type.ts +25 -0
- package/src/tools/local-system/Intervention/WriteFile/index.tsx +1 -1
- package/src/tools/renders.ts +4 -0
- package/src/store/chat/agents/createToolEngine.ts +0 -22
|
@@ -1,4 +1,38 @@
|
|
|
1
1
|
{
|
|
2
|
+
"builtins": {
|
|
3
|
+
"lobe-knowledge-base": {
|
|
4
|
+
"apiName": {
|
|
5
|
+
"readKnowledge": "Bilgi tabanını oku",
|
|
6
|
+
"searchKnowledgeBase": "Bilgi tabanında ara"
|
|
7
|
+
},
|
|
8
|
+
"title": "Bilgi Tabanı"
|
|
9
|
+
},
|
|
10
|
+
"lobe-local-system": {
|
|
11
|
+
"apiName": {
|
|
12
|
+
"editLocalFile": "Dosyayı düzenle",
|
|
13
|
+
"getCommandOutput": "Komut çıktısını al",
|
|
14
|
+
"globLocalFiles": "Dosyaları desenle ara",
|
|
15
|
+
"grepContent": "İçerikte ara",
|
|
16
|
+
"killCommand": "Komut çalışmasını durdur",
|
|
17
|
+
"listLocalFiles": "Dosya listesini görüntüle",
|
|
18
|
+
"moveLocalFiles": "Dosyaları taşı",
|
|
19
|
+
"readLocalFile": "Dosya içeriğini oku",
|
|
20
|
+
"renameLocalFile": "Yeniden adlandır",
|
|
21
|
+
"runCommand": "Komut çalıştır",
|
|
22
|
+
"searchLocalFiles": "Dosyalarda ara",
|
|
23
|
+
"writeLocalFile": "Dosyaya yaz"
|
|
24
|
+
},
|
|
25
|
+
"title": "Yerel Sistem"
|
|
26
|
+
},
|
|
27
|
+
"lobe-web-browsing": {
|
|
28
|
+
"apiName": {
|
|
29
|
+
"crawlMultiPages": "Birden fazla sayfanın içeriğini oku",
|
|
30
|
+
"crawlSinglePage": "Sayfa içeriğini oku",
|
|
31
|
+
"search": "Sayfada ara"
|
|
32
|
+
},
|
|
33
|
+
"title": "İnternette Arama"
|
|
34
|
+
}
|
|
35
|
+
},
|
|
2
36
|
"confirm": "Onayla",
|
|
3
37
|
"debug": {
|
|
4
38
|
"arguments": "Çağrı parametreleri",
|
|
@@ -251,23 +285,6 @@
|
|
|
251
285
|
"content": "Eklenti çağrılıyor...",
|
|
252
286
|
"plugin": "Eklenti çalışıyor..."
|
|
253
287
|
},
|
|
254
|
-
"localSystem": {
|
|
255
|
-
"apiName": {
|
|
256
|
-
"editLocalFile": "Dosyayı Düzenle",
|
|
257
|
-
"getCommandOutput": "Komut Çıktısını Al",
|
|
258
|
-
"globLocalFiles": "Dosyaları Ara",
|
|
259
|
-
"grepContent": "İçeriği Ara",
|
|
260
|
-
"killCommand": "Komut Yürütmesini Durdur",
|
|
261
|
-
"listLocalFiles": "Dosya listesini görüntüle",
|
|
262
|
-
"moveLocalFiles": "Dosya taşı",
|
|
263
|
-
"readLocalFile": "Dosya içeriğini oku",
|
|
264
|
-
"renameLocalFile": "Dosya adını değiştir",
|
|
265
|
-
"runCommand": "Komutu Çalıştır",
|
|
266
|
-
"searchLocalFiles": "Dosya ara",
|
|
267
|
-
"writeLocalFile": "Dosyaya yaz"
|
|
268
|
-
},
|
|
269
|
-
"title": "Yerel Sistem"
|
|
270
|
-
},
|
|
271
288
|
"mcpInstall": {
|
|
272
289
|
"CHECKING_INSTALLATION": "Kurulum ortamı kontrol ediliyor...",
|
|
273
290
|
"COMPLETED": "Kurulum tamamlandı",
|
|
@@ -375,11 +392,6 @@
|
|
|
375
392
|
"warning": "⚠️ Lütfen bu eklentinin kaynağına güvendiğinizden emin olun, kötü amaçlı eklentiler sistem güvenliğinizi tehlikeye atabilir."
|
|
376
393
|
},
|
|
377
394
|
"search": {
|
|
378
|
-
"apiName": {
|
|
379
|
-
"crawlMultiPages": "Birden fazla sayfa içeriği oku",
|
|
380
|
-
"crawlSinglePage": "Sayfa içeriği oku",
|
|
381
|
-
"search": "Sayfa ara"
|
|
382
|
-
},
|
|
383
395
|
"config": {
|
|
384
396
|
"addKey": "Anahtar ekle",
|
|
385
397
|
"close": "Sil",
|
package/locales/tr-TR/tool.json
CHANGED
|
@@ -14,6 +14,14 @@
|
|
|
14
14
|
"images": "Görseller:",
|
|
15
15
|
"prompt": "İpucu"
|
|
16
16
|
},
|
|
17
|
+
"lobe-knowledge-base": {
|
|
18
|
+
"readKnowledge": {
|
|
19
|
+
"meta": {
|
|
20
|
+
"chars": "Karakter Sayısı",
|
|
21
|
+
"lines": "Satır Sayısı"
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
},
|
|
17
25
|
"localFiles": {
|
|
18
26
|
"editFile": {
|
|
19
27
|
"newString": "Şununla değiştir",
|
|
@@ -1,4 +1,38 @@
|
|
|
1
1
|
{
|
|
2
|
+
"builtins": {
|
|
3
|
+
"lobe-knowledge-base": {
|
|
4
|
+
"apiName": {
|
|
5
|
+
"readKnowledge": "Đọc nội dung cơ sở tri thức",
|
|
6
|
+
"searchKnowledgeBase": "Tìm kiếm trong cơ sở tri thức"
|
|
7
|
+
},
|
|
8
|
+
"title": "Cơ sở tri thức"
|
|
9
|
+
},
|
|
10
|
+
"lobe-local-system": {
|
|
11
|
+
"apiName": {
|
|
12
|
+
"editLocalFile": "Chỉnh sửa tệp",
|
|
13
|
+
"getCommandOutput": "Lấy kết quả mã lệnh",
|
|
14
|
+
"globLocalFiles": "Tìm kiếm tệp theo mẫu",
|
|
15
|
+
"grepContent": "Tìm kiếm nội dung",
|
|
16
|
+
"killCommand": "Dừng thực thi mã lệnh",
|
|
17
|
+
"listLocalFiles": "Xem danh sách tệp",
|
|
18
|
+
"moveLocalFiles": "Di chuyển tệp",
|
|
19
|
+
"readLocalFile": "Đọc nội dung tệp",
|
|
20
|
+
"renameLocalFile": "Đổi tên tệp",
|
|
21
|
+
"runCommand": "Thực thi mã lệnh",
|
|
22
|
+
"searchLocalFiles": "Tìm kiếm tệp",
|
|
23
|
+
"writeLocalFile": "Ghi nội dung vào tệp"
|
|
24
|
+
},
|
|
25
|
+
"title": "Hệ thống cục bộ"
|
|
26
|
+
},
|
|
27
|
+
"lobe-web-browsing": {
|
|
28
|
+
"apiName": {
|
|
29
|
+
"crawlMultiPages": "Đọc nội dung nhiều trang",
|
|
30
|
+
"crawlSinglePage": "Đọc nội dung trang",
|
|
31
|
+
"search": "Tìm kiếm trang"
|
|
32
|
+
},
|
|
33
|
+
"title": "Tìm kiếm trực tuyến"
|
|
34
|
+
}
|
|
35
|
+
},
|
|
2
36
|
"confirm": "Xác nhận",
|
|
3
37
|
"debug": {
|
|
4
38
|
"arguments": "Tham số gọi",
|
|
@@ -251,23 +285,6 @@
|
|
|
251
285
|
"content": "Đang gọi plugin...",
|
|
252
286
|
"plugin": "Plugin đang chạy..."
|
|
253
287
|
},
|
|
254
|
-
"localSystem": {
|
|
255
|
-
"apiName": {
|
|
256
|
-
"editLocalFile": "Chỉnh sửa tệp",
|
|
257
|
-
"getCommandOutput": "Lấy đầu ra mã lệnh",
|
|
258
|
-
"globLocalFiles": "Tìm kiếm tệp",
|
|
259
|
-
"grepContent": "Tìm kiếm nội dung",
|
|
260
|
-
"killCommand": "Dừng thực thi mã",
|
|
261
|
-
"listLocalFiles": "Xem danh sách tệp",
|
|
262
|
-
"moveLocalFiles": "Di chuyển tệp",
|
|
263
|
-
"readLocalFile": "Đọc nội dung tệp",
|
|
264
|
-
"renameLocalFile": "Đổi tên",
|
|
265
|
-
"runCommand": "Chạy mã",
|
|
266
|
-
"searchLocalFiles": "Tìm kiếm tệp",
|
|
267
|
-
"writeLocalFile": "Ghi tệp"
|
|
268
|
-
},
|
|
269
|
-
"title": "Hệ thống cục bộ"
|
|
270
|
-
},
|
|
271
288
|
"mcpInstall": {
|
|
272
289
|
"CHECKING_INSTALLATION": "Đang kiểm tra môi trường cài đặt...",
|
|
273
290
|
"COMPLETED": "Hoàn thành cài đặt",
|
|
@@ -375,11 +392,6 @@
|
|
|
375
392
|
"warning": "⚠️ Vui lòng xác nhận bạn tin tưởng nguồn plugin này, plugin độc hại có thể gây nguy hiểm cho hệ thống của bạn."
|
|
376
393
|
},
|
|
377
394
|
"search": {
|
|
378
|
-
"apiName": {
|
|
379
|
-
"crawlMultiPages": "Đọc nội dung nhiều trang",
|
|
380
|
-
"crawlSinglePage": "Đọc nội dung trang",
|
|
381
|
-
"search": "Tìm kiếm trang"
|
|
382
|
-
},
|
|
383
395
|
"config": {
|
|
384
396
|
"addKey": "Thêm khóa bí mật",
|
|
385
397
|
"close": "Xóa",
|
package/locales/vi-VN/tool.json
CHANGED
|
@@ -14,6 +14,14 @@
|
|
|
14
14
|
"images": "Hình ảnh:",
|
|
15
15
|
"prompt": "Từ khóa"
|
|
16
16
|
},
|
|
17
|
+
"lobe-knowledge-base": {
|
|
18
|
+
"readKnowledge": {
|
|
19
|
+
"meta": {
|
|
20
|
+
"chars": "Số ký tự",
|
|
21
|
+
"lines": "Số dòng"
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
},
|
|
17
25
|
"localFiles": {
|
|
18
26
|
"editFile": {
|
|
19
27
|
"newString": "Thay thế bằng",
|
|
@@ -1,4 +1,38 @@
|
|
|
1
1
|
{
|
|
2
|
+
"builtins": {
|
|
3
|
+
"lobe-knowledge-base": {
|
|
4
|
+
"apiName": {
|
|
5
|
+
"readKnowledge": "读取知识库内容",
|
|
6
|
+
"searchKnowledgeBase": "搜索知识库"
|
|
7
|
+
},
|
|
8
|
+
"title": "知识库"
|
|
9
|
+
},
|
|
10
|
+
"lobe-local-system": {
|
|
11
|
+
"apiName": {
|
|
12
|
+
"editLocalFile": "编辑文件",
|
|
13
|
+
"getCommandOutput": "获取代码输出",
|
|
14
|
+
"globLocalFiles": "匹配搜索文件",
|
|
15
|
+
"grepContent": "搜索内容",
|
|
16
|
+
"killCommand": "终止代码执行",
|
|
17
|
+
"listLocalFiles": "查看文件列表",
|
|
18
|
+
"moveLocalFiles": "移动文件",
|
|
19
|
+
"readLocalFile": "读取文件内容",
|
|
20
|
+
"renameLocalFile": "重命名",
|
|
21
|
+
"runCommand": "执行代码",
|
|
22
|
+
"searchLocalFiles": "搜索文件",
|
|
23
|
+
"writeLocalFile": "写入文件"
|
|
24
|
+
},
|
|
25
|
+
"title": "本地系统"
|
|
26
|
+
},
|
|
27
|
+
"lobe-web-browsing": {
|
|
28
|
+
"apiName": {
|
|
29
|
+
"crawlMultiPages": "读取多个页面内容",
|
|
30
|
+
"crawlSinglePage": "读取页面内容",
|
|
31
|
+
"search": "搜索页面"
|
|
32
|
+
},
|
|
33
|
+
"title": "联网搜索"
|
|
34
|
+
}
|
|
35
|
+
},
|
|
2
36
|
"confirm": "确定",
|
|
3
37
|
"debug": {
|
|
4
38
|
"arguments": "调用参数",
|
|
@@ -251,23 +285,6 @@
|
|
|
251
285
|
"content": "调用插件中...",
|
|
252
286
|
"plugin": "插件运行中..."
|
|
253
287
|
},
|
|
254
|
-
"localSystem": {
|
|
255
|
-
"apiName": {
|
|
256
|
-
"editLocalFile": "编辑文件",
|
|
257
|
-
"getCommandOutput": "获取代码输出",
|
|
258
|
-
"globLocalFiles": "匹配搜索文件",
|
|
259
|
-
"grepContent": "搜索内容",
|
|
260
|
-
"killCommand": "终止代码执行",
|
|
261
|
-
"listLocalFiles": "查看文件列表",
|
|
262
|
-
"moveLocalFiles": "移动文件",
|
|
263
|
-
"readLocalFile": "读取文件内容",
|
|
264
|
-
"renameLocalFile": "重命名",
|
|
265
|
-
"runCommand": "执行代码",
|
|
266
|
-
"searchLocalFiles": "搜索文件",
|
|
267
|
-
"writeLocalFile": "写入文件"
|
|
268
|
-
},
|
|
269
|
-
"title": "本地系统"
|
|
270
|
-
},
|
|
271
288
|
"mcpInstall": {
|
|
272
289
|
"CHECKING_INSTALLATION": "检查安装环境...",
|
|
273
290
|
"COMPLETED": "安装完成",
|
|
@@ -375,11 +392,6 @@
|
|
|
375
392
|
"warning": "⚠️ 请确认您信任此插件的来源,恶意插件可能会危害您的系统安全。"
|
|
376
393
|
},
|
|
377
394
|
"search": {
|
|
378
|
-
"apiName": {
|
|
379
|
-
"crawlMultiPages": "读取多个页面内容",
|
|
380
|
-
"crawlSinglePage": "读取页面内容",
|
|
381
|
-
"search": "搜索页面"
|
|
382
|
-
},
|
|
383
395
|
"config": {
|
|
384
396
|
"addKey": "添加秘钥",
|
|
385
397
|
"close": "删除",
|
package/locales/zh-CN/tool.json
CHANGED
|
@@ -1,4 +1,38 @@
|
|
|
1
1
|
{
|
|
2
|
+
"builtins": {
|
|
3
|
+
"lobe-knowledge-base": {
|
|
4
|
+
"apiName": {
|
|
5
|
+
"readKnowledge": "讀取知識庫內容",
|
|
6
|
+
"searchKnowledgeBase": "搜尋知識庫"
|
|
7
|
+
},
|
|
8
|
+
"title": "知識庫"
|
|
9
|
+
},
|
|
10
|
+
"lobe-local-system": {
|
|
11
|
+
"apiName": {
|
|
12
|
+
"editLocalFile": "編輯檔案",
|
|
13
|
+
"getCommandOutput": "取得程式碼輸出",
|
|
14
|
+
"globLocalFiles": "匹配搜尋檔案",
|
|
15
|
+
"grepContent": "搜尋內容",
|
|
16
|
+
"killCommand": "終止程式碼執行",
|
|
17
|
+
"listLocalFiles": "查看檔案清單",
|
|
18
|
+
"moveLocalFiles": "移動檔案",
|
|
19
|
+
"readLocalFile": "讀取檔案內容",
|
|
20
|
+
"renameLocalFile": "重新命名",
|
|
21
|
+
"runCommand": "執行程式碼",
|
|
22
|
+
"searchLocalFiles": "搜尋檔案",
|
|
23
|
+
"writeLocalFile": "寫入檔案"
|
|
24
|
+
},
|
|
25
|
+
"title": "本機系統"
|
|
26
|
+
},
|
|
27
|
+
"lobe-web-browsing": {
|
|
28
|
+
"apiName": {
|
|
29
|
+
"crawlMultiPages": "讀取多個頁面內容",
|
|
30
|
+
"crawlSinglePage": "讀取頁面內容",
|
|
31
|
+
"search": "搜尋頁面"
|
|
32
|
+
},
|
|
33
|
+
"title": "網路搜尋"
|
|
34
|
+
}
|
|
35
|
+
},
|
|
2
36
|
"confirm": "確定",
|
|
3
37
|
"debug": {
|
|
4
38
|
"arguments": "調用參數",
|
|
@@ -251,23 +285,6 @@
|
|
|
251
285
|
"content": "調用插件中...",
|
|
252
286
|
"plugin": "插件運行中..."
|
|
253
287
|
},
|
|
254
|
-
"localSystem": {
|
|
255
|
-
"apiName": {
|
|
256
|
-
"editLocalFile": "編輯檔案",
|
|
257
|
-
"getCommandOutput": "取得程式輸出",
|
|
258
|
-
"globLocalFiles": "匹配搜尋檔案",
|
|
259
|
-
"grepContent": "搜尋內容",
|
|
260
|
-
"killCommand": "終止程式執行",
|
|
261
|
-
"listLocalFiles": "查看檔案列表",
|
|
262
|
-
"moveLocalFiles": "移動檔案",
|
|
263
|
-
"readLocalFile": "讀取檔案內容",
|
|
264
|
-
"renameLocalFile": "重新命名",
|
|
265
|
-
"runCommand": "執行程式碼",
|
|
266
|
-
"searchLocalFiles": "搜尋檔案",
|
|
267
|
-
"writeLocalFile": "寫入檔案"
|
|
268
|
-
},
|
|
269
|
-
"title": "本機系統"
|
|
270
|
-
},
|
|
271
288
|
"mcpInstall": {
|
|
272
289
|
"CHECKING_INSTALLATION": "檢查安裝環境...",
|
|
273
290
|
"COMPLETED": "安裝完成",
|
|
@@ -375,11 +392,6 @@
|
|
|
375
392
|
"warning": "⚠️ 請確認您信任此插件的來源,惡意插件可能會危害您的系統安全。"
|
|
376
393
|
},
|
|
377
394
|
"search": {
|
|
378
|
-
"apiName": {
|
|
379
|
-
"crawlMultiPages": "讀取多個頁面內容",
|
|
380
|
-
"crawlSinglePage": "讀取頁面內容",
|
|
381
|
-
"search": "搜尋頁面"
|
|
382
|
-
},
|
|
383
395
|
"config": {
|
|
384
396
|
"addKey": "添加密鑰",
|
|
385
397
|
"close": "刪除",
|
package/locales/zh-TW/tool.json
CHANGED
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.99",
|
|
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",
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
// @vitest-environment node
|
|
2
|
+
import { afterEach, beforeEach, describe, expect, it } from 'vitest';
|
|
3
|
+
|
|
4
|
+
import { documents, files, users } from '../../schemas';
|
|
5
|
+
import { LobeChatDatabase } from '../../type';
|
|
6
|
+
import { DocumentModel } from '../document';
|
|
7
|
+
import { FileModel } from '../file';
|
|
8
|
+
import { getTestDB } from './_util';
|
|
9
|
+
|
|
10
|
+
const serverDB: LobeChatDatabase = await getTestDB();
|
|
11
|
+
|
|
12
|
+
const userId = 'document-model-test-user-id';
|
|
13
|
+
const userId2 = 'document-model-test-user-id-2';
|
|
14
|
+
const documentModel = new DocumentModel(serverDB, userId);
|
|
15
|
+
const documentModel2 = new DocumentModel(serverDB, userId2);
|
|
16
|
+
const fileModel = new FileModel(serverDB, userId);
|
|
17
|
+
const fileModel2 = new FileModel(serverDB, userId2);
|
|
18
|
+
|
|
19
|
+
beforeEach(async () => {
|
|
20
|
+
await serverDB.delete(users);
|
|
21
|
+
await serverDB.insert(users).values([{ id: userId }, { id: userId2 }]);
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
afterEach(async () => {
|
|
25
|
+
await serverDB.delete(users);
|
|
26
|
+
await serverDB.delete(files);
|
|
27
|
+
await serverDB.delete(documents);
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
// Helper to create a minimal valid document
|
|
31
|
+
const createTestDocument = async (model: DocumentModel, fModel: FileModel, content: string) => {
|
|
32
|
+
const { id: fileId } = await fModel.create({
|
|
33
|
+
fileType: 'text/plain',
|
|
34
|
+
name: 'test.txt',
|
|
35
|
+
size: 100,
|
|
36
|
+
url: 'https://example.com/test.txt',
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
// Fetch the file to get complete data
|
|
40
|
+
const file = await fModel.findById(fileId);
|
|
41
|
+
if (!file) throw new Error('File not found after creation');
|
|
42
|
+
|
|
43
|
+
const { id } = await model.create({
|
|
44
|
+
content,
|
|
45
|
+
fileId: file.id,
|
|
46
|
+
fileType: 'text/plain',
|
|
47
|
+
source: file.url,
|
|
48
|
+
sourceType: 'file',
|
|
49
|
+
totalCharCount: content.length,
|
|
50
|
+
totalLineCount: content.split('\n').length,
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
return { documentId: id, file };
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
describe('DocumentModel', () => {
|
|
57
|
+
describe('findByFileId', () => {
|
|
58
|
+
it('should find document by fileId', async () => {
|
|
59
|
+
const { documentId, file } = await createTestDocument(
|
|
60
|
+
documentModel,
|
|
61
|
+
fileModel,
|
|
62
|
+
'Test content for file',
|
|
63
|
+
);
|
|
64
|
+
|
|
65
|
+
const found = await documentModel.findByFileId(file.id);
|
|
66
|
+
expect(found).toBeDefined();
|
|
67
|
+
expect(found?.id).toBe(documentId);
|
|
68
|
+
expect(found?.fileId).toBe(file.id);
|
|
69
|
+
expect(found?.content).toBe('Test content for file');
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
it('should not find document from another user', async () => {
|
|
73
|
+
const { file } = await createTestDocument(documentModel, fileModel, 'Test content');
|
|
74
|
+
|
|
75
|
+
// Try to find with another user's model
|
|
76
|
+
const found = await documentModel2.findByFileId(file.id);
|
|
77
|
+
expect(found).toBeUndefined();
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
it('should return undefined for non-existent fileId', async () => {
|
|
81
|
+
const found = await documentModel.findByFileId('non-existent-file-id');
|
|
82
|
+
expect(found).toBeUndefined();
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
it('should return the first document when multiple documents exist for same file', async () => {
|
|
86
|
+
const { id: fileId } = await fileModel.create({
|
|
87
|
+
fileType: 'text/plain',
|
|
88
|
+
name: 'test.txt',
|
|
89
|
+
size: 100,
|
|
90
|
+
url: 'https://example.com/test.txt',
|
|
91
|
+
});
|
|
92
|
+
|
|
93
|
+
const file = await fileModel.findById(fileId);
|
|
94
|
+
if (!file) throw new Error('File not found after creation');
|
|
95
|
+
|
|
96
|
+
const { id: firstId } = await documentModel.create({
|
|
97
|
+
content: 'First document',
|
|
98
|
+
fileId: file.id,
|
|
99
|
+
fileType: 'text/plain',
|
|
100
|
+
source: file.url,
|
|
101
|
+
sourceType: 'file',
|
|
102
|
+
totalCharCount: 14,
|
|
103
|
+
totalLineCount: 1,
|
|
104
|
+
});
|
|
105
|
+
|
|
106
|
+
await documentModel.create({
|
|
107
|
+
content: 'Second document',
|
|
108
|
+
fileId: file.id,
|
|
109
|
+
fileType: 'text/plain',
|
|
110
|
+
source: file.url,
|
|
111
|
+
sourceType: 'file',
|
|
112
|
+
totalCharCount: 15,
|
|
113
|
+
totalLineCount: 1,
|
|
114
|
+
});
|
|
115
|
+
|
|
116
|
+
const found = await documentModel.findByFileId(file.id);
|
|
117
|
+
expect(found).toBeDefined();
|
|
118
|
+
// Should return the first created document
|
|
119
|
+
expect(found?.id).toBe(firstId);
|
|
120
|
+
});
|
|
121
|
+
|
|
122
|
+
it('should handle different file types', async () => {
|
|
123
|
+
const { id: pdfFileId } = await fileModel.create({
|
|
124
|
+
fileType: 'application/pdf',
|
|
125
|
+
name: 'document.pdf',
|
|
126
|
+
size: 5000,
|
|
127
|
+
url: 'https://example.com/document.pdf',
|
|
128
|
+
});
|
|
129
|
+
|
|
130
|
+
const pdfFile = await fileModel.findById(pdfFileId);
|
|
131
|
+
if (!pdfFile) throw new Error('File not found after creation');
|
|
132
|
+
|
|
133
|
+
await documentModel.create({
|
|
134
|
+
content: 'PDF content',
|
|
135
|
+
fileId: pdfFile.id,
|
|
136
|
+
fileType: 'application/pdf',
|
|
137
|
+
source: pdfFile.url,
|
|
138
|
+
sourceType: 'file',
|
|
139
|
+
totalCharCount: 11,
|
|
140
|
+
totalLineCount: 1,
|
|
141
|
+
});
|
|
142
|
+
|
|
143
|
+
const found = await documentModel.findByFileId(pdfFile.id);
|
|
144
|
+
expect(found).toBeDefined();
|
|
145
|
+
expect(found?.fileType).toBe('application/pdf');
|
|
146
|
+
expect(found?.content).toBe('PDF content');
|
|
147
|
+
});
|
|
148
|
+
});
|
|
149
|
+
});
|
|
@@ -181,10 +181,12 @@ export class ChunkModel {
|
|
|
181
181
|
semanticSearchForChat = async ({
|
|
182
182
|
embedding,
|
|
183
183
|
fileIds,
|
|
184
|
+
topK = 15,
|
|
184
185
|
}: {
|
|
185
186
|
embedding: number[];
|
|
186
187
|
fileIds: string[] | undefined;
|
|
187
188
|
query: string;
|
|
189
|
+
topK?: number;
|
|
188
190
|
}) => {
|
|
189
191
|
const similarity = sql<number>`1 - (${cosineDistance(embeddings.embeddings, embedding)})`;
|
|
190
192
|
|
|
@@ -210,7 +212,7 @@ export class ChunkModel {
|
|
|
210
212
|
.where(inArray(fileChunks.fileId, fileIds))
|
|
211
213
|
.orderBy((t) => desc(t.similarity))
|
|
212
214
|
// Relaxed to 15 for now
|
|
213
|
-
.limit(
|
|
215
|
+
.limit(topK);
|
|
214
216
|
|
|
215
217
|
return result.map((item) => {
|
|
216
218
|
return {
|
|
@@ -40,7 +40,13 @@ export class DocumentModel {
|
|
|
40
40
|
|
|
41
41
|
findById = async (id: string): Promise<DocumentItem | undefined> => {
|
|
42
42
|
return this.db.query.documents.findFirst({
|
|
43
|
-
where: and(eq(documents.
|
|
43
|
+
where: and(eq(documents.userId, this.userId), eq(documents.id, id)),
|
|
44
|
+
});
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
findByFileId = async (fileId: string) => {
|
|
48
|
+
return this.db.query.documents.findFirst({
|
|
49
|
+
where: and(eq(documents.userId, this.userId), eq(documents.fileId, fileId)),
|
|
44
50
|
});
|
|
45
51
|
};
|
|
46
52
|
|
|
@@ -48,6 +54,6 @@ export class DocumentModel {
|
|
|
48
54
|
return this.db
|
|
49
55
|
.update(documents)
|
|
50
56
|
.set({ ...value, updatedAt: new Date() })
|
|
51
|
-
.where(and(eq(documents.
|
|
57
|
+
.where(and(eq(documents.userId, this.userId), eq(documents.id, id)));
|
|
52
58
|
};
|
|
53
59
|
}
|
package/packages/prompts/src/prompts/knowledgeBaseQA/__snapshots__/formatFileContents.test.ts.snap
ADDED
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
|
|
2
|
+
|
|
3
|
+
exports[`promptFileContents > should format multiple file contents 1`] = `
|
|
4
|
+
"<knowledge_base_files totalCount="3">
|
|
5
|
+
<instruction>Use the information from these files to answer the user's question. Always cite the source files.</instruction>
|
|
6
|
+
<file id="file-001" name="auth-guide.md">
|
|
7
|
+
First file content about API authentication.
|
|
8
|
+
</file>
|
|
9
|
+
<file id="file-002" name="db-setup.md">
|
|
10
|
+
Second file content about database setup and configuration.
|
|
11
|
+
</file>
|
|
12
|
+
<file id="file-003" name="deployment.md">
|
|
13
|
+
Third file content with deployment instructions.
|
|
14
|
+
</file>
|
|
15
|
+
</knowledge_base_files>"
|
|
16
|
+
`;
|
|
17
|
+
|
|
18
|
+
exports[`promptFileContents > should format single file content 1`] = `
|
|
19
|
+
"<knowledge_base_files totalCount="1">
|
|
20
|
+
<instruction>Use the information from these files to answer the user's question. Always cite the source files.</instruction>
|
|
21
|
+
<file id="file-001" name="document.md">
|
|
22
|
+
This is the file content with some important information.
|
|
23
|
+
</file>
|
|
24
|
+
</knowledge_base_files>"
|
|
25
|
+
`;
|
|
26
|
+
|
|
27
|
+
exports[`promptFileContents > should handle file with error 1`] = `
|
|
28
|
+
"<knowledge_base_files totalCount="1">
|
|
29
|
+
<instruction>Use the information from these files to answer the user's question. Always cite the source files.</instruction>
|
|
30
|
+
<file id="file-404" name="missing.md" error="File not found" />
|
|
31
|
+
</knowledge_base_files>"
|
|
32
|
+
`;
|
|
33
|
+
|
|
34
|
+
exports[`promptFileContents > should handle file with long content 1`] = `
|
|
35
|
+
"<knowledge_base_files totalCount="1">
|
|
36
|
+
<instruction>Use the information from these files to answer the user's question. Always cite the source files.</instruction>
|
|
37
|
+
<file id="file-long" name="comprehensive-guide.md">
|
|
38
|
+
# Comprehensive Guide
|
|
39
|
+
|
|
40
|
+
## Introduction
|
|
41
|
+
This is a very long document with multiple sections and detailed information.
|
|
42
|
+
|
|
43
|
+
## Section 1
|
|
44
|
+
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
|
|
45
|
+
|
|
46
|
+
## Section 2
|
|
47
|
+
Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.
|
|
48
|
+
|
|
49
|
+
## Conclusion
|
|
50
|
+
Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.
|
|
51
|
+
</file>
|
|
52
|
+
</knowledge_base_files>"
|
|
53
|
+
`;
|
|
54
|
+
|
|
55
|
+
exports[`promptFileContents > should handle file with special characters in name 1`] = `
|
|
56
|
+
"<knowledge_base_files totalCount="1">
|
|
57
|
+
<instruction>Use the information from these files to answer the user's question. Always cite the source files.</instruction>
|
|
58
|
+
<file id="file-special" name="FAQ: Q&A (2024).md">
|
|
59
|
+
Content from a file with special characters in the name.
|
|
60
|
+
</file>
|
|
61
|
+
</knowledge_base_files>"
|
|
62
|
+
`;
|
|
63
|
+
|
|
64
|
+
exports[`promptFileContents > should handle mixed successful and error files 1`] = `
|
|
65
|
+
"<knowledge_base_files totalCount="3">
|
|
66
|
+
<instruction>Use the information from these files to answer the user's question. Always cite the source files.</instruction>
|
|
67
|
+
<file id="file-001" name="success.md">
|
|
68
|
+
Successfully loaded content from this file.
|
|
69
|
+
</file>
|
|
70
|
+
<file id="file-002" name="restricted.md" error="Permission denied" />
|
|
71
|
+
<file id="file-003" name="another-success.md">
|
|
72
|
+
Another successfully loaded file with more content.
|
|
73
|
+
</file>
|
|
74
|
+
</knowledge_base_files>"
|
|
75
|
+
`;
|