@lobehub/lobehub 2.0.0-next.293 → 2.0.0-next.295
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/.github/workflows/release-desktop-beta.yml +6 -6
- package/.github/workflows/release-desktop-stable.yml +11 -11
- package/CHANGELOG.md +52 -0
- package/apps/desktop/electron.vite.config.ts +0 -1
- package/apps/desktop/src/main/__mocks__/node-mac-permissions.ts +0 -1
- package/apps/desktop/src/main/__mocks__/setup.ts +0 -1
- package/apps/desktop/src/main/controllers/McpCtr.ts +50 -18
- package/apps/desktop/src/main/controllers/__tests__/SystemCtr.test.ts +1 -4
- package/apps/desktop/src/main/libs/mcp/client.ts +54 -2
- package/apps/desktop/tsconfig.json +4 -10
- package/changelog/v1.json +14 -0
- package/e2e/scripts/setup.ts +45 -32
- package/package.json +1 -1
- package/packages/database/src/models/__tests__/knowledgeBase.test.ts +1 -1
- package/packages/database/src/repositories/knowledge/index.ts +1 -4
- package/packages/types/src/discover/assistants.ts +2 -2
- package/scripts/migrate-spa-navigation.ts +129 -0
- package/src/app/(backend)/api/workflows/memory-user-memory/pipelines/chat-topic/process-topics/route.ts +112 -109
- package/src/app/(backend)/api/workflows/memory-user-memory/pipelines/chat-topic/process-user-topics/route.ts +125 -113
- package/src/app/(backend)/api/workflows/memory-user-memory/pipelines/chat-topic/process-users/route.ts +74 -65
- package/src/app/[variants]/(auth)/auth-error/page.tsx +1 -1
- package/src/app/[variants]/(auth)/login/[[...login]]/page.tsx +1 -1
- package/src/app/[variants]/(auth)/next-auth/error/AuthErrorPage.tsx +1 -1
- package/src/app/[variants]/(auth)/next-auth/signin/AuthSignInBox.tsx +1 -1
- package/src/app/[variants]/(auth)/oauth/callback/error/page.tsx +1 -1
- package/src/app/[variants]/(auth)/oauth/callback/success/page.tsx +1 -1
- package/src/app/[variants]/(auth)/oauth/consent/[uid]/page.tsx +1 -1
- package/src/app/[variants]/(auth)/reset-password/layout.tsx +1 -1
- package/src/app/[variants]/(auth)/reset-password/page.tsx +2 -2
- package/src/app/[variants]/(auth)/signin/layout.tsx +1 -1
- package/src/app/[variants]/(auth)/signin/useSignIn.ts +1 -1
- package/src/app/[variants]/(auth)/signup/[[...signup]]/BetterAuthSignUpForm.tsx +2 -2
- package/src/app/[variants]/(auth)/signup/[[...signup]]/page.tsx +1 -1
- package/src/app/[variants]/(auth)/signup/[[...signup]]/useSignUp.tsx +1 -1
- package/src/app/[variants]/(auth)/verify-email/layout.tsx +1 -1
- package/src/app/[variants]/(auth)/verify-email/page.tsx +2 -2
- package/src/app/[variants]/(main)/_layout/index.tsx +1 -1
- package/src/app/[variants]/(main)/agent/_layout/AgentIdSync.tsx +12 -1
- package/src/app/[variants]/(main)/agent/_layout/Sidebar/Cron/CronTopicGroup.tsx +1 -1
- package/src/app/[variants]/(main)/agent/_layout/Sidebar/Header/AddTopicButon.tsx +1 -1
- package/src/app/[variants]/(main)/agent/_layout/Sidebar/Header/Nav.tsx +1 -1
- package/src/app/[variants]/(main)/agent/_layout/Sidebar/Topic/AllTopicsDrawer/index.tsx +1 -1
- package/src/app/[variants]/(main)/agent/_layout/Sidebar/Topic/hooks/useThreadNavigation.ts +1 -1
- package/src/app/[variants]/(main)/agent/_layout/Sidebar/Topic/hooks/useTopicNavigation.ts +1 -1
- package/src/app/[variants]/(main)/agent/features/TelemetryNotification.tsx +2 -3
- package/src/app/[variants]/(main)/community/(detail)/assistant/features/Details/Nav.tsx +9 -9
- package/src/app/[variants]/(main)/community/(detail)/assistant/features/Details/Versions/index.tsx +2 -3
- package/src/app/[variants]/(main)/community/(detail)/features/MakedownRender.tsx +1 -2
- package/src/app/[variants]/(main)/community/(detail)/features/ShareButton.tsx +2 -3
- package/src/app/[variants]/(main)/community/(detail)/features/Toc/Heading.tsx +2 -3
- package/src/app/[variants]/(main)/community/(detail)/mcp/features/Details/Versions/index.tsx +2 -2
- package/src/app/[variants]/(main)/community/(detail)/model/features/Details/Nav.tsx +12 -11
- package/src/app/[variants]/(main)/community/(detail)/model/features/Details/Parameter/ParameterItem.tsx +2 -3
- package/src/app/[variants]/(main)/community/(detail)/provider/features/Details/Nav.tsx +11 -10
- package/src/app/[variants]/(main)/community/(detail)/provider/features/Header.tsx +10 -9
- package/src/app/[variants]/(main)/community/(list)/(home)/index.tsx +1 -1
- package/src/app/[variants]/(main)/community/(list)/assistant/features/Category/useCategory.tsx +1 -1
- package/src/app/[variants]/(main)/community/(list)/features/SortButton/index.tsx +2 -3
- package/src/app/[variants]/(main)/community/_layout/Sidebar/Header/Nav.tsx +1 -1
- package/src/app/[variants]/(main)/community/features/CreateButton/Inner.tsx +1 -1
- package/src/app/[variants]/(main)/community/features/CreateButton/index.tsx +1 -1
- package/src/app/[variants]/(main)/community/features/Search.tsx +1 -2
- package/src/app/[variants]/(main)/community/features/Title.tsx +5 -5
- package/src/app/[variants]/(main)/group/_layout/GroupIdSync.tsx +12 -1
- package/src/app/[variants]/(main)/group/_layout/Sidebar/Header/Nav.tsx +1 -1
- package/src/app/[variants]/(main)/group/_layout/Sidebar/Topic/AllTopicsDrawer/index.tsx +1 -1
- package/src/app/[variants]/(main)/group/_layout/Sidebar/Topic/hooks/useThreadNavigation.ts +1 -1
- package/src/app/[variants]/(main)/group/features/Conversation/Header/ShareButton/index.tsx +1 -1
- package/src/app/[variants]/(main)/group/features/TelemetryNotification.tsx +2 -3
- package/src/app/[variants]/(main)/home/_layout/Body/Agent/AllAgentsDrawer/index.tsx +1 -1
- package/src/app/[variants]/(main)/hooks/useActiveTabKey.ts +6 -11
- package/src/app/[variants]/(main)/image/NotSupportClient.tsx +4 -3
- package/src/app/[variants]/(main)/image/_layout/ConfigPanel/components/ImageUpload.tsx +1 -1
- package/src/app/[variants]/(main)/image/_layout/ConfigPanel/components/MultiImagesUpload/ImageManageModal.tsx +1 -1
- package/src/app/[variants]/(main)/image/_layout/ConfigPanel/components/MultiImagesUpload/index.tsx +1 -1
- package/src/app/[variants]/(main)/memory/(home)/features/RoleTagCloud/index.tsx +1 -1
- package/src/app/[variants]/(main)/memory/_layout/Sidebar/Header/Nav.tsx +1 -1
- package/src/app/[variants]/(main)/memory/features/SourceLink.tsx +1 -1
- package/src/app/[variants]/(main)/page/_layout/Body/AllPagesDrawer/index.tsx +1 -1
- package/src/app/[variants]/(main)/settings/about/features/ItemCard.tsx +2 -3
- package/src/app/[variants]/(main)/settings/about/features/ItemLink.tsx +2 -3
- package/src/app/[variants]/(main)/settings/about/features/Version.tsx +6 -7
- package/src/app/[variants]/(main)/settings/features/SettingsContent.tsx +1 -1
- package/src/app/[variants]/(main)/settings/features/UpgradeAlert.tsx +4 -4
- package/src/app/[variants]/(main)/settings/provider/(list)/Footer.tsx +2 -2
- package/src/app/[variants]/(main)/settings/provider/detail/index.tsx +1 -1
- package/src/app/[variants]/(main)/settings/provider/detail/ollama/CheckError.tsx +1 -1
- package/src/app/[variants]/(main)/settings/provider/features/ProviderConfig/index.tsx +12 -6
- package/src/app/[variants]/(main)/settings/security/index.tsx +1 -1
- package/src/app/[variants]/(main)/settings/stats/features/overview/ShareButton/ShareModal.tsx +1 -1
- package/src/app/[variants]/(main)/settings/stats/features/rankings/AssistantsRank.tsx +1 -1
- package/src/app/[variants]/(main)/settings/stats/features/rankings/TopicsRank.tsx +1 -1
- package/src/app/[variants]/(mobile)/_layout/index.tsx +1 -1
- package/src/app/[variants]/(mobile)/chat/settings/features/AgentInfoDescription/index.tsx +1 -1
- package/src/app/[variants]/(mobile)/chat/settings/features/SettingButton.tsx +1 -1
- package/src/app/[variants]/(mobile)/router/index.tsx +1 -1
- package/src/app/[variants]/page.tsx +1 -1
- package/src/app/[variants]/router/index.tsx +1 -1
- package/src/components/404/index.tsx +4 -4
- package/src/components/Analytics/index.tsx +1 -1
- package/src/components/BrandWatermark/index.tsx +4 -4
- package/src/components/Branding/ProductLogo/Custom.tsx +1 -1
- package/src/components/Error/index.tsx +3 -4
- package/src/components/GoBack/index.tsx +2 -2
- package/src/components/LabsModal/LabCard.tsx +1 -1
- package/src/components/Link.tsx +25 -5
- package/src/components/OllamaSetupGuide/index.tsx +5 -4
- package/src/components/WebFavicon/index.tsx +1 -1
- package/src/components/client/ClientResponsiveContent/index.tsx +1 -1
- package/src/components/client/ClientResponsiveLayout.tsx +1 -1
- package/src/components/mdx/Image.tsx +1 -1
- package/src/components/mdx/Link.tsx +26 -9
- package/src/features/AlertBanner/CloudBanner.tsx +2 -3
- package/src/features/ChatInput/ActionBar/Model/ControlsForm.tsx +8 -7
- package/src/features/ChatInput/ActionBar/Params/Controls.tsx +1 -3
- package/src/features/ChatInput/ActionBar/Token/index.tsx +1 -1
- package/src/features/ChatInput/Mobile/index.tsx +1 -1
- package/src/features/Conversation/ChatItem/components/MessageContent/index.tsx +1 -1
- package/src/features/Conversation/Error/OllamaBizError/index.tsx +1 -1
- package/src/features/Conversation/Error/OllamaSetupGuide/Desktop.tsx +1 -2
- package/src/features/Conversation/Error/index.tsx +1 -1
- package/src/features/Conversation/Messages/AssistantGroup/Tool/Actions/Settings.tsx +1 -1
- package/src/features/Conversation/Messages/AssistantGroup/Tool/index.tsx +1 -1
- package/src/features/Conversation/Messages/AssistantGroup/index.tsx +1 -1
- package/src/features/Conversation/Messages/Tool/Tool/index.tsx +1 -1
- package/src/features/Conversation/Messages/components/SearchGrounding.tsx +1 -1
- package/src/features/DataImporter/Error.tsx +3 -3
- package/src/features/DevPanel/CacheViewer/cacheProvider.tsx +2 -1
- package/src/features/DevPanel/MetadataViewer/Og.tsx +1 -1
- package/src/features/DevPanel/features/FloatPanel.tsx +1 -1
- package/src/features/DevPanel/features/Table/TooltipContent.tsx +3 -4
- package/src/features/DevPanel/index.tsx +1 -1
- package/src/features/EditorCanvas/InlineToolbar.tsx +1 -6
- package/src/features/FileViewer/NotSupport/index.tsx +2 -3
- package/src/features/Follow/index.tsx +8 -9
- package/src/features/LibraryModal/AddFilesToKnowledgeBase/SelectForm.tsx +2 -2
- package/src/features/MCP/MCPInstallProgress/InstallError/ErrorDetails.tsx +61 -83
- package/src/features/MCP/Scores.tsx +1 -1
- package/src/features/MCPPluginDetail/Nav.tsx +8 -8
- package/src/features/MCPPluginDetail/Overview/TagList.tsx +1 -1
- package/src/features/MobileTabBar/index.tsx +2 -1
- package/src/features/OllamaSetupGuide/Desktop.tsx +1 -2
- package/src/features/PWAInstall/Install.tsx +1 -1
- package/src/features/PWAInstall/index.tsx +1 -1
- package/src/features/PluginDevModal/MCPManifestForm/index.tsx +30 -3
- package/src/features/PluginStore/McpList/index.tsx +1 -1
- package/src/features/PluginStore/PluginList/Detail/Header.tsx +6 -6
- package/src/features/PluginsUI/Render/DefaultType/index.tsx +1 -1
- package/src/features/Portal/Artifacts/Body/Renderer/index.tsx +1 -1
- package/src/features/ResourceManager/components/ChunkDrawer/index.tsx +1 -1
- package/src/features/ResourceManager/components/Explorer/ListView/Skeleton.tsx +26 -26
- package/src/features/ResourceManager/components/Explorer/ToolBar/BatchActionsDropdown.tsx +147 -149
- package/src/features/ResourceManager/index.tsx +1 -1
- package/src/features/Setting/Footer.tsx +4 -5
- package/src/features/User/UserPanel/PanelContent.tsx +1 -1
- package/src/hooks/useActiveTabKey.ts +6 -3
- package/src/hooks/useIsSingleMode.test.ts +10 -24
- package/src/hooks/useIsSingleMode.ts +4 -2
- package/src/hooks/useIsSubSlug.ts +2 -1
- package/src/hooks/useQuery.ts +5 -5
- package/src/layout/GlobalProvider/AppTheme.tsx +2 -2
- package/src/layout/GlobalProvider/StyleRegistry.tsx +1 -1
- package/src/layout/GlobalProvider/useUserStateRedirect.ts +13 -25
- package/src/libs/mcp/types.ts +31 -0
- package/src/libs/next/Image.tsx +13 -0
- package/src/libs/next/Link.tsx +13 -0
- package/src/libs/next/dynamic.tsx +13 -0
- package/src/libs/next/index.ts +22 -0
- package/src/libs/next/navigation.ts +22 -0
- package/src/libs/router/Link.tsx +30 -0
- package/src/libs/router/index.ts +18 -0
- package/src/libs/router/navigation.ts +72 -0
- package/src/server/modules/AgentRuntime/AgentStateManager.ts +5 -1
- package/src/store/chat/slices/portal/selectors.test.ts +5 -15
- package/src/store/page/index.ts +1 -1
- package/src/store/page/slices/crud/index.ts +1 -1
- package/src/store/tool/slices/mcpStore/action.ts +26 -11
- package/src/app/[variants]/(main)/hooks/usePathname.ts +0 -10
- package/src/app/[variants]/(main)/hooks/useQuery.ts +0 -12
- package/src/app/[variants]/(main)/hooks/useRouter.ts +0 -22
- package/src/app/[variants]/(main)/hooks/useSearchParams.ts +0 -11
|
@@ -4,7 +4,7 @@ name: Release Desktop Beta
|
|
|
4
4
|
# Beta/Nightly 频道发版工作流
|
|
5
5
|
# ============================================
|
|
6
6
|
# 触发条件: 发布包含 pre-release 标识的 release
|
|
7
|
-
# 如: v2.0.0-beta.1, v2.0.0-alpha.1, v2.0.0-rc.1, v2.0.0-nightly.xxx
|
|
7
|
+
# 如: v2.0.0-beta.1, v2.0.0-alpha.1, v2.0.0-rc.1, v2.0.0-nightly.xxx, v2.0.0-next.292
|
|
8
8
|
#
|
|
9
9
|
# 注意: Stable 版本 (如 v2.0.0) 由 release-desktop-stable.yml 处理
|
|
10
10
|
# ============================================
|
|
@@ -24,10 +24,10 @@ env:
|
|
|
24
24
|
|
|
25
25
|
jobs:
|
|
26
26
|
# ============================================
|
|
27
|
-
# 检查是否为 Beta/Nightly 版本 (排除 Stable)
|
|
27
|
+
# 检查是否为 Beta/Nightly/Next 版本 (排除 Stable)
|
|
28
28
|
# ============================================
|
|
29
29
|
check-beta:
|
|
30
|
-
name: Check if Beta/Nightly Release
|
|
30
|
+
name: Check if Beta/Nightly/Next Release
|
|
31
31
|
runs-on: ubuntu-latest
|
|
32
32
|
outputs:
|
|
33
33
|
is_beta: ${{ steps.check.outputs.is_beta }}
|
|
@@ -40,10 +40,10 @@ jobs:
|
|
|
40
40
|
version="${version#v}"
|
|
41
41
|
echo "version=${version}" >> $GITHUB_OUTPUT
|
|
42
42
|
|
|
43
|
-
# Beta/Nightly 版本包含 beta/alpha/rc/nightly
|
|
44
|
-
if [[ "$version" == *"beta"* ]] || [[ "$version" == *"alpha"* ]] || [[ "$version" == *"rc"* ]] || [[ "$version" == *"nightly"* ]]; then
|
|
43
|
+
# Beta/Nightly/Next 版本包含 beta/alpha/rc/nightly/next
|
|
44
|
+
if [[ "$version" == *"beta"* ]] || [[ "$version" == *"alpha"* ]] || [[ "$version" == *"rc"* ]] || [[ "$version" == *"nightly"* ]] || [[ "$version" == *"next"* ]]; then
|
|
45
45
|
echo "is_beta=true" >> $GITHUB_OUTPUT
|
|
46
|
-
echo "✅ Beta/Nightly release detected: $version"
|
|
46
|
+
echo "✅ Beta/Nightly/Next release detected: $version"
|
|
47
47
|
else
|
|
48
48
|
echo "is_beta=false" >> $GITHUB_OUTPUT
|
|
49
49
|
echo "⏭️ Skipping: $version is a stable release (handled by release-desktop-stable.yml)"
|
|
@@ -3,10 +3,10 @@ name: Release Desktop Stable
|
|
|
3
3
|
# ============================================
|
|
4
4
|
# Stable 频道发版工作流
|
|
5
5
|
# ============================================
|
|
6
|
-
# 触发条件: 发布不含 pre-release
|
|
6
|
+
# 触发条件: 发布不含 pre-release 后缀的 release (如 v2.0.0)
|
|
7
7
|
#
|
|
8
8
|
# 与 Beta 的区别:
|
|
9
|
-
# 1. 仅响应 stable 版本 tag (
|
|
9
|
+
# 1. 仅响应 stable 版本 tag (不含任何 '-' 后缀)
|
|
10
10
|
# 2. 使用 STABLE 专用的 Umami 配置
|
|
11
11
|
# 3. 额外上传到 S3 更新服务器
|
|
12
12
|
# 4. 构建时注入 UPDATE_SERVER_URL 让客户端从 S3 检查更新
|
|
@@ -89,8 +89,8 @@ jobs:
|
|
|
89
89
|
if [ "${{ github.event_name }}" == "workflow_dispatch" ]; then
|
|
90
90
|
# 手动触发: 使用输入的版本号
|
|
91
91
|
version="${{ inputs.version }}"
|
|
92
|
+
version="${version#v}"
|
|
92
93
|
echo "is_manual=true" >> $GITHUB_OUTPUT
|
|
93
|
-
echo "is_stable=true" >> $GITHUB_OUTPUT
|
|
94
94
|
echo "version=${version}" >> $GITHUB_OUTPUT
|
|
95
95
|
echo "release_notes=" >> $GITHUB_OUTPUT
|
|
96
96
|
echo "🔧 Manual trigger: version=${version}"
|
|
@@ -106,15 +106,15 @@ jobs:
|
|
|
106
106
|
printf '%s\n' "$release_body"
|
|
107
107
|
echo "EOF"
|
|
108
108
|
} >> $GITHUB_OUTPUT
|
|
109
|
+
fi
|
|
109
110
|
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
fi
|
|
111
|
+
# 检查是否为 stable 版本 (不含任何 '-' 后缀)
|
|
112
|
+
if [[ "$version" == *"-"* ]]; then
|
|
113
|
+
echo "is_stable=false" >> $GITHUB_OUTPUT
|
|
114
|
+
echo "⏭️ Skipping: $version is not a stable release"
|
|
115
|
+
else
|
|
116
|
+
echo "is_stable=true" >> $GITHUB_OUTPUT
|
|
117
|
+
echo "✅ Stable release detected: $version"
|
|
118
118
|
fi
|
|
119
119
|
|
|
120
120
|
# ============================================
|
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,58 @@
|
|
|
2
2
|
|
|
3
3
|
# Changelog
|
|
4
4
|
|
|
5
|
+
## [Version 2.0.0-next.295](https://github.com/lobehub/lobe-chat/compare/v2.0.0-next.294...v2.0.0-next.295)
|
|
6
|
+
|
|
7
|
+
<sup>Released on **2026-01-15**</sup>
|
|
8
|
+
|
|
9
|
+
#### ♻ Code Refactoring
|
|
10
|
+
|
|
11
|
+
- **misc**: Migrate Next.js navigation APIs to React Router for SPA.
|
|
12
|
+
|
|
13
|
+
<br/>
|
|
14
|
+
|
|
15
|
+
<details>
|
|
16
|
+
<summary><kbd>Improvements and Fixes</kbd></summary>
|
|
17
|
+
|
|
18
|
+
#### Code refactoring
|
|
19
|
+
|
|
20
|
+
- **misc**: Migrate Next.js navigation APIs to React Router for SPA, closes [#11394](https://github.com/lobehub/lobe-chat/issues/11394) ([2253d46](https://github.com/lobehub/lobe-chat/commit/2253d46))
|
|
21
|
+
|
|
22
|
+
</details>
|
|
23
|
+
|
|
24
|
+
<div align="right">
|
|
25
|
+
|
|
26
|
+
[](#readme-top)
|
|
27
|
+
|
|
28
|
+
</div>
|
|
29
|
+
|
|
30
|
+
## [Version 2.0.0-next.294](https://github.com/lobehub/lobe-chat/compare/v2.0.0-next.293...v2.0.0-next.294)
|
|
31
|
+
|
|
32
|
+
<sup>Released on **2026-01-15**</sup>
|
|
33
|
+
|
|
34
|
+
#### 🐛 Bug Fixes
|
|
35
|
+
|
|
36
|
+
- **chat**: Reset activeTopicId when switching agent/group.
|
|
37
|
+
- **mcp**: Fix installation check hanging issue in desktop app.
|
|
38
|
+
|
|
39
|
+
<br/>
|
|
40
|
+
|
|
41
|
+
<details>
|
|
42
|
+
<summary><kbd>Improvements and Fixes</kbd></summary>
|
|
43
|
+
|
|
44
|
+
#### What's fixed
|
|
45
|
+
|
|
46
|
+
- **chat**: Reset activeTopicId when switching agent/group, closes [#11523](https://github.com/lobehub/lobe-chat/issues/11523) ([fde54b0](https://github.com/lobehub/lobe-chat/commit/fde54b0))
|
|
47
|
+
- **mcp**: Fix installation check hanging issue in desktop app, closes [#11524](https://github.com/lobehub/lobe-chat/issues/11524) ([b9341c3](https://github.com/lobehub/lobe-chat/commit/b9341c3))
|
|
48
|
+
|
|
49
|
+
</details>
|
|
50
|
+
|
|
51
|
+
<div align="right">
|
|
52
|
+
|
|
53
|
+
[](#readme-top)
|
|
54
|
+
|
|
55
|
+
</div>
|
|
56
|
+
|
|
5
57
|
## [Version 2.0.0-next.293](https://github.com/lobehub/lobe-chat/compare/v2.0.0-next.292...v2.0.0-next.293)
|
|
6
58
|
|
|
7
59
|
<sup>Released on **2026-01-15**</sup>
|
|
@@ -7,7 +7,7 @@ import superjson from 'superjson';
|
|
|
7
7
|
import FileService from '@/services/fileSrv';
|
|
8
8
|
import { createLogger } from '@/utils/logger';
|
|
9
9
|
|
|
10
|
-
import { MCPClient } from '../libs/mcp/client';
|
|
10
|
+
import { MCPClient, MCPConnectionError } from '../libs/mcp/client';
|
|
11
11
|
import type { MCPClientParams, ToolCallContent, ToolCallResult } from '../libs/mcp/types';
|
|
12
12
|
import { ControllerModule, IpcMethod } from './index';
|
|
13
13
|
|
|
@@ -228,8 +228,9 @@ export default class McpCtr extends ControllerModule {
|
|
|
228
228
|
type: 'stdio',
|
|
229
229
|
};
|
|
230
230
|
|
|
231
|
-
|
|
231
|
+
let client: MCPClient | undefined;
|
|
232
232
|
try {
|
|
233
|
+
client = await this.createClient(params);
|
|
233
234
|
const manifest = await client.listManifests();
|
|
234
235
|
const identifier = input.name;
|
|
235
236
|
|
|
@@ -257,8 +258,25 @@ export default class McpCtr extends ControllerModule {
|
|
|
257
258
|
mcpParams: params,
|
|
258
259
|
type: 'mcp' as any,
|
|
259
260
|
});
|
|
261
|
+
} catch (error) {
|
|
262
|
+
// If it's an MCPConnectionError with stderr logs, enhance the error message
|
|
263
|
+
if (error instanceof MCPConnectionError && error.stderrLogs.length > 0) {
|
|
264
|
+
const stderrOutput = error.stderrLogs.join('\n');
|
|
265
|
+
const enhancedError = new Error(
|
|
266
|
+
`${error.message}\n\n--- STDIO Process Output ---\n${stderrOutput}`,
|
|
267
|
+
);
|
|
268
|
+
enhancedError.name = error.name;
|
|
269
|
+
logger.error('getStdioMcpServerManifest failed with STDIO logs:', {
|
|
270
|
+
message: error.message,
|
|
271
|
+
stderrLogs: error.stderrLogs,
|
|
272
|
+
});
|
|
273
|
+
throw enhancedError;
|
|
274
|
+
}
|
|
275
|
+
throw error;
|
|
260
276
|
} finally {
|
|
261
|
-
|
|
277
|
+
if (client) {
|
|
278
|
+
await client.disconnect();
|
|
279
|
+
}
|
|
262
280
|
}
|
|
263
281
|
}
|
|
264
282
|
|
|
@@ -313,8 +331,9 @@ export default class McpCtr extends ControllerModule {
|
|
|
313
331
|
type: 'stdio',
|
|
314
332
|
};
|
|
315
333
|
|
|
316
|
-
|
|
334
|
+
let client: MCPClient | undefined;
|
|
317
335
|
try {
|
|
336
|
+
client = await this.createClient(params);
|
|
318
337
|
const args = safeParseToRecord(input.args);
|
|
319
338
|
|
|
320
339
|
const raw = (await client.callTool(input.toolName, args)) as ToolCallResult;
|
|
@@ -328,10 +347,25 @@ export default class McpCtr extends ControllerModule {
|
|
|
328
347
|
success: true,
|
|
329
348
|
});
|
|
330
349
|
} catch (error) {
|
|
350
|
+
// If it's an MCPConnectionError with stderr logs, enhance the error message
|
|
351
|
+
if (error instanceof MCPConnectionError && error.stderrLogs.length > 0) {
|
|
352
|
+
const stderrOutput = error.stderrLogs.join('\n');
|
|
353
|
+
const enhancedError = new Error(
|
|
354
|
+
`${error.message}\n\n--- STDIO Process Output ---\n${stderrOutput}`,
|
|
355
|
+
);
|
|
356
|
+
enhancedError.name = error.name;
|
|
357
|
+
logger.error('callTool failed with STDIO logs:', {
|
|
358
|
+
message: error.message,
|
|
359
|
+
stderrLogs: error.stderrLogs,
|
|
360
|
+
});
|
|
361
|
+
throw enhancedError;
|
|
362
|
+
}
|
|
331
363
|
logger.error('callTool failed:', error);
|
|
332
364
|
throw error;
|
|
333
365
|
} finally {
|
|
334
|
-
|
|
366
|
+
if (client) {
|
|
367
|
+
await client.disconnect();
|
|
368
|
+
}
|
|
335
369
|
}
|
|
336
370
|
}
|
|
337
371
|
|
|
@@ -361,8 +395,9 @@ export default class McpCtr extends ControllerModule {
|
|
|
361
395
|
}
|
|
362
396
|
|
|
363
397
|
private async checkSystemDependency(dependency: any) {
|
|
398
|
+
const checkCommand = dependency.checkCommand || `${dependency.name} --version`;
|
|
399
|
+
|
|
364
400
|
try {
|
|
365
|
-
const checkCommand = dependency.checkCommand || `${dependency.name} --version`;
|
|
366
401
|
const { stdout, stderr } = await execPromise(checkCommand);
|
|
367
402
|
|
|
368
403
|
if (stderr && !stdout) {
|
|
@@ -444,22 +479,19 @@ export default class McpCtr extends ControllerModule {
|
|
|
444
479
|
const packageName = details?.packageName;
|
|
445
480
|
if (!packageName) return { installed: false };
|
|
446
481
|
|
|
482
|
+
// Only check global npm list - do NOT use npx as it may download packages
|
|
447
483
|
try {
|
|
448
484
|
const { stdout } = await execPromise(`npm list -g ${packageName} --depth=0`);
|
|
449
|
-
if (!stdout.includes('(empty)') && stdout.includes(packageName))
|
|
485
|
+
if (!stdout.includes('(empty)') && stdout.includes(packageName)) {
|
|
486
|
+
return { installed: true };
|
|
487
|
+
}
|
|
450
488
|
} catch {
|
|
451
|
-
// ignore
|
|
489
|
+
// ignore - package not found in global list
|
|
452
490
|
}
|
|
453
491
|
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
} catch (error) {
|
|
458
|
-
return {
|
|
459
|
-
error: error instanceof Error ? error.message : 'Unknown error',
|
|
460
|
-
installed: false,
|
|
461
|
-
};
|
|
462
|
-
}
|
|
492
|
+
// For npm packages, we don't require pre-installation
|
|
493
|
+
// npx will handle downloading and running on-demand during actual MCP connection
|
|
494
|
+
return { installed: false };
|
|
463
495
|
}
|
|
464
496
|
|
|
465
497
|
if (installationMethod === 'python') {
|
|
@@ -553,7 +585,7 @@ export default class McpCtr extends ControllerModule {
|
|
|
553
585
|
const bestResult = recommendedResult || firstInstallableResult || results[0];
|
|
554
586
|
|
|
555
587
|
const checkResult: CheckMcpInstallResult = {
|
|
556
|
-
...
|
|
588
|
+
...bestResult,
|
|
557
589
|
allOptions: results as any,
|
|
558
590
|
platform: process.platform,
|
|
559
591
|
success: true,
|
|
@@ -4,10 +4,7 @@ import { beforeEach, describe, expect, it, vi } from 'vitest';
|
|
|
4
4
|
import type { App } from '@/core/App';
|
|
5
5
|
import type { IpcContext } from '@/utils/ipc';
|
|
6
6
|
import { IpcHandler } from '@/utils/ipc/base';
|
|
7
|
-
import {
|
|
8
|
-
__resetMacPermissionsModuleCache,
|
|
9
|
-
__setMacPermissionsModule,
|
|
10
|
-
} from '@/utils/permissions';
|
|
7
|
+
import { __resetMacPermissionsModuleCache, __setMacPermissionsModule } from '@/utils/permissions';
|
|
11
8
|
|
|
12
9
|
import SystemController from '../SystemCtr';
|
|
13
10
|
|
|
@@ -6,15 +6,31 @@ import {
|
|
|
6
6
|
import { StreamableHTTPClientTransport } from '@modelcontextprotocol/sdk/client/streamableHttp.js';
|
|
7
7
|
import type { Transport } from '@modelcontextprotocol/sdk/shared/transport.js';
|
|
8
8
|
import type { Progress } from '@modelcontextprotocol/sdk/types.js';
|
|
9
|
+
import type { Readable } from 'node:stream';
|
|
9
10
|
|
|
10
11
|
import { getDesktopEnv } from '@/env';
|
|
11
12
|
|
|
12
13
|
import type { MCPClientParams, McpPrompt, McpResource, McpTool, ToolCallResult } from './types';
|
|
13
14
|
|
|
15
|
+
/**
|
|
16
|
+
* Custom error class for MCP connection errors that includes STDIO logs
|
|
17
|
+
*/
|
|
18
|
+
export class MCPConnectionError extends Error {
|
|
19
|
+
readonly stderrLogs: string[];
|
|
20
|
+
|
|
21
|
+
constructor(message: string, stderrLogs: string[] = []) {
|
|
22
|
+
super(message);
|
|
23
|
+
this.name = 'MCPConnectionError';
|
|
24
|
+
this.stderrLogs = stderrLogs;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
|
|
14
28
|
export class MCPClient {
|
|
15
29
|
private readonly mcp: Client;
|
|
16
30
|
|
|
17
31
|
private transport: Transport;
|
|
32
|
+
private stderrLogs: string[] = [];
|
|
33
|
+
private isStdio: boolean = false;
|
|
18
34
|
|
|
19
35
|
constructor(params: MCPClientParams) {
|
|
20
36
|
this.mcp = new Client({ name: 'lobehub-desktop-mcp-client', version: '1.0.0' });
|
|
@@ -40,14 +56,21 @@ export class MCPClient {
|
|
|
40
56
|
}
|
|
41
57
|
|
|
42
58
|
case 'stdio': {
|
|
43
|
-
this.
|
|
59
|
+
this.isStdio = true;
|
|
60
|
+
const stdioTransport = new StdioClientTransport({
|
|
44
61
|
args: params.args,
|
|
45
62
|
command: params.command,
|
|
46
63
|
env: {
|
|
47
64
|
...getDefaultEnvironment(),
|
|
48
65
|
...params.env,
|
|
49
66
|
},
|
|
67
|
+
stderr: 'pipe', // Capture stderr for better error messages
|
|
50
68
|
});
|
|
69
|
+
|
|
70
|
+
// Listen to stderr stream to collect logs
|
|
71
|
+
this.setupStderrListener(stdioTransport);
|
|
72
|
+
|
|
73
|
+
this.transport = stdioTransport;
|
|
51
74
|
break;
|
|
52
75
|
}
|
|
53
76
|
|
|
@@ -60,16 +83,45 @@ export class MCPClient {
|
|
|
60
83
|
}
|
|
61
84
|
}
|
|
62
85
|
|
|
86
|
+
private setupStderrListener(transport: StdioClientTransport) {
|
|
87
|
+
const stderr = transport.stderr as Readable | null;
|
|
88
|
+
if (stderr) {
|
|
89
|
+
stderr.on('data', (chunk: Buffer) => {
|
|
90
|
+
const text = chunk.toString('utf8');
|
|
91
|
+
// Split by newlines and filter empty lines
|
|
92
|
+
const lines = text.split('\n').filter((line) => line.trim());
|
|
93
|
+
this.stderrLogs.push(...lines);
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* Get collected stderr logs from the STDIO process
|
|
100
|
+
*/
|
|
101
|
+
getStderrLogs(): string[] {
|
|
102
|
+
return this.stderrLogs;
|
|
103
|
+
}
|
|
104
|
+
|
|
63
105
|
private isMethodNotFoundError(error: unknown) {
|
|
64
106
|
const err = error as any;
|
|
65
107
|
if (!err) return false;
|
|
108
|
+
// eslint-disable-next-line unicorn/numeric-separators-style
|
|
66
109
|
if (err.code === -32601) return true;
|
|
67
110
|
if (typeof err.message === 'string' && err.message.includes('Method not found')) return true;
|
|
68
111
|
return false;
|
|
69
112
|
}
|
|
70
113
|
|
|
71
114
|
async initialize(options: { onProgress?: (progress: Progress) => void } = {}) {
|
|
72
|
-
|
|
115
|
+
try {
|
|
116
|
+
await this.mcp.connect(this.transport, { onprogress: options.onProgress });
|
|
117
|
+
} catch (error) {
|
|
118
|
+
// If this is a STDIO connection and we have stderr logs, enhance the error
|
|
119
|
+
if (this.isStdio && this.stderrLogs.length > 0) {
|
|
120
|
+
const originalMessage = error instanceof Error ? error.message : String(error);
|
|
121
|
+
throw new MCPConnectionError(originalMessage, this.stderrLogs);
|
|
122
|
+
}
|
|
123
|
+
throw error;
|
|
124
|
+
}
|
|
73
125
|
}
|
|
74
126
|
|
|
75
127
|
async disconnect() {
|
|
@@ -15,15 +15,9 @@
|
|
|
15
15
|
"moduleResolution": "bundler",
|
|
16
16
|
"resolveJsonModule": true,
|
|
17
17
|
"paths": {
|
|
18
|
-
"@/*": [
|
|
19
|
-
|
|
20
|
-
]
|
|
21
|
-
"~common/*": [
|
|
22
|
-
"./src/common/*"
|
|
23
|
-
],
|
|
24
|
-
"*": [
|
|
25
|
-
"./*"
|
|
26
|
-
]
|
|
18
|
+
"@/*": ["./src/main/*"],
|
|
19
|
+
"~common/*": ["./src/common/*"],
|
|
20
|
+
"*": ["./*"]
|
|
27
21
|
}
|
|
28
22
|
},
|
|
29
23
|
"include": [
|
|
@@ -33,4 +27,4 @@
|
|
|
33
27
|
"electron-builder.js",
|
|
34
28
|
"native-deps.config.js"
|
|
35
29
|
]
|
|
36
|
-
}
|
|
30
|
+
}
|
package/changelog/v1.json
CHANGED
|
@@ -1,4 +1,18 @@
|
|
|
1
1
|
[
|
|
2
|
+
{
|
|
3
|
+
"children": {
|
|
4
|
+
"improvements": [
|
|
5
|
+
"Migrate Next.js navigation APIs to React Router for SPA."
|
|
6
|
+
]
|
|
7
|
+
},
|
|
8
|
+
"date": "2026-01-15",
|
|
9
|
+
"version": "2.0.0-next.295"
|
|
10
|
+
},
|
|
11
|
+
{
|
|
12
|
+
"children": {},
|
|
13
|
+
"date": "2026-01-15",
|
|
14
|
+
"version": "2.0.0-next.294"
|
|
15
|
+
},
|
|
2
16
|
{
|
|
3
17
|
"children": {},
|
|
4
18
|
"date": "2026-01-15",
|
package/e2e/scripts/setup.ts
CHANGED
|
@@ -16,9 +16,7 @@
|
|
|
16
16
|
* --port <port> Server port (default: 3006)
|
|
17
17
|
* --help Show help message
|
|
18
18
|
*/
|
|
19
|
-
|
|
20
|
-
import { type ChildProcess, spawn, spawnSync } from 'node:child_process';
|
|
21
|
-
import { existsSync, unlinkSync, writeFileSync } from 'node:fs';
|
|
19
|
+
import { spawn, spawnSync } from 'node:child_process';
|
|
22
20
|
import { resolve } from 'node:path';
|
|
23
21
|
|
|
24
22
|
// ============================================================================
|
|
@@ -33,21 +31,27 @@ const CONFIG = {
|
|
|
33
31
|
defaultPort: 3006,
|
|
34
32
|
dockerImage: 'paradedb/paradedb:latest',
|
|
35
33
|
projectRoot: resolve(__dirname, '../..'),
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
// Secrets (for e2e testing only)
|
|
39
|
-
secrets: {
|
|
40
|
-
betterAuthSecret: 'e2e-test-secret-key-for-better-auth-32chars!',
|
|
41
|
-
keyVaultsSecret: 'LA7n9k3JdEcbSgml2sxfw+4TV1AzaaFU5+R176aQz4s=',
|
|
42
|
-
},
|
|
34
|
+
|
|
43
35
|
|
|
44
|
-
|
|
45
|
-
|
|
36
|
+
// S3 Mock (required even if not testing file uploads)
|
|
37
|
+
s3Mock: {
|
|
46
38
|
accessKeyId: 'e2e-mock-access-key',
|
|
47
39
|
bucket: 'e2e-mock-bucket',
|
|
48
40
|
endpoint: 'https://e2e-mock-s3.localhost',
|
|
49
41
|
secretAccessKey: 'e2e-mock-secret-key',
|
|
42
|
+
},
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
// 2 minutes
|
|
47
|
+
// Secrets (for e2e testing only)
|
|
48
|
+
secrets: {
|
|
49
|
+
betterAuthSecret: 'e2e-test-secret-key-for-better-auth-32chars!',
|
|
50
|
+
keyVaultsSecret: 'LA7n9k3JdEcbSgml2sxfw+4TV1AzaaFU5+R176aQz4s=',
|
|
50
51
|
},
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
serverTimeout: 120_000,
|
|
51
55
|
};
|
|
52
56
|
|
|
53
57
|
// ============================================================================
|
|
@@ -55,11 +59,11 @@ const CONFIG = {
|
|
|
55
59
|
// ============================================================================
|
|
56
60
|
|
|
57
61
|
const colors = {
|
|
58
|
-
cyan: (s: string) => `\
|
|
59
|
-
dim: (s: string) => `\
|
|
60
|
-
green: (s: string) => `\
|
|
61
|
-
red: (s: string) => `\
|
|
62
|
-
yellow: (s: string) => `\
|
|
62
|
+
cyan: (s: string) => `\u001B[36m${s}\u001B[0m`,
|
|
63
|
+
dim: (s: string) => `\u001B[2m${s}\u001B[0m`,
|
|
64
|
+
green: (s: string) => `\u001B[32m${s}\u001B[0m`,
|
|
65
|
+
red: (s: string) => `\u001B[31m${s}\u001B[0m`,
|
|
66
|
+
yellow: (s: string) => `\u001B[33m${s}\u001B[0m`,
|
|
63
67
|
};
|
|
64
68
|
|
|
65
69
|
function log(emoji: string, message: string) {
|
|
@@ -73,12 +77,12 @@ function logStep(step: number, total: number, message: string) {
|
|
|
73
77
|
function exec(
|
|
74
78
|
command: string,
|
|
75
79
|
args: string[] = [],
|
|
76
|
-
options: { cwd?: string; silent?: boolean } = {}
|
|
80
|
+
options: { cwd?: string; silent?: boolean } = {},
|
|
77
81
|
) {
|
|
78
82
|
const { cwd = CONFIG.projectRoot, silent = false } = options;
|
|
79
83
|
const result = spawnSync(command, args, {
|
|
80
84
|
cwd,
|
|
81
|
-
encoding: '
|
|
85
|
+
encoding: 'utf8',
|
|
82
86
|
shell: true,
|
|
83
87
|
stdio: silent ? 'pipe' : 'inherit',
|
|
84
88
|
});
|
|
@@ -88,7 +92,7 @@ function exec(
|
|
|
88
92
|
function execAsync(
|
|
89
93
|
command: string,
|
|
90
94
|
args: string[] = [],
|
|
91
|
-
env: Record<string, string> = {}
|
|
95
|
+
env: Record<string, string> = {},
|
|
92
96
|
): Promise<void> {
|
|
93
97
|
return new Promise((resolve, reject) => {
|
|
94
98
|
const child = spawn(command, args, {
|
|
@@ -111,14 +115,16 @@ function execAsync(
|
|
|
111
115
|
}
|
|
112
116
|
|
|
113
117
|
async function sleep(ms: number): Promise<void> {
|
|
114
|
-
return new Promise((resolve) =>
|
|
118
|
+
return new Promise((resolve) => {
|
|
119
|
+
setTimeout(resolve, ms);
|
|
120
|
+
});
|
|
115
121
|
}
|
|
116
122
|
|
|
117
123
|
async function waitForCondition(
|
|
118
124
|
check: () => Promise<boolean>,
|
|
119
125
|
timeout: number,
|
|
120
126
|
interval: number = 1000,
|
|
121
|
-
onWait?: () => void
|
|
127
|
+
onWait?: () => void,
|
|
122
128
|
): Promise<boolean> {
|
|
123
129
|
const startTime = Date.now();
|
|
124
130
|
while (Date.now() - startTime < timeout) {
|
|
@@ -204,7 +210,7 @@ async function startPostgres(): Promise<void> {
|
|
|
204
210
|
},
|
|
205
211
|
30_000,
|
|
206
212
|
2000,
|
|
207
|
-
() => process.stdout.write('.')
|
|
213
|
+
() => process.stdout.write('.'),
|
|
208
214
|
);
|
|
209
215
|
|
|
210
216
|
console.log();
|
|
@@ -327,7 +333,7 @@ async function startServer(port: number): Promise<void> {
|
|
|
327
333
|
() => isServerRunning(port),
|
|
328
334
|
CONFIG.serverTimeout,
|
|
329
335
|
2000,
|
|
330
|
-
() => process.stdout.write('.')
|
|
336
|
+
() => process.stdout.write('.'),
|
|
331
337
|
);
|
|
332
338
|
|
|
333
339
|
console.log();
|
|
@@ -412,27 +418,34 @@ function parseArgs(): Options {
|
|
|
412
418
|
for (let i = 0; i < args.length; i++) {
|
|
413
419
|
switch (args[i]) {
|
|
414
420
|
case '--help':
|
|
415
|
-
case '-h':
|
|
421
|
+
case '-h': {
|
|
416
422
|
options.help = true;
|
|
417
423
|
break;
|
|
418
|
-
|
|
424
|
+
}
|
|
425
|
+
case '--clean': {
|
|
419
426
|
options.clean = true;
|
|
420
427
|
break;
|
|
421
|
-
|
|
428
|
+
}
|
|
429
|
+
case '--skip-db': {
|
|
422
430
|
options.skipDb = true;
|
|
423
431
|
break;
|
|
424
|
-
|
|
432
|
+
}
|
|
433
|
+
case '--skip-migrate': {
|
|
425
434
|
options.skipMigrate = true;
|
|
426
435
|
break;
|
|
427
|
-
|
|
436
|
+
}
|
|
437
|
+
case '--build': {
|
|
428
438
|
options.build = true;
|
|
429
439
|
break;
|
|
430
|
-
|
|
440
|
+
}
|
|
441
|
+
case '--start': {
|
|
431
442
|
options.start = true;
|
|
432
443
|
break;
|
|
433
|
-
|
|
444
|
+
}
|
|
445
|
+
case '--port': {
|
|
434
446
|
options.port = parseInt(args[++i], 10) || CONFIG.defaultPort;
|
|
435
447
|
break;
|
|
448
|
+
}
|
|
436
449
|
}
|
|
437
450
|
}
|
|
438
451
|
|
|
@@ -526,4 +539,4 @@ ${colors.green('✅ E2E environment setup completed!')}
|
|
|
526
539
|
}
|
|
527
540
|
}
|
|
528
541
|
|
|
529
|
-
main();
|
|
542
|
+
await main();
|
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.295",
|
|
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",
|
|
@@ -4,6 +4,7 @@ import { afterEach, beforeEach, describe, expect, it } from 'vitest';
|
|
|
4
4
|
|
|
5
5
|
import { sleep } from '@/utils/sleep';
|
|
6
6
|
|
|
7
|
+
import { getTestDB } from '../../core/getTestDB';
|
|
7
8
|
import {
|
|
8
9
|
NewKnowledgeBase,
|
|
9
10
|
documents,
|
|
@@ -15,7 +16,6 @@ import {
|
|
|
15
16
|
} from '../../schemas';
|
|
16
17
|
import { LobeChatDatabase } from '../../type';
|
|
17
18
|
import { KnowledgeBaseModel } from '../knowledgeBase';
|
|
18
|
-
import { getTestDB } from '../../core/getTestDB';
|
|
19
19
|
|
|
20
20
|
const serverDB: LobeChatDatabase = await getTestDB();
|
|
21
21
|
|
|
@@ -556,10 +556,7 @@ export class KnowledgeRepo {
|
|
|
556
556
|
// When in a knowledge base, return standalone documents (folders and notes without fileId)
|
|
557
557
|
// that have the knowledgeBaseId column set. Documents with fileId are already
|
|
558
558
|
// returned by the file query via their linked file records.
|
|
559
|
-
kbWhereConditions.push(
|
|
560
|
-
sql`d.file_id IS NULL`,
|
|
561
|
-
sql`d.knowledge_base_id = ${knowledgeBaseId}`,
|
|
562
|
-
);
|
|
559
|
+
kbWhereConditions.push(sql`d.file_id IS NULL`, sql`d.knowledge_base_id = ${knowledgeBaseId}`);
|
|
563
560
|
|
|
564
561
|
return sql`
|
|
565
562
|
SELECT
|