@lobehub/lobehub 2.0.0-next.311 → 2.0.0-next.313
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 +59 -0
- package/apps/desktop/src/main/controllers/AuthCtr.ts +75 -7
- package/changelog/v1.json +21 -0
- package/docs/usage/providers/internlm.mdx +2 -2
- package/docs/usage/providers/internlm.zh-CN.mdx +3 -3
- package/e2e/README.md +1 -1
- package/e2e/src/features/community/detail-pages.feature +2 -2
- package/e2e/src/features/community/interactions.feature +5 -5
- package/e2e/src/features/community/smoke.feature +1 -1
- package/e2e/src/steps/community/detail-pages.steps.ts +6 -4
- package/e2e/src/steps/community/interactions.steps.ts +3 -3
- package/locales/en-US/error.json +10 -1
- package/locales/en-US/subscription.json +1 -1
- package/locales/zh-CN/desktop-onboarding.json +5 -0
- package/locales/zh-CN/error.json +10 -1
- package/locales/zh-CN/subscription.json +1 -1
- package/package.json +1 -1
- package/packages/agent-runtime/src/agents/GeneralChatAgent.ts +14 -2
- package/packages/agent-runtime/src/agents/__tests__/GeneralChatAgent.test.ts +275 -1
- package/packages/builtin-tool-agent-builder/src/systemRole.ts +9 -0
- package/packages/builtin-tool-cloud-sandbox/package.json +1 -0
- package/packages/builtin-tool-cloud-sandbox/src/ExecutionRuntime/index.ts +105 -134
- package/packages/builtin-tool-cloud-sandbox/src/executor/index.ts +254 -0
- package/packages/builtin-tool-cloud-sandbox/src/index.ts +1 -0
- package/packages/builtin-tool-cloud-sandbox/src/types/api.ts +22 -0
- package/packages/builtin-tool-cloud-sandbox/src/types/index.ts +4 -0
- package/packages/builtin-tool-cloud-sandbox/src/types/params.ts +85 -0
- package/packages/builtin-tool-cloud-sandbox/src/types/service.ts +48 -0
- package/packages/builtin-tool-cloud-sandbox/src/{types.ts → types/state.ts} +0 -23
- package/packages/builtin-tool-memory/src/manifest.ts +5 -5
- package/packages/editor-runtime/src/__tests__/EditorRuntime.real.test.ts +1 -1
- package/packages/editor-runtime/src/__tests__/EditorRuntime.test.ts +1 -1
- package/packages/electron-client-ipc/src/events/index.ts +5 -1
- package/packages/electron-client-ipc/src/events/remoteServer.ts +23 -0
- package/packages/memory-user-memory/src/schemas/index.ts +0 -1
- package/packages/model-bank/src/modelProviders/internlm.ts +1 -1
- package/packages/model-runtime/src/core/RouterRuntime/createRuntime.ts +5 -15
- package/packages/model-runtime/src/providers/internlm/index.test.ts +15 -15
- package/packages/model-runtime/src/providers/internlm/index.ts +1 -1
- package/packages/types/src/tool/intervention.ts +4 -2
- package/packages/types/src/user/preference.ts +1 -0
- package/public/favicon-32x-32-error.ico +0 -0
- package/public/favicon-32x32-done-dev.ico +0 -0
- package/public/favicon-32x32-done.ico +0 -0
- package/public/favicon-32x32-error-dev.ico +0 -0
- package/public/favicon-32x32-progress-dev.ico +0 -0
- package/public/favicon-32x32-progress.ico +0 -0
- package/public/favicon-done-dev.ico +0 -0
- package/public/favicon-done.ico +0 -0
- package/public/favicon-error-dev.ico +0 -0
- package/public/favicon-error.ico +0 -0
- package/public/favicon-progress-dev.ico +0 -0
- package/public/favicon-progress.ico +0 -0
- package/src/app/[variants]/(desktop)/desktop-onboarding/features/LoginStep.tsx +84 -26
- package/src/app/[variants]/(main)/_layout/DesktopAutoOidcOnFirstOpen.tsx +4 -0
- package/src/app/[variants]/(main)/agent/profile/features/Header/AgentPublishButton/PublishResultModal.tsx +1 -1
- package/src/app/[variants]/(main)/community/(detail)/_layout/Header.tsx +15 -3
- package/src/app/[variants]/(main)/community/(detail)/{assistant → agent}/features/Details/Overview/TagList.tsx +1 -1
- package/src/app/[variants]/(main)/community/(detail)/{assistant → agent}/features/Details/Related/index.tsx +2 -2
- package/src/app/[variants]/(main)/community/(detail)/{assistant → agent}/features/Details/SystemRole/TagList.tsx +1 -1
- package/src/app/[variants]/(main)/community/(detail)/{assistant → agent}/features/Details/SystemRole/index.tsx +1 -1
- package/src/app/[variants]/(main)/community/(detail)/{assistant → agent}/features/Header.tsx +2 -2
- package/src/app/[variants]/(main)/community/(detail)/{assistant → agent}/features/Sidebar/ActionButton/AddAgent.tsx +1 -1
- package/src/app/[variants]/(main)/community/(detail)/{assistant → agent}/features/Sidebar/ActionButton/index.tsx +1 -1
- package/src/app/[variants]/(main)/community/(detail)/{assistant → agent}/features/Sidebar/Related/index.tsx +2 -2
- package/src/app/[variants]/(main)/community/(detail)/{assistant → agent}/features/StatusPage/index.tsx +2 -2
- package/src/app/[variants]/(main)/community/(detail)/user/features/UserAgentCard.tsx +2 -2
- package/src/app/[variants]/(main)/community/(detail)/user/features/UserFavoriteAgents.tsx +1 -1
- package/src/app/[variants]/(main)/community/(list)/(home)/index.tsx +2 -2
- package/src/app/[variants]/(main)/community/(list)/(home)/loading.tsx +1 -1
- package/src/app/[variants]/(main)/community/(list)/{assistant → agent}/Client.tsx +5 -1
- package/src/app/[variants]/(main)/community/(list)/{assistant → agent}/features/Category/index.tsx +1 -1
- package/src/app/[variants]/(main)/community/(list)/{assistant → agent}/features/List/Item.tsx +1 -1
- package/src/app/[variants]/(main)/community/(list)/{assistant → agent}/features/MarketSourceSwitch.tsx +1 -1
- package/src/app/[variants]/(main)/community/_layout/Sidebar/Header/Nav.tsx +2 -2
- package/src/app/[variants]/(main)/home/features/CommunityAgents/List.tsx +1 -1
- package/src/app/[variants]/(main)/home/features/CommunityAgents/index.tsx +1 -1
- package/src/app/[variants]/(mobile)/_layout/index.tsx +1 -1
- package/src/app/[variants]/(mobile)/router/mobileRouter.config.tsx +6 -6
- package/src/app/[variants]/router/desktopRouter.config.tsx +8 -8
- package/src/app/[variants]/share/t/[id]/_layout/index.tsx +1 -1
- package/src/business/server/user.ts +4 -0
- package/src/features/CommandMenu/SearchResults.tsx +1 -1
- package/src/features/Conversation/Messages/Task/Actions/index.tsx +0 -2
- package/src/features/Conversation/Messages/Task/index.tsx +1 -1
- package/src/features/Conversation/Messages/Tasks/shared/ProcessingState.tsx +0 -2
- package/src/features/Electron/navigation/routeMetadata.ts +1 -1
- package/src/features/NavPanel/components/NavPanelDraggable.tsx +0 -14
- package/src/features/ResourceManager/components/Explorer/ItemDropdown/useFileItemDropdown.tsx +4 -3
- package/src/features/SharePopover/index.tsx +5 -3
- package/src/hooks/useAppOrigin.ts +16 -0
- package/src/layout/GlobalProvider/FaviconProvider.tsx +92 -0
- package/src/layout/GlobalProvider/index.tsx +15 -11
- package/src/layout/GlobalProvider/useUserStateRedirect.ts +37 -24
- package/src/libs/next/config/define-config.ts +1 -1
- package/src/libs/trusted-client/index.ts +2 -5
- package/src/locales/default/desktop-onboarding.ts +5 -0
- package/src/locales/default/error.ts +11 -0
- package/src/locales/default/subscription.ts +1 -1
- package/src/server/modules/AgentRuntime/RuntimeExecutors.ts +2 -0
- package/src/server/routers/lambda/user.ts +24 -10
- package/src/server/services/agentRuntime/AgentRuntimeService.test.ts +3 -0
- package/src/server/services/agentRuntime/AgentRuntimeService.ts +8 -5
- package/src/server/services/agentRuntime/types.ts +7 -0
- package/src/server/services/aiAgent/__tests__/execGroupSubAgentTask.test.ts +3 -0
- package/src/server/services/aiAgent/index.ts +10 -4
- package/src/server/services/market/index.ts +7 -0
- package/src/server/services/sandbox/index.ts +120 -0
- package/src/server/services/toolExecution/builtin.ts +12 -18
- package/src/server/services/toolExecution/index.ts +1 -1
- package/src/server/services/toolExecution/serverRuntimes/cloudSandbox.ts +31 -0
- package/src/server/services/toolExecution/serverRuntimes/index.ts +55 -0
- package/src/server/services/toolExecution/serverRuntimes/types.ts +14 -0
- package/src/server/services/toolExecution/serverRuntimes/webBrowsing.ts +20 -0
- package/src/server/services/toolExecution/types.ts +2 -0
- package/src/server/sitemap.test.ts +5 -5
- package/src/server/sitemap.ts +3 -3
- package/src/services/{codeInterpreter.ts → cloudSandbox.ts} +3 -3
- package/src/services/electron/remoteServer.ts +8 -0
- package/src/store/chat/agents/GroupOrchestration/__tests__/batch-exec-async-tasks.test.ts +626 -0
- package/src/store/chat/agents/GroupOrchestration/createGroupOrchestrationExecutors.ts +294 -0
- package/src/store/chat/slices/plugin/action.test.ts +0 -48
- package/src/store/chat/slices/plugin/actions/pluginTypes.ts +0 -131
- package/src/store/tool/slices/builtin/executors/index.ts +2 -0
- package/src/store/user/slices/settings/selectors/toolIntervention.test.ts +143 -0
- package/src/store/user/slices/settings/selectors/toolIntervention.ts +11 -2
- package/packages/memory-user-memory/src/schemas/jsonSchemas.ts +0 -37
- /package/src/app/[variants]/(main)/community/(detail)/{assistant → agent}/features/DetailProvider.tsx +0 -0
- /package/src/app/[variants]/(main)/community/(detail)/{assistant → agent}/features/Details/Capabilities/Block.tsx +0 -0
- /package/src/app/[variants]/(main)/community/(detail)/{assistant → agent}/features/Details/Capabilities/Knowledge.tsx +0 -0
- /package/src/app/[variants]/(main)/community/(detail)/{assistant → agent}/features/Details/Capabilities/KnowledgeItem.tsx +0 -0
- /package/src/app/[variants]/(main)/community/(detail)/{assistant → agent}/features/Details/Capabilities/PluginItem.tsx +0 -0
- /package/src/app/[variants]/(main)/community/(detail)/{assistant → agent}/features/Details/Capabilities/Plugins.tsx +0 -0
- /package/src/app/[variants]/(main)/community/(detail)/{assistant → agent}/features/Details/Capabilities/index.tsx +0 -0
- /package/src/app/[variants]/(main)/community/(detail)/{assistant → agent}/features/Details/Nav.tsx +0 -0
- /package/src/app/[variants]/(main)/community/(detail)/{assistant → agent}/features/Details/Overview/index.tsx +0 -0
- /package/src/app/[variants]/(main)/community/(detail)/{assistant → agent}/features/Details/Versions/index.tsx +0 -0
- /package/src/app/[variants]/(main)/community/(detail)/{assistant → agent}/features/Details/index.tsx +0 -0
- /package/src/app/[variants]/(main)/community/(detail)/{assistant → agent}/features/Sidebar/Related/Item.tsx +0 -0
- /package/src/app/[variants]/(main)/community/(detail)/{assistant → agent}/features/Sidebar/Summary/index.tsx +0 -0
- /package/src/app/[variants]/(main)/community/(detail)/{assistant → agent}/features/Sidebar/TocList/index.tsx +0 -0
- /package/src/app/[variants]/(main)/community/(detail)/{assistant → agent}/features/Sidebar/index.tsx +0 -0
- /package/src/app/[variants]/(main)/community/(detail)/{assistant → agent}/index.tsx +0 -0
- /package/src/app/[variants]/(main)/community/(detail)/{assistant → agent}/loading.tsx +0 -0
- /package/src/app/[variants]/(main)/community/(list)/{assistant → agent}/_layout/index.tsx +0 -0
- /package/src/app/[variants]/(main)/community/(list)/{assistant → agent}/_layout/style.ts +0 -0
- /package/src/app/[variants]/(main)/community/(list)/{assistant → agent}/features/Category/useCategory.tsx +0 -0
- /package/src/app/[variants]/(main)/community/(list)/{assistant → agent}/features/List/TokenTag.tsx +0 -0
- /package/src/app/[variants]/(main)/community/(list)/{assistant → agent}/features/List/index.tsx +0 -0
- /package/src/app/[variants]/(main)/community/(list)/{assistant → agent}/index.tsx +0 -0
- /package/src/app/[variants]/(main)/community/(list)/{assistant → agent}/loading.tsx +0 -0
|
@@ -3,12 +3,12 @@
|
|
|
3
3
|
import { Flexbox } from '@lobehub/ui';
|
|
4
4
|
import { McpIcon, ProviderIcon } from '@lobehub/ui/icons';
|
|
5
5
|
import { Bot, Brain, ShapesIcon } from 'lucide-react';
|
|
6
|
-
import { usePathname } from '@/libs/router/navigation';
|
|
7
6
|
import { memo, useMemo } from 'react';
|
|
8
7
|
import { useTranslation } from 'react-i18next';
|
|
9
8
|
import { Link, useNavigate } from 'react-router-dom';
|
|
10
9
|
|
|
11
10
|
import NavItem, { type NavItemProps } from '@/features/NavPanel/components/NavItem';
|
|
11
|
+
import { usePathname } from '@/libs/router/navigation';
|
|
12
12
|
import { DiscoverTab } from '@/types/discover';
|
|
13
13
|
|
|
14
14
|
interface Item {
|
|
@@ -42,7 +42,7 @@ const Nav = memo(() => {
|
|
|
42
42
|
icon: Bot,
|
|
43
43
|
key: DiscoverTab.Assistants,
|
|
44
44
|
title: t('tab.assistant'),
|
|
45
|
-
url: '/community/
|
|
45
|
+
url: '/community/agent',
|
|
46
46
|
},
|
|
47
47
|
{
|
|
48
48
|
icon: McpIcon,
|
|
@@ -15,7 +15,7 @@ const CloudBanner = dynamic(() => import('@/features/AlertBanner/CloudBanner'));
|
|
|
15
15
|
const MOBILE_NAV_ROUTES = new Set([
|
|
16
16
|
'/',
|
|
17
17
|
'/community',
|
|
18
|
-
'/community/
|
|
18
|
+
'/community/agent',
|
|
19
19
|
'/community/mcp',
|
|
20
20
|
'/community/plugin',
|
|
21
21
|
'/community/model',
|
|
@@ -65,10 +65,10 @@ export const mobileRoutes: RouteConfig[] = [
|
|
|
65
65
|
children: [
|
|
66
66
|
{
|
|
67
67
|
element: dynamicElement(
|
|
68
|
-
() => import('../../(main)/community/(list)/
|
|
69
|
-
'Mobile > Discover > List >
|
|
68
|
+
() => import('../../(main)/community/(list)/agent'),
|
|
69
|
+
'Mobile > Discover > List > Agent',
|
|
70
70
|
),
|
|
71
|
-
path: '
|
|
71
|
+
path: 'agent',
|
|
72
72
|
},
|
|
73
73
|
],
|
|
74
74
|
},
|
|
@@ -113,12 +113,12 @@ export const mobileRoutes: RouteConfig[] = [
|
|
|
113
113
|
{
|
|
114
114
|
element: dynamicElement(
|
|
115
115
|
() =>
|
|
116
|
-
import('../../(main)/community/(detail)/
|
|
116
|
+
import('../../(main)/community/(detail)/agent').then(
|
|
117
117
|
(m) => m.MobileDiscoverAssistantDetailPage,
|
|
118
118
|
),
|
|
119
|
-
'Mobile > Discover > Detail >
|
|
119
|
+
'Mobile > Discover > Detail > Agent',
|
|
120
120
|
),
|
|
121
|
-
path: '
|
|
121
|
+
path: 'agent/:slug',
|
|
122
122
|
},
|
|
123
123
|
{
|
|
124
124
|
element: dynamicElement(
|
|
@@ -94,17 +94,17 @@ export const desktopRoutes: RouteConfig[] = [
|
|
|
94
94
|
children: [
|
|
95
95
|
{
|
|
96
96
|
element: dynamicElement(
|
|
97
|
-
() => import('../(main)/community/(list)/
|
|
98
|
-
'Desktop > Discover > List >
|
|
97
|
+
() => import('../(main)/community/(list)/agent'),
|
|
98
|
+
'Desktop > Discover > List > Agent',
|
|
99
99
|
),
|
|
100
100
|
index: true,
|
|
101
101
|
},
|
|
102
102
|
],
|
|
103
103
|
element: dynamicElement(
|
|
104
|
-
() => import('../(main)/community/(list)/
|
|
105
|
-
'Desktop > Discover > List >
|
|
104
|
+
() => import('../(main)/community/(list)/agent/_layout'),
|
|
105
|
+
'Desktop > Discover > List > Agent > Layout',
|
|
106
106
|
),
|
|
107
|
-
path: '
|
|
107
|
+
path: 'agent',
|
|
108
108
|
},
|
|
109
109
|
{
|
|
110
110
|
children: [
|
|
@@ -163,10 +163,10 @@ export const desktopRoutes: RouteConfig[] = [
|
|
|
163
163
|
children: [
|
|
164
164
|
{
|
|
165
165
|
element: dynamicElement(
|
|
166
|
-
() => import('../(main)/community/(detail)/
|
|
167
|
-
'Desktop > Discover > Detail >
|
|
166
|
+
() => import('../(main)/community/(detail)/agent'),
|
|
167
|
+
'Desktop > Discover > Detail > Agent',
|
|
168
168
|
),
|
|
169
|
-
path: '
|
|
169
|
+
path: 'agent/:slug',
|
|
170
170
|
},
|
|
171
171
|
{
|
|
172
172
|
element: dynamicElement(
|
|
@@ -116,7 +116,7 @@ const ShareTopicLayout = memo<PropsWithChildren>(({ children }) => {
|
|
|
116
116
|
// If agent has marketIdentifier, render as link to assistant page
|
|
117
117
|
if (agentMarketIdentifier && !data?.groupMeta?.title) {
|
|
118
118
|
return (
|
|
119
|
-
<a href={`/community/
|
|
119
|
+
<a href={`/community/agent/${agentMarketIdentifier}`} rel="noreferrer" target="_blank">
|
|
120
120
|
<Typography.Text ellipsis strong>
|
|
121
121
|
{agentOrGroupTitle}
|
|
122
122
|
</Typography.Text>
|
|
@@ -13,6 +13,10 @@ export async function getIsInWaitList(userId: string): Promise<boolean> {
|
|
|
13
13
|
return false;
|
|
14
14
|
}
|
|
15
15
|
|
|
16
|
+
export async function getIsInviteCodeRequired(userId: string): Promise<boolean> {
|
|
17
|
+
return false;
|
|
18
|
+
}
|
|
19
|
+
|
|
16
20
|
export async function initNewUserForBusiness(
|
|
17
21
|
userId: string,
|
|
18
22
|
createdAt: Date | null | undefined,
|
|
@@ -43,7 +43,7 @@ const TaskMessage = memo<TaskMessageProps>(({ id, index, disableEditing, isLates
|
|
|
43
43
|
const editing = useConversationStore(messageStateSelectors.isMessageEditing(id));
|
|
44
44
|
const generating = useConversationStore(messageStateSelectors.isMessageGenerating(id));
|
|
45
45
|
const creating = useConversationStore(messageStateSelectors.isMessageCreating(id));
|
|
46
|
-
const newScreen = useNewScreen({ creating, isLatestItem });
|
|
46
|
+
const newScreen = useNewScreen({ creating: generating || creating, isLatestItem });
|
|
47
47
|
|
|
48
48
|
const errorContent = useErrorContent(error);
|
|
49
49
|
|
|
@@ -13,7 +13,6 @@ import { systemStatusSelectors } from '@/store/global/selectors';
|
|
|
13
13
|
import { isMacOS } from '@/utils/platform';
|
|
14
14
|
|
|
15
15
|
import { useNavPanelSizeChangeHandler } from '../hooks/useNavPanel';
|
|
16
|
-
import { BACK_BUTTON_ID } from './BackButton';
|
|
17
16
|
|
|
18
17
|
const motionVariants = {
|
|
19
18
|
animate: { opacity: 1, x: 0 },
|
|
@@ -78,12 +77,6 @@ const draggableStyles = createStaticStyles(({ css, cssVar }) => ({
|
|
|
78
77
|
width 0.2s ${cssVar.motionEaseOut};
|
|
79
78
|
}
|
|
80
79
|
|
|
81
|
-
#${BACK_BUTTON_ID} {
|
|
82
|
-
width: 0 !important;
|
|
83
|
-
opacity: 0;
|
|
84
|
-
transition: all 0.2s ${cssVar.motionEaseOut};
|
|
85
|
-
}
|
|
86
|
-
|
|
87
80
|
&:hover {
|
|
88
81
|
#${TOGGLE_BUTTON_ID} {
|
|
89
82
|
width: 32px !important;
|
|
@@ -94,13 +87,6 @@ const draggableStyles = createStaticStyles(({ css, cssVar }) => ({
|
|
|
94
87
|
width: 14px !important;
|
|
95
88
|
opacity: 1;
|
|
96
89
|
}
|
|
97
|
-
|
|
98
|
-
&:hover {
|
|
99
|
-
#${BACK_BUTTON_ID} {
|
|
100
|
-
width: 24px !important;
|
|
101
|
-
opacity: 1;
|
|
102
|
-
}
|
|
103
|
-
}
|
|
104
90
|
}
|
|
105
91
|
`,
|
|
106
92
|
}));
|
package/src/features/ResourceManager/components/Explorer/ItemDropdown/useFileItemDropdown.tsx
CHANGED
|
@@ -17,6 +17,7 @@ import { shallow } from 'zustand/shallow';
|
|
|
17
17
|
import RepoIcon from '@/components/LibIcon';
|
|
18
18
|
import { clearTreeFolderCache } from '@/features/ResourceManager/components/LibraryHierarchy';
|
|
19
19
|
import { PAGE_FILE_TYPE } from '@/features/ResourceManager/constants';
|
|
20
|
+
import { useAppOrigin } from '@/hooks/useAppOrigin';
|
|
20
21
|
import { documentService } from '@/services/document';
|
|
21
22
|
import { useFileStore } from '@/store/file';
|
|
22
23
|
import { useKnowledgeBaseStore } from '@/store/library';
|
|
@@ -53,6 +54,7 @@ export const useFileItemDropdown = ({
|
|
|
53
54
|
}: UseFileItemDropdownParams): UseFileItemDropdownReturn => {
|
|
54
55
|
const { t } = useTranslation(['components', 'common', 'knowledgeBase']);
|
|
55
56
|
const { message, modal } = App.useApp();
|
|
57
|
+
const appOrigin = useAppOrigin();
|
|
56
58
|
|
|
57
59
|
const { deleteResource, refreshFileList } = useFileStore(
|
|
58
60
|
(s) => ({
|
|
@@ -184,11 +186,10 @@ export const useFileItemDropdown = ({
|
|
|
184
186
|
// For pages, use the route path instead of the storage URL
|
|
185
187
|
let urlToCopy = url;
|
|
186
188
|
if (isPage) {
|
|
187
|
-
const baseUrl = window.location.origin;
|
|
188
189
|
if (libraryId) {
|
|
189
|
-
urlToCopy = `${
|
|
190
|
+
urlToCopy = `${appOrigin}/resource/library/${libraryId}?file=${id}`;
|
|
190
191
|
} else {
|
|
191
|
-
urlToCopy = `${
|
|
192
|
+
urlToCopy = `${appOrigin}/resource?file=${id}`;
|
|
192
193
|
}
|
|
193
194
|
}
|
|
194
195
|
|
|
@@ -2,11 +2,12 @@
|
|
|
2
2
|
|
|
3
3
|
import { Button, Flexbox, Popover, copyToClipboard, usePopoverContext } from '@lobehub/ui';
|
|
4
4
|
import { App, Divider, Select, Skeleton, Typography } from 'antd';
|
|
5
|
-
import {
|
|
5
|
+
import { ExternalLinkIcon, LinkIcon, LockIcon } from 'lucide-react';
|
|
6
6
|
import { type ReactNode, memo, useCallback, useEffect, useRef, useState } from 'react';
|
|
7
7
|
import { useTranslation } from 'react-i18next';
|
|
8
8
|
import useSWR from 'swr';
|
|
9
9
|
|
|
10
|
+
import { useAppOrigin } from '@/hooks/useAppOrigin';
|
|
10
11
|
import { useIsMobile } from '@/hooks/useIsMobile';
|
|
11
12
|
import { topicService } from '@/services/topic';
|
|
12
13
|
import { useChatStore } from '@/store/chat';
|
|
@@ -26,6 +27,7 @@ const SharePopoverContent = memo<SharePopoverContentProps>(({ onOpenModal }) =>
|
|
|
26
27
|
const [updating, setUpdating] = useState(false);
|
|
27
28
|
const { close } = usePopoverContext();
|
|
28
29
|
const containerRef = useRef<HTMLDivElement>(null);
|
|
30
|
+
const appOrigin = useAppOrigin();
|
|
29
31
|
|
|
30
32
|
const activeTopicId = useChatStore((s) => s.activeTopicId);
|
|
31
33
|
|
|
@@ -46,7 +48,7 @@ const SharePopoverContent = memo<SharePopoverContentProps>(({ onOpenModal }) =>
|
|
|
46
48
|
}
|
|
47
49
|
}, [isLoading, shareInfo, activeTopicId, mutate]);
|
|
48
50
|
|
|
49
|
-
const shareUrl = shareInfo?.id ? `${
|
|
51
|
+
const shareUrl = shareInfo?.id ? `${appOrigin}/share/t/${shareInfo.id}` : '';
|
|
50
52
|
const currentVisibility = (shareInfo?.visibility as Visibility) || 'private';
|
|
51
53
|
|
|
52
54
|
const updateVisibility = useCallback(
|
|
@@ -178,7 +180,7 @@ const SharePopoverContent = memo<SharePopoverContentProps>(({ onOpenModal }) =>
|
|
|
178
180
|
>
|
|
179
181
|
{t('shareModal.popover.moreOptions')}
|
|
180
182
|
</Button>
|
|
181
|
-
<Button icon={
|
|
183
|
+
<Button icon={LinkIcon} onClick={handleCopyLink} size="small" type="primary">
|
|
182
184
|
{t('shareModal.copyLink')}
|
|
183
185
|
</Button>
|
|
184
186
|
</Flexbox>
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
|
|
3
|
+
import { isDesktop } from '@lobechat/const';
|
|
4
|
+
|
|
5
|
+
import { useElectronStore } from '@/store/electron';
|
|
6
|
+
import { electronSyncSelectors } from '@/store/electron/selectors';
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Returns the correct app origin URL for sharing/linking.
|
|
10
|
+
* - Web: uses window.location.origin
|
|
11
|
+
* - Desktop: uses remoteServerUrl from electron store
|
|
12
|
+
*/
|
|
13
|
+
export const useAppOrigin = () => {
|
|
14
|
+
const remoteServerUrl = useElectronStore(electronSyncSelectors.remoteServerUrl);
|
|
15
|
+
return isDesktop ? remoteServerUrl : window.location.origin;
|
|
16
|
+
};
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
|
|
3
|
+
import { type ReactNode, createContext, memo, useCallback, useContext, useState } from 'react';
|
|
4
|
+
|
|
5
|
+
export type FaviconState = 'default' | 'done' | 'error' | 'progress';
|
|
6
|
+
|
|
7
|
+
interface FaviconContextValue {
|
|
8
|
+
currentState: FaviconState;
|
|
9
|
+
isDevMode: boolean;
|
|
10
|
+
setFavicon: (state: FaviconState) => void;
|
|
11
|
+
setIsDevMode: (isDev: boolean) => void;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
const FaviconContext = createContext<FaviconContextValue | null>(null);
|
|
15
|
+
|
|
16
|
+
export const useFavicon = () => {
|
|
17
|
+
const context = useContext(FaviconContext);
|
|
18
|
+
if (!context) {
|
|
19
|
+
throw new Error('useFavicon must be used within FaviconProvider');
|
|
20
|
+
}
|
|
21
|
+
return context;
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
const stateToFileName: Record<FaviconState, string> = {
|
|
25
|
+
default: '',
|
|
26
|
+
done: '-done',
|
|
27
|
+
error: '-error',
|
|
28
|
+
progress: '-progress',
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
const getFaviconPath = (state: FaviconState, isDev: boolean, size?: '32x32'): string => {
|
|
32
|
+
const devSuffix = isDev ? '-dev' : '';
|
|
33
|
+
const stateSuffix = stateToFileName[state];
|
|
34
|
+
const sizeSuffix = size ? `-${size}` : '';
|
|
35
|
+
return `/favicon${sizeSuffix}${stateSuffix}${devSuffix}.ico`;
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
const updateFaviconDOM = (state: FaviconState, isDev: boolean) => {
|
|
39
|
+
if (typeof document === 'undefined') return;
|
|
40
|
+
|
|
41
|
+
const head = document.head;
|
|
42
|
+
const existingLinks = document.querySelectorAll<HTMLLinkElement>(
|
|
43
|
+
'link[rel="icon"], link[rel="shortcut icon"]',
|
|
44
|
+
);
|
|
45
|
+
|
|
46
|
+
// Remove existing favicon links and create new ones to bust cache
|
|
47
|
+
existingLinks.forEach((link) => {
|
|
48
|
+
const oldHref = link.href;
|
|
49
|
+
const is32 = oldHref.includes('32x32');
|
|
50
|
+
const rel = link.rel;
|
|
51
|
+
|
|
52
|
+
// Remove old link
|
|
53
|
+
link.remove();
|
|
54
|
+
|
|
55
|
+
// Create new link with cache-busting query param
|
|
56
|
+
const newLink = document.createElement('link');
|
|
57
|
+
newLink.rel = rel;
|
|
58
|
+
newLink.href = `${getFaviconPath(state, isDev, is32 ? '32x32' : undefined)}?v=${Date.now()}`;
|
|
59
|
+
head.append(newLink);
|
|
60
|
+
});
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
const defaultIsDev = process.env.NODE_ENV === 'development';
|
|
64
|
+
|
|
65
|
+
export const FaviconProvider = memo<{ children: ReactNode }>(({ children }) => {
|
|
66
|
+
const [currentState, setCurrentState] = useState<FaviconState>('default');
|
|
67
|
+
const [isDevMode, setIsDevModeState] = useState<boolean>(defaultIsDev);
|
|
68
|
+
|
|
69
|
+
const setFavicon = useCallback(
|
|
70
|
+
(state: FaviconState) => {
|
|
71
|
+
setCurrentState(state);
|
|
72
|
+
updateFaviconDOM(state, isDevMode);
|
|
73
|
+
},
|
|
74
|
+
[isDevMode],
|
|
75
|
+
);
|
|
76
|
+
|
|
77
|
+
const setIsDevMode = useCallback(
|
|
78
|
+
(isDev: boolean) => {
|
|
79
|
+
setIsDevModeState(isDev);
|
|
80
|
+
updateFaviconDOM(currentState, isDev);
|
|
81
|
+
},
|
|
82
|
+
[currentState],
|
|
83
|
+
);
|
|
84
|
+
|
|
85
|
+
return (
|
|
86
|
+
<FaviconContext.Provider value={{ currentState, isDevMode, setFavicon, setIsDevMode }}>
|
|
87
|
+
{children}
|
|
88
|
+
</FaviconContext.Provider>
|
|
89
|
+
);
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
FaviconProvider.displayName = 'FaviconProvider';
|
|
@@ -14,6 +14,7 @@ import { ServerConfigStoreProvider } from '@/store/serverConfig/Provider';
|
|
|
14
14
|
import { getAntdLocale } from '@/utils/locale';
|
|
15
15
|
|
|
16
16
|
import AppTheme from './AppTheme';
|
|
17
|
+
import { FaviconProvider } from './FaviconProvider';
|
|
17
18
|
import { GroupWizardProvider } from './GroupWizardProvider';
|
|
18
19
|
import ImportSettings from './ImportSettings';
|
|
19
20
|
import Locale from './Locale';
|
|
@@ -65,17 +66,20 @@ const GlobalLayout = async ({
|
|
|
65
66
|
>
|
|
66
67
|
<QueryProvider>
|
|
67
68
|
<StoreInitialization />
|
|
68
|
-
<
|
|
69
|
-
<
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
69
|
+
<FaviconProvider>
|
|
70
|
+
{/* {process.env.NODE_ENV === 'development' && <FaviconTestPanel />} */}
|
|
71
|
+
<GroupWizardProvider>
|
|
72
|
+
<DragUploadProvider>
|
|
73
|
+
<LazyMotion features={domMax}>
|
|
74
|
+
<TooltipGroup layoutAnimation={false}>
|
|
75
|
+
<LobeAnalyticsProviderWrapper>{children}</LobeAnalyticsProviderWrapper>
|
|
76
|
+
</TooltipGroup>
|
|
77
|
+
<ModalHost />
|
|
78
|
+
<ContextMenuHost />
|
|
79
|
+
</LazyMotion>
|
|
80
|
+
</DragUploadProvider>
|
|
81
|
+
</GroupWizardProvider>
|
|
82
|
+
</FaviconProvider>
|
|
79
83
|
</QueryProvider>
|
|
80
84
|
<Suspense>
|
|
81
85
|
{ENABLE_BUSINESS_FEATURES ? <ReferralProvider /> : null}
|
|
@@ -20,43 +20,51 @@ export const useDesktopUserStateRedirect = () => {
|
|
|
20
20
|
const dataSyncConfig = useElectronStore((s) => s.dataSyncConfig);
|
|
21
21
|
const logout = useUserStore((s) => s.logout);
|
|
22
22
|
|
|
23
|
-
const
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
23
|
+
const openExternalAndLogout = useCallback(
|
|
24
|
+
async (path: string) => {
|
|
25
|
+
const baseUrl = dataSyncConfig.remoteServerUrl || OFFICIAL_URL;
|
|
26
|
+
let targetUrl = baseUrl;
|
|
27
|
+
try {
|
|
28
|
+
targetUrl = new URL(path, baseUrl).toString();
|
|
29
|
+
} catch {
|
|
30
|
+
// Ignore: keep fallback URL for external open attempt.
|
|
31
|
+
}
|
|
31
32
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
33
|
+
try {
|
|
34
|
+
const { electronSystemService } = await import('@/services/electron/system');
|
|
35
|
+
await electronSystemService.openExternalLink(targetUrl);
|
|
36
|
+
} catch {
|
|
37
|
+
// Ignore: fallback to logout flow even if IPC is unavailable.
|
|
38
|
+
}
|
|
38
39
|
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
40
|
+
try {
|
|
41
|
+
const { remoteServerService } = await import('@/services/electron/remoteServer');
|
|
42
|
+
await remoteServerService.clearRemoteServerConfig();
|
|
43
|
+
} catch {
|
|
44
|
+
// Ignore: fallback to logout flow even if IPC is unavailable.
|
|
45
|
+
}
|
|
45
46
|
|
|
46
|
-
|
|
47
|
-
|
|
47
|
+
await logout();
|
|
48
|
+
},
|
|
49
|
+
[dataSyncConfig.remoteServerUrl, logout],
|
|
50
|
+
);
|
|
48
51
|
|
|
49
52
|
return useCallback(
|
|
50
53
|
(state: UserInitializationState) => {
|
|
51
54
|
if (state.isInWaitList === true) {
|
|
52
|
-
void
|
|
55
|
+
void openExternalAndLogout('/waitlist');
|
|
56
|
+
return;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
if (state.isInviteCodeRequired === true) {
|
|
60
|
+
void openExternalAndLogout('/invite-code');
|
|
53
61
|
return;
|
|
54
62
|
}
|
|
55
63
|
|
|
56
64
|
if (!getDesktopOnboardingCompleted()) return;
|
|
57
65
|
// Desktop onboarding is handled by desktop-only flow.
|
|
58
66
|
},
|
|
59
|
-
[
|
|
67
|
+
[openExternalAndLogout],
|
|
60
68
|
);
|
|
61
69
|
};
|
|
62
70
|
|
|
@@ -68,6 +76,11 @@ export const useWebUserStateRedirect = () =>
|
|
|
68
76
|
return;
|
|
69
77
|
}
|
|
70
78
|
|
|
79
|
+
if (state.isInviteCodeRequired === true) {
|
|
80
|
+
redirectIfNotOn(pathname, '/invite-code');
|
|
81
|
+
return;
|
|
82
|
+
}
|
|
83
|
+
|
|
71
84
|
if (!onboardingSelectors.needsOnboarding(state)) return;
|
|
72
85
|
|
|
73
86
|
redirectIfNotOn(pathname, '/onboarding');
|
|
@@ -31,14 +31,11 @@ export const generateTrustedClientToken = (userInfo: TrustedClientUserInfo): str
|
|
|
31
31
|
return undefined;
|
|
32
32
|
}
|
|
33
33
|
|
|
34
|
-
if (!userInfo.email) {
|
|
35
|
-
return undefined;
|
|
36
|
-
}
|
|
37
|
-
|
|
38
34
|
try {
|
|
39
35
|
const payload = buildTrustedClientPayload({
|
|
40
36
|
clientId: MARKET_TRUSTED_CLIENT_ID,
|
|
41
|
-
|
|
37
|
+
// TODO: remove '' when sdk update
|
|
38
|
+
email: userInfo.email || '',
|
|
42
39
|
name: userInfo.name,
|
|
43
40
|
userId: userInfo.userId,
|
|
44
41
|
});
|
|
@@ -73,6 +73,7 @@ export default {
|
|
|
73
73
|
'screen4.title2': 'Your choice helps us improve',
|
|
74
74
|
'screen4.title3': 'You can change this anytime in settings',
|
|
75
75
|
|
|
76
|
+
'screen5.actions.cancel': 'Cancel',
|
|
76
77
|
'screen5.actions.connectToServer': 'Connect to Server',
|
|
77
78
|
'screen5.actions.connecting': 'Connecting...',
|
|
78
79
|
'screen5.actions.signInCloud': 'Sign in to LobeHub Cloud',
|
|
@@ -80,6 +81,10 @@ export default {
|
|
|
80
81
|
'screen5.actions.signingIn': 'Signing in...',
|
|
81
82
|
'screen5.actions.signingOut': 'Signing out...',
|
|
82
83
|
'screen5.actions.tryAgain': 'Try Again',
|
|
84
|
+
'screen5.auth.phase.browserOpened': 'Browser opened, please sign in...',
|
|
85
|
+
'screen5.auth.phase.verifying': 'Verifying credentials...',
|
|
86
|
+
'screen5.auth.phase.waitingForAuth': 'Waiting for authorization...',
|
|
87
|
+
'screen5.auth.remaining': 'Remaining: {{time}}s',
|
|
83
88
|
'screen5.badge': 'Sign in',
|
|
84
89
|
'screen5.description':
|
|
85
90
|
'Sign in to sync Agents, Groups, settings, and Context across all devices.',
|
|
@@ -16,6 +16,12 @@ export default {
|
|
|
16
16
|
'import.incompatible.description':
|
|
17
17
|
'This file was exported from a higher version. Please try upgrading to the latest version and then re-importing.',
|
|
18
18
|
'import.incompatible.title': 'Current application does not support importing this file',
|
|
19
|
+
'inviteCode.currentEmail': 'Current account: {{email}}',
|
|
20
|
+
'inviteCode.desc':
|
|
21
|
+
'An invite code is required to access LobeHub. Please enter a valid invite code to continue.',
|
|
22
|
+
'inviteCode.friends': 'Friends',
|
|
23
|
+
'inviteCode.getCodeHint': 'Get an invite code from:',
|
|
24
|
+
'inviteCode.title': 'Invite Code Required',
|
|
19
25
|
'loginRequired.desc': 'You will be redirected to the login page shortly',
|
|
20
26
|
'loginRequired.title': 'Please log in to use this feature',
|
|
21
27
|
'notFound.backHome': 'Back to Home',
|
|
@@ -238,5 +244,10 @@ export default {
|
|
|
238
244
|
'upload.title': 'File upload failed. Please check your network connection or try again later',
|
|
239
245
|
'upload.unknownError': 'Error reason: {{reason}}',
|
|
240
246
|
'upload.uploadFailed': 'File upload failed.',
|
|
247
|
+
'waitlist.currentEmail': 'Current account: {{email}}',
|
|
248
|
+
'waitlist.desc':
|
|
249
|
+
'Your account is not on the whitelist. Please contact the administrator to request access.',
|
|
250
|
+
'waitlist.switchAccount': 'Switch Account',
|
|
251
|
+
'waitlist.title': 'Access Restricted',
|
|
241
252
|
...businessErrorsLocales,
|
|
242
253
|
};
|
|
@@ -328,7 +328,7 @@ export default {
|
|
|
328
328
|
'referral.rules.backfill.expiredTip':
|
|
329
329
|
'Backfill period has expired. Cannot backfill after 3 days of registration',
|
|
330
330
|
'referral.rules.backfill.link': 'Backfill Invite Code',
|
|
331
|
-
'referral.rules.backfill.placeholder': 'Enter invite code',
|
|
331
|
+
'referral.rules.backfill.placeholder': 'Enter invite code or link',
|
|
332
332
|
'referral.rules.backfill.submit': 'Confirm Binding',
|
|
333
333
|
'referral.rules.backfill.success': 'Invite code bound successfully',
|
|
334
334
|
'referral.rules.backfill.title': 'Backfill Invite Code',
|
|
@@ -36,6 +36,7 @@ export interface RuntimeExecutorContext {
|
|
|
36
36
|
stepIndex: number;
|
|
37
37
|
streamManager: IStreamEventManager;
|
|
38
38
|
toolExecutionService: ToolExecutionService;
|
|
39
|
+
topicId?: string;
|
|
39
40
|
userId?: string;
|
|
40
41
|
}
|
|
41
42
|
|
|
@@ -475,6 +476,7 @@ export const createRuntimeExecutors = (
|
|
|
475
476
|
const executionResult = await toolExecutionService.executeTool(chatToolPayload, {
|
|
476
477
|
serverDB: ctx.serverDB,
|
|
477
478
|
toolManifestMap: state.toolManifestMap,
|
|
479
|
+
topicId: ctx.topicId,
|
|
478
480
|
userId: ctx.userId,
|
|
479
481
|
});
|
|
480
482
|
|