@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.
- package/CHANGELOG.md +50 -0
- package/Dockerfile +44 -52
- package/changelog/v2.json +18 -0
- package/locales/ar/chat.json +4 -0
- package/locales/ar/models.json +65 -0
- package/locales/bg-BG/chat.json +4 -0
- package/locales/bg-BG/models.json +10 -0
- package/locales/de-DE/chat.json +4 -0
- package/locales/de-DE/models.json +41 -0
- package/locales/en-US/chat.json +4 -0
- package/locales/es-ES/chat.json +4 -0
- package/locales/es-ES/models.json +50 -0
- package/locales/fa-IR/chat.json +4 -0
- package/locales/fa-IR/models.json +39 -0
- package/locales/fr-FR/chat.json +4 -0
- package/locales/fr-FR/models.json +9 -0
- package/locales/it-IT/chat.json +4 -0
- package/locales/it-IT/models.json +62 -0
- package/locales/ja-JP/chat.json +4 -0
- package/locales/ja-JP/models.json +40 -0
- package/locales/ko-KR/chat.json +4 -0
- package/locales/ko-KR/models.json +31 -0
- package/locales/nl-NL/chat.json +4 -0
- package/locales/nl-NL/models.json +52 -0
- package/locales/pl-PL/chat.json +4 -0
- package/locales/pl-PL/models.json +43 -0
- package/locales/pt-BR/chat.json +4 -0
- package/locales/pt-BR/models.json +92 -0
- package/locales/ru-RU/chat.json +4 -0
- package/locales/ru-RU/models.json +34 -0
- package/locales/tr-TR/chat.json +4 -0
- package/locales/tr-TR/models.json +55 -0
- package/locales/vi-VN/chat.json +4 -0
- package/locales/vi-VN/models.json +31 -0
- package/locales/zh-CN/chat.json +4 -0
- package/locales/zh-TW/chat.json +4 -0
- package/package.json +1 -1
- package/packages/agent-runtime/src/groupOrchestration/GroupOrchestrationSupervisor.ts +18 -1
- package/packages/agent-runtime/src/groupOrchestration/__tests__/GroupOrchestrationSupervisor.test.ts +76 -5
- package/packages/agent-runtime/src/groupOrchestration/types.ts +3 -3
- package/packages/builtin-tool-group-management/src/client/Intervention/ExecuteTask.tsx +11 -11
- package/packages/builtin-tool-group-management/src/client/Intervention/ExecuteTasks.tsx +78 -79
- package/packages/builtin-tool-group-management/src/client/Render/ExecuteTask/index.tsx +3 -3
- package/packages/builtin-tool-group-management/src/client/Render/ExecuteTasks/index.tsx +61 -63
- package/packages/builtin-tool-group-management/src/client/Streaming/ExecuteTask/index.tsx +3 -3
- package/packages/builtin-tool-group-management/src/executor.test.ts +7 -9
- package/packages/builtin-tool-group-management/src/executor.ts +3 -3
- package/packages/builtin-tool-group-management/src/manifest.ts +49 -50
- package/packages/builtin-tool-group-management/src/systemRole.ts +153 -5
- package/packages/builtin-tool-group-management/src/types.ts +3 -2
- package/packages/builtin-tool-gtd/src/systemRole.ts +4 -4
- package/packages/context-engine/src/processors/TasksFlatten.ts +7 -5
- package/packages/context-engine/src/processors/__tests__/TasksFlatten.test.ts +164 -0
- package/packages/conversation-flow/src/__tests__/fixtures/inputs/agentGroup/index.ts +4 -0
- package/packages/conversation-flow/src/__tests__/fixtures/inputs/agentGroup/supervisor-after-multi-tasks.json +91 -0
- package/packages/conversation-flow/src/__tests__/fixtures/inputs/agentGroup/supervisor-content-only.json +74 -0
- package/packages/conversation-flow/src/__tests__/parse.test.ts +37 -0
- package/packages/conversation-flow/src/transformation/FlatListBuilder.ts +70 -4
- package/packages/conversation-flow/src/transformation/__tests__/FlatListBuilder.test.ts +147 -0
- package/packages/model-bank/src/aiModels/cerebras.ts +2 -22
- package/packages/model-bank/src/aiModels/google.ts +1 -44
- package/packages/model-bank/src/aiModels/nvidia.ts +12 -16
- package/packages/model-bank/src/aiModels/siliconcloud.ts +20 -0
- package/packages/model-bank/src/aiModels/volcengine.ts +69 -0
- package/packages/model-bank/src/aiModels/wenxin.ts +41 -38
- package/packages/model-bank/src/aiModels/zhipu.ts +58 -28
- package/packages/model-bank/src/types/aiModel.ts +29 -0
- package/packages/model-runtime/src/core/usageConverters/utils/computeChatCost.test.ts +2 -2
- package/packages/model-runtime/src/providers/google/createImage.test.ts +12 -12
- package/packages/model-runtime/src/providers/openrouter/index.test.ts +102 -0
- package/packages/model-runtime/src/providers/openrouter/index.ts +19 -7
- package/packages/model-runtime/src/providers/vercelaigateway/index.test.ts +47 -0
- package/packages/model-runtime/src/providers/vercelaigateway/index.ts +7 -1
- package/packages/types/src/message/ui/chat.ts +2 -0
- package/packages/types/src/tool/builtin.ts +5 -5
- package/src/features/Conversation/ChatItem/components/Title.tsx +1 -1
- package/src/features/Conversation/ChatList/index.tsx +0 -1
- package/src/features/Conversation/Messages/GroupTasks/TaskItem/ClientTaskItem.tsx +183 -0
- package/src/features/Conversation/Messages/GroupTasks/TaskItem/ServerTaskItem.tsx +94 -0
- package/src/features/Conversation/Messages/GroupTasks/TaskItem/TaskTitle.tsx +177 -0
- package/src/features/Conversation/Messages/GroupTasks/TaskItem/index.tsx +26 -0
- package/src/features/Conversation/Messages/GroupTasks/TaskItem/useClientTaskStats.ts +93 -0
- package/src/features/Conversation/Messages/GroupTasks/index.tsx +151 -0
- package/src/features/Conversation/Messages/Supervisor/index.tsx +7 -1
- package/src/features/Conversation/Messages/Task/ClientTaskDetail/index.tsx +72 -91
- package/src/features/Conversation/Messages/Task/TaskDetailPanel/StatusContent.tsx +46 -17
- package/src/features/Conversation/Messages/Tasks/TaskItem/ClientTaskItem.tsx +9 -24
- package/src/features/Conversation/Messages/Tasks/TaskItem/ServerTaskItem.tsx +18 -38
- package/src/features/Conversation/Messages/Tasks/shared/ErrorState.tsx +45 -2
- package/src/features/Conversation/Messages/Tasks/shared/InitializingState.tsx +16 -1
- package/src/features/Conversation/Messages/Tasks/shared/TaskContent.tsx +68 -0
- package/src/features/Conversation/Messages/Tasks/shared/TaskMessages.tsx +383 -0
- package/src/features/Conversation/Messages/Tasks/shared/index.ts +4 -0
- package/src/features/Conversation/Messages/Tasks/shared/useTaskPolling.ts +48 -0
- package/src/features/Conversation/Messages/index.tsx +5 -0
- package/src/locales/default/chat.ts +4 -0
- package/src/server/modules/AgentRuntime/RuntimeExecutors.ts +4 -0
- package/src/server/modules/AgentRuntime/__tests__/RuntimeExecutors.test.ts +106 -1
- package/src/server/services/aiAgent/__tests__/execAgent.threadId.test.ts +2 -2
- package/src/server/utils/truncateToolResult.ts +1 -4
- package/src/store/chat/agents/GroupOrchestration/__tests__/batch-exec-async-tasks.test.ts +15 -15
- package/src/store/chat/agents/GroupOrchestration/createGroupOrchestrationExecutors.ts +22 -15
- package/src/store/chat/agents/__tests__/createAgentExecutors/exec-tasks.test.ts +21 -10
- package/src/store/chat/agents/createAgentExecutors.ts +2 -0
- package/src/store/chat/slices/aiAgent/actions/groupOrchestration.ts +10 -7
- package/src/features/Conversation/Messages/Task/ClientTaskDetail/CompletedState.tsx +0 -108
- package/src/features/Conversation/Messages/Task/ClientTaskDetail/InstructionAccordion.tsx +0 -63
- 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',
|
|
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
|
-
|
|
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',
|
|
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',
|
|
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',
|
|
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
|
-
|
|
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,
|
|
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
|
-
|
|
103
|
+
instruction: {
|
|
104
104
|
description:
|
|
105
|
-
'Clear
|
|
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', '
|
|
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
|
|
87
|
+
Does the task require extended, multi-step work?
|
|
88
|
+
(complex creation, deep research, lengthy generation)
|
|
50
89
|
│
|
|
51
|
-
├─── YES ──→
|
|
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 ───→
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
});
|