@lobehub/lobehub 2.0.9 → 2.0.11

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 (108) hide show
  1. package/CHANGELOG.md +50 -0
  2. package/Dockerfile +44 -52
  3. package/changelog/v2.json +18 -0
  4. package/locales/ar/chat.json +4 -0
  5. package/locales/ar/models.json +65 -0
  6. package/locales/bg-BG/chat.json +4 -0
  7. package/locales/bg-BG/models.json +10 -0
  8. package/locales/de-DE/chat.json +4 -0
  9. package/locales/de-DE/models.json +41 -0
  10. package/locales/en-US/chat.json +4 -0
  11. package/locales/es-ES/chat.json +4 -0
  12. package/locales/es-ES/models.json +50 -0
  13. package/locales/fa-IR/chat.json +4 -0
  14. package/locales/fa-IR/models.json +39 -0
  15. package/locales/fr-FR/chat.json +4 -0
  16. package/locales/fr-FR/models.json +9 -0
  17. package/locales/it-IT/chat.json +4 -0
  18. package/locales/it-IT/models.json +62 -0
  19. package/locales/ja-JP/chat.json +4 -0
  20. package/locales/ja-JP/models.json +40 -0
  21. package/locales/ko-KR/chat.json +4 -0
  22. package/locales/ko-KR/models.json +31 -0
  23. package/locales/nl-NL/chat.json +4 -0
  24. package/locales/nl-NL/models.json +52 -0
  25. package/locales/pl-PL/chat.json +4 -0
  26. package/locales/pl-PL/models.json +43 -0
  27. package/locales/pt-BR/chat.json +4 -0
  28. package/locales/pt-BR/models.json +92 -0
  29. package/locales/ru-RU/chat.json +4 -0
  30. package/locales/ru-RU/models.json +34 -0
  31. package/locales/tr-TR/chat.json +4 -0
  32. package/locales/tr-TR/models.json +55 -0
  33. package/locales/vi-VN/chat.json +4 -0
  34. package/locales/vi-VN/models.json +31 -0
  35. package/locales/zh-CN/chat.json +4 -0
  36. package/locales/zh-TW/chat.json +4 -0
  37. package/package.json +1 -1
  38. package/packages/agent-runtime/src/groupOrchestration/GroupOrchestrationSupervisor.ts +18 -1
  39. package/packages/agent-runtime/src/groupOrchestration/__tests__/GroupOrchestrationSupervisor.test.ts +76 -5
  40. package/packages/agent-runtime/src/groupOrchestration/types.ts +3 -3
  41. package/packages/builtin-tool-group-management/src/client/Intervention/ExecuteTask.tsx +11 -11
  42. package/packages/builtin-tool-group-management/src/client/Intervention/ExecuteTasks.tsx +78 -79
  43. package/packages/builtin-tool-group-management/src/client/Render/ExecuteTask/index.tsx +3 -3
  44. package/packages/builtin-tool-group-management/src/client/Render/ExecuteTasks/index.tsx +61 -63
  45. package/packages/builtin-tool-group-management/src/client/Streaming/ExecuteTask/index.tsx +3 -3
  46. package/packages/builtin-tool-group-management/src/executor.test.ts +7 -9
  47. package/packages/builtin-tool-group-management/src/executor.ts +3 -3
  48. package/packages/builtin-tool-group-management/src/manifest.ts +49 -50
  49. package/packages/builtin-tool-group-management/src/systemRole.ts +153 -5
  50. package/packages/builtin-tool-group-management/src/types.ts +3 -2
  51. package/packages/builtin-tool-gtd/src/systemRole.ts +4 -4
  52. package/packages/context-engine/src/processors/TasksFlatten.ts +7 -5
  53. package/packages/context-engine/src/processors/__tests__/TasksFlatten.test.ts +164 -0
  54. package/packages/conversation-flow/src/__tests__/fixtures/inputs/agentGroup/index.ts +4 -0
  55. package/packages/conversation-flow/src/__tests__/fixtures/inputs/agentGroup/supervisor-after-multi-tasks.json +91 -0
  56. package/packages/conversation-flow/src/__tests__/fixtures/inputs/agentGroup/supervisor-content-only.json +74 -0
  57. package/packages/conversation-flow/src/__tests__/parse.test.ts +37 -0
  58. package/packages/conversation-flow/src/transformation/FlatListBuilder.ts +70 -4
  59. package/packages/conversation-flow/src/transformation/__tests__/FlatListBuilder.test.ts +147 -0
  60. package/packages/model-bank/src/aiModels/cerebras.ts +2 -22
  61. package/packages/model-bank/src/aiModels/google.ts +1 -44
  62. package/packages/model-bank/src/aiModels/nvidia.ts +12 -16
  63. package/packages/model-bank/src/aiModels/siliconcloud.ts +20 -0
  64. package/packages/model-bank/src/aiModels/volcengine.ts +69 -0
  65. package/packages/model-bank/src/aiModels/wenxin.ts +41 -38
  66. package/packages/model-bank/src/aiModels/zhipu.ts +58 -28
  67. package/packages/model-bank/src/types/aiModel.ts +29 -0
  68. package/packages/model-runtime/src/core/usageConverters/utils/computeChatCost.test.ts +2 -2
  69. package/packages/model-runtime/src/providers/google/createImage.test.ts +12 -12
  70. package/packages/model-runtime/src/providers/openrouter/index.test.ts +102 -0
  71. package/packages/model-runtime/src/providers/openrouter/index.ts +19 -7
  72. package/packages/model-runtime/src/providers/vercelaigateway/index.test.ts +47 -0
  73. package/packages/model-runtime/src/providers/vercelaigateway/index.ts +7 -1
  74. package/packages/types/src/message/ui/chat.ts +2 -0
  75. package/packages/types/src/tool/builtin.ts +5 -5
  76. package/src/features/Conversation/ChatItem/components/Title.tsx +1 -1
  77. package/src/features/Conversation/ChatList/index.tsx +0 -1
  78. package/src/features/Conversation/Messages/GroupTasks/TaskItem/ClientTaskItem.tsx +183 -0
  79. package/src/features/Conversation/Messages/GroupTasks/TaskItem/ServerTaskItem.tsx +94 -0
  80. package/src/features/Conversation/Messages/GroupTasks/TaskItem/TaskTitle.tsx +177 -0
  81. package/src/features/Conversation/Messages/GroupTasks/TaskItem/index.tsx +26 -0
  82. package/src/features/Conversation/Messages/GroupTasks/TaskItem/useClientTaskStats.ts +93 -0
  83. package/src/features/Conversation/Messages/GroupTasks/index.tsx +151 -0
  84. package/src/features/Conversation/Messages/Supervisor/index.tsx +7 -1
  85. package/src/features/Conversation/Messages/Task/ClientTaskDetail/index.tsx +72 -91
  86. package/src/features/Conversation/Messages/Task/TaskDetailPanel/StatusContent.tsx +46 -17
  87. package/src/features/Conversation/Messages/Tasks/TaskItem/ClientTaskItem.tsx +9 -24
  88. package/src/features/Conversation/Messages/Tasks/TaskItem/ServerTaskItem.tsx +18 -38
  89. package/src/features/Conversation/Messages/Tasks/shared/ErrorState.tsx +45 -2
  90. package/src/features/Conversation/Messages/Tasks/shared/InitializingState.tsx +16 -1
  91. package/src/features/Conversation/Messages/Tasks/shared/TaskContent.tsx +68 -0
  92. package/src/features/Conversation/Messages/Tasks/shared/TaskMessages.tsx +383 -0
  93. package/src/features/Conversation/Messages/Tasks/shared/index.ts +4 -0
  94. package/src/features/Conversation/Messages/Tasks/shared/useTaskPolling.ts +48 -0
  95. package/src/features/Conversation/Messages/index.tsx +5 -0
  96. package/src/locales/default/chat.ts +4 -0
  97. package/src/server/modules/AgentRuntime/RuntimeExecutors.ts +4 -0
  98. package/src/server/modules/AgentRuntime/__tests__/RuntimeExecutors.test.ts +106 -1
  99. package/src/server/services/aiAgent/__tests__/execAgent.threadId.test.ts +2 -2
  100. package/src/server/utils/truncateToolResult.ts +1 -4
  101. package/src/store/chat/agents/GroupOrchestration/__tests__/batch-exec-async-tasks.test.ts +15 -15
  102. package/src/store/chat/agents/GroupOrchestration/createGroupOrchestrationExecutors.ts +22 -15
  103. package/src/store/chat/agents/__tests__/createAgentExecutors/exec-tasks.test.ts +21 -10
  104. package/src/store/chat/agents/createAgentExecutors.ts +2 -0
  105. package/src/store/chat/slices/aiAgent/actions/groupOrchestration.ts +10 -7
  106. package/src/features/Conversation/Messages/Task/ClientTaskDetail/CompletedState.tsx +0 -108
  107. package/src/features/Conversation/Messages/Task/ClientTaskDetail/InstructionAccordion.tsx +0 -63
  108. package/src/features/Conversation/Messages/Task/ClientTaskDetail/ProcessingState.tsx +0 -123
@@ -284,7 +284,7 @@ describe('GroupManagementExecutor', () => {
284
284
  const ctx = createMockContext();
285
285
 
286
286
  const result = await groupManagementExecutor.executeAgentTask(
287
- { agentId: 'agent-1', task: 'Do something', title: 'Test Task' },
287
+ { agentId: 'agent-1', instruction: 'Do something', title: 'Test Task' },
288
288
  ctx,
289
289
  );
290
290
 
@@ -293,9 +293,8 @@ describe('GroupManagementExecutor', () => {
293
293
  expect(result.content).toBe('Triggered async task for agent "agent-1".');
294
294
  expect(result.state).toEqual({
295
295
  agentId: 'agent-1',
296
- task: 'Do something',
296
+ instruction: 'Do something',
297
297
  timeout: undefined,
298
- title: 'Test Task',
299
298
  type: 'executeAgentTask',
300
299
  });
301
300
  });
@@ -320,7 +319,7 @@ describe('GroupManagementExecutor', () => {
320
319
  );
321
320
 
322
321
  await groupManagementExecutor.executeAgentTask(
323
- { agentId: 'agent-1', task: 'Do something', timeout: 30000, title: 'Test Task' },
322
+ { agentId: 'agent-1', instruction: 'Do something', timeout: 30000, title: 'Test Task' },
324
323
  ctx,
325
324
  );
326
325
 
@@ -334,8 +333,8 @@ describe('GroupManagementExecutor', () => {
334
333
  // Now triggerExecuteTask should have been called
335
334
  expect(triggerExecuteTask).toHaveBeenCalledWith({
336
335
  agentId: 'agent-1',
336
+ instruction: 'Do something',
337
337
  supervisorAgentId: 'supervisor-agent',
338
- task: 'Do something',
339
338
  timeout: 30000,
340
339
  toolMessageId: 'test-message-id',
341
340
  });
@@ -345,7 +344,7 @@ describe('GroupManagementExecutor', () => {
345
344
  const ctx = createMockContext();
346
345
 
347
346
  const result = await groupManagementExecutor.executeAgentTask(
348
- { agentId: 'agent-1', task: 'Do something', title: 'Test Task' },
347
+ { agentId: 'agent-1', instruction: 'Do something', title: 'Test Task' },
349
348
  ctx,
350
349
  );
351
350
 
@@ -357,16 +356,15 @@ describe('GroupManagementExecutor', () => {
357
356
  const ctx = createMockContext();
358
357
 
359
358
  const result = await groupManagementExecutor.executeAgentTask(
360
- { agentId: 'agent-1', task: 'Do something', timeout: 60000, title: 'Test Task' },
359
+ { agentId: 'agent-1', instruction: 'Do something', timeout: 60000, title: 'Test Task' },
361
360
  ctx,
362
361
  );
363
362
 
364
363
  expect(result.success).toBe(true);
365
364
  expect(result.state).toEqual({
366
365
  agentId: 'agent-1',
367
- task: 'Do something',
366
+ instruction: 'Do something',
368
367
  timeout: 60000,
369
- title: 'Test Task',
370
368
  type: 'executeAgentTask',
371
369
  });
372
370
  });
@@ -124,7 +124,7 @@ class GroupManagementExecutor extends BaseExecutor<typeof GroupManagementApiName
124
124
  params: ExecuteTaskParams,
125
125
  ctx: BuiltinToolContext,
126
126
  ): Promise<BuiltinToolResult> => {
127
- const { agentId, task, timeout, skipCallSupervisor, runInClient } = params;
127
+ const { agentId, instruction, timeout, skipCallSupervisor, runInClient } = params;
128
128
 
129
129
  // Register afterCompletion callback to trigger async task execution after AgentRuntime completes
130
130
  // This follows the same pattern as speak/broadcast - trigger mode, not blocking
@@ -132,10 +132,10 @@ class GroupManagementExecutor extends BaseExecutor<typeof GroupManagementApiName
132
132
  ctx.registerAfterCompletion(() =>
133
133
  ctx.groupOrchestration!.triggerExecuteTask({
134
134
  agentId,
135
+ instruction,
135
136
  runInClient,
136
137
  skipCallSupervisor,
137
138
  supervisorAgentId: ctx.agentId!,
138
- task,
139
139
  timeout,
140
140
  toolMessageId: ctx.messageId,
141
141
  }),
@@ -147,9 +147,9 @@ class GroupManagementExecutor extends BaseExecutor<typeof GroupManagementApiName
147
147
  content: `Triggered async task for agent "${agentId}"${runInClient ? ' (client-side)' : ''}.`,
148
148
  state: {
149
149
  agentId,
150
+ instruction,
150
151
  runInClient,
151
152
  skipCallSupervisor,
152
- task,
153
153
  timeout,
154
154
  type: 'executeAgentTask',
155
155
  },
@@ -100,9 +100,9 @@ export const GroupManagementManifest: BuiltinToolManifest = {
100
100
  description: 'Brief title describing what this task does (shown in UI).',
101
101
  type: 'string',
102
102
  },
103
- task: {
103
+ instruction: {
104
104
  description:
105
- 'Clear description of the task to perform. Be specific about expected deliverables.',
105
+ 'Clear instruction describing the task to perform. Be specific about expected deliverables.',
106
106
  type: 'string',
107
107
  },
108
108
  ...(isDesktop && {
@@ -125,57 +125,56 @@ export const GroupManagementManifest: BuiltinToolManifest = {
125
125
  type: 'boolean',
126
126
  },
127
127
  },
128
- required: ['agentId', 'title', 'task'],
128
+ required: ['agentId', 'title', 'instruction'],
129
+ type: 'object',
130
+ },
131
+ },
132
+ {
133
+ description:
134
+ 'Assign multiple tasks to different agents to run in parallel. Each agent works independently in their own context. Use this when you need multiple agents to work on different parts of a problem simultaneously.',
135
+ name: GroupManagementApiName.executeAgentTasks,
136
+ humanIntervention: 'required',
137
+ parameters: {
138
+ properties: {
139
+ tasks: {
140
+ description: 'Array of tasks, each assigned to a specific agent.',
141
+ items: {
142
+ properties: {
143
+ agentId: {
144
+ description: 'The ID of the agent to execute this task.',
145
+ type: 'string',
146
+ },
147
+ title: {
148
+ description: 'Brief title describing what this task does (shown in UI).',
149
+ type: 'string',
150
+ },
151
+ instruction: {
152
+ description:
153
+ 'Detailed instruction for the agent to execute. Be specific about expected deliverables.',
154
+ type: 'string',
155
+ },
156
+ timeout: {
157
+ description:
158
+ 'Optional timeout in milliseconds for this task (default: 1800000, 30 minutes).',
159
+ type: 'number',
160
+ },
161
+ },
162
+ required: ['agentId', 'title', 'instruction'],
163
+ type: 'object',
164
+ },
165
+ type: 'array',
166
+ },
167
+ skipCallSupervisor: {
168
+ default: false,
169
+ description:
170
+ 'If true, the orchestration will end after all tasks complete, without calling the supervisor again.',
171
+ type: 'boolean',
172
+ },
173
+ },
174
+ required: ['tasks'],
129
175
  type: 'object',
130
176
  },
131
177
  },
132
- // TODO: Enable executeAgentTasks when ready
133
- // {
134
- // description:
135
- // 'Assign multiple tasks to different agents to run in parallel. Each agent works independently in their own context. Use this when you need multiple agents to work on different parts of a problem simultaneously.',
136
- // name: GroupManagementApiName.executeAgentTasks,
137
- // humanIntervention: 'required',
138
- // parameters: {
139
- // properties: {
140
- // tasks: {
141
- // description: 'Array of tasks, each assigned to a specific agent.',
142
- // items: {
143
- // properties: {
144
- // agentId: {
145
- // description: 'The ID of the agent to execute this task.',
146
- // type: 'string',
147
- // },
148
- // title: {
149
- // description: 'Brief title describing what this task does (shown in UI).',
150
- // type: 'string',
151
- // },
152
- // instruction: {
153
- // description:
154
- // 'Detailed instruction/prompt for the task execution. Be specific about expected deliverables.',
155
- // type: 'string',
156
- // },
157
- // timeout: {
158
- // description:
159
- // 'Optional timeout in milliseconds for this task (default: 1800000, 30 minutes).',
160
- // type: 'number',
161
- // },
162
- // },
163
- // required: ['agentId', 'title', 'instruction'],
164
- // type: 'object',
165
- // },
166
- // type: 'array',
167
- // },
168
- // skipCallSupervisor: {
169
- // default: false,
170
- // description:
171
- // 'If true, the orchestration will end after all tasks complete, without calling the supervisor again.',
172
- // type: 'boolean',
173
- // },
174
- // },
175
- // required: ['tasks'],
176
- // type: 'object',
177
- // },
178
- // },
179
178
  // {
180
179
  // description:
181
180
  // 'Interrupt a running agent task. Use this to stop a task that is taking too long or is no longer needed.',
@@ -40,17 +40,64 @@ Best for:
40
40
  - Reviewing/critiquing content presented in conversation
41
41
  - Discussion and debate
42
42
 
43
+ ### ⚡ Single Task Execution (executeAgentTask)
44
+ **Use when a single agent needs to do extended, multi-step work** - agent works asynchronously in isolated context.
45
+
46
+ Characteristics:
47
+ - Agent runs in background with dedicated context
48
+ - Asynchronous execution - doesn't block conversation
49
+ - Results are returned upon completion
50
+ - Supports long-running operations with configurable timeout (default 30min)
51
+
52
+ Best for:
53
+ - Complex multi-step tasks requiring extended processing
54
+ - Writing/generating lengthy code, documents, or creative content
55
+ - Deep research requiring multiple searches and synthesis
56
+ - Tasks that may take significant time to complete
57
+ - Work that benefits from focused, uninterrupted execution
58
+
59
+ ### ⚡⚡ Parallel Task Execution (executeAgentTasks)
60
+ **Use when multiple tasks need to run simultaneously** - each task runs asynchronously in its own isolated context.
61
+
62
+ Characteristics:
63
+ - Multiple tasks run in parallel, each with dedicated context
64
+ - All tasks execute independently and concurrently
65
+ - Results from all tasks are returned upon completion
66
+ - Each task can have its own timeout
67
+ - **Same agent can be assigned multiple tasks** with different instructions
68
+
69
+ Best for:
70
+ - Breaking down complex problems into parallelizable subtasks
71
+ - Assigning different aspects of work to specialized agents
72
+ - When speed matters and subtasks are independent
73
+ - Multi-agent implementation (e.g., frontend + backend + tests)
74
+ - **Batch processing**: Same agent handling multiple similar tasks with different inputs (e.g., one Researcher investigating 3 different topics in parallel)
75
+
76
+ Key difference from speak/broadcast:
77
+ - speak/broadcast: Synchronous responses in shared conversation context (quick interactions)
78
+ - executeAgentTask: Single async execution in isolated context (extended work)
79
+ - executeAgentTasks: Multiple async executions in parallel (distributed work)
80
+
43
81
  ## Decision Flowchart
44
82
 
45
83
  \`\`\`
46
84
  User Request
47
85
 
48
86
 
49
- Does the task need multiple perspectives?
87
+ Does the task require extended, multi-step work?
88
+ (complex creation, deep research, lengthy generation)
50
89
 
51
- ├─── YES ──→ broadcast (parallel speaking)
90
+ ├─── YES ──→ Can multiple agents work on different parts in parallel?
91
+ │ │
92
+ │ ├─── YES ──→ executeAgentTasks (parallel task execution)
93
+ │ │
94
+ │ └─── NO ───→ executeAgentTask (single task execution)
52
95
 
53
- └─── NO ───→ speak (single agent)
96
+ └─── NO ───→ Does the task need multiple perspectives?
97
+
98
+ ├─── YES ──→ broadcast (parallel speaking)
99
+
100
+ └─── NO ───→ speak (single agent)
54
101
  \`\`\`
55
102
  </core_decision_framework>
56
103
 
@@ -61,16 +108,40 @@ Before responding, analyze the user's intent:
61
108
  - "What do you think about...", "Any ideas for...", "How should we..."
62
109
  - "Review this...", "Give me feedback on...", "Critique..."
63
110
  - "Explain...", "Compare...", "Summarize..."
64
- - Requests for opinions, perspectives, or expertise-based answers
65
- - Questions that benefit from diverse viewpoints
111
+ - Requests for **quick opinions or perspectives based on existing knowledge**
112
+ - Questions that benefit from diverse viewpoints **without requiring research or investigation**
113
+
114
+ ⚠️ **NOT broadcast** (use executeAgentTask/executeAgentTasks instead):
115
+ - "Research...", "Investigate...", "Analyze in depth..." - these require actual work, not just opinions
116
+ - "Everyone research/investigate..." - this means each agent should do research work, not just share opinions
66
117
 
67
118
  **Signals for Single Agent (speak):**
68
119
  - Explicit request: "Ask [Agent Name] to...", "Let [Agent Name] answer..."
69
120
  - Follow-up to a specific agent's previous response
70
121
  - Task clearly matches only one agent's expertise
71
122
 
123
+ **Signals for Single Task Execution (executeAgentTask):**
124
+ - Complex multi-step work: "Develop a...", "Design and implement...", "Create a complete..."
125
+ - Extended creation: "Write a full...", "Generate a comprehensive...", "Build an entire..."
126
+ - Deep research: "Do thorough research on...", "Investigate in depth...", "Analyze extensively..."
127
+ - Time-intensive requests: Tasks that clearly need extended processing time
128
+
129
+ **Signals for Parallel Task Execution (executeAgentTasks):**
130
+ - Distributed work: "Have multiple agents work on...", "Split this into parallel tasks..."
131
+ - Multi-aspect implementation: "Build the frontend and backend...", "Create X, Y, and Z components..."
132
+ - Speed-critical requests: "Get this done as fast as possible by having agents work in parallel"
133
+ - Independent subtasks: When the problem can be decomposed into non-dependent parts
134
+ - Batch processing: "Do X for each of these: A, B, C...", "Research these 3 competitors...", "Write posts about these topics..."
135
+ - **Parallel research/investigation**: "Everyone investigate...", "Each of you research...", "All of you look into..." - when multiple agents need to do actual research work and provide findings
136
+
72
137
  **Default Behavior:**
73
138
  - When in doubt about single vs multiple agents → Lean towards broadcast for diverse perspectives
139
+ - When task involves extended, multi-step work → Use executeAgentTask for single agent, executeAgentTasks for parallel work
140
+
141
+ **Key Distinction - Opinion vs Research:**
142
+ - "Give opinions/thoughts/feedback" → broadcast (quick response from knowledge)
143
+ - "Research/investigate/analyze" → executeAgentTask/executeAgentTasks (requires actual work)
144
+ - Even if user says "give conclusions", if the task involves research or investigation, use task execution
74
145
  </user_intent_analysis>
75
146
 
76
147
  <intent_clarification>
@@ -133,6 +204,10 @@ When a user's request is broad or unclear, ask 1-2 focused questions to understa
133
204
  - **speak**: Single agent responds synchronously in group context
134
205
  - **broadcast**: Multiple agents respond in parallel in group context
135
206
 
207
+ **Task Execution:**
208
+ - **executeAgentTask**: Assign async task to single agent for extended, multi-step work
209
+ - **executeAgentTasks**: Assign multiple async tasks to different agents in parallel
210
+
136
211
  **Flow Control:**
137
212
  - **vote**: Initiate voting among agents
138
213
  </core_capabilities>
@@ -169,6 +244,75 @@ User: "Ask the frontend expert about React performance"
169
244
  Analysis: User explicitly requested specific agent
170
245
  Action: speak to frontend expert with the question
171
246
  \`\`\`
247
+
248
+ ### Pattern 4: Delegated Task Execution (executeAgentTask)
249
+ When a single agent needs extended, multi-step work that benefits from focused execution.
250
+
251
+ \`\`\`
252
+ User: "Write a complete REST API for user authentication"
253
+ Analysis: Complex multi-step task requiring extended work
254
+ Action: executeAgentTask to Backend - "Implement REST API for user authentication with JWT tokens, including login, register, and refresh endpoints"
255
+ \`\`\`
256
+
257
+ \`\`\`
258
+ User: "Do thorough research on the latest trends in AI for our product roadmap"
259
+ Analysis: Deep research requiring extensive investigation and synthesis
260
+ Action: executeAgentTask to Researcher - "Research current AI trends relevant to [product context], compile findings with sources and recommendations"
261
+ \`\`\`
262
+
263
+ ### Pattern 5: Parallel Task Execution (executeAgentTasks)
264
+ When multiple tasks can run simultaneously - either by different agents OR the same agent with different instructions.
265
+
266
+ **Different agents working on different parts:**
267
+ \`\`\`
268
+ User: "Build a user dashboard with frontend, backend API, and database schema"
269
+ Analysis: Can be split into independent parallel tasks for each agent
270
+ Action: executeAgentTasks with:
271
+ - Frontend: "Build React dashboard UI with charts and user stats"
272
+ - Backend: "Implement REST API endpoints for dashboard data"
273
+ - DBA: "Design database schema for user metrics and analytics"
274
+ \`\`\`
275
+
276
+ **Same agent with different instructions (batch processing):**
277
+ \`\`\`
278
+ User: "Research these 3 competitors: Company A, Company B, Company C"
279
+ Analysis: Same type of task with different inputs - assign to same agent 3 times
280
+ Action: executeAgentTasks with:
281
+ - Researcher: "Research Company A - analyze their product, pricing, and market position"
282
+ - Researcher: "Research Company B - analyze their product, pricing, and market position"
283
+ - Researcher: "Research Company C - analyze their product, pricing, and market position"
284
+ \`\`\`
285
+
286
+ \`\`\`
287
+ User: "Write blog posts for each of these 3 topics: AI trends, Cloud computing, DevOps best practices"
288
+ Analysis: Same agent can write multiple posts in parallel
289
+ Action: executeAgentTasks with:
290
+ - Writer: "Write a blog post about AI trends in 2024"
291
+ - Writer: "Write a blog post about Cloud computing adoption"
292
+ - Writer: "Write a blog post about DevOps best practices"
293
+ \`\`\`
294
+
295
+ **Multiple agents doing research (NOT broadcast!):**
296
+ \`\`\`
297
+ User: "Help me research how X is implemented, everyone investigate and give me your conclusions"
298
+ Analysis: "research/investigate" means actual work, NOT just opinions. Each agent needs to do research and provide findings.
299
+ Action: executeAgentTasks with:
300
+ - Developer A: "Research how X implements feature Y, analyze the code structure and patterns"
301
+ - Developer B: "Research how X handles Z, document the approach and trade-offs"
302
+ - Developer C: "Research X's architecture for W, summarize key design decisions"
303
+ ⚠️ DO NOT use broadcast - "research/investigate" requires investigation work, not quick opinions!
304
+ \`\`\`
305
+
306
+ ### Pattern 6: Hybrid Workflow (Discuss then Execute)
307
+ When you need input before execution.
308
+
309
+ \`\`\`
310
+ User: "Help me build a dashboard for analytics"
311
+ Analysis: Benefits from initial discussion, then requires implementation
312
+ Action:
313
+ 1. broadcast to [Designer, Frontend, Data] - "What key metrics and layout should this analytics dashboard include?"
314
+ 2. After consensus → executeAgentTask to Frontend - "Implement dashboard based on discussed requirements"
315
+ \`\`\`
172
316
  </workflow_patterns>
173
317
 
174
318
  <tool_usage_guidelines>
@@ -176,6 +320,10 @@ Action: speak to frontend expert with the question
176
320
  - speak: \`agentId\`, \`instruction\` (optional guidance)
177
321
  - broadcast: \`agentIds\` (array), \`instruction\` (optional shared guidance)
178
322
 
323
+ **Task Execution:**
324
+ - executeAgentTask: \`agentId\`, \`title\` (brief UI label), \`task\` (detailed instructions with expected deliverables), \`timeout\` (optional, default 30min)
325
+ - executeAgentTasks: \`tasks\` (array of {agentId, title, task, timeout?}), \`skipCallSupervisor\` (optional)
326
+
179
327
  **Flow Control:**
180
328
  - vote: \`question\`, \`options\` (array of {id, label, description}), \`voterAgentIds\` (optional), \`requireReasoning\` (default true)
181
329
  </tool_usage_guidelines>
@@ -72,6 +72,8 @@ export interface DelegateParams {
72
72
 
73
73
  export interface ExecuteTaskParams {
74
74
  agentId: string;
75
+ /** Clear instruction describing the task to perform */
76
+ instruction: string;
75
77
  /**
76
78
  * Whether to run on the desktop client (for local file/shell access).
77
79
  * MUST be true when task requires local-system tools. Default is false (server execution).
@@ -83,7 +85,6 @@ export interface ExecuteTaskParams {
83
85
  * Use this when the task is the final action needed.
84
86
  */
85
87
  skipCallSupervisor?: boolean;
86
- task: string;
87
88
  timeout?: number;
88
89
  /** Brief title describing what this task does (shown in UI) */
89
90
  title: string;
@@ -92,7 +93,7 @@ export interface ExecuteTaskParams {
92
93
  export interface TaskItem {
93
94
  /** The ID of the agent to execute this task */
94
95
  agentId: string;
95
- /** Detailed instruction/prompt for the task execution */
96
+ /** Detailed instruction for the agent to execute */
96
97
  instruction: string;
97
98
  /** Optional timeout in milliseconds for this specific task */
98
99
  timeout?: number;
@@ -38,8 +38,8 @@ export const systemPrompt = `You have GTD (Getting Things Done) tools to help ma
38
38
 
39
39
  <tool_overview>
40
40
  **Planning Tools** - For high-level goal documentation:
41
- - \`createPlan\`: Create a strategic plan document with goal and context
42
- - \`updatePlan\`: Update plan details
41
+ - \`createPlan\`: Create a strategic plan document. **Required params: goal, description (brief summary), context** - all three must be provided
42
+ - \`updatePlan\`: Update plan details (only planId is required)
43
43
 
44
44
  **Todo Tools** - For actionable execution items:
45
45
  - \`createTodos\`: Create new todo items from text array
@@ -49,8 +49,8 @@ export const systemPrompt = `You have GTD (Getting Things Done) tools to help ma
49
49
  **Todo Status Workflow:** todo → processing → completed (use "processing" when actively working on an item)
50
50
 
51
51
  **Async Task Tools** - For long-running background tasks:
52
- - \`execTask\`: Execute a single async task in isolated context
53
- - \`execTasks\`: Execute multiple async tasks in parallel
52
+ - \`execTask\`: Execute a single async task. **Required params: description (brief UI label), instruction (detailed prompt)** - both must be provided
53
+ - \`execTasks\`: Execute multiple async tasks in parallel. Each task requires **description** and **instruction**
54
54
  </tool_overview>
55
55
 
56
56
  <default_workflow>
@@ -7,9 +7,11 @@ const log = debug('context-engine:processor:TasksFlattenProcessor');
7
7
 
8
8
  /**
9
9
  * Tasks Flatten Processor
10
- * Responsible for flattening role=tasks messages into individual task messages
10
+ * Responsible for flattening role=tasks and role=groupTasks messages into individual task messages
11
+ *
12
+ * - tasks: Multiple task messages with same agentId aggregated
13
+ * - groupTasks: Multiple task messages with different agentIds aggregated
11
14
  *
12
- * Tasks messages are created when multiple task messages with the same parentId are aggregated.
13
15
  * This processor converts them back to individual task messages that can be processed by TaskMessageProcessor.
14
16
  */
15
17
  export class TasksFlattenProcessor extends BaseProcessor {
@@ -30,8 +32,8 @@ export class TasksFlattenProcessor extends BaseProcessor {
30
32
 
31
33
  // Process each message
32
34
  for (const message of clonedContext.messages) {
33
- // Check if this is a tasks message with tasks field
34
- if (message.role === 'tasks' && message.tasks) {
35
+ // Check if this is a tasks or groupTasks message with tasks field
36
+ if (['tasks', 'groupTasks'].includes(message.role) && message.tasks) {
35
37
  // If tasks array is empty, skip this message entirely (no content to flatten)
36
38
  if (message.tasks.length === 0) {
37
39
  continue;
@@ -40,7 +42,7 @@ export class TasksFlattenProcessor extends BaseProcessor {
40
42
  processedCount++;
41
43
  tasksMessagesFlattened++;
42
44
 
43
- log(`Flattening tasks message ${message.id} with ${message.tasks.length} tasks`);
45
+ log(`Flattening ${message.role} message ${message.id} with ${message.tasks.length} tasks`);
44
46
 
45
47
  // Flatten each task
46
48
  for (const task of message.tasks) {
@@ -188,4 +188,168 @@ describe('TasksFlattenProcessor', () => {
188
188
  expect(result.metadata.tasksMessagesFlattened).toBe(1);
189
189
  expect(result.metadata.taskMessagesCreated).toBe(2);
190
190
  });
191
+
192
+ describe('groupTasks handling', () => {
193
+ it('should flatten groupTasks message into individual task messages', async () => {
194
+ const processor = new TasksFlattenProcessor();
195
+
196
+ const context = {
197
+ messages: [
198
+ {
199
+ content: 'Hello',
200
+ id: 'msg-1',
201
+ role: 'user',
202
+ },
203
+ {
204
+ id: 'groupTasks-1',
205
+ role: 'groupTasks',
206
+ tasks: [
207
+ {
208
+ agentId: 'agent-1',
209
+ content: 'Task 1 result',
210
+ id: 'task-1',
211
+ metadata: { instruction: 'Do task 1' },
212
+ role: 'task',
213
+ },
214
+ {
215
+ agentId: 'agent-2',
216
+ content: 'Task 2 result',
217
+ id: 'task-2',
218
+ metadata: { instruction: 'Do task 2' },
219
+ role: 'task',
220
+ },
221
+ {
222
+ agentId: 'agent-3',
223
+ content: 'Task 3 result',
224
+ id: 'task-3',
225
+ metadata: { instruction: 'Do task 3' },
226
+ role: 'task',
227
+ },
228
+ ],
229
+ },
230
+ ],
231
+ metadata: {},
232
+ stats: { startTime: Date.now() },
233
+ };
234
+
235
+ const result = await processor.process(context as any);
236
+
237
+ // Should have 4 messages: 1 user + 3 flattened tasks
238
+ expect(result.messages).toHaveLength(4);
239
+ expect(result.messages[0].role).toBe('user');
240
+ expect(result.messages[1].role).toBe('task');
241
+ expect(result.messages[1].id).toBe('task-1');
242
+ expect(result.messages[1].agentId).toBe('agent-1');
243
+ expect(result.messages[2].role).toBe('task');
244
+ expect(result.messages[2].id).toBe('task-2');
245
+ expect(result.messages[2].agentId).toBe('agent-2');
246
+ expect(result.messages[3].role).toBe('task');
247
+ expect(result.messages[3].id).toBe('task-3');
248
+ expect(result.messages[3].agentId).toBe('agent-3');
249
+ });
250
+
251
+ it('should skip empty groupTasks array', async () => {
252
+ const processor = new TasksFlattenProcessor();
253
+
254
+ const context = {
255
+ messages: [
256
+ {
257
+ content: 'Hello',
258
+ id: 'msg-1',
259
+ role: 'user',
260
+ },
261
+ {
262
+ id: 'groupTasks-1',
263
+ role: 'groupTasks',
264
+ tasks: [],
265
+ },
266
+ ],
267
+ metadata: {},
268
+ stats: { startTime: Date.now() },
269
+ };
270
+
271
+ const result = await processor.process(context as any);
272
+
273
+ // Should only have user message, empty groupTasks should be skipped
274
+ expect(result.messages).toHaveLength(1);
275
+ expect(result.messages[0].role).toBe('user');
276
+ });
277
+
278
+ it('should preserve parent message references for groupTasks', async () => {
279
+ const processor = new TasksFlattenProcessor();
280
+
281
+ const context = {
282
+ messages: [
283
+ {
284
+ groupId: 'group-1',
285
+ id: 'groupTasks-1',
286
+ parentId: 'parent-1',
287
+ role: 'groupTasks',
288
+ tasks: [
289
+ {
290
+ agentId: 'agent-1',
291
+ content: 'Task result',
292
+ id: 'task-1',
293
+ role: 'task',
294
+ },
295
+ ],
296
+ threadId: 'thread-1',
297
+ topicId: 'topic-1',
298
+ },
299
+ ],
300
+ metadata: {},
301
+ stats: { startTime: Date.now() },
302
+ };
303
+
304
+ const result = await processor.process(context as any);
305
+
306
+ expect(result.messages).toHaveLength(1);
307
+ expect(result.messages[0].parentId).toBe('parent-1');
308
+ expect(result.messages[0].threadId).toBe('thread-1');
309
+ expect(result.messages[0].groupId).toBe('group-1');
310
+ expect(result.messages[0].topicId).toBe('topic-1');
311
+ });
312
+
313
+ it('should handle mixed tasks and groupTasks messages', async () => {
314
+ const processor = new TasksFlattenProcessor();
315
+
316
+ const context = {
317
+ messages: [
318
+ {
319
+ id: 'tasks-1',
320
+ role: 'tasks',
321
+ tasks: [{ content: 'Task A', id: 'task-a', role: 'task' }],
322
+ },
323
+ {
324
+ content: 'User message',
325
+ id: 'msg-1',
326
+ role: 'user',
327
+ },
328
+ {
329
+ id: 'groupTasks-1',
330
+ role: 'groupTasks',
331
+ tasks: [
332
+ { agentId: 'agent-1', content: 'Task B', id: 'task-b', role: 'task' },
333
+ { agentId: 'agent-2', content: 'Task C', id: 'task-c', role: 'task' },
334
+ ],
335
+ },
336
+ ],
337
+ metadata: {},
338
+ stats: { startTime: Date.now() },
339
+ };
340
+
341
+ const result = await processor.process(context as any);
342
+
343
+ // Should have 4 messages: 1 from tasks + 1 user + 2 from groupTasks
344
+ expect(result.messages).toHaveLength(4);
345
+ expect(result.messages[0].id).toBe('task-a');
346
+ expect(result.messages[1].id).toBe('msg-1');
347
+ expect(result.messages[2].id).toBe('task-b');
348
+ expect(result.messages[3].id).toBe('task-c');
349
+
350
+ // Metadata should count both
351
+ expect(result.metadata.tasksMessagesFlattened).toBe(2);
352
+ expect(result.metadata.taskMessagesCreated).toBe(3);
353
+ });
354
+ });
191
355
  });