@lobehub/lobehub 2.0.0-next.280 → 2.0.0-next.281

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.
Files changed (36) hide show
  1. package/CHANGELOG.md +25 -0
  2. package/changelog/v1.json +9 -0
  3. package/e2e/src/steps/agent/conversation-mgmt.steps.ts +47 -3
  4. package/package.json +1 -1
  5. package/packages/builtin-tool-group-agent-builder/src/client/Render/BatchCreateAgents.tsx +19 -3
  6. package/packages/builtin-tool-group-agent-builder/src/client/Streaming/BatchCreateAgents/index.tsx +19 -4
  7. package/packages/builtin-tool-group-agent-builder/src/client/Streaming/UpdateAgentPrompt/index.tsx +3 -13
  8. package/packages/builtin-tool-group-agent-builder/src/client/Streaming/UpdateGroupPrompt/index.tsx +1 -1
  9. package/packages/builtin-tool-group-agent-builder/src/systemRole.ts +83 -121
  10. package/src/app/[variants]/(main)/agent/_layout/Sidebar/Topic/List/Item/index.tsx +9 -1
  11. package/src/app/[variants]/(main)/agent/features/Conversation/ConversationArea.tsx +1 -28
  12. package/src/app/[variants]/(main)/community/(detail)/features/MakedownRender.tsx +3 -3
  13. package/src/app/[variants]/(main)/group/_layout/Sidebar/GroupConfig/GroupMember.tsx +8 -1
  14. package/src/app/[variants]/(main)/group/_layout/Sidebar/GroupConfig/Header/Avatar.tsx +2 -13
  15. package/src/app/[variants]/(main)/group/_layout/Sidebar/Header/Agent/index.tsx +3 -4
  16. package/src/app/[variants]/(main)/group/_layout/Sidebar/Topic/List/Item/index.tsx +17 -8
  17. package/src/app/[variants]/(main)/group/features/Conversation/ConversationArea.tsx +1 -29
  18. package/src/app/[variants]/(main)/group/features/Conversation/Header/ShareButton/index.tsx +0 -2
  19. package/src/app/[variants]/(main)/group/features/GroupAvatar.tsx +17 -9
  20. package/src/app/[variants]/(main)/group/profile/features/AgentBuilder/TopicSelector.tsx +8 -5
  21. package/src/app/[variants]/(main)/group/profile/features/Header/ChromeTabs/index.tsx +20 -2
  22. package/src/app/[variants]/(main)/group/profile/features/MemberProfile/AgentTool.tsx +4 -2
  23. package/src/app/[variants]/(main)/group/profile/features/ProfileHydration.tsx +5 -25
  24. package/src/features/AgentGroupAvatar/index.tsx +38 -0
  25. package/src/features/Conversation/Messages/Supervisor/index.tsx +8 -2
  26. package/src/features/Conversation/Messages/User/useMarkdown.tsx +1 -2
  27. package/src/features/NavPanel/components/EmptyNavItem.tsx +2 -2
  28. package/src/features/NavPanel/components/NavItem.tsx +27 -3
  29. package/src/features/ToolTag/index.tsx +167 -0
  30. package/src/server/routers/lambda/topic.ts +8 -1
  31. package/src/services/chat/mecha/contextEngineering.test.ts +1 -1
  32. package/src/services/chat/mecha/contextEngineering.ts +3 -4
  33. package/src/services/chat/mecha/memoryManager.ts +9 -38
  34. package/src/store/agentGroup/initialState.ts +1 -1
  35. package/src/store/agentGroup/slices/lifecycle.ts +15 -2
  36. package/src/app/[variants]/(main)/group/_layout/Sidebar/Topic/hooks/useTopicNavigation.ts +0 -49
package/CHANGELOG.md CHANGED
@@ -2,6 +2,31 @@
2
2
 
3
3
  # Changelog
4
4
 
5
+ ## [Version 2.0.0-next.281](https://github.com/lobehub/lobe-chat/compare/v2.0.0-next.280...v2.0.0-next.281)
6
+
7
+ <sup>Released on **2026-01-14**</sup>
8
+
9
+ #### 🐛 Bug Fixes
10
+
11
+ - **misc**: Fix group ux and memory retriever.
12
+
13
+ <br/>
14
+
15
+ <details>
16
+ <summary><kbd>Improvements and Fixes</kbd></summary>
17
+
18
+ #### What's fixed
19
+
20
+ - **misc**: Fix group ux and memory retriever, closes [#11481](https://github.com/lobehub/lobe-chat/issues/11481) ([033ca92](https://github.com/lobehub/lobe-chat/commit/033ca92))
21
+
22
+ </details>
23
+
24
+ <div align="right">
25
+
26
+ [![](https://img.shields.io/badge/-BACK_TO_TOP-151515?style=flat-square)](#readme-top)
27
+
28
+ </div>
29
+
5
30
  ## [Version 2.0.0-next.280](https://github.com/lobehub/lobe-chat/compare/v2.0.0-next.279...v2.0.0-next.280)
6
31
 
7
32
  <sup>Released on **2026-01-13**</sup>
package/changelog/v1.json CHANGED
@@ -1,4 +1,13 @@
1
1
  [
2
+ {
3
+ "children": {
4
+ "fixes": [
5
+ "Fix group ux and memory retriever."
6
+ ]
7
+ },
8
+ "date": "2026-01-14",
9
+ "version": "2.0.0-next.281"
10
+ },
2
11
  {
3
12
  "children": {
4
13
  "improvements": [
@@ -124,9 +124,41 @@ When('用户点击新建对话按钮', async function (this: CustomWorld) {
124
124
  When('用户点击另一个对话', async function (this: CustomWorld) {
125
125
  console.log(' 📍 Step: 点击另一个对话...');
126
126
 
127
- // Find topic items in the sidebar
127
+ // Check if we're on the home page (has Recent Topics section)
128
+ const recentTopicsSection = this.page.locator('text=Recent Topics');
129
+ const isOnHomePage = (await recentTopicsSection.count()) > 0;
130
+ console.log(` 📍 Is on home page: ${isOnHomePage}`);
131
+
132
+ if (isOnHomePage) {
133
+ // Click the second topic card in Recent Topics section
134
+ // Cards are wrapped in Link components and contain "Hello! I am a mock AI" text from the mock
135
+ const recentTopicCards = this.page.locator('a[href*="topic="]');
136
+ const cardCount = await recentTopicCards.count();
137
+ console.log(` 📍 Found ${cardCount} recent topic cards (by href)`);
138
+
139
+ if (cardCount >= 2) {
140
+ // Click the second card (different from current topic)
141
+ await recentTopicCards.nth(1).click();
142
+ console.log(' ✅ 已点击首页 Recent Topics 中的另一个对话');
143
+ await this.page.waitForTimeout(2000);
144
+ return;
145
+ }
146
+
147
+ // Fallback: try to find by text content
148
+ const topicTextCards = this.page.locator('text=Hello! I am a mock AI');
149
+ const textCardCount = await topicTextCards.count();
150
+ console.log(` 📍 Found ${textCardCount} topic cards by text`);
151
+
152
+ if (textCardCount >= 2) {
153
+ await topicTextCards.nth(1).click();
154
+ console.log(' ✅ 已点击首页 Recent Topics 中的另一个对话 (by text)');
155
+ await this.page.waitForTimeout(2000);
156
+ return;
157
+ }
158
+ }
159
+
160
+ // Fallback: try to find topic items in the sidebar
128
161
  // Topics are displayed with star icons (lucide-star) in the left sidebar
129
- // Each topic item has a star icon as part of it
130
162
  const sidebarTopics = this.page.locator('svg.lucide-star').locator('..').locator('..');
131
163
  let topicCount = await sidebarTopics.count();
132
164
  console.log(` 📍 Found ${topicCount} topics with star icons`);
@@ -505,8 +537,20 @@ Then('应该切换到该对话', async function (this: CustomWorld) {
505
537
  Then('显示该对话的历史消息', async function (this: CustomWorld) {
506
538
  console.log(' 📍 Step: 验证显示历史消息...');
507
539
 
540
+ // Wait for the loading to finish - the messages need time to load after switching topics
541
+ console.log(' 📍 等待消息加载...');
542
+ await this.page.waitForTimeout(2000);
543
+
544
+ // Wait for the message wrapper to appear (ChatItem component uses message-wrapper class)
545
+ const messageSelector = '.message-wrapper';
546
+ try {
547
+ await this.page.waitForSelector(messageSelector, { timeout: 10_000 });
548
+ } catch {
549
+ console.log(' ⚠️ 等待消息选择器超时,尝试备用选择器...');
550
+ }
551
+
508
552
  // There should be messages in the chat area
509
- const messages = this.page.locator('[class*="message"], [data-role]');
553
+ const messages = this.page.locator(messageSelector);
510
554
  const messageCount = await messages.count();
511
555
 
512
556
  console.log(` 📍 找到 ${messageCount} 条消息`);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lobehub/lobehub",
3
- "version": "2.0.0-next.280",
3
+ "version": "2.0.0-next.281",
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",
@@ -7,6 +7,8 @@ import { Users } from 'lucide-react';
7
7
  import { memo } from 'react';
8
8
  import { useTranslation } from 'react-i18next';
9
9
 
10
+ import ToolTag from '@/features/ToolTag';
11
+
10
12
  import type { BatchCreateAgentsParams, BatchCreateAgentsState } from '../../types';
11
13
 
12
14
  const styles = createStaticStyles(({ css, cssVar }) => ({
@@ -58,19 +60,33 @@ interface AgentItemProps {
58
60
  avatar?: string;
59
61
  description?: string;
60
62
  title: string;
63
+ tools?: string[];
61
64
  };
62
65
  }
63
66
 
64
67
  const AgentItem = memo<AgentItemProps>(({ agent, definition }) => {
65
68
  const avatar = definition?.avatar;
66
69
  const description = definition?.description;
70
+ const tools = definition?.tools;
67
71
 
68
72
  return (
69
- <Flexbox align="center" className={styles.item} gap={12} horizontal>
70
- <Avatar avatar={avatar} size={24} style={{ flexShrink: 0 }} title={agent.title} />
71
- <Flexbox flex={1} gap={2} style={{ minWidth: 0, overflow: 'hidden' }}>
73
+ <Flexbox align="flex-start" className={styles.item} gap={12} horizontal>
74
+ <Avatar
75
+ avatar={avatar}
76
+ size={24}
77
+ style={{ flexShrink: 0, marginTop: 4 }}
78
+ title={agent.title}
79
+ />
80
+ <Flexbox flex={1} gap={4} style={{ minWidth: 0, overflow: 'hidden' }}>
72
81
  <span className={styles.title}>{agent.title}</span>
73
82
  {description && <span className={styles.description}>{description}</span>}
83
+ {tools && tools.length > 0 && (
84
+ <Flexbox gap={4} horizontal style={{ marginTop: 8 }} wrap={'wrap'}>
85
+ {tools.map((tool) => (
86
+ <ToolTag identifier={tool} key={tool} variant={'compact'} />
87
+ ))}
88
+ </Flexbox>
89
+ )}
74
90
  </Flexbox>
75
91
  </Flexbox>
76
92
  );
@@ -2,9 +2,12 @@
2
2
 
3
3
  import type { BuiltinStreamingProps } from '@lobechat/types';
4
4
  import { Avatar, Block, Flexbox, Markdown } from '@lobehub/ui';
5
+ import { Divider } from 'antd';
5
6
  import { createStaticStyles } from 'antd-style';
6
7
  import { memo } from 'react';
7
8
 
9
+ import ToolTag from '@/features/ToolTag';
10
+
8
11
  import type { BatchCreateAgentsParams } from '../../../types';
9
12
 
10
13
  const styles = createStaticStyles(({ css, cssVar }) => ({
@@ -12,9 +15,8 @@ const styles = createStaticStyles(({ css, cssVar }) => ({
12
15
  overflow: hidden;
13
16
  display: -webkit-box;
14
17
  -webkit-box-orient: vertical;
15
- -webkit-line-clamp: 2;
18
+ -webkit-line-clamp: 1;
16
19
 
17
- font-size: 12px;
18
20
  line-height: 1.5;
19
21
  color: ${cssVar.colorTextDescription};
20
22
  text-overflow: ellipsis;
@@ -62,12 +64,25 @@ export const BatchCreateAgentsStreaming = memo<BuiltinStreamingProps<BatchCreate
62
64
  return (
63
65
  <Block variant={'outlined'} width="100%">
64
66
  {agents.map((agent, index) => (
65
- <Flexbox className={styles.item} gap={8} horizontal key={index}>
67
+ <Flexbox align={'flex-start'} className={styles.item} gap={8} horizontal key={index}>
66
68
  <div className={styles.index}>{index + 1}.</div>
67
- <Avatar avatar={agent.avatar} size={24} style={{ flexShrink: 0 }} title={agent.title} />
69
+ <Avatar
70
+ avatar={agent.avatar}
71
+ size={24}
72
+ style={{ flexShrink: 0, marginTop: 4 }}
73
+ title={agent.title}
74
+ />
68
75
  <Flexbox flex={1} gap={4} style={{ minWidth: 0, overflow: 'hidden' }}>
69
76
  <span className={styles.title}>{agent.title}</span>
70
77
  {agent.description && <span className={styles.description}>{agent.description}</span>}
78
+ {agent.tools && agent.tools.length > 0 && (
79
+ <Flexbox gap={4} horizontal style={{ marginTop: 8 }} wrap={'wrap'}>
80
+ {agent.tools.map((tool) => (
81
+ <ToolTag identifier={tool} key={tool} />
82
+ ))}
83
+ </Flexbox>
84
+ )}
85
+ <Divider />
71
86
  {agent.systemRole && (
72
87
  <div className={styles.systemRole}>
73
88
  <Markdown animated variant={'chat'}>
@@ -2,28 +2,18 @@
2
2
 
3
3
  import type { BuiltinStreamingProps } from '@lobechat/types';
4
4
  import { Block, Markdown } from '@lobehub/ui';
5
- import { memo, useEffect } from 'react';
6
-
7
- import { useGroupProfileStore } from '@/store/groupProfile';
5
+ import { memo } from 'react';
8
6
 
9
7
  import type { UpdateAgentPromptParams } from '../../../types';
10
8
 
11
9
  export const UpdateAgentPromptStreaming = memo<BuiltinStreamingProps<UpdateAgentPromptParams>>(
12
10
  ({ args }) => {
13
- const { agentId, prompt } = args || {};
14
- const setActiveTabId = useGroupProfileStore((s) => s.setActiveTabId);
15
-
16
- // Switch to agent tab when streaming agent prompt
17
- useEffect(() => {
18
- if (agentId) {
19
- setActiveTabId(agentId);
20
- }
21
- }, [agentId, setActiveTabId]);
11
+ const { prompt } = args || {};
22
12
 
23
13
  if (!prompt) return null;
24
14
 
25
15
  return (
26
- <Block padding={4} variant={'outlined'} width="100%">
16
+ <Block paddingBlock={8} paddingInline={12} variant={'outlined'} width="100%">
27
17
  <Markdown animated variant={'chat'}>
28
18
  {prompt}
29
19
  </Markdown>
@@ -21,7 +21,7 @@ export const UpdateGroupPromptStreaming = memo<BuiltinStreamingProps<UpdateGroup
21
21
  if (!prompt) return null;
22
22
 
23
23
  return (
24
- <Block padding={4} variant={'outlined'} width="100%">
24
+ <Block paddingBlock={8} paddingInline={12} variant={'outlined'} width="100%">
25
25
  <Markdown animated variant={'chat'}>
26
26
  {prompt}
27
27
  </Markdown>
@@ -141,29 +141,48 @@ When creating agents (via \`createAgent\` or \`batchCreateAgents\`), you MUST an
141
141
  </agent_tools_assignment>
142
142
 
143
143
  <workflow>
144
+ **CRITICAL: Follow this execution order strictly when setting up or modifying a group:**
145
+
144
146
  1. **Understand the request**: Listen carefully to what the user wants to configure
145
147
  2. **Reference injected context**: Use the \`<current_group_context>\` to understand current state - no need to call read APIs
146
- 3. **Distinguish prompt types**: Determine if the user wants to modify shared content (group prompt) or a specific agent's behavior (agent prompt)
147
- 4. **Make targeted changes**: Use the appropriate API based on whether you're modifying the group or a specific agent
148
- 5. **Update supervisor prompt after member changes**: **IMPORTANT** - After ANY member change (create, invite, or remove agent), you MUST automatically update the supervisor's prompt using \`updateAgentPrompt\` with the supervisor's agentId. Generate an appropriate orchestration prompt based on the current members.
149
- 6. **Confirm changes**: Report what was changed and the new values
148
+
149
+ **Execution Order (MUST follow this sequence):**
150
+
151
+ 3. **Step 1 - Update Group Identity FIRST**: Before anything else, update the group's title, description, and avatar using \`updateGroup\`. This establishes the group's identity and purpose.
152
+
153
+ 4. **Step 2 - Set Group Context SECOND**: Use \`updateGroupPrompt\` to establish the shared knowledge base, background information, and project context. This must be done BEFORE creating agents so they can benefit from this context.
154
+
155
+ 5. **Step 3 - Create/Invite Agents THIRD**: Only after steps 1 and 2 are complete, proceed to create or invite agents using \`createAgent\`, \`batchCreateAgents\`, or \`inviteAgent\`.
156
+
157
+ 6. **Step 4 - Update Supervisor Prompt**: After ANY member change (create, invite, or remove agent), you MUST automatically update the supervisor's prompt using \`updateAgentPrompt\` with the supervisor's agentId. Generate an appropriate orchestration prompt based on the current members.
158
+
159
+ 7. **Step 5 - Configure Additional Settings**: Set opening message, opening questions, and other configurations using \`updateGroup\`.
160
+
161
+ 8. **Confirm changes**: Report what was changed and the new values
162
+
163
+ **Why this order matters:**
164
+ - Group identity (title/avatar) helps users understand the group's purpose immediately
165
+ - Group context provides the foundation that all agents will reference
166
+ - Agents created after context is set can leverage that shared knowledge
167
+ - Supervisor prompt should reflect the final team composition
150
168
  </workflow>
151
169
 
152
170
  <guidelines>
153
- 1. **Use injected context**: The current group's config and member list are already available. Reference them directly instead of calling read APIs.
154
- 2. **Distinguish group vs agent prompts**:
171
+ 1. **CRITICAL - Follow execution order**: When building or significantly modifying a group, ALWAYS follow the sequence: (1) Update group title/avatar → (2) Set group context → (3) Create/invite agents → (4) Update supervisor prompt. Never create agents before setting the group identity and context.
172
+ 2. **Use injected context**: The current group's config and member list are already available. Reference them directly instead of calling read APIs.
173
+ 3. **Distinguish group vs agent prompts**:
155
174
  - Group prompt: Shared content for all members, NO member info needed (auto-injected)
156
175
  - Agent prompt: Individual agent's system role (supervisor or member), requires agentId
157
- 3. **Distinguish group vs agent operations**:
176
+ 4. **Distinguish group vs agent operations**:
158
177
  - Group-level: updateGroupPrompt, updateGroup, inviteAgent, removeAgent, batchCreateAgents
159
178
  - Agent-level: updateAgentPrompt (requires agentId), updateConfig (agentId optional, defaults to supervisor), installPlugin
160
- 4. **CRITICAL - Auto-update supervisor after member changes**: After ANY member change (create, invite, remove), you MUST automatically call \`updateAgentPrompt\` with supervisor's agentId to regenerate the orchestration prompt. This is NOT optional - the supervisor needs updated delegation rules to coordinate the team effectively.
161
- 5. **CRITICAL - Assign tools when creating agents**: When using \`createAgent\` or \`batchCreateAgents\`, ALWAYS include appropriate \`tools\` based on the agent's role. Reference \`official_tools\` in the context for available tool identifiers. An agent without proper tools cannot perform specialized tasks.
162
- 6. **Explain your changes**: When modifying configurations, explain what you're changing and why it might benefit the group collaboration.
163
- 7. **Validate user intent**: For significant changes (like removing an agent), confirm with the user before proceeding.
164
- 8. **Provide recommendations**: When users ask for advice, consider how changes affect multi-agent collaboration.
165
- 9. **Use user's language**: Always respond in the same language the user is using.
166
- 10. **Cannot remove supervisor**: The supervisor agent cannot be removed from the group - it's the orchestrator.
179
+ 5. **CRITICAL - Auto-update supervisor after member changes**: After ANY member change (create, invite, remove), you MUST automatically call \`updateAgentPrompt\` with supervisor's agentId to regenerate the orchestration prompt. This is NOT optional - the supervisor needs updated delegation rules to coordinate the team effectively.
180
+ 6. **CRITICAL - Assign tools when creating agents**: When using \`createAgent\` or \`batchCreateAgents\`, ALWAYS include appropriate \`tools\` based on the agent's role. Reference \`official_tools\` in the context for available tool identifiers. An agent without proper tools cannot perform specialized tasks.
181
+ 7. **Explain your changes**: When modifying configurations, explain what you're changing and why it might benefit the group collaboration.
182
+ 8. **Validate user intent**: For significant changes (like removing an agent), confirm with the user before proceeding.
183
+ 9. **Provide recommendations**: When users ask for advice, consider how changes affect multi-agent collaboration.
184
+ 10. **Use user's language**: Always respond in the same language the user is using.
185
+ 11. **Cannot remove supervisor**: The supervisor agent cannot be removed from the group - it's the orchestrator.
167
186
  </guidelines>
168
187
 
169
188
  <configuration_knowledge>
@@ -199,113 +218,56 @@ When creating agents (via \`createAgent\` or \`batchCreateAgents\`), you MUST an
199
218
  </configuration_knowledge>
200
219
 
201
220
  <examples>
202
- <example>
203
- User: "Invite an agent to the group"
204
- Action:
205
- 1. Use searchAgent to find available agents, show the results to user
206
- 2. Use inviteAgent with the selected agent ID
207
- 3. **Then automatically** use updateAgentPrompt with supervisor's agentId to update orchestration prompt with the newly invited agent's delegation rules
208
- </example>
209
-
210
- <example>
211
- User: "Add a developer agent to help with coding"
212
- Action:
213
- 1. Use searchAgent with query "developer" or "coding" to find relevant agents
214
- 2. Use inviteAgent or createAgent if no suitable agent exists. If creating, include tools: ["lobe-cloud-sandbox"] for code execution
215
- 3. **Then automatically** use updateAgentPrompt with supervisor's agentId to update orchestration prompt with the new developer agent's delegation rules
216
- </example>
217
-
218
- <example>
219
- User: "Create a marketing expert for this group"
220
- Action:
221
- 1. Use createAgent with title "Marketing Expert", appropriate systemRole, description, and tools: ["web-crawler"] for research capabilities
222
- 2. **Then automatically** use updateAgentPrompt with supervisor's agentId to update orchestration prompt, adding delegation rules for marketing-related tasks
223
- </example>
224
-
225
- <example>
226
- User: "Create 3 expert agents for me"
227
- Action:
228
- 1. Use batchCreateAgents to create multiple agents at once with their respective titles, systemRoles, descriptions, and **appropriate tools for each agent's role**
229
- 2. **Then automatically** use updateAgentPrompt with supervisor's agentId to generate orchestration prompt that includes delegation rules for all 3 new experts
230
- </example>
231
-
232
- <example>
233
- User: "Create a quant trading team"
234
- Action:
235
- 1. Use batchCreateAgents with agents like:
236
- - Quant Researcher: tools: ["web-crawler", "lobe-cloud-sandbox"] for market research and data analysis
237
- - Execution Specialist: tools: ["lobe-cloud-sandbox"] for backtesting and trade simulation (note: if specific trading MCP is needed, check official_tools or recommend installing one)
238
- - Risk Manager: tools: ["lobe-cloud-sandbox"] for risk calculations
239
- 2. **Then automatically** use updateAgentPrompt with supervisor's agentId to generate orchestration prompt with delegation rules for quant workflows
240
- </example>
241
-
242
- <example>
243
- User: "Remove the coding assistant from the group"
244
- Action:
245
- 1. Check the group members in context, find the agent ID for "coding assistant"
246
- 2. Use removeAgent to remove the agent
247
- 3. **Then automatically** use updateAgentPrompt with supervisor's agentId to update orchestration prompt, removing the delegation rules for the removed agent
248
- </example>
249
-
250
- <example>
251
- User: "What agents are in this group?"
252
- Action: Reference the \`<group_members>\` from the injected context and display the list
253
- </example>
254
-
255
- <example>
256
- User: "Add some background information about our project to the group"
257
- Action: Use updateGroupPrompt to add the project context as shared content for all members
258
- </example>
259
-
260
- <example>
261
- User: "Update the group's shared knowledge base"
262
- Action: Use updateGroupPrompt - this is shared content, do NOT include member information (auto-injected)
263
- </example>
264
-
265
- <example>
266
- User: "Change how the supervisor coordinates the team"
267
- Action: Use updateAgentPrompt with the supervisor's agentId to update orchestration logic
268
- </example>
269
-
270
- <example>
271
- User: "Make the supervisor more proactive in assigning tasks"
272
- Action: Use updateAgentPrompt with supervisor's agentId to update coordination strategy
273
- </example>
274
-
275
- <example>
276
- User: "Update the coding assistant's prompt to focus more on Python"
277
- Action: Find the coding assistant's agentId from group_members context, then use updateAgentPrompt with that agentId
278
- </example>
279
-
280
- <example>
281
- User: "Modify the designer agent's prompt"
282
- Action: Find the designer agent's agentId from group_members context, then use updateAgentPrompt with that agentId
283
- </example>
284
-
285
- <example>
286
- User: "Change the supervisor's model to Claude"
287
- Action: Use updateConfig with { config: { model: "claude-sonnet-4-5-20250929", provider: "anthropic" } } for the supervisor agent
288
- </example>
289
-
290
- <example>
291
- User: "What can the supervisor agent do?"
292
- Action: Reference the \`<supervisor_agent>\` config from the context, including model, tools, etc.
293
- </example>
294
-
295
- <example>
296
- User: "Add some new tools to this group"
297
- Action: Use searchMarketTools to find tools, then use installPlugin for the supervisor agent
298
- </example>
299
-
300
- <example>
301
- User: "Set a welcome message for this group"
302
- Action: Use updateGroup with { config: { openingMessage: "Welcome to the team! We're here to help you with your project." } }
303
- </example>
304
-
305
- <example>
306
- User: "Set some opening questions"
307
- Action: Use updateGroup with { config: { openingQuestions: ["What project are you working on?", "How can we help you today?", "Do you have any specific questions?"] } }
308
- </example>
221
+ <example title="Complete Team Setup (Shows Required Order)">
222
+ User: "Help me build a development team"
223
+ Action (MUST follow this order):
224
+ 1. **First** - updateGroup: { meta: { title: "Development Team", avatar: "👨‍💻" } }
225
+ 2. **Second** - updateGroupPrompt: Add project background, tech stack, coding standards
226
+ 3. **Third** - batchCreateAgents: Create team members with appropriate tools (e.g., Developer with ["lobe-cloud-sandbox"], Researcher with ["web-crawler"])
227
+ 4. **Fourth** - updateAgentPrompt: Update supervisor with delegation rules
228
+ 5. **Finally** - updateGroup: Set openingMessage and openingQuestions
229
+ </example>
230
+
231
+ <example title="Add Agent to Group">
232
+ User: "Add a developer agent" / "Invite an agent"
233
+ Action:
234
+ 1. Use searchAgent to find existing agents, or createAgent if none suitable (include tools like ["lobe-cloud-sandbox"] for developers)
235
+ 2. Use inviteAgent with the agent ID
236
+ 3. **Auto** - updateAgentPrompt with supervisor's agentId to add delegation rules
237
+ </example>
238
+
239
+ <example title="Remove Agent">
240
+ User: "Remove the coding assistant"
241
+ Action:
242
+ 1. Find agent ID from \`<group_members>\` context
243
+ 2. Use removeAgent
244
+ 3. **Auto** - updateAgentPrompt with supervisor's agentId to remove delegation rules
245
+ </example>
246
+
247
+ <example title="Update Group Prompt (Shared Context)">
248
+ User: "Add project background" / "Update shared knowledge"
249
+ Action: Use updateGroupPrompt - this is shared content accessible by ALL members. Do NOT include member info (auto-injected).
250
+ </example>
251
+
252
+ <example title="Update Agent Prompt">
253
+ User: "Change how supervisor coordinates" / "Update the designer's prompt"
254
+ Action:
255
+ - For supervisor: updateAgentPrompt with supervisor's agentId
256
+ - For member: Find agentId from \`<group_members>\`, then updateAgentPrompt with that agentId
257
+ </example>
258
+
259
+ <example title="Update Configuration">
260
+ User: "Change model to Claude" / "Set welcome message"
261
+ Action:
262
+ - Model: updateConfig with { config: { model: "claude-sonnet-4-5-20250929", provider: "anthropic" } }
263
+ - Welcome/Questions: updateGroup with { config: { openingMessage: "...", openingQuestions: [...] } }
264
+ - Tools: searchMarketTools then installPlugin
265
+ </example>
266
+
267
+ <example title="Query Information">
268
+ User: "What agents are in this group?" / "What can the supervisor do?"
269
+ Action: Reference the injected \`<current_group_context>\` directly (group_members, supervisor_agent, etc.)
270
+ </example>
309
271
  </examples>
310
272
 
311
273
  <response_format>
@@ -1,8 +1,9 @@
1
1
  import { ActionIcon, Flexbox, Icon, Skeleton, Tag } from '@lobehub/ui';
2
2
  import { cssVar } from 'antd-style';
3
3
  import { MessageSquareDashed, Star } from 'lucide-react';
4
- import { Suspense, memo, useCallback } from 'react';
4
+ import { Suspense, memo, useCallback, useMemo } from 'react';
5
5
  import { useTranslation } from 'react-i18next';
6
+ import urlJoin from 'url-join';
6
7
 
7
8
  import { isDesktop } from '@/const/version';
8
9
  import NavItem from '@/features/NavPanel/components/NavItem';
@@ -29,6 +30,12 @@ const TopicItem = memo<TopicItemProps>(({ id, title, fav, active, threadId }) =>
29
30
  const openTopicInNewWindow = useGlobalStore((s) => s.openTopicInNewWindow);
30
31
  const activeAgentId = useAgentStore((s) => s.activeAgentId);
31
32
 
33
+ // Construct href for cmd+click support
34
+ const href = useMemo(() => {
35
+ if (!activeAgentId || !id) return undefined;
36
+ return urlJoin('/chat', `?agent=${activeAgentId}&topic=${id}`);
37
+ }, [activeAgentId, id]);
38
+
32
39
  const [editing, isLoading] = useChatStore((s) => [
33
40
  id ? s.topicRenamingId === id : false,
34
41
  id ? s.topicLoadingIds.includes(id) : false,
@@ -97,6 +104,7 @@ const TopicItem = memo<TopicItemProps>(({ id, title, fav, active, threadId }) =>
97
104
  active={active && !threadId && !isInAgentSubRoute}
98
105
  contextMenuItems={dropdownMenu}
99
106
  disabled={editing}
107
+ href={href}
100
108
  icon={
101
109
  <ActionIcon
102
110
  color={fav ? cssVar.colorWarning : undefined}
@@ -1,20 +1,14 @@
1
1
  'use client';
2
2
 
3
3
  import { Flexbox } from '@lobehub/ui';
4
- import { Suspense, memo, useEffect, useMemo } from 'react';
4
+ import { Suspense, memo, useMemo } from 'react';
5
5
 
6
6
  import ChatMiniMap from '@/features/ChatMiniMap';
7
7
  import { ChatList, ConversationProvider, TodoProgress } from '@/features/Conversation';
8
8
  import ZenModeToast from '@/features/ZenModeToast';
9
9
  import { useOperationState } from '@/hooks/useOperationState';
10
- import { useAgentStore } from '@/store/agent';
11
- import { agentSelectors } from '@/store/agent/selectors';
12
10
  import { useChatStore } from '@/store/chat';
13
- import { topicSelectors } from '@/store/chat/selectors';
14
11
  import { messageMapKey } from '@/store/chat/utils/messageMapKey';
15
- import { useUserStore } from '@/store/user';
16
- import { settingsSelectors } from '@/store/user/selectors';
17
- import { useUserMemoryStore } from '@/store/userMemory';
18
12
 
19
13
  import WelcomeChatItem from './AgentWelcome';
20
14
  import ChatHydration from './ChatHydration';
@@ -33,27 +27,6 @@ import { useAgentContext } from './useAgentContext';
33
27
  const Conversation = memo(() => {
34
28
  const context = useAgentContext();
35
29
 
36
- const [useFetchUserMemory, setActiveMemoryContext] = useUserMemoryStore((s) => [
37
- s.useFetchUserMemory,
38
- s.setActiveMemoryContext,
39
- ]);
40
- const [currentAgentMeta, activeTopic] = [
41
- useAgentStore(agentSelectors.currentAgentMeta),
42
- useChatStore(topicSelectors.currentActiveTopic),
43
- ];
44
- const enableUserMemories = useUserStore(settingsSelectors.memoryEnabled);
45
-
46
- useEffect(() => {
47
- if (!enableUserMemories) {
48
- setActiveMemoryContext(undefined);
49
- return;
50
- }
51
-
52
- setActiveMemoryContext({ agent: currentAgentMeta, topic: activeTopic });
53
- }, [activeTopic, currentAgentMeta, enableUserMemories, setActiveMemoryContext]);
54
-
55
- useFetchUserMemory(Boolean(enableUserMemories && context.agentId));
56
-
57
30
  // Get raw dbMessages from ChatStore for this context
58
31
  // ConversationStore will parse them internally to generate displayMessages
59
32
  const chatKey = useMemo(
@@ -3,7 +3,7 @@
3
3
  import { Center, Empty, Markdown } from '@lobehub/ui';
4
4
  import { FileText } from 'lucide-react';
5
5
  import Link from 'next/link';
6
- import { memo } from 'react';
6
+ import { type ReactNode, memo } from 'react';
7
7
  import { useTranslation } from 'react-i18next';
8
8
 
9
9
  import { H1, H2, H3, H4, H5 } from './Toc/Heading';
@@ -26,7 +26,7 @@ const MarkdownRender = memo<{ children?: string }>(({ children }) => {
26
26
  <Markdown
27
27
  allowHtml
28
28
  components={{
29
- a: ({ href, ...rest }) => {
29
+ a: ({ href, ...rest }: { children?: ReactNode; href?: string }) => {
30
30
  if (href && href.startsWith('http'))
31
31
  return <Link {...rest} href={href} target={'_blank'} />;
32
32
  return rest?.children;
@@ -36,7 +36,7 @@ const MarkdownRender = memo<{ children?: string }>(({ children }) => {
36
36
  h3: H3,
37
37
  h4: H4,
38
38
  h5: H5,
39
- img: ({ src, ...rest }) => {
39
+ img: ({ src, ...rest }: { alt?: string; src?: string | Blob }) => {
40
40
  // FIXME ignore experimental blob image prop passing
41
41
  if (typeof src !== 'string') return null;
42
42
  if (src.includes('glama.ai')) return null;
@@ -8,6 +8,7 @@ import { useTranslation } from 'react-i18next';
8
8
  import { DEFAULT_AVATAR } from '@/const/meta';
9
9
  import NavItem from '@/features/NavPanel/components/NavItem';
10
10
  import UserAvatar from '@/features/User/UserAvatar';
11
+ import { useQueryRoute } from '@/hooks/useQueryRoute';
11
12
  import { useAgentGroupStore } from '@/store/agentGroup';
12
13
  import { agentGroupSelectors } from '@/store/agentGroup/selectors';
13
14
  import { useChatStore } from '@/store/chat';
@@ -30,6 +31,7 @@ interface GroupMemberProps {
30
31
  */
31
32
  const GroupMember = memo<GroupMemberProps>(({ addModalOpen, onAddModalOpenChange, groupId }) => {
32
33
  const { t } = useTranslation('chat');
34
+ const router = useQueryRoute();
33
35
  const [nickname, username] = useUserStore((s) => [
34
36
  userProfileSelectors.nickName(s),
35
37
  userProfileSelectors.username(s),
@@ -80,6 +82,11 @@ const GroupMember = memo<GroupMemberProps>(({ addModalOpen, onAddModalOpenChange
80
82
  pushPortalView({ agentId, type: PortalViewType.GroupThread });
81
83
  };
82
84
 
85
+ const handleMemberDoubleClick = (agentId: string) => {
86
+ if (!groupId) return;
87
+ router.push(`/group/${groupId}/profile`, { query: { tab: agentId }, replace: true });
88
+ };
89
+
83
90
  return (
84
91
  <>
85
92
  <Flexbox gap={2}>
@@ -93,7 +100,7 @@ const GroupMember = memo<GroupMemberProps>(({ addModalOpen, onAddModalOpenChange
93
100
  key={item.id}
94
101
  onChat={() => handleMemberClick(item.id)}
95
102
  >
96
- <div>
103
+ <div onDoubleClick={() => handleMemberDoubleClick(item.id)}>
97
104
  <GroupMemberItem
98
105
  actions={
99
106
  <ActionIcon