@lobehub/lobehub 2.0.0-next.287 → 2.0.0-next.289

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 (62) hide show
  1. package/CHANGELOG.md +50 -0
  2. package/changelog/v1.json +18 -0
  3. package/locales/en-US/plugin.json +3 -5
  4. package/locales/zh-CN/plugin.json +3 -5
  5. package/locales/zh-CN/tool.json +2 -0
  6. package/package.json +1 -1
  7. package/packages/builtin-agents/src/agents/group-supervisor/index.ts +12 -1
  8. package/packages/builtin-agents/src/agents/group-supervisor/systemRole.ts +0 -7
  9. package/packages/builtin-tool-cloud-sandbox/src/client/Inspector/EditLocalFile/index.tsx +93 -0
  10. package/packages/builtin-tool-cloud-sandbox/src/client/Inspector/GlobLocalFiles/index.tsx +73 -0
  11. package/packages/builtin-tool-cloud-sandbox/src/client/Inspector/GrepContent/index.tsx +69 -0
  12. package/packages/builtin-tool-cloud-sandbox/src/client/Inspector/ListLocalFiles/index.tsx +68 -0
  13. package/packages/builtin-tool-cloud-sandbox/src/client/Inspector/ReadLocalFile/index.tsx +74 -0
  14. package/packages/builtin-tool-cloud-sandbox/src/client/Inspector/SearchLocalFiles/index.tsx +70 -0
  15. package/packages/builtin-tool-cloud-sandbox/src/client/Inspector/WriteLocalFile/index.tsx +57 -0
  16. package/packages/builtin-tool-cloud-sandbox/src/client/Inspector/index.ts +14 -0
  17. package/packages/builtin-tool-cloud-sandbox/src/client/Render/WriteFile/index.tsx +54 -35
  18. package/packages/builtin-tool-cloud-sandbox/src/client/components/FilePathDisplay.tsx +52 -0
  19. package/packages/builtin-tool-group-management/src/client/Inspector/ExecuteTasks/index.tsx +90 -0
  20. package/packages/builtin-tool-group-management/src/client/Inspector/index.ts +2 -0
  21. package/packages/builtin-tool-group-management/src/client/Intervention/ExecuteTasks.tsx +237 -0
  22. package/packages/builtin-tool-group-management/src/client/Intervention/index.ts +4 -1
  23. package/packages/builtin-tool-group-management/src/client/Render/index.ts +1 -1
  24. package/packages/builtin-tool-group-management/src/client/Streaming/ExecuteTask/index.tsx +69 -0
  25. package/packages/builtin-tool-group-management/src/client/Streaming/ExecuteTasks/index.tsx +87 -0
  26. package/packages/builtin-tool-group-management/src/client/Streaming/index.ts +4 -0
  27. package/packages/builtin-tool-group-management/src/executor.test.ts +8 -311
  28. package/packages/builtin-tool-group-management/src/executor.ts +5 -160
  29. package/packages/builtin-tool-group-management/src/manifest.ts +50 -94
  30. package/packages/builtin-tool-group-management/src/systemRole.ts +251 -172
  31. package/packages/builtin-tool-group-management/src/types.ts +29 -40
  32. package/packages/context-engine/src/engine/messages/MessagesEngine.ts +22 -4
  33. package/packages/context-engine/src/engine/messages/types.ts +4 -4
  34. package/packages/context-engine/src/processors/GroupOrchestrationFilter.ts +211 -0
  35. package/packages/context-engine/src/processors/GroupRoleTransform.ts +261 -0
  36. package/packages/context-engine/src/processors/__tests__/GroupOrchestrationFilter.test.ts +770 -0
  37. package/packages/context-engine/src/processors/__tests__/GroupRoleTransform.test.ts +553 -0
  38. package/packages/context-engine/src/processors/index.ts +7 -2
  39. package/packages/context-engine/src/providers/__tests__/GroupContextInjector.test.ts +4 -16
  40. package/packages/context-engine/src/providers/__tests__/__snapshots__/GroupContextInjector.test.ts.snap +23 -28
  41. package/packages/prompts/src/prompts/agentGroup/__snapshots__/index.test.ts.snap +0 -7
  42. package/packages/prompts/src/prompts/agentGroup/groupContext.ts +0 -7
  43. package/src/app/[variants]/(main)/group/features/Conversation/AgentWelcome/OpeningQuestions.tsx +4 -8
  44. package/src/app/[variants]/(main)/group/features/Conversation/MainChatInput/GroupChat.tsx +0 -3
  45. package/src/app/[variants]/(main)/group/features/Conversation/useGroupContext.ts +3 -0
  46. package/src/features/ChatInput/Desktop/index.tsx +1 -3
  47. package/src/features/Conversation/store/slices/message/action/crud.ts +2 -2
  48. package/src/locales/default/plugin.ts +3 -5
  49. package/src/locales/default/tool.ts +3 -0
  50. package/src/services/chat/mecha/agentConfigResolver.test.ts +160 -0
  51. package/src/services/chat/mecha/agentConfigResolver.ts +15 -3
  52. package/src/services/chat/mecha/contextEngineering.ts +2 -1
  53. package/src/store/chat/agents/GroupOrchestration/createGroupOrchestrationExecutors.ts +4 -2
  54. package/src/store/chat/slices/aiChat/actions/conversationLifecycle.ts +2 -0
  55. package/src/store/chat/slices/aiChat/actions/streamingExecutor.ts +1 -18
  56. package/src/store/chat/slices/message/selectors/displayMessage.test.ts +24 -0
  57. package/src/store/chat/slices/message/selectors/displayMessage.ts +6 -1
  58. package/src/store/chat/slices/topic/action.test.ts +10 -4
  59. package/src/store/chat/slices/topic/action.ts +3 -2
  60. package/src/store/document/slices/document/action.ts +8 -0
  61. package/packages/context-engine/src/processors/GroupMessageSender.ts +0 -138
  62. package/packages/context-engine/src/processors/__tests__/GroupMessageSender.test.ts +0 -274
@@ -0,0 +1,87 @@
1
+ 'use client';
2
+
3
+ import { DEFAULT_AVATAR } from '@lobechat/const';
4
+ import type { AgentGroupMember, BuiltinStreamingProps } from '@lobechat/types';
5
+ import { Avatar, Flexbox, Markdown } from '@lobehub/ui';
6
+ import { createStaticStyles, useTheme } from 'antd-style';
7
+ import { memo, useMemo } from 'react';
8
+
9
+ import { useAgentGroupStore } from '@/store/agentGroup';
10
+ import { agentGroupSelectors } from '@/store/agentGroup/selectors';
11
+
12
+ import type { ExecuteTasksParams } from '../../../types';
13
+
14
+ const styles = createStaticStyles(({ css, cssVar }) => ({
15
+ container: css`
16
+ display: flex;
17
+ flex-direction: column;
18
+ gap: 12px;
19
+ `,
20
+ instruction: css`
21
+ font-size: 13px;
22
+ color: ${cssVar.colorTextSecondary};
23
+ `,
24
+ taskCard: css`
25
+ padding: 12px;
26
+ border-radius: 8px;
27
+ background: ${cssVar.colorFillQuaternary};
28
+ `,
29
+ taskTitle: css`
30
+ font-size: 13px;
31
+ font-weight: 500;
32
+ color: ${cssVar.colorText};
33
+ `,
34
+ }));
35
+
36
+ export const ExecuteTasksStreaming = memo<BuiltinStreamingProps<ExecuteTasksParams>>(({ args }) => {
37
+ const { tasks } = args || {};
38
+ const theme = useTheme();
39
+
40
+ // Get active group ID and agents from store
41
+ const activeGroupId = useAgentGroupStore(agentGroupSelectors.activeGroupId);
42
+ const groupAgents = useAgentGroupStore((s) =>
43
+ activeGroupId ? agentGroupSelectors.getGroupAgents(activeGroupId)(s) : [],
44
+ );
45
+
46
+ // Get agent details for each task
47
+ const tasksWithAgents = useMemo(() => {
48
+ if (!tasks?.length || !groupAgents.length) return [];
49
+ return tasks.map((task) => ({
50
+ ...task,
51
+ agent: groupAgents.find((agent) => agent.id === task.agentId) as AgentGroupMember | undefined,
52
+ }));
53
+ }, [tasks, groupAgents]);
54
+
55
+ if (!tasksWithAgents.length) return null;
56
+
57
+ return (
58
+ <div className={styles.container}>
59
+ {tasksWithAgents.map((task, index) => (
60
+ <div className={styles.taskCard} key={task.agentId || index}>
61
+ <Flexbox gap={8}>
62
+ <Flexbox align={'center'} gap={8} horizontal>
63
+ <Avatar
64
+ avatar={task.agent?.avatar || DEFAULT_AVATAR}
65
+ background={task.agent?.backgroundColor || theme.colorBgContainer}
66
+ shape={'square'}
67
+ size={20}
68
+ />
69
+ <span className={styles.taskTitle}>{task.title || task.agent?.title || 'Task'}</span>
70
+ </Flexbox>
71
+ {task.instruction && (
72
+ <div className={styles.instruction}>
73
+ <Markdown animated variant={'chat'}>
74
+ {task.instruction}
75
+ </Markdown>
76
+ </div>
77
+ )}
78
+ </Flexbox>
79
+ </div>
80
+ ))}
81
+ </div>
82
+ );
83
+ });
84
+
85
+ ExecuteTasksStreaming.displayName = 'ExecuteTasksStreaming';
86
+
87
+ export default ExecuteTasksStreaming;
@@ -2,6 +2,8 @@ import type { BuiltinStreaming } from '@lobechat/types';
2
2
 
3
3
  import { GroupManagementApiName } from '../../types';
4
4
  import { BroadcastStreaming } from './Broadcast';
5
+ import { ExecuteTaskStreaming } from './ExecuteTask';
6
+ import { ExecuteTasksStreaming } from './ExecuteTasks';
5
7
  import { SpeakStreaming } from './Speak';
6
8
 
7
9
  /**
@@ -12,5 +14,7 @@ import { SpeakStreaming } from './Speak';
12
14
  */
13
15
  export const GroupManagementStreamings: Record<string, BuiltinStreaming> = {
14
16
  [GroupManagementApiName.broadcast]: BroadcastStreaming as BuiltinStreaming,
17
+ [GroupManagementApiName.executeAgentTask]: ExecuteTaskStreaming as BuiltinStreaming,
18
+ [GroupManagementApiName.executeAgentTasks]: ExecuteTasksStreaming as BuiltinStreaming,
15
19
  [GroupManagementApiName.speak]: SpeakStreaming as BuiltinStreaming,
16
20
  };
@@ -8,29 +8,12 @@ import type {
8
8
  import { groupManagementExecutor } from './executor';
9
9
 
10
10
  // Mock agentGroupStore
11
- const mockAddAgentsToGroup = vi.fn();
12
- const mockRemoveAgentFromGroup = vi.fn();
13
-
14
11
  vi.mock('@/store/agentGroup', () => ({
15
12
  agentGroupSelectors: {
16
13
  getAgentByIdFromGroup: vi.fn(() => () => undefined),
17
14
  },
18
15
  useAgentGroupStore: {
19
- getState: () => ({
20
- addAgentsToGroup: mockAddAgentsToGroup,
21
- removeAgentFromGroup: mockRemoveAgentFromGroup,
22
- }),
23
- },
24
- }));
25
-
26
- // Mock agentService
27
- const mockQueryAgents = vi.fn();
28
- const mockCreateAgent = vi.fn();
29
-
30
- vi.mock('@/services/agent', () => ({
31
- agentService: {
32
- createAgent: (...args: any[]) => mockCreateAgent(...args),
33
- queryAgents: (...args: any[]) => mockQueryAgents(...args),
16
+ getState: () => ({}),
34
17
  },
35
18
  }));
36
19
 
@@ -288,78 +271,6 @@ describe('GroupManagementExecutor', () => {
288
271
  });
289
272
  });
290
273
 
291
- describe('searchAgent', () => {
292
- beforeEach(() => {
293
- vi.clearAllMocks();
294
- });
295
-
296
- it('should return community not supported message when source is community', async () => {
297
- const ctx = createMockContext();
298
-
299
- const result = await groupManagementExecutor.searchAgent(
300
- { query: 'test', source: 'community' },
301
- ctx,
302
- );
303
-
304
- expect(result.success).toBe(true);
305
- expect(result.content).toContain('Community agent search is not yet supported');
306
- expect(result.state).toEqual({ agents: [], source: 'community', total: 0 });
307
- });
308
-
309
- it('should search user agents and return formatted results', async () => {
310
- mockQueryAgents.mockResolvedValue([
311
- { id: 'agent-1', title: 'Code Assistant', description: 'Helps with coding', avatar: '🤖' },
312
- { id: 'agent-2', title: 'Writer', description: null, avatar: null },
313
- ]);
314
-
315
- const ctx = createMockContext();
316
- const result = await groupManagementExecutor.searchAgent({ query: 'test' }, ctx);
317
-
318
- expect(result.success).toBe(true);
319
- expect(mockQueryAgents).toHaveBeenCalledWith({ keyword: 'test', limit: 10 });
320
- expect(result.content).toContain('Found 2 agents');
321
- expect(result.content).toContain('Code Assistant');
322
- expect(result.content).toContain('Writer');
323
- expect(result.state.agents).toHaveLength(2);
324
- expect(result.state.total).toBe(2);
325
- });
326
-
327
- it('should return no results message when no agents found', async () => {
328
- mockQueryAgents.mockResolvedValue([]);
329
-
330
- const ctx = createMockContext();
331
- const result = await groupManagementExecutor.searchAgent({ query: 'nonexistent' }, ctx);
332
-
333
- expect(result.success).toBe(true);
334
- expect(result.content).toContain('No agents found matching "nonexistent"');
335
- expect(result.state).toEqual({ agents: [], query: 'nonexistent', total: 0 });
336
- });
337
-
338
- it('should pass limit to queryAgents', async () => {
339
- mockQueryAgents.mockResolvedValue([
340
- { id: 'agent-1', title: 'Agent 1' },
341
- { id: 'agent-2', title: 'Agent 2' },
342
- ]);
343
-
344
- const ctx = createMockContext();
345
- const result = await groupManagementExecutor.searchAgent({ query: 'test', limit: 2 }, ctx);
346
-
347
- expect(result.success).toBe(true);
348
- expect(mockQueryAgents).toHaveBeenCalledWith({ keyword: 'test', limit: 2 });
349
- expect(result.state.agents).toHaveLength(2);
350
- });
351
-
352
- it('should handle errors gracefully', async () => {
353
- mockQueryAgents.mockRejectedValue(new Error('Network error'));
354
-
355
- const ctx = createMockContext();
356
- const result = await groupManagementExecutor.searchAgent({ query: 'test' }, ctx);
357
-
358
- expect(result.success).toBe(false);
359
- expect(result.content).toBe('Failed to search agents: Network error');
360
- });
361
- });
362
-
363
274
  describe('getAgentInfo', () => {
364
275
  it('should return error when no groupId in context', async () => {
365
276
  const ctx = createMockContext();
@@ -372,221 +283,7 @@ describe('GroupManagementExecutor', () => {
372
283
  });
373
284
  });
374
285
 
375
- describe('inviteAgent', () => {
376
- beforeEach(() => {
377
- vi.clearAllMocks();
378
- });
379
-
380
- it('should return error when no groupId in context', async () => {
381
- const ctx = createMockContext();
382
-
383
- const result = await groupManagementExecutor.inviteAgent({ agentId: 'agent-1' }, ctx);
384
-
385
- expect(result.success).toBe(false);
386
- expect(result.content).toBe('No group context available');
387
- });
388
-
389
- it('should successfully invite agent when groupId is available', async () => {
390
- mockAddAgentsToGroup.mockResolvedValue(undefined);
391
-
392
- const ctx: BuiltinToolContext = {
393
- ...createMockContext(),
394
- groupId: 'test-group-id',
395
- };
396
-
397
- const result = await groupManagementExecutor.inviteAgent({ agentId: 'agent-1' }, ctx);
398
-
399
- expect(result.success).toBe(true);
400
- expect(mockAddAgentsToGroup).toHaveBeenCalledWith('test-group-id', ['agent-1']);
401
- expect(result.content).toBe('Agent "agent-1" has been invited to the group.');
402
- expect(result.state).toEqual({ agentId: 'agent-1', type: 'inviteAgent' });
403
- });
404
-
405
- it('should handle errors during invitation', async () => {
406
- mockAddAgentsToGroup.mockRejectedValue(new Error('Database error'));
407
-
408
- const ctx: BuiltinToolContext = {
409
- ...createMockContext(),
410
- groupId: 'test-group-id',
411
- };
412
-
413
- const result = await groupManagementExecutor.inviteAgent({ agentId: 'agent-1' }, ctx);
414
-
415
- expect(result.success).toBe(false);
416
- expect(result.content).toBe('Failed to invite agent "agent-1": Database error');
417
- });
418
- });
419
-
420
- describe('removeAgent', () => {
421
- beforeEach(() => {
422
- vi.clearAllMocks();
423
- });
424
-
425
- it('should return error when no groupId in context', async () => {
426
- const ctx = createMockContext();
427
-
428
- const result = await groupManagementExecutor.removeAgent({ agentId: 'agent-1' }, ctx);
429
-
430
- expect(result.success).toBe(false);
431
- expect(result.content).toBe('No group context available');
432
- });
433
-
434
- it('should successfully remove agent when groupId is available', async () => {
435
- mockRemoveAgentFromGroup.mockResolvedValue(undefined);
436
-
437
- const ctx: BuiltinToolContext = {
438
- ...createMockContext(),
439
- groupId: 'test-group-id',
440
- };
441
-
442
- const result = await groupManagementExecutor.removeAgent({ agentId: 'agent-1' }, ctx);
443
-
444
- expect(result.success).toBe(true);
445
- expect(mockRemoveAgentFromGroup).toHaveBeenCalledWith('test-group-id', 'agent-1');
446
- expect(result.content).toBe('Agent "agent-1" has been removed from the group.');
447
- expect(result.state).toEqual({ agentId: 'agent-1', type: 'removeAgent' });
448
- });
449
-
450
- it('should handle errors during removal', async () => {
451
- mockRemoveAgentFromGroup.mockRejectedValue(new Error('Agent not found'));
452
-
453
- const ctx: BuiltinToolContext = {
454
- ...createMockContext(),
455
- groupId: 'test-group-id',
456
- };
457
-
458
- const result = await groupManagementExecutor.removeAgent({ agentId: 'agent-1' }, ctx);
459
-
460
- expect(result.success).toBe(false);
461
- expect(result.content).toBe('Failed to remove agent "agent-1": Agent not found');
462
- });
463
- });
464
-
465
- describe('createAgent', () => {
466
- beforeEach(() => {
467
- vi.clearAllMocks();
468
- });
469
-
470
- it('should return error when no groupId in context', async () => {
471
- const ctx = createMockContext();
472
-
473
- const result = await groupManagementExecutor.createAgent(
474
- { title: 'New Agent', systemRole: 'You are a helpful assistant' },
475
- ctx,
476
- );
477
-
478
- expect(result.success).toBe(false);
479
- expect(result.content).toBe('No group context available');
480
- });
481
-
482
- it('should successfully create a virtual agent and add to group', async () => {
483
- mockCreateAgent.mockResolvedValue({
484
- agentId: 'new-agent-id',
485
- sessionId: 'new-session-id',
486
- });
487
-
488
- const ctx: BuiltinToolContext = {
489
- ...createMockContext(),
490
- groupId: 'test-group-id',
491
- };
492
-
493
- const result = await groupManagementExecutor.createAgent(
494
- {
495
- avatar: '🤖',
496
- description: 'A helpful coding assistant',
497
- systemRole: 'You are a coding expert',
498
- title: 'Code Helper',
499
- },
500
- ctx,
501
- );
502
-
503
- expect(result.success).toBe(true);
504
- expect(mockCreateAgent).toHaveBeenCalledWith({
505
- config: {
506
- avatar: '🤖',
507
- description: 'A helpful coding assistant',
508
- systemRole: 'You are a coding expert',
509
- title: 'Code Helper',
510
- virtual: true,
511
- },
512
- groupId: 'test-group-id',
513
- });
514
- expect(result.content).toBe('Agent "Code Helper" has been created and added to the group.');
515
- expect(result.state).toEqual({
516
- agentId: 'new-agent-id',
517
- title: 'Code Helper',
518
- type: 'createAgent',
519
- });
520
- });
521
-
522
- it('should handle case when agentId is not returned', async () => {
523
- mockCreateAgent.mockResolvedValue({
524
- sessionId: 'new-session-id',
525
- // No agentId returned
526
- });
527
-
528
- const ctx: BuiltinToolContext = {
529
- ...createMockContext(),
530
- groupId: 'test-group-id',
531
- };
532
-
533
- const result = await groupManagementExecutor.createAgent(
534
- { title: 'New Agent', systemRole: 'Test' },
535
- ctx,
536
- );
537
-
538
- expect(result.success).toBe(false);
539
- expect(result.content).toBe('Failed to create agent: No agent ID returned');
540
- });
541
-
542
- it('should handle errors during creation', async () => {
543
- mockCreateAgent.mockRejectedValue(new Error('Database connection failed'));
544
-
545
- const ctx: BuiltinToolContext = {
546
- ...createMockContext(),
547
- groupId: 'test-group-id',
548
- };
549
-
550
- const result = await groupManagementExecutor.createAgent(
551
- { title: 'New Agent', systemRole: 'Test' },
552
- ctx,
553
- );
554
-
555
- expect(result.success).toBe(false);
556
- expect(result.content).toBe('Failed to create agent: Database connection failed');
557
- });
558
-
559
- it('should create agent with minimal params (only required fields)', async () => {
560
- mockCreateAgent.mockResolvedValue({
561
- agentId: 'minimal-agent-id',
562
- sessionId: 'minimal-session-id',
563
- });
564
-
565
- const ctx: BuiltinToolContext = {
566
- ...createMockContext(),
567
- groupId: 'test-group-id',
568
- };
569
-
570
- const result = await groupManagementExecutor.createAgent(
571
- { title: 'Minimal Agent', systemRole: 'Basic assistant' },
572
- ctx,
573
- );
574
-
575
- expect(result.success).toBe(true);
576
- expect(mockCreateAgent).toHaveBeenCalledWith({
577
- config: {
578
- avatar: undefined,
579
- description: undefined,
580
- systemRole: 'Basic assistant',
581
- title: 'Minimal Agent',
582
- virtual: true,
583
- },
584
- groupId: 'test-group-id',
585
- });
586
- });
587
- });
588
-
589
- describe('executeTask', () => {
286
+ describe('executeAgentTask', () => {
590
287
  beforeEach(() => {
591
288
  vi.clearAllMocks();
592
289
  });
@@ -594,7 +291,7 @@ describe('GroupManagementExecutor', () => {
594
291
  it('should return stop=true to terminate supervisor execution', async () => {
595
292
  const ctx = createMockContext();
596
293
 
597
- const result = await groupManagementExecutor.executeTask(
294
+ const result = await groupManagementExecutor.executeAgentTask(
598
295
  { agentId: 'agent-1', task: 'Do something' },
599
296
  ctx,
600
297
  );
@@ -606,7 +303,7 @@ describe('GroupManagementExecutor', () => {
606
303
  agentId: 'agent-1',
607
304
  task: 'Do something',
608
305
  timeout: undefined,
609
- type: 'executeTask',
306
+ type: 'executeAgentTask',
610
307
  });
611
308
  });
612
309
 
@@ -628,7 +325,7 @@ describe('GroupManagementExecutor', () => {
628
325
  registerAfterCompletion,
629
326
  );
630
327
 
631
- await groupManagementExecutor.executeTask(
328
+ await groupManagementExecutor.executeAgentTask(
632
329
  { agentId: 'agent-1', task: 'Do something', timeout: 30000 },
633
330
  ctx,
634
331
  );
@@ -653,7 +350,7 @@ describe('GroupManagementExecutor', () => {
653
350
  it('should not fail when groupOrchestration is not available', async () => {
654
351
  const ctx = createMockContext();
655
352
 
656
- const result = await groupManagementExecutor.executeTask(
353
+ const result = await groupManagementExecutor.executeAgentTask(
657
354
  { agentId: 'agent-1', task: 'Do something' },
658
355
  ctx,
659
356
  );
@@ -665,7 +362,7 @@ describe('GroupManagementExecutor', () => {
665
362
  it('should include timeout in state when provided', async () => {
666
363
  const ctx = createMockContext();
667
364
 
668
- const result = await groupManagementExecutor.executeTask(
365
+ const result = await groupManagementExecutor.executeAgentTask(
669
366
  { agentId: 'agent-1', task: 'Do something', timeout: 60000 },
670
367
  ctx,
671
368
  );
@@ -675,7 +372,7 @@ describe('GroupManagementExecutor', () => {
675
372
  agentId: 'agent-1',
676
373
  task: 'Do something',
677
374
  timeout: 60000,
678
- type: 'executeTask',
375
+ type: 'executeAgentTask',
679
376
  });
680
377
  });
681
378
  });
@@ -3,10 +3,11 @@
3
3
  * Lobe Group Management Executor
4
4
  *
5
5
  * Handles all group management tool calls for multi-agent orchestration.
6
+ * Note: Member management (searchAgent, inviteAgent, createAgent, removeAgent)
7
+ * is handled by group-agent-builder. This executor focuses on orchestration.
6
8
  */
7
9
  import {
8
10
  BroadcastParams,
9
- CreateAgentParams,
10
11
  CreateWorkflowParams,
11
12
  DelegateParams,
12
13
  ExecuteTaskParams,
@@ -14,9 +15,6 @@ import {
14
15
  GroupManagementApiName,
15
16
  GroupManagementIdentifier,
16
17
  InterruptParams,
17
- InviteAgentParams,
18
- RemoveAgentParams,
19
- SearchAgentParams,
20
18
  SpeakParams,
21
19
  SummarizeParams,
22
20
  VoteParams,
@@ -24,166 +22,13 @@ import {
24
22
  import { formatAgentProfile } from '@lobechat/prompts';
25
23
  import { BaseExecutor, type BuiltinToolContext, type BuiltinToolResult } from '@lobechat/types';
26
24
 
27
- import { agentService } from '@/services/agent';
28
25
  import { agentGroupSelectors, useAgentGroupStore } from '@/store/agentGroup';
29
26
 
30
27
  class GroupManagementExecutor extends BaseExecutor<typeof GroupManagementApiName> {
31
28
  readonly identifier = GroupManagementIdentifier;
32
29
  protected readonly apiEnum = GroupManagementApiName;
33
30
 
34
- // ==================== Member Management ====================
35
-
36
- searchAgent = async (
37
- params: SearchAgentParams,
38
- _ctx: BuiltinToolContext,
39
- ): Promise<BuiltinToolResult> => {
40
- const { query, limit = 10, source = 'user' } = params;
41
-
42
- // Currently only support searching user's own agents
43
- // Community search can be added in the future
44
- if (source === 'community') {
45
- return {
46
- content:
47
- 'Community agent search is not yet supported. Please use source="user" to search your own agents.',
48
- state: { agents: [], source, total: 0 },
49
- success: true,
50
- };
51
- }
52
-
53
- try {
54
- const results = await agentService.queryAgents({ keyword: query, limit });
55
-
56
- const agents = results.map((agent) => ({
57
- avatar: agent.avatar,
58
- description: agent.description,
59
- id: agent.id,
60
- title: agent.title,
61
- }));
62
-
63
- const total = agents.length;
64
-
65
- if (total === 0) {
66
- return {
67
- content: query
68
- ? `No agents found matching "${query}".`
69
- : 'No agents found. You can create a new agent or search with different keywords.',
70
- state: { agents: [], query, total: 0 },
71
- success: true,
72
- };
73
- }
74
-
75
- // Format agents list for LLM consumption
76
- const agentList = agents
77
- .map(
78
- (a, i) =>
79
- `${i + 1}. ${a.title || 'Untitled'} (ID: ${a.id})${a.description ? ` - ${a.description}` : ''}`,
80
- )
81
- .join('\n');
82
-
83
- return {
84
- content: `Found ${total} agent${total > 1 ? 's' : ''} matching "${query}":\n${agentList}`,
85
- state: { agents, query, total },
86
- success: true,
87
- };
88
- } catch (error) {
89
- return {
90
- content: `Failed to search agents: ${error instanceof Error ? error.message : 'Unknown error'}`,
91
- success: false,
92
- };
93
- }
94
- };
95
-
96
- inviteAgent = async (
97
- params: InviteAgentParams,
98
- ctx: BuiltinToolContext,
99
- ): Promise<BuiltinToolResult> => {
100
- const { groupId } = ctx;
101
-
102
- if (!groupId) {
103
- return { content: 'No group context available', success: false };
104
- }
105
-
106
- try {
107
- await useAgentGroupStore.getState().addAgentsToGroup(groupId, [params.agentId]);
108
-
109
- return {
110
- content: `Agent "${params.agentId}" has been invited to the group.`,
111
- state: { agentId: params.agentId, type: 'inviteAgent' },
112
- success: true,
113
- };
114
- } catch (error) {
115
- return {
116
- content: `Failed to invite agent "${params.agentId}": ${error instanceof Error ? error.message : 'Unknown error'}`,
117
- success: false,
118
- };
119
- }
120
- };
121
-
122
- createAgent = async (
123
- params: CreateAgentParams,
124
- ctx: BuiltinToolContext,
125
- ): Promise<BuiltinToolResult> => {
126
- const { groupId } = ctx;
127
-
128
- if (!groupId) {
129
- return { content: 'No group context available', success: false };
130
- }
131
-
132
- try {
133
- // Create a virtual agent (agents created by supervisor are virtual)
134
- const result = await agentService.createAgent({
135
- config: {
136
- avatar: params.avatar,
137
- description: params.description,
138
- systemRole: params.systemRole,
139
- title: params.title,
140
- virtual: true,
141
- },
142
- groupId,
143
- });
144
-
145
- if (!result.agentId) {
146
- return { content: 'Failed to create agent: No agent ID returned', success: false };
147
- }
148
-
149
- return {
150
- content: `Agent "${params.title}" has been created and added to the group.`,
151
- state: { agentId: result.agentId, title: params.title, type: 'createAgent' },
152
- success: true,
153
- };
154
- } catch (error) {
155
- return {
156
- content: `Failed to create agent: ${error instanceof Error ? error.message : 'Unknown error'}`,
157
- success: false,
158
- };
159
- }
160
- };
161
-
162
- removeAgent = async (
163
- params: RemoveAgentParams,
164
- ctx: BuiltinToolContext,
165
- ): Promise<BuiltinToolResult> => {
166
- const { groupId } = ctx;
167
-
168
- if (!groupId) {
169
- return { content: 'No group context available', success: false };
170
- }
171
-
172
- try {
173
- await useAgentGroupStore.getState().removeAgentFromGroup(groupId, params.agentId);
174
-
175
- return {
176
- content: `Agent "${params.agentId}" has been removed from the group.`,
177
- state: { agentId: params.agentId, type: 'removeAgent' },
178
- success: true,
179
- };
180
- } catch (error) {
181
- return {
182
- content: `Failed to remove agent "${params.agentId}": ${error instanceof Error ? error.message : 'Unknown error'}`,
183
- success: false,
184
- };
185
- }
186
- };
31
+ // ==================== Agent Info ====================
187
32
 
188
33
  getAgentInfo = async (
189
34
  params: GetAgentInfoParams,
@@ -306,7 +151,7 @@ class GroupManagementExecutor extends BaseExecutor<typeof GroupManagementApiName
306
151
 
307
152
  // ==================== Task Execution ====================
308
153
 
309
- executeTask = async (
154
+ executeAgentTask = async (
310
155
  params: ExecuteTaskParams,
311
156
  ctx: BuiltinToolContext,
312
157
  ): Promise<BuiltinToolResult> => {
@@ -333,7 +178,7 @@ class GroupManagementExecutor extends BaseExecutor<typeof GroupManagementApiName
333
178
  skipCallSupervisor: params.skipCallSupervisor,
334
179
  task: params.task,
335
180
  timeout: params.timeout,
336
- type: 'executeTask',
181
+ type: 'executeAgentTask',
337
182
  },
338
183
  stop: true,
339
184
  success: true,