🐛 fix: try to fix group supervisor id not sync successful (#11570)

* improve code

* fix share button suspense

* update streaming issue

* improve

* fix share button issue

* fix store sync
This commit is contained in:
Arvin Xu
2026-01-18 01:10:43 +08:00
committed by GitHub
parent dea1b25e2d
commit ef51c17f59
10 changed files with 97 additions and 23 deletions

View File

@@ -0,0 +1,27 @@
'use client';
import type { BuiltinStreamingProps } from '@lobechat/types';
import { Block, Markdown } from '@lobehub/ui';
import { memo } from 'react';
import type { UpdatePromptParams } from '../../../types';
export const UpdatePromptStreaming = memo<BuiltinStreamingProps<UpdatePromptParams>>(
({ args }) => {
const { prompt } = args || {};
if (!prompt) return null;
return (
<Block paddingBlock={8} paddingInline={12} variant={'outlined'} width="100%">
<Markdown animated variant={'chat'}>
{prompt}
</Markdown>
</Block>
);
},
);
UpdatePromptStreaming.displayName = 'UpdatePromptStreaming';
export default UpdatePromptStreaming;

View File

@@ -0,0 +1,16 @@
import type { BuiltinStreaming } from '@lobechat/types';
import { AgentBuilderApiName } from '../../types';
import { UpdatePromptStreaming } from './UpdatePrompt';
/**
* Agent Builder Streaming Components Registry
*
* Streaming components render tool calls while they are
* still executing, allowing real-time feedback to users.
*/
export const AgentBuilderStreamings: Record<string, BuiltinStreaming> = {
[AgentBuilderApiName.updatePrompt]: UpdatePromptStreaming as BuiltinStreaming,
};
export { UpdatePromptStreaming } from './UpdatePrompt';

View File

@@ -14,6 +14,9 @@ export { AgentBuilderInterventions } from './Intervention';
// Render components (read-only snapshots)
export { AgentBuilderRenders } from './Render';
// Streaming components (real-time tool execution feedback)
export { AgentBuilderStreamings } from './Streaming';
// Re-export types and manifest for convenience
export { AgentBuilderManifest } from '../manifest';
export * from '../types';

View File

@@ -26,8 +26,12 @@ const AgentIdSync = () => {
// Clear activeAgentId when unmounting (leaving chat page)
useUnmount(() => {
useAgentStore.setState({ activeAgentId: undefined });
useChatStore.setState({ activeAgentId: undefined, activeTopicId: undefined });
useAgentStore.setState({ activeAgentId: undefined }, false, 'AgentIdSync/unmountAgentId');
useChatStore.setState(
{ activeAgentId: undefined, activeTopicId: undefined },
false,
'AgentIdSync/unmountAgentId',
);
});
return null;

View File

@@ -6,6 +6,7 @@ import dynamic from 'next/dynamic';
import { memo } from 'react';
import { useTranslation } from 'react-i18next';
import { withSuspense } from '@/components/withSuspense';
import { DESKTOP_HEADER_ICON_SIZE, MOBILE_HEADER_ICON_SIZE } from '@/const/layoutTokens';
import { useWorkspaceModal } from '@/hooks/useWorkspaceModal';
import { useChatStore } from '@/store/chat';
@@ -54,4 +55,4 @@ const ShareButton = memo<ShareButtonProps>(({ mobile, setOpen, open }) => {
);
});
export default ShareButton;
export default withSuspense(ShareButton);

View File

@@ -1,7 +1,8 @@
import { Flexbox, TooltipGroup } from '@lobehub/ui';
import React, { memo } from 'react';
import React, { Suspense, memo } from 'react';
import DragUploadZone, { useUploadFiles } from '@/components/DragUploadZone';
import Loading from '@/components/Loading/BrandTextLoading';
import { useAgentStore } from '@/store/agent';
import { agentSelectors } from '@/store/agent/selectors';
import { useGlobalStore } from '@/store/global';
@@ -25,14 +26,20 @@ const ChatConversation = memo(() => {
const { handleUploadFiles } = useUploadFiles({ model, provider });
return (
<DragUploadZone onUploadFiles={handleUploadFiles} style={wrapperStyle}>
<Flexbox height={'100%'} style={{ overflow: 'hidden', position: 'relative' }} width={'100%'}>
{showHeader && <ChatHeader />}
<TooltipGroup>
<ConversationArea />
</TooltipGroup>
</Flexbox>
</DragUploadZone>
<Suspense fallback={<Loading debugId="Agent > ChatConversation" />}>
<DragUploadZone onUploadFiles={handleUploadFiles} style={wrapperStyle}>
<Flexbox
height={'100%'}
style={{ overflow: 'hidden', position: 'relative' }}
width={'100%'}
>
{showHeader && <ChatHeader />}
<TooltipGroup>
<ConversationArea />
</TooltipGroup>
</Flexbox>
</DragUploadZone>
</Suspense>
);
});

View File

@@ -10,7 +10,7 @@ import { parseAsString, useQueryState } from '@/hooks/useQueryParam';
import { useChatStore } from '@/store/chat';
import { useGroupProfileStore } from '@/store/groupProfile';
const ProfileHydration = memo(() => {
const StoreSync = memo(() => {
const editor = useEditor();
const editorState = useEditorState(editor);
const flushSave = useGroupProfileStore((s) => s.flushSave);
@@ -32,6 +32,11 @@ const ProfileHydration = memo(() => {
useEffect(() => {
const urlTopicId = builderTopicId ?? undefined;
useChatStore.setState({ activeTopicId: urlTopicId });
return () => {
// Clear activeTopicId when unmounting (leaving group profile page)
useChatStore.setState({ activeTopicId: undefined }, false, 'GroupProfileUnmounted');
};
}, [builderTopicId]);
// Register hotkeys
@@ -40,15 +45,19 @@ const ProfileHydration = memo(() => {
// Clear state when unmounting
useUnmount(() => {
useGroupProfileStore.setState({
activeTabId: 'group',
editor: undefined,
editorState: undefined,
saveStateMap: {},
});
useGroupProfileStore.setState(
{
activeTabId: 'group',
editor: undefined,
editorState: undefined,
saveStateMap: {},
},
false,
'GroupProfileUnmounted',
);
});
return null;
});
export default ProfileHydration;
export default StoreSync;

View File

@@ -9,11 +9,11 @@ import { useAgentGroupStore } from '@/store/agentGroup';
import { agentGroupSelectors } from '@/store/agentGroup/selectors';
import { useGroupProfileStore } from '@/store/groupProfile';
import StoreSync from './StoreSync';
import AgentBuilder from './features/AgentBuilder';
import GroupProfileSettings from './features/GroupProfile';
import Header from './features/Header';
import MemberProfile from './features/MemberProfile';
import ProfileHydration from './features/ProfileHydration';
const ProfileArea = memo(() => {
const editor = useGroupProfileStore((s) => s.editor);
@@ -51,7 +51,7 @@ const ProfileArea = memo(() => {
const GroupProfile: FC = () => {
return (
<Suspense fallback={<Loading debugId="GroupProfile" />}>
<ProfileHydration />
<StoreSync />
<Flexbox height={'100%'} horizontal width={'100%'}>
<ProfileArea />
<AgentBuilder />

View File

@@ -37,7 +37,9 @@ const TopicSelector = memo<TopicSelectorProps>(({ agentId }) => {
const { t } = useTranslation('topic');
// Fetch topics for the agent builder
useChatStore((s) => s.useFetchTopics)(true, { agentId });
const useFetchTopics = useChatStore((s) => s.useFetchTopics);
useFetchTopics(true, { agentId });
const [activeTopicId, switchTopic, topics] = useChatStore((s) => [
s.activeTopicId,

View File

@@ -1,3 +1,7 @@
import {
AgentBuilderManifest,
AgentBuilderStreamings,
} from '@lobechat/builtin-tool-agent-builder/client';
import {
CloudSandboxManifest,
CloudSandboxStreamings,
@@ -28,6 +32,7 @@ import { type BuiltinStreaming } from '@lobechat/types';
* The component should fetch streaming content from store internally.
*/
const BuiltinToolStreamings: Record<string, Record<string, BuiltinStreaming>> = {
[AgentBuilderManifest.identifier]: AgentBuilderStreamings as Record<string, BuiltinStreaming>,
[CloudSandboxManifest.identifier]: CloudSandboxStreamings as Record<string, BuiltinStreaming>,
[GroupAgentBuilderManifest.identifier]: GroupAgentBuilderStreamings as Record<
string,