@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.
- package/CHANGELOG.md +25 -0
- package/changelog/v1.json +9 -0
- package/e2e/src/steps/agent/conversation-mgmt.steps.ts +47 -3
- package/package.json +1 -1
- package/packages/builtin-tool-group-agent-builder/src/client/Render/BatchCreateAgents.tsx +19 -3
- package/packages/builtin-tool-group-agent-builder/src/client/Streaming/BatchCreateAgents/index.tsx +19 -4
- package/packages/builtin-tool-group-agent-builder/src/client/Streaming/UpdateAgentPrompt/index.tsx +3 -13
- package/packages/builtin-tool-group-agent-builder/src/client/Streaming/UpdateGroupPrompt/index.tsx +1 -1
- package/packages/builtin-tool-group-agent-builder/src/systemRole.ts +83 -121
- package/src/app/[variants]/(main)/agent/_layout/Sidebar/Topic/List/Item/index.tsx +9 -1
- package/src/app/[variants]/(main)/agent/features/Conversation/ConversationArea.tsx +1 -28
- package/src/app/[variants]/(main)/community/(detail)/features/MakedownRender.tsx +3 -3
- package/src/app/[variants]/(main)/group/_layout/Sidebar/GroupConfig/GroupMember.tsx +8 -1
- package/src/app/[variants]/(main)/group/_layout/Sidebar/GroupConfig/Header/Avatar.tsx +2 -13
- package/src/app/[variants]/(main)/group/_layout/Sidebar/Header/Agent/index.tsx +3 -4
- package/src/app/[variants]/(main)/group/_layout/Sidebar/Topic/List/Item/index.tsx +17 -8
- package/src/app/[variants]/(main)/group/features/Conversation/ConversationArea.tsx +1 -29
- package/src/app/[variants]/(main)/group/features/Conversation/Header/ShareButton/index.tsx +0 -2
- package/src/app/[variants]/(main)/group/features/GroupAvatar.tsx +17 -9
- package/src/app/[variants]/(main)/group/profile/features/AgentBuilder/TopicSelector.tsx +8 -5
- package/src/app/[variants]/(main)/group/profile/features/Header/ChromeTabs/index.tsx +20 -2
- package/src/app/[variants]/(main)/group/profile/features/MemberProfile/AgentTool.tsx +4 -2
- package/src/app/[variants]/(main)/group/profile/features/ProfileHydration.tsx +5 -25
- package/src/features/AgentGroupAvatar/index.tsx +38 -0
- package/src/features/Conversation/Messages/Supervisor/index.tsx +8 -2
- package/src/features/Conversation/Messages/User/useMarkdown.tsx +1 -2
- package/src/features/NavPanel/components/EmptyNavItem.tsx +2 -2
- package/src/features/NavPanel/components/NavItem.tsx +27 -3
- package/src/features/ToolTag/index.tsx +167 -0
- package/src/server/routers/lambda/topic.ts +8 -1
- package/src/services/chat/mecha/contextEngineering.test.ts +1 -1
- package/src/services/chat/mecha/contextEngineering.ts +3 -4
- package/src/services/chat/mecha/memoryManager.ts +9 -38
- package/src/store/agentGroup/initialState.ts +1 -1
- package/src/store/agentGroup/slices/lifecycle.ts +15 -2
- 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
|
+
[](#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
|
@@ -124,9 +124,41 @@ When('用户点击新建对话按钮', async function (this: CustomWorld) {
|
|
|
124
124
|
When('用户点击另一个对话', async function (this: CustomWorld) {
|
|
125
125
|
console.log(' 📍 Step: 点击另一个对话...');
|
|
126
126
|
|
|
127
|
-
//
|
|
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(
|
|
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.
|
|
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="
|
|
70
|
-
<Avatar
|
|
71
|
-
|
|
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
|
);
|
package/packages/builtin-tool-group-agent-builder/src/client/Streaming/BatchCreateAgents/index.tsx
CHANGED
|
@@ -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:
|
|
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
|
|
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'}>
|
package/packages/builtin-tool-group-agent-builder/src/client/Streaming/UpdateAgentPrompt/index.tsx
CHANGED
|
@@ -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
|
|
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 {
|
|
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
|
|
16
|
+
<Block paddingBlock={8} paddingInline={12} variant={'outlined'} width="100%">
|
|
27
17
|
<Markdown animated variant={'chat'}>
|
|
28
18
|
{prompt}
|
|
29
19
|
</Markdown>
|
package/packages/builtin-tool-group-agent-builder/src/client/Streaming/UpdateGroupPrompt/index.tsx
CHANGED
|
@@ -21,7 +21,7 @@ export const UpdateGroupPromptStreaming = memo<BuiltinStreamingProps<UpdateGroup
|
|
|
21
21
|
if (!prompt) return null;
|
|
22
22
|
|
|
23
23
|
return (
|
|
24
|
-
<Block
|
|
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
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
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. **
|
|
154
|
-
2. **
|
|
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
|
-
|
|
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
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
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: "
|
|
204
|
-
Action:
|
|
205
|
-
1.
|
|
206
|
-
2.
|
|
207
|
-
3. **
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
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,
|
|
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
|