@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
package/src/libs/mcp/types.ts
CHANGED
|
@@ -240,3 +240,34 @@ export function createMCPError(
|
|
|
240
240
|
|
|
241
241
|
return error;
|
|
242
242
|
}
|
|
243
|
+
|
|
244
|
+
/**
|
|
245
|
+
* STDIO Process Output separator used in enhanced error messages
|
|
246
|
+
*/
|
|
247
|
+
const STDIO_OUTPUT_SEPARATOR = '--- STDIO Process Output ---';
|
|
248
|
+
|
|
249
|
+
/**
|
|
250
|
+
* Parse error message to extract STDIO process output logs
|
|
251
|
+
* The enhanced error format from desktop is:
|
|
252
|
+
* "Original message\n\n--- STDIO Process Output ---\nlogs..."
|
|
253
|
+
*/
|
|
254
|
+
export interface ParsedStdioError {
|
|
255
|
+
errorLog?: string;
|
|
256
|
+
originalMessage: string;
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
export function parseStdioErrorMessage(errorMessage: string): ParsedStdioError {
|
|
260
|
+
const separatorIndex = errorMessage.indexOf(STDIO_OUTPUT_SEPARATOR);
|
|
261
|
+
|
|
262
|
+
if (separatorIndex === -1) {
|
|
263
|
+
return { originalMessage: errorMessage };
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
const originalMessage = errorMessage.slice(0, separatorIndex).trim();
|
|
267
|
+
const errorLog = errorMessage.slice(separatorIndex + STDIO_OUTPUT_SEPARATOR.length).trim();
|
|
268
|
+
|
|
269
|
+
return {
|
|
270
|
+
errorLog: errorLog || undefined,
|
|
271
|
+
originalMessage: originalMessage || errorMessage,
|
|
272
|
+
};
|
|
273
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Image component wrapper for Next.js Image.
|
|
3
|
+
* This module provides a unified interface that can be easily replaced
|
|
4
|
+
* with a generic <img> or custom image component in the future.
|
|
5
|
+
*
|
|
6
|
+
* @see Phase 3.4: LOBE-2991
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
// Re-export the Image component
|
|
10
|
+
|
|
11
|
+
// Re-export types
|
|
12
|
+
export type { ImageProps, StaticImageData } from 'next/image';
|
|
13
|
+
export { default } from 'next/image';
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Link component wrapper for Next.js Link.
|
|
3
|
+
* This module provides a unified interface that can be easily replaced
|
|
4
|
+
* with react-router-dom Link in the future.
|
|
5
|
+
*
|
|
6
|
+
* @see Phase 3.2: LOBE-2989
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
// Re-export the Link component
|
|
10
|
+
|
|
11
|
+
// Re-export the type for props
|
|
12
|
+
export type { LinkProps } from 'next/link';
|
|
13
|
+
export { default } from 'next/link';
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Dynamic import wrapper for Next.js dynamic.
|
|
3
|
+
* This module provides a unified interface that can be easily replaced
|
|
4
|
+
* with React.lazy + Suspense in the future.
|
|
5
|
+
*
|
|
6
|
+
* @see Phase 3.3: LOBE-2990
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
// Re-export the dynamic function
|
|
10
|
+
|
|
11
|
+
// Re-export types
|
|
12
|
+
export type { DynamicOptions, Loader, LoaderComponent } from 'next/dynamic';
|
|
13
|
+
export { default } from 'next/dynamic';
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Next.js wrapper module
|
|
3
|
+
*
|
|
4
|
+
* This module provides unified interfaces for Next.js-specific APIs,
|
|
5
|
+
* making it easier to migrate from Next.js to other frameworks (e.g., Vite + React Router).
|
|
6
|
+
*
|
|
7
|
+
* Usage:
|
|
8
|
+
* - import { useRouter, usePathname } from '@/libs/next/navigation';
|
|
9
|
+
* - import Link from '@/libs/next/Link';
|
|
10
|
+
* - import dynamic from '@/libs/next/dynamic';
|
|
11
|
+
* - import Image from '@/libs/next/Image';
|
|
12
|
+
*
|
|
13
|
+
* @see RFC 147: LOBE-2850 - Phase 3
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
// Navigation exports
|
|
17
|
+
export * from './navigation';
|
|
18
|
+
|
|
19
|
+
// Component exports (re-export as named for convenience)
|
|
20
|
+
export { default as dynamic } from './dynamic';
|
|
21
|
+
export { default as Image } from './Image';
|
|
22
|
+
export { default as Link } from './Link';
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Navigation utilities wrapper for Next.js navigation APIs.
|
|
3
|
+
* This module provides a unified interface that can be easily replaced
|
|
4
|
+
* with react-router-dom in the future.
|
|
5
|
+
*
|
|
6
|
+
* @see Phase 3.1: LOBE-2988
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
// Re-export all navigation hooks and utilities from Next.js
|
|
10
|
+
export {
|
|
11
|
+
notFound,
|
|
12
|
+
ReadonlyURLSearchParams,
|
|
13
|
+
redirect,
|
|
14
|
+
useParams,
|
|
15
|
+
usePathname,
|
|
16
|
+
useRouter,
|
|
17
|
+
useSearchParams,
|
|
18
|
+
useServerInsertedHTML,
|
|
19
|
+
} from 'next/navigation';
|
|
20
|
+
|
|
21
|
+
// Re-export types
|
|
22
|
+
export type { RedirectType } from 'next/navigation';
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* React Router Link component wrapper.
|
|
3
|
+
* Provides a Next.js-like API (href prop) while using React Router internally.
|
|
4
|
+
*
|
|
5
|
+
* @see RFC 147: LOBE-2850 - Phase 3
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import React, { memo } from 'react';
|
|
9
|
+
import { Link as ReactRouterLink, type LinkProps as ReactRouterLinkProps } from 'react-router-dom';
|
|
10
|
+
|
|
11
|
+
interface LinkProps extends Omit<ReactRouterLinkProps, 'to'> {
|
|
12
|
+
children?: React.ReactNode;
|
|
13
|
+
href?: string;
|
|
14
|
+
to?: string;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Link component for React Router.
|
|
19
|
+
* Provides a Next.js-like API (href prop) while using React Router internally.
|
|
20
|
+
*/
|
|
21
|
+
const Link = memo<LinkProps>(({ href, to, ...props }) => {
|
|
22
|
+
const linkTo = href || to || '/';
|
|
23
|
+
return <ReactRouterLink {...props} to={linkTo} />;
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
Link.displayName = 'Link';
|
|
27
|
+
|
|
28
|
+
export default Link;
|
|
29
|
+
|
|
30
|
+
export type { LinkProps };
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* React Router wrapper module for SPA routing.
|
|
3
|
+
*
|
|
4
|
+
* This module provides unified interfaces for React Router APIs,
|
|
5
|
+
* with a Next.js-like API surface for easier migration.
|
|
6
|
+
*
|
|
7
|
+
* Usage:
|
|
8
|
+
* - import { useRouter, usePathname, useSearchParams } from '@/libs/router';
|
|
9
|
+
* - import Link from '@/libs/router/Link';
|
|
10
|
+
*
|
|
11
|
+
* @see RFC 147: LOBE-2850 - Phase 3
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
// Navigation exports
|
|
15
|
+
export * from './navigation';
|
|
16
|
+
|
|
17
|
+
// Component exports
|
|
18
|
+
export { default as Link } from './Link';
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* React Router navigation hooks wrapper.
|
|
3
|
+
* This module provides unified navigation hooks for SPA routing.
|
|
4
|
+
*
|
|
5
|
+
* Usage:
|
|
6
|
+
* - import { useRouter, usePathname, useSearchParams, useQuery } from '@/libs/router/navigation';
|
|
7
|
+
*
|
|
8
|
+
* @see RFC 147: LOBE-2850 - Phase 3
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
import qs from 'query-string';
|
|
12
|
+
import { useMemo } from 'react';
|
|
13
|
+
import {
|
|
14
|
+
useLocation,
|
|
15
|
+
useNavigate,
|
|
16
|
+
useParams as useReactRouterParams,
|
|
17
|
+
useSearchParams as useReactRouterSearchParams,
|
|
18
|
+
} from 'react-router-dom';
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Hook to get router navigation functions.
|
|
22
|
+
* Provides a Next.js-like API using React Router.
|
|
23
|
+
*/
|
|
24
|
+
export const useRouter = () => {
|
|
25
|
+
const navigate = useNavigate();
|
|
26
|
+
|
|
27
|
+
return useMemo(
|
|
28
|
+
() => ({
|
|
29
|
+
back: () => navigate(-1),
|
|
30
|
+
forward: () => navigate(1),
|
|
31
|
+
// Note: prefetch is not supported in React Router
|
|
32
|
+
prefetch: () => {},
|
|
33
|
+
push: (href: string) => navigate(href),
|
|
34
|
+
replace: (href: string) => navigate(href, { replace: true }),
|
|
35
|
+
}),
|
|
36
|
+
[navigate]
|
|
37
|
+
);
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Hook to get current pathname.
|
|
42
|
+
*/
|
|
43
|
+
export const usePathname = () => {
|
|
44
|
+
const location = useLocation();
|
|
45
|
+
return location.pathname;
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Hook to get search params.
|
|
50
|
+
* Returns [searchParams, setSearchParams] tuple similar to React Router.
|
|
51
|
+
*/
|
|
52
|
+
export const useSearchParams = () => {
|
|
53
|
+
return useReactRouterSearchParams();
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Hook to get route params.
|
|
58
|
+
*/
|
|
59
|
+
export const useParams = <T extends Record<string, string | undefined> = Record<string, string | undefined>>() => {
|
|
60
|
+
return useReactRouterParams<T>();
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* Hook to get query parameters as a parsed object.
|
|
65
|
+
*/
|
|
66
|
+
export const useQuery = () => {
|
|
67
|
+
const [searchParams] = useReactRouterSearchParams();
|
|
68
|
+
return useMemo(() => qs.parse(searchParams.toString()), [searchParams]);
|
|
69
|
+
};
|
|
70
|
+
|
|
71
|
+
// Re-export types
|
|
72
|
+
export type { Location, NavigateFunction, Params } from 'react-router-dom';
|
|
@@ -1,4 +1,8 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
type AgentEvent,
|
|
3
|
+
type AgentRuntimeContext,
|
|
4
|
+
type AgentState,
|
|
5
|
+
} from '@lobechat/agent-runtime';
|
|
2
6
|
import debug from 'debug';
|
|
3
7
|
import type { Redis } from 'ioredis';
|
|
4
8
|
|
|
@@ -111,9 +111,7 @@ describe('chatDockSelectors', () => {
|
|
|
111
111
|
|
|
112
112
|
it('should return the messageId when ToolUI view is on stack', () => {
|
|
113
113
|
const state = createState({
|
|
114
|
-
portalStack: [
|
|
115
|
-
{ type: PortalViewType.ToolUI, messageId: 'test-id', identifier: 'test' },
|
|
116
|
-
],
|
|
114
|
+
portalStack: [{ type: PortalViewType.ToolUI, messageId: 'test-id', identifier: 'test' }],
|
|
117
115
|
});
|
|
118
116
|
expect(chatPortalSelectors.toolMessageId(state)).toBe('test-id');
|
|
119
117
|
});
|
|
@@ -122,9 +120,7 @@ describe('chatDockSelectors', () => {
|
|
|
122
120
|
describe('isMessageToolUIOpen', () => {
|
|
123
121
|
it('should return false when id does not match or showDock is false', () => {
|
|
124
122
|
const state = createState({
|
|
125
|
-
portalStack: [
|
|
126
|
-
{ type: PortalViewType.ToolUI, messageId: 'test-id', identifier: 'test' },
|
|
127
|
-
],
|
|
123
|
+
portalStack: [{ type: PortalViewType.ToolUI, messageId: 'test-id', identifier: 'test' }],
|
|
128
124
|
showPortal: false,
|
|
129
125
|
});
|
|
130
126
|
expect(chatPortalSelectors.isPluginUIOpen('test-id')(state)).toBe(false);
|
|
@@ -133,9 +129,7 @@ describe('chatDockSelectors', () => {
|
|
|
133
129
|
|
|
134
130
|
it('should return true when id matches and showDock is true', () => {
|
|
135
131
|
const state = createState({
|
|
136
|
-
portalStack: [
|
|
137
|
-
{ type: PortalViewType.ToolUI, messageId: 'test-id', identifier: 'test' },
|
|
138
|
-
],
|
|
132
|
+
portalStack: [{ type: PortalViewType.ToolUI, messageId: 'test-id', identifier: 'test' }],
|
|
139
133
|
showPortal: true,
|
|
140
134
|
});
|
|
141
135
|
expect(chatPortalSelectors.isPluginUIOpen('test-id')(state)).toBe(true);
|
|
@@ -149,9 +143,7 @@ describe('chatDockSelectors', () => {
|
|
|
149
143
|
|
|
150
144
|
it('should return true when ToolUI view is on stack', () => {
|
|
151
145
|
const state = createState({
|
|
152
|
-
portalStack: [
|
|
153
|
-
{ type: PortalViewType.ToolUI, messageId: 'test-id', identifier: 'test' },
|
|
154
|
-
],
|
|
146
|
+
portalStack: [{ type: PortalViewType.ToolUI, messageId: 'test-id', identifier: 'test' }],
|
|
155
147
|
});
|
|
156
148
|
expect(chatPortalSelectors.showPluginUI(state)).toBe(true);
|
|
157
149
|
});
|
|
@@ -164,9 +156,7 @@ describe('chatDockSelectors', () => {
|
|
|
164
156
|
|
|
165
157
|
it('should return the identifier when ToolUI view is on stack', () => {
|
|
166
158
|
const state = createState({
|
|
167
|
-
portalStack: [
|
|
168
|
-
{ type: PortalViewType.ToolUI, messageId: 'test-id', identifier: 'test' },
|
|
169
|
-
],
|
|
159
|
+
portalStack: [{ type: PortalViewType.ToolUI, messageId: 'test-id', identifier: 'test' }],
|
|
170
160
|
});
|
|
171
161
|
expect(chatPortalSelectors.toolUIIdentifier(state)).toBe('test');
|
|
172
162
|
});
|
package/src/store/page/index.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
export * from './selectors';
|
|
2
|
-
export { getPageStoreState, type PageStore,usePageStore } from './store';
|
|
2
|
+
export { getPageStoreState, type PageStore, usePageStore } from './store';
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
export { createCrudSlice, type CrudAction } from './action';
|
|
2
|
-
export { type CrudState,initialCrudState } from './initialState';
|
|
2
|
+
export { type CrudState, initialCrudState } from './initialState';
|
|
@@ -9,7 +9,7 @@ import { gt, valid } from 'semver';
|
|
|
9
9
|
import useSWR, { type SWRResponse } from 'swr';
|
|
10
10
|
import { type StateCreator } from 'zustand/vanilla';
|
|
11
11
|
|
|
12
|
-
import { type MCPErrorData } from '@/libs/mcp/types';
|
|
12
|
+
import { type MCPErrorData, parseStdioErrorMessage } from '@/libs/mcp/types';
|
|
13
13
|
import { discoverService } from '@/services/discover';
|
|
14
14
|
import { mcpService } from '@/services/mcp';
|
|
15
15
|
import { pluginService } from '@/services/plugin';
|
|
@@ -132,6 +132,8 @@ const buildCloudMcpManifest = (params: {
|
|
|
132
132
|
// Test connection result type
|
|
133
133
|
export interface TestMcpConnectionResult {
|
|
134
134
|
error?: string;
|
|
135
|
+
/** STDIO process output logs for debugging */
|
|
136
|
+
errorLog?: string;
|
|
135
137
|
manifest?: LobeChatPluginManifest;
|
|
136
138
|
success: boolean;
|
|
137
139
|
}
|
|
@@ -301,8 +303,6 @@ export const createMCPPluginStoreSlice: StateCreator<
|
|
|
301
303
|
// Check if cloudEndPoint is available: web + stdio type + haveCloudEndpoint exists
|
|
302
304
|
const hasCloudEndpoint = !isDesktop && stdioOption && haveCloudEndpoint;
|
|
303
305
|
|
|
304
|
-
console.log('hasCloudEndpoint', hasCloudEndpoint);
|
|
305
|
-
|
|
306
306
|
let shouldUseHttpDeployment = !!httpOption && (!hasNonHttpDeployment || !isDesktop);
|
|
307
307
|
|
|
308
308
|
if (hasCloudEndpoint) {
|
|
@@ -592,7 +592,7 @@ export const createMCPPluginStoreSlice: StateCreator<
|
|
|
592
592
|
event: 'install',
|
|
593
593
|
identifier: plugin.identifier,
|
|
594
594
|
source: 'self',
|
|
595
|
-
})
|
|
595
|
+
});
|
|
596
596
|
|
|
597
597
|
discoverService.reportMcpInstallResult({
|
|
598
598
|
identifier: plugin.identifier,
|
|
@@ -653,10 +653,22 @@ export const createMCPPluginStoreSlice: StateCreator<
|
|
|
653
653
|
};
|
|
654
654
|
} else {
|
|
655
655
|
// Fallback handling for normal errors
|
|
656
|
-
const
|
|
656
|
+
const rawErrorMessage = error instanceof Error ? error.message : String(error);
|
|
657
|
+
|
|
658
|
+
// Parse STDIO error message to extract process output logs
|
|
659
|
+
const { originalMessage, errorLog } = parseStdioErrorMessage(rawErrorMessage);
|
|
660
|
+
|
|
657
661
|
errorInfo = {
|
|
658
|
-
message:
|
|
662
|
+
message: originalMessage,
|
|
659
663
|
metadata: {
|
|
664
|
+
errorLog,
|
|
665
|
+
params: connection
|
|
666
|
+
? {
|
|
667
|
+
args: connection.args,
|
|
668
|
+
command: connection.command,
|
|
669
|
+
type: connection.type,
|
|
670
|
+
}
|
|
671
|
+
: undefined,
|
|
660
672
|
step: 'installation_error',
|
|
661
673
|
timestamp: Date.now(),
|
|
662
674
|
},
|
|
@@ -800,7 +812,7 @@ export const createMCPPluginStoreSlice: StateCreator<
|
|
|
800
812
|
event: 'activate',
|
|
801
813
|
identifier: identifier,
|
|
802
814
|
source: 'self',
|
|
803
|
-
})
|
|
815
|
+
});
|
|
804
816
|
|
|
805
817
|
return { manifest, success: true };
|
|
806
818
|
} catch (error) {
|
|
@@ -809,20 +821,23 @@ export const createMCPPluginStoreSlice: StateCreator<
|
|
|
809
821
|
return { error: 'Test cancelled', success: false };
|
|
810
822
|
}
|
|
811
823
|
|
|
812
|
-
const
|
|
824
|
+
const rawErrorMessage = error instanceof Error ? error.message : String(error);
|
|
825
|
+
|
|
826
|
+
// Parse STDIO error message to extract process output logs
|
|
827
|
+
const { originalMessage, errorLog } = parseStdioErrorMessage(rawErrorMessage);
|
|
813
828
|
|
|
814
829
|
// Set error state
|
|
815
830
|
set(
|
|
816
831
|
produce((draft: MCPStoreState) => {
|
|
817
832
|
draft.mcpTestLoading[identifier] = false;
|
|
818
|
-
draft.mcpTestErrors[identifier] =
|
|
833
|
+
draft.mcpTestErrors[identifier] = originalMessage;
|
|
819
834
|
delete draft.mcpTestAbortControllers[identifier];
|
|
820
835
|
}),
|
|
821
836
|
false,
|
|
822
837
|
n('testMcpConnection/error'),
|
|
823
838
|
);
|
|
824
839
|
|
|
825
|
-
return { error:
|
|
840
|
+
return { error: originalMessage, errorLog, success: false };
|
|
826
841
|
}
|
|
827
842
|
},
|
|
828
843
|
|
|
@@ -834,7 +849,7 @@ export const createMCPPluginStoreSlice: StateCreator<
|
|
|
834
849
|
event: 'uninstall',
|
|
835
850
|
identifier: identifier,
|
|
836
851
|
source: 'self',
|
|
837
|
-
})
|
|
852
|
+
});
|
|
838
853
|
},
|
|
839
854
|
|
|
840
855
|
updateMCPInstallProgress: (identifier, progress) => {
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
import qs from 'query-string';
|
|
2
|
-
import { useMemo } from 'react';
|
|
3
|
-
import { useSearchParams } from 'react-router-dom';
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* Hook to get query parameters
|
|
7
|
-
* React Router version for (main) directory
|
|
8
|
-
*/
|
|
9
|
-
export const useQuery = () => {
|
|
10
|
-
const [searchParams] = useSearchParams();
|
|
11
|
-
return useMemo(() => qs.parse(searchParams.toString()), [searchParams]);
|
|
12
|
-
};
|
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
import { useNavigate } from 'react-router-dom';
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Hook to get router navigation functions
|
|
5
|
-
* React Router version for (main) directory
|
|
6
|
-
*
|
|
7
|
-
* Provides a Next.js-like API using React Router
|
|
8
|
-
*/
|
|
9
|
-
export const useRouter = () => {
|
|
10
|
-
const navigate = useNavigate();
|
|
11
|
-
|
|
12
|
-
return {
|
|
13
|
-
back: () => navigate(-1),
|
|
14
|
-
forward: () => navigate(1),
|
|
15
|
-
// Note: prefetch is not supported in React Router
|
|
16
|
-
prefetch: () => {},
|
|
17
|
-
|
|
18
|
-
push: (href: string) => navigate(href),
|
|
19
|
-
|
|
20
|
-
replace: (href: string) => navigate(href, { replace: true }),
|
|
21
|
-
};
|
|
22
|
-
};
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
import { useSearchParams as useReactRouterSearchParams } from 'react-router-dom';
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Hook to get search params
|
|
5
|
-
* React Router version for (main) directory
|
|
6
|
-
*
|
|
7
|
-
* Returns [searchParams, setSearchParams] tuple similar to React Router
|
|
8
|
-
*/
|
|
9
|
-
export const useSearchParams = () => {
|
|
10
|
-
return useReactRouterSearchParams();
|
|
11
|
-
};
|