Skip to content

Commit 02eba3c

Browse files
authored
✨ feat: support parallel topic agent runtime (#10273)
* add * refactor to support split topic running * refactor to support split topic running * support loading * fix tests * fix tests * fix tests * fix getDbMessageById
1 parent 7461d4e commit 02eba3c

File tree

20 files changed

+1368
-317
lines changed

20 files changed

+1368
-317
lines changed

src/app/[variants]/(main)/chat/components/topic/features/Topic/TopicListContent/TopicItem/TopicContent.tsx

Lines changed: 20 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -97,15 +97,15 @@ const TopicContent = memo<TopicContentProps>(({ id, title, fav, showMore }) => {
9797
},
9898
...(isDesktop
9999
? [
100-
{
101-
icon: <Icon icon={ExternalLink} />,
102-
key: 'openInNewWindow',
103-
label: t('actions.openInNewWindow'),
104-
onClick: () => {
105-
openTopicInNewWindow(activeId, id);
100+
{
101+
icon: <Icon icon={ExternalLink} />,
102+
key: 'openInNewWindow',
103+
label: t('actions.openInNewWindow'),
104+
onClick: () => {
105+
openTopicInNewWindow(activeId, id);
106+
},
106107
},
107-
},
108-
]
108+
]
109109
: []),
110110
{
111111
type: 'divider',
@@ -153,7 +153,16 @@ const TopicContent = memo<TopicContentProps>(({ id, title, fav, showMore }) => {
153153
},
154154
},
155155
],
156-
[id, activeId, autoRenameTopicTitle, duplicateTopic, removeTopic, t, toggleEditing, openTopicInNewWindow],
156+
[
157+
id,
158+
activeId,
159+
autoRenameTopicTitle,
160+
duplicateTopic,
161+
removeTopic,
162+
t,
163+
toggleEditing,
164+
openTopicInNewWindow,
165+
],
157166
);
158167

159168
return (
@@ -180,7 +189,7 @@ const TopicContent = memo<TopicContentProps>(({ id, title, fav, showMore }) => {
180189
spin={isLoading}
181190
/>
182191
{!editing ? (
183-
title === LOADING_FLAT ? (
192+
title === LOADING_FLAT || (isLoading && !title) ? (
184193
<Flexbox flex={1} height={28} justify={'center'}>
185194
<BubblesLoading />
186195
</Flexbox>
@@ -190,7 +199,7 @@ const TopicContent = memo<TopicContentProps>(({ id, title, fav, showMore }) => {
190199
ellipsis={{ rows: 1, tooltip: { placement: 'left', title } }}
191200
onDoubleClick={() => {
192201
if (isDesktop) {
193-
openTopicInNewWindow(activeId, id)
202+
openTopicInNewWindow(activeId, id);
194203
}
195204
}}
196205
style={{ margin: 0 }}

src/app/[variants]/layout.tsx

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { SpeedInsights } from '@vercel/speed-insights/next';
22
import { ThemeAppearance } from 'antd-style';
33
import { ResolvingViewport } from 'next';
4+
import { NuqsAdapter } from 'nuqs/adapters/next/app';
45
import { ReactNode } from 'react';
56
import { isRtlLang } from 'rtl-detect';
67

@@ -13,16 +14,14 @@ import GlobalProvider from '@/layout/GlobalProvider';
1314
import { Locales } from '@/locales/resources';
1415
import { DynamicLayoutProps } from '@/types/next';
1516
import { RouteVariants } from '@/utils/server/routeVariants';
16-
import { NuqsAdapter } from 'nuqs/adapters/next/app';
1717

1818
const inVercel = process.env.VERCEL === '1';
1919

2020
interface RootLayoutProps extends DynamicLayoutProps {
2121
children: ReactNode;
22-
modal: ReactNode;
2322
}
2423

25-
const RootLayout = async ({ children, params, modal }: RootLayoutProps) => {
24+
const RootLayout = async ({ children, params }: RootLayoutProps) => {
2625
const { variants } = await params;
2726

2827
const { locale, isMobile, theme, primaryColor, neutralColor } =
@@ -50,7 +49,6 @@ const RootLayout = async ({ children, params, modal }: RootLayoutProps) => {
5049
>
5150
<AuthProvider>
5251
{children}
53-
{!isMobile && modal}
5452
</AuthProvider>
5553
<PWAInstall />
5654
</GlobalProvider>

src/services/message/index.ts

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -77,12 +77,21 @@ export class MessageService {
7777
return lambdaClient.message.getHeatmaps.query();
7878
};
7979

80-
updateMessageError = async (id: string, value: ChatMessageError) => {
80+
updateMessageError = async (
81+
id: string,
82+
value: ChatMessageError,
83+
options?: { sessionId?: string | null; topicId?: string | null },
84+
) => {
8185
const error = value.type
8286
? value
8387
: { body: value, message: value.message, type: 'ApplicationRuntimeError' };
8488

85-
return lambdaClient.message.update.mutate({ id, value: { error } });
89+
return lambdaClient.message.update.mutate({
90+
id,
91+
sessionId: options?.sessionId,
92+
topicId: options?.topicId,
93+
value: { error },
94+
});
8695
};
8796

8897
updateMessagePluginArguments = async (id: string, value: string | Record<string, any>) => {

src/store/chat/agents/createAgentExecutors.ts

Lines changed: 31 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import type { ChatToolPayload, CreateMessageParams } from '@lobechat/types';
1515
import debug from 'debug';
1616
import pMap from 'p-map';
1717

18+
import { LOADING_FLAT } from '@/const/message';
1819
import type { ChatStore } from '@/store/chat/store';
1920

2021
const log = debug('lobe-store:agent-executors');
@@ -36,7 +37,9 @@ export const createAgentExecutors = (context: {
3637
inPortalThread?: boolean;
3738
inSearchWorkflow?: boolean;
3839
ragQuery?: string;
40+
sessionId?: string;
3941
threadId?: string;
42+
topicId?: string | null;
4043
traceId?: string;
4144
};
4245
parentId: string;
@@ -75,16 +78,22 @@ export const createAgentExecutors = (context: {
7578
llmPayload.parentMessageId = context.parentId;
7679
}
7780
// Create assistant message (following server-side pattern)
78-
const assistantMessageItem = await context.get().optimisticCreateMessage({
79-
content: '',
80-
model: llmPayload.model,
81-
parentId: llmPayload.parentMessageId,
82-
provider: llmPayload.provider,
83-
role: 'assistant',
84-
sessionId: state.metadata!.sessionId!,
85-
threadId: state.metadata?.threadId,
86-
topicId: state.metadata?.topicId,
87-
});
81+
const assistantMessageItem = await context.get().optimisticCreateMessage(
82+
{
83+
content: LOADING_FLAT,
84+
model: llmPayload.model,
85+
parentId: llmPayload.parentMessageId,
86+
provider: llmPayload.provider,
87+
role: 'assistant',
88+
sessionId: state.metadata!.sessionId!,
89+
threadId: state.metadata?.threadId,
90+
topicId: state.metadata?.topicId,
91+
},
92+
{
93+
sessionId: state.metadata!.sessionId!,
94+
topicId: state.metadata?.topicId,
95+
},
96+
);
8897

8998
if (!assistantMessageItem) {
9099
throw new Error('Failed to create assistant message');
@@ -269,13 +278,16 @@ export const createAgentExecutors = (context: {
269278
parentId: payload.parentMessageId,
270279
plugin: chatToolPayload,
271280
role: 'tool',
272-
sessionId: context.get().activeId,
281+
sessionId: state.metadata!.sessionId!,
273282
threadId: context.params.threadId,
274283
tool_call_id: chatToolPayload.id,
275-
topicId: context.get().activeTopicId,
284+
topicId: state.metadata?.topicId,
276285
};
277286

278-
const createResult = await context.get().optimisticCreateMessage(toolMessageParams);
287+
const createResult = await context.get().optimisticCreateMessage(toolMessageParams, {
288+
sessionId: state.metadata!.sessionId!,
289+
topicId: state.metadata?.topicId,
290+
});
279291

280292
if (!createResult) {
281293
log(
@@ -450,13 +462,16 @@ export const createAgentExecutors = (context: {
450462
},
451463
pluginIntervention: { status: 'pending' },
452464
role: 'tool',
453-
sessionId: context.get().activeId,
465+
sessionId: state.metadata!.sessionId!,
454466
threadId: context.params.threadId,
455467
tool_call_id: toolPayload.id,
456-
topicId: context.get().activeTopicId,
468+
topicId: state.metadata?.topicId,
457469
};
458470

459-
const createResult = await context.get().optimisticCreateMessage(toolMessageParams);
471+
const createResult = await context.get().optimisticCreateMessage(toolMessageParams, {
472+
sessionId: state.metadata!.sessionId!,
473+
topicId: state.metadata?.topicId,
474+
});
460475

461476
if (!createResult) {
462477
log(

0 commit comments

Comments
 (0)