omgkit 2.1.1 → 2.2.0
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/package.json +1 -1
- package/plugin/skills/SKILL_STANDARDS.md +743 -0
- package/plugin/skills/databases/mongodb/SKILL.md +797 -28
- package/plugin/skills/databases/prisma/SKILL.md +776 -30
- package/plugin/skills/databases/redis/SKILL.md +885 -25
- package/plugin/skills/devops/aws/SKILL.md +686 -28
- package/plugin/skills/devops/github-actions/SKILL.md +684 -29
- package/plugin/skills/devops/kubernetes/SKILL.md +621 -24
- package/plugin/skills/frameworks/django/SKILL.md +920 -20
- package/plugin/skills/frameworks/express/SKILL.md +1361 -35
- package/plugin/skills/frameworks/fastapi/SKILL.md +1260 -33
- package/plugin/skills/frameworks/laravel/SKILL.md +1244 -31
- package/plugin/skills/frameworks/nestjs/SKILL.md +1005 -26
- package/plugin/skills/frameworks/rails/SKILL.md +594 -28
- package/plugin/skills/frameworks/spring/SKILL.md +528 -35
- package/plugin/skills/frameworks/vue/SKILL.md +1296 -27
- package/plugin/skills/frontend/accessibility/SKILL.md +1108 -34
- package/plugin/skills/frontend/frontend-design/SKILL.md +1304 -26
- package/plugin/skills/frontend/responsive/SKILL.md +847 -21
- package/plugin/skills/frontend/shadcn-ui/SKILL.md +976 -38
- package/plugin/skills/frontend/tailwindcss/SKILL.md +831 -35
- package/plugin/skills/frontend/threejs/SKILL.md +1298 -29
- package/plugin/skills/languages/javascript/SKILL.md +935 -31
- package/plugin/skills/methodology/brainstorming/SKILL.md +597 -23
- package/plugin/skills/methodology/defense-in-depth/SKILL.md +832 -34
- package/plugin/skills/methodology/dispatching-parallel-agents/SKILL.md +665 -31
- package/plugin/skills/methodology/executing-plans/SKILL.md +556 -24
- package/plugin/skills/methodology/finishing-development-branch/SKILL.md +595 -25
- package/plugin/skills/methodology/problem-solving/SKILL.md +429 -61
- package/plugin/skills/methodology/receiving-code-review/SKILL.md +536 -24
- package/plugin/skills/methodology/requesting-code-review/SKILL.md +632 -21
- package/plugin/skills/methodology/root-cause-tracing/SKILL.md +641 -30
- package/plugin/skills/methodology/sequential-thinking/SKILL.md +262 -3
- package/plugin/skills/methodology/systematic-debugging/SKILL.md +571 -32
- package/plugin/skills/methodology/test-driven-development/SKILL.md +779 -24
- package/plugin/skills/methodology/testing-anti-patterns/SKILL.md +691 -29
- package/plugin/skills/methodology/token-optimization/SKILL.md +598 -29
- package/plugin/skills/methodology/verification-before-completion/SKILL.md +543 -22
- package/plugin/skills/methodology/writing-plans/SKILL.md +590 -18
- package/plugin/skills/omega/omega-architecture/SKILL.md +838 -39
- package/plugin/skills/omega/omega-coding/SKILL.md +636 -39
- package/plugin/skills/omega/omega-sprint/SKILL.md +855 -48
- package/plugin/skills/omega/omega-testing/SKILL.md +940 -41
- package/plugin/skills/omega/omega-thinking/SKILL.md +703 -50
- package/plugin/skills/security/better-auth/SKILL.md +1065 -28
- package/plugin/skills/security/oauth/SKILL.md +968 -31
- package/plugin/skills/security/owasp/SKILL.md +894 -33
- package/plugin/skills/testing/playwright/SKILL.md +764 -38
- package/plugin/skills/testing/pytest/SKILL.md +873 -36
- package/plugin/skills/testing/vitest/SKILL.md +980 -35
|
@@ -1,43 +1,677 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: dispatching-parallel-agents
|
|
3
|
-
description: Parallel agent
|
|
3
|
+
description: Parallel agent orchestration for maximum efficiency through concurrent task execution
|
|
4
|
+
category: methodology
|
|
5
|
+
triggers:
|
|
6
|
+
- parallel agents
|
|
7
|
+
- concurrent execution
|
|
8
|
+
- agent orchestration
|
|
9
|
+
- spawn agents
|
|
10
|
+
- parallel tasks
|
|
11
|
+
- multi-agent
|
|
12
|
+
- task parallelization
|
|
4
13
|
---
|
|
5
14
|
|
|
6
|
-
# Dispatching Parallel Agents
|
|
15
|
+
# Dispatching Parallel Agents
|
|
7
16
|
|
|
8
|
-
|
|
9
|
-
- Independent tasks
|
|
10
|
-
- No shared state
|
|
11
|
-
- Different file scopes
|
|
12
|
-
- Research + implementation
|
|
17
|
+
Master **parallel agent orchestration** for maximum efficiency through concurrent task execution. This skill provides patterns for identifying parallelizable work, dispatching agents effectively, and aggregating results.
|
|
13
18
|
|
|
14
|
-
##
|
|
19
|
+
## Purpose
|
|
20
|
+
|
|
21
|
+
Maximize development velocity through parallelization:
|
|
22
|
+
|
|
23
|
+
- Identify tasks that can run concurrently
|
|
24
|
+
- Dispatch specialized agents for different concerns
|
|
25
|
+
- Reduce total execution time significantly
|
|
26
|
+
- Maintain coordination between parallel tasks
|
|
27
|
+
- Aggregate results from multiple agents
|
|
28
|
+
- Handle failures gracefully in parallel execution
|
|
29
|
+
- Balance parallelism with resource constraints
|
|
30
|
+
|
|
31
|
+
## Features
|
|
32
|
+
|
|
33
|
+
### 1. Parallel Execution Model
|
|
34
|
+
|
|
35
|
+
```markdown
|
|
36
|
+
## Agent Orchestration Architecture
|
|
37
|
+
|
|
38
|
+
┌─────────────────────────────────────────────────────────────────────────┐
|
|
39
|
+
│ PARALLEL AGENT MODEL │
|
|
40
|
+
├─────────────────────────────────────────────────────────────────────────┤
|
|
41
|
+
│ │
|
|
42
|
+
│ ┌─────────────────────┐ │
|
|
43
|
+
│ │ Main Agent │ │
|
|
44
|
+
│ │ (Orchestrator) │ │
|
|
45
|
+
│ └──────────┬──────────┘ │
|
|
46
|
+
│ │ │
|
|
47
|
+
│ ┌──────────┴──────────┐ │
|
|
48
|
+
│ │ Task Analysis │ │
|
|
49
|
+
│ │ & Distribution │ │
|
|
50
|
+
│ └──────────┬──────────┘ │
|
|
51
|
+
│ │ │
|
|
52
|
+
│ ┌─────────────────────┼─────────────────────┐ │
|
|
53
|
+
│ │ │ │ │
|
|
54
|
+
│ ▼ ▼ ▼ │
|
|
55
|
+
│ ┌─────────┐ ┌─────────┐ ┌─────────┐ │
|
|
56
|
+
│ │ Agent A │ │ Agent B │ │ Agent C │ │
|
|
57
|
+
│ │ (Task 1)│ │ (Task 2)│ │ (Task 3)│ │
|
|
58
|
+
│ └────┬────┘ └────┬────┘ └────┬────┘ │
|
|
59
|
+
│ │ │ │ │
|
|
60
|
+
│ │ Result A │ Result B │ Result C │
|
|
61
|
+
│ │ │ │ │
|
|
62
|
+
│ └─────────────────────┼─────────────────────┘ │
|
|
63
|
+
│ │ │
|
|
64
|
+
│ ┌──────────┴──────────┐ │
|
|
65
|
+
│ │ Aggregation & │ │
|
|
66
|
+
│ │ Integration │ │
|
|
67
|
+
│ └──────────┬──────────┘ │
|
|
68
|
+
│ │ │
|
|
69
|
+
│ ┌──────────┴──────────┐ │
|
|
70
|
+
│ │ Final Response │ │
|
|
71
|
+
│ └─────────────────────┘ │
|
|
72
|
+
│ │
|
|
73
|
+
│ TIMING COMPARISON: │
|
|
74
|
+
│ Sequential: ████████████████████████████ (Task1 + Task2 + Task3) │
|
|
75
|
+
│ Parallel: ████████████ (max(Task1, Task2, Task3)) │
|
|
76
|
+
│ │
|
|
77
|
+
└─────────────────────────────────────────────────────────────────────────┘
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
### 2. Task Parallelization Analysis
|
|
81
|
+
|
|
82
|
+
```typescript
|
|
83
|
+
/**
|
|
84
|
+
* Determine which tasks can run in parallel
|
|
85
|
+
*/
|
|
86
|
+
|
|
87
|
+
interface Task {
|
|
88
|
+
id: string;
|
|
89
|
+
description: string;
|
|
90
|
+
dependencies: string[];
|
|
91
|
+
resources: string[];
|
|
92
|
+
estimatedDuration: number;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
interface ParallelizationAnalysis {
|
|
96
|
+
canParallelize: boolean;
|
|
97
|
+
reason: string;
|
|
98
|
+
suggestedGroups: Task[][];
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
function analyzeParallelization(tasks: Task[]): ParallelizationAnalysis {
|
|
102
|
+
// Build dependency graph
|
|
103
|
+
const dependencyGraph = buildDependencyGraph(tasks);
|
|
104
|
+
|
|
105
|
+
// Identify independent task groups
|
|
106
|
+
const groups = findIndependentGroups(dependencyGraph);
|
|
107
|
+
|
|
108
|
+
// Check for resource conflicts
|
|
109
|
+
const resourceConflicts = findResourceConflicts(tasks);
|
|
110
|
+
|
|
111
|
+
if (groups.length === 1 && groups[0].length === tasks.length) {
|
|
112
|
+
return {
|
|
113
|
+
canParallelize: false,
|
|
114
|
+
reason: 'All tasks have sequential dependencies',
|
|
115
|
+
suggestedGroups: [tasks]
|
|
116
|
+
};
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
return {
|
|
120
|
+
canParallelize: true,
|
|
121
|
+
reason: `Found ${groups.length} independent task groups`,
|
|
122
|
+
suggestedGroups: groups
|
|
123
|
+
};
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
// Parallelization criteria
|
|
127
|
+
const parallelizationCriteria = {
|
|
128
|
+
canParallelize: [
|
|
129
|
+
'Independent code changes (different files)',
|
|
130
|
+
'Research tasks on different topics',
|
|
131
|
+
'Tests for different modules',
|
|
132
|
+
'Documentation for different features',
|
|
133
|
+
'Analysis of separate concerns'
|
|
134
|
+
],
|
|
135
|
+
|
|
136
|
+
cannotParallelize: [
|
|
137
|
+
'Tasks with data dependencies',
|
|
138
|
+
'Sequential workflow steps',
|
|
139
|
+
'Tasks modifying same files',
|
|
140
|
+
'Tasks sharing mutable state',
|
|
141
|
+
'Order-dependent operations'
|
|
142
|
+
],
|
|
143
|
+
|
|
144
|
+
requiresCoordination: [
|
|
145
|
+
'Shared configuration files',
|
|
146
|
+
'Database schema changes',
|
|
147
|
+
'API contract changes',
|
|
148
|
+
'Merge operations'
|
|
149
|
+
]
|
|
150
|
+
};
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
### 3. Agent Dispatch Patterns
|
|
154
|
+
|
|
155
|
+
```typescript
|
|
156
|
+
/**
|
|
157
|
+
* Patterns for dispatching parallel agents
|
|
158
|
+
*/
|
|
159
|
+
|
|
160
|
+
// Pattern 1: Fan-out / Fan-in
|
|
161
|
+
async function fanOutFanIn<T, R>(
|
|
162
|
+
items: T[],
|
|
163
|
+
processor: (item: T) => Promise<R>,
|
|
164
|
+
aggregator: (results: R[]) => R
|
|
165
|
+
): Promise<R> {
|
|
166
|
+
// Fan-out: dispatch all in parallel
|
|
167
|
+
const promises = items.map(item => processor(item));
|
|
168
|
+
|
|
169
|
+
// Fan-in: wait for all and aggregate
|
|
170
|
+
const results = await Promise.all(promises);
|
|
171
|
+
|
|
172
|
+
return aggregator(results);
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
// Example: Parallel code review
|
|
176
|
+
const codeReviewResult = await fanOutFanIn(
|
|
177
|
+
['security', 'performance', 'style'],
|
|
178
|
+
async (concern) => {
|
|
179
|
+
const agent = await spawnAgent({
|
|
180
|
+
type: 'code-reviewer',
|
|
181
|
+
focus: concern,
|
|
182
|
+
files: changedFiles
|
|
183
|
+
});
|
|
184
|
+
return agent.getResults();
|
|
185
|
+
},
|
|
186
|
+
(reviews) => combineReviews(reviews)
|
|
187
|
+
);
|
|
188
|
+
|
|
189
|
+
// Pattern 2: Parallel with timeout
|
|
190
|
+
async function parallelWithTimeout<T>(
|
|
191
|
+
tasks: Array<() => Promise<T>>,
|
|
192
|
+
timeoutMs: number
|
|
193
|
+
): Promise<SettledResult<T>[]> {
|
|
194
|
+
const wrappedTasks = tasks.map(task =>
|
|
195
|
+
Promise.race([
|
|
196
|
+
task().then(value => ({ status: 'fulfilled', value })),
|
|
197
|
+
timeout(timeoutMs).then(() => ({
|
|
198
|
+
status: 'rejected',
|
|
199
|
+
reason: 'Timeout exceeded'
|
|
200
|
+
}))
|
|
201
|
+
])
|
|
202
|
+
);
|
|
203
|
+
|
|
204
|
+
return Promise.all(wrappedTasks);
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
// Pattern 3: Parallel with concurrency limit
|
|
208
|
+
async function parallelWithLimit<T, R>(
|
|
209
|
+
items: T[],
|
|
210
|
+
processor: (item: T) => Promise<R>,
|
|
211
|
+
concurrencyLimit: number
|
|
212
|
+
): Promise<R[]> {
|
|
213
|
+
const results: R[] = [];
|
|
214
|
+
const executing: Promise<void>[] = [];
|
|
215
|
+
|
|
216
|
+
for (const item of items) {
|
|
217
|
+
const promise = processor(item).then(result => {
|
|
218
|
+
results.push(result);
|
|
219
|
+
});
|
|
220
|
+
|
|
221
|
+
executing.push(promise);
|
|
222
|
+
|
|
223
|
+
if (executing.length >= concurrencyLimit) {
|
|
224
|
+
await Promise.race(executing);
|
|
225
|
+
// Remove completed promises
|
|
226
|
+
executing.splice(
|
|
227
|
+
executing.findIndex(p => p === promise),
|
|
228
|
+
1
|
|
229
|
+
);
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
await Promise.all(executing);
|
|
234
|
+
return results;
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
// Pattern 4: Dependent parallel groups
|
|
238
|
+
async function executeInWaves(taskGroups: Task[][]): Promise<void> {
|
|
239
|
+
for (const group of taskGroups) {
|
|
240
|
+
// Execute all tasks in this wave in parallel
|
|
241
|
+
await Promise.all(
|
|
242
|
+
group.map(task => executeTask(task))
|
|
243
|
+
);
|
|
244
|
+
// Next wave depends on this wave completing
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
```
|
|
248
|
+
|
|
249
|
+
### 4. Agent Specialization
|
|
250
|
+
|
|
251
|
+
```typescript
|
|
252
|
+
/**
|
|
253
|
+
* Dispatch specialized agents for different concerns
|
|
254
|
+
*/
|
|
255
|
+
|
|
256
|
+
type AgentType =
|
|
257
|
+
| 'explorer' // Codebase exploration
|
|
258
|
+
| 'implementer' // Code writing
|
|
259
|
+
| 'tester' // Test creation
|
|
260
|
+
| 'reviewer' // Code review
|
|
261
|
+
| 'documenter' // Documentation
|
|
262
|
+
| 'debugger' // Bug investigation
|
|
263
|
+
| 'researcher'; // Information gathering
|
|
264
|
+
|
|
265
|
+
interface AgentConfig {
|
|
266
|
+
type: AgentType;
|
|
267
|
+
prompt: string;
|
|
268
|
+
context?: string;
|
|
269
|
+
timeout?: number;
|
|
270
|
+
priority?: 'high' | 'normal' | 'low';
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
// Agent specialization examples
|
|
274
|
+
const agentSpecializations = {
|
|
275
|
+
explorer: {
|
|
276
|
+
strengths: [
|
|
277
|
+
'Understanding codebase structure',
|
|
278
|
+
'Finding relevant files',
|
|
279
|
+
'Mapping dependencies'
|
|
280
|
+
],
|
|
281
|
+
bestFor: [
|
|
282
|
+
'Initial project exploration',
|
|
283
|
+
'Finding implementation locations',
|
|
284
|
+
'Understanding patterns'
|
|
285
|
+
],
|
|
286
|
+
prompt_template: `
|
|
287
|
+
Explore the codebase to answer: {question}
|
|
288
|
+
Focus on: {focus_areas}
|
|
289
|
+
Return: File paths, key functions, relationships
|
|
290
|
+
`
|
|
291
|
+
},
|
|
292
|
+
|
|
293
|
+
implementer: {
|
|
294
|
+
strengths: [
|
|
295
|
+
'Writing production code',
|
|
296
|
+
'Following patterns',
|
|
297
|
+
'Complete implementations'
|
|
298
|
+
],
|
|
299
|
+
bestFor: [
|
|
300
|
+
'Feature implementation',
|
|
301
|
+
'Bug fixes',
|
|
302
|
+
'Refactoring'
|
|
303
|
+
],
|
|
304
|
+
prompt_template: `
|
|
305
|
+
Implement: {feature_description}
|
|
306
|
+
Context: {existing_code}
|
|
307
|
+
Requirements: {requirements}
|
|
308
|
+
Return: Complete, tested code
|
|
309
|
+
`
|
|
310
|
+
},
|
|
311
|
+
|
|
312
|
+
tester: {
|
|
313
|
+
strengths: [
|
|
314
|
+
'Test case design',
|
|
315
|
+
'Edge case identification',
|
|
316
|
+
'Coverage analysis'
|
|
317
|
+
],
|
|
318
|
+
bestFor: [
|
|
319
|
+
'Unit test creation',
|
|
320
|
+
'Integration test design',
|
|
321
|
+
'Test strategy planning'
|
|
322
|
+
],
|
|
323
|
+
prompt_template: `
|
|
324
|
+
Create tests for: {code_under_test}
|
|
325
|
+
Coverage requirements: {coverage_target}
|
|
326
|
+
Focus on: {critical_paths}
|
|
327
|
+
Return: Test files with assertions
|
|
328
|
+
`
|
|
329
|
+
},
|
|
330
|
+
|
|
331
|
+
reviewer: {
|
|
332
|
+
strengths: [
|
|
333
|
+
'Issue identification',
|
|
334
|
+
'Best practice enforcement',
|
|
335
|
+
'Security analysis'
|
|
336
|
+
],
|
|
337
|
+
bestFor: [
|
|
338
|
+
'Code review',
|
|
339
|
+
'Security audit',
|
|
340
|
+
'Performance review'
|
|
341
|
+
],
|
|
342
|
+
prompt_template: `
|
|
343
|
+
Review this code for: {review_focus}
|
|
344
|
+
Standards: {coding_standards}
|
|
345
|
+
Return: Issues with severity and fixes
|
|
346
|
+
`
|
|
347
|
+
}
|
|
348
|
+
};
|
|
349
|
+
```
|
|
350
|
+
|
|
351
|
+
### 5. Result Aggregation
|
|
352
|
+
|
|
353
|
+
```typescript
|
|
354
|
+
/**
|
|
355
|
+
* Aggregate results from parallel agents
|
|
356
|
+
*/
|
|
357
|
+
|
|
358
|
+
interface AgentResult {
|
|
359
|
+
agentId: string;
|
|
360
|
+
agentType: AgentType;
|
|
361
|
+
status: 'success' | 'partial' | 'failed';
|
|
362
|
+
data: unknown;
|
|
363
|
+
duration: number;
|
|
364
|
+
tokensUsed: number;
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
class ResultAggregator {
|
|
368
|
+
private results: AgentResult[] = [];
|
|
369
|
+
|
|
370
|
+
addResult(result: AgentResult): void {
|
|
371
|
+
this.results.push(result);
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
// Aggregation strategies
|
|
375
|
+
aggregateByMerge(): MergedResult {
|
|
376
|
+
// Combine all results into one
|
|
377
|
+
return {
|
|
378
|
+
allIssues: this.results.flatMap(r => r.data.issues || []),
|
|
379
|
+
allSuggestions: this.results.flatMap(r => r.data.suggestions || []),
|
|
380
|
+
summary: this.generateSummary()
|
|
381
|
+
};
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
aggregateByConsensus<T>(extractor: (r: AgentResult) => T): T | null {
|
|
385
|
+
// Find consensus among agents
|
|
386
|
+
const values = this.results.map(extractor);
|
|
387
|
+
const counts = new Map<string, number>();
|
|
388
|
+
|
|
389
|
+
for (const value of values) {
|
|
390
|
+
const key = JSON.stringify(value);
|
|
391
|
+
counts.set(key, (counts.get(key) || 0) + 1);
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
// Return most common result
|
|
395
|
+
let maxCount = 0;
|
|
396
|
+
let consensus: T | null = null;
|
|
397
|
+
|
|
398
|
+
for (const [key, count] of counts) {
|
|
399
|
+
if (count > maxCount) {
|
|
400
|
+
maxCount = count;
|
|
401
|
+
consensus = JSON.parse(key);
|
|
402
|
+
}
|
|
403
|
+
}
|
|
404
|
+
|
|
405
|
+
return consensus;
|
|
406
|
+
}
|
|
407
|
+
|
|
408
|
+
aggregateByPriority(): PrioritizedResult {
|
|
409
|
+
// Sort results by agent priority/expertise
|
|
410
|
+
const sorted = this.results.sort((a, b) =>
|
|
411
|
+
getAgentPriority(a.agentType) - getAgentPriority(b.agentType)
|
|
412
|
+
);
|
|
413
|
+
|
|
414
|
+
return {
|
|
415
|
+
primary: sorted[0].data,
|
|
416
|
+
supporting: sorted.slice(1).map(r => r.data)
|
|
417
|
+
};
|
|
418
|
+
}
|
|
419
|
+
|
|
420
|
+
generateSummary(): string {
|
|
421
|
+
const successCount = this.results.filter(r => r.status === 'success').length;
|
|
422
|
+
const totalDuration = this.results.reduce((sum, r) => sum + r.duration, 0);
|
|
423
|
+
const totalTokens = this.results.reduce((sum, r) => sum + r.tokensUsed, 0);
|
|
424
|
+
|
|
425
|
+
return `
|
|
426
|
+
Agents: ${this.results.length}
|
|
427
|
+
Successful: ${successCount}
|
|
428
|
+
Total duration: ${totalDuration}ms
|
|
429
|
+
Total tokens: ${totalTokens}
|
|
430
|
+
`;
|
|
431
|
+
}
|
|
432
|
+
}
|
|
433
|
+
```
|
|
434
|
+
|
|
435
|
+
### 6. Error Handling in Parallel
|
|
436
|
+
|
|
437
|
+
```typescript
|
|
438
|
+
/**
|
|
439
|
+
* Handle failures gracefully in parallel execution
|
|
440
|
+
*/
|
|
441
|
+
|
|
442
|
+
interface ParallelExecutionOptions {
|
|
443
|
+
failFast: boolean; // Stop all on first failure
|
|
444
|
+
retryFailed: boolean; // Retry failed tasks
|
|
445
|
+
maxRetries: number;
|
|
446
|
+
continueOnError: boolean; // Continue with partial results
|
|
447
|
+
}
|
|
448
|
+
|
|
449
|
+
async function executeParallelWithErrorHandling<T>(
|
|
450
|
+
tasks: Array<() => Promise<T>>,
|
|
451
|
+
options: ParallelExecutionOptions
|
|
452
|
+
): Promise<ExecutionResult<T>> {
|
|
453
|
+
const results: T[] = [];
|
|
454
|
+
const errors: Error[] = [];
|
|
455
|
+
|
|
456
|
+
if (options.failFast) {
|
|
457
|
+
// Use Promise.all - fails on first error
|
|
458
|
+
try {
|
|
459
|
+
return {
|
|
460
|
+
results: await Promise.all(tasks.map(t => t())),
|
|
461
|
+
errors: [],
|
|
462
|
+
status: 'complete'
|
|
463
|
+
};
|
|
464
|
+
} catch (error) {
|
|
465
|
+
return {
|
|
466
|
+
results: [],
|
|
467
|
+
errors: [error as Error],
|
|
468
|
+
status: 'failed'
|
|
469
|
+
};
|
|
470
|
+
}
|
|
471
|
+
}
|
|
472
|
+
|
|
473
|
+
// Use Promise.allSettled - collects all results
|
|
474
|
+
const settled = await Promise.allSettled(tasks.map(t => t()));
|
|
475
|
+
|
|
476
|
+
for (const result of settled) {
|
|
477
|
+
if (result.status === 'fulfilled') {
|
|
478
|
+
results.push(result.value);
|
|
479
|
+
} else {
|
|
480
|
+
errors.push(result.reason);
|
|
481
|
+
}
|
|
482
|
+
}
|
|
483
|
+
|
|
484
|
+
// Retry failed tasks if configured
|
|
485
|
+
if (options.retryFailed && errors.length > 0) {
|
|
486
|
+
const failedIndices = settled
|
|
487
|
+
.map((r, i) => r.status === 'rejected' ? i : -1)
|
|
488
|
+
.filter(i => i >= 0);
|
|
489
|
+
|
|
490
|
+
for (let attempt = 0; attempt < options.maxRetries; attempt++) {
|
|
491
|
+
const retryResults = await Promise.allSettled(
|
|
492
|
+
failedIndices.map(i => tasks[i]())
|
|
493
|
+
);
|
|
494
|
+
|
|
495
|
+
retryResults.forEach((r, idx) => {
|
|
496
|
+
if (r.status === 'fulfilled') {
|
|
497
|
+
results.push(r.value);
|
|
498
|
+
errors.splice(idx, 1);
|
|
499
|
+
}
|
|
500
|
+
});
|
|
501
|
+
|
|
502
|
+
if (errors.length === 0) break;
|
|
503
|
+
}
|
|
504
|
+
}
|
|
505
|
+
|
|
506
|
+
return {
|
|
507
|
+
results,
|
|
508
|
+
errors,
|
|
509
|
+
status: errors.length === 0 ? 'complete' : 'partial'
|
|
510
|
+
};
|
|
511
|
+
}
|
|
15
512
|
```
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
513
|
+
|
|
514
|
+
## Use Cases
|
|
515
|
+
|
|
516
|
+
### Feature Implementation with Parallel Agents
|
|
517
|
+
|
|
518
|
+
```typescript
|
|
519
|
+
/**
|
|
520
|
+
* Implement a feature using multiple specialized agents
|
|
521
|
+
*/
|
|
522
|
+
|
|
523
|
+
async function implementFeatureWithParallelAgents(
|
|
524
|
+
feature: FeatureSpec
|
|
525
|
+
): Promise<Implementation> {
|
|
526
|
+
// Phase 1: Parallel exploration
|
|
527
|
+
const [
|
|
528
|
+
existingPatterns,
|
|
529
|
+
relatedCode,
|
|
530
|
+
testPatterns
|
|
531
|
+
] = await Promise.all([
|
|
532
|
+
spawnAgent({
|
|
533
|
+
type: 'explorer',
|
|
534
|
+
prompt: `Find similar features in the codebase`
|
|
535
|
+
}),
|
|
536
|
+
spawnAgent({
|
|
537
|
+
type: 'explorer',
|
|
538
|
+
prompt: `Find code that will be affected by ${feature.name}`
|
|
539
|
+
}),
|
|
540
|
+
spawnAgent({
|
|
541
|
+
type: 'explorer',
|
|
542
|
+
prompt: `Find test patterns for similar features`
|
|
543
|
+
})
|
|
544
|
+
]);
|
|
545
|
+
|
|
546
|
+
// Phase 2: Parallel implementation (after exploration complete)
|
|
547
|
+
const [
|
|
548
|
+
featureCode,
|
|
549
|
+
tests,
|
|
550
|
+
documentation
|
|
551
|
+
] = await Promise.all([
|
|
552
|
+
spawnAgent({
|
|
553
|
+
type: 'implementer',
|
|
554
|
+
prompt: `Implement ${feature.name}`,
|
|
555
|
+
context: existingPatterns
|
|
556
|
+
}),
|
|
557
|
+
spawnAgent({
|
|
558
|
+
type: 'tester',
|
|
559
|
+
prompt: `Create tests for ${feature.name}`,
|
|
560
|
+
context: testPatterns
|
|
561
|
+
}),
|
|
562
|
+
spawnAgent({
|
|
563
|
+
type: 'documenter',
|
|
564
|
+
prompt: `Document ${feature.name}`,
|
|
565
|
+
context: feature.spec
|
|
566
|
+
})
|
|
567
|
+
]);
|
|
568
|
+
|
|
569
|
+
// Phase 3: Parallel review
|
|
570
|
+
const [
|
|
571
|
+
codeReview,
|
|
572
|
+
testReview
|
|
573
|
+
] = await Promise.all([
|
|
574
|
+
spawnAgent({
|
|
575
|
+
type: 'reviewer',
|
|
576
|
+
prompt: 'Review implementation for issues',
|
|
577
|
+
context: featureCode
|
|
578
|
+
}),
|
|
579
|
+
spawnAgent({
|
|
580
|
+
type: 'reviewer',
|
|
581
|
+
prompt: 'Review tests for coverage and quality',
|
|
582
|
+
context: tests
|
|
583
|
+
})
|
|
584
|
+
]);
|
|
585
|
+
|
|
586
|
+
return aggregateResults({
|
|
587
|
+
featureCode,
|
|
588
|
+
tests,
|
|
589
|
+
documentation,
|
|
590
|
+
reviews: [codeReview, testReview]
|
|
591
|
+
});
|
|
592
|
+
}
|
|
30
593
|
```
|
|
31
594
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
595
|
+
### Multi-Concern Code Review
|
|
596
|
+
|
|
597
|
+
```typescript
|
|
598
|
+
/**
|
|
599
|
+
* Review code from multiple perspectives in parallel
|
|
600
|
+
*/
|
|
601
|
+
|
|
602
|
+
async function multiConcernReview(
|
|
603
|
+
files: string[]
|
|
604
|
+
): Promise<ComprehensiveReview> {
|
|
605
|
+
const [
|
|
606
|
+
securityReview,
|
|
607
|
+
performanceReview,
|
|
608
|
+
styleReview,
|
|
609
|
+
accessibilityReview
|
|
610
|
+
] = await Promise.all([
|
|
611
|
+
spawnAgent({
|
|
612
|
+
type: 'reviewer',
|
|
613
|
+
prompt: `Security review: check for vulnerabilities, injection, auth issues`,
|
|
614
|
+
files
|
|
615
|
+
}),
|
|
616
|
+
spawnAgent({
|
|
617
|
+
type: 'reviewer',
|
|
618
|
+
prompt: `Performance review: check for N+1, memory leaks, inefficiencies`,
|
|
619
|
+
files
|
|
620
|
+
}),
|
|
621
|
+
spawnAgent({
|
|
622
|
+
type: 'reviewer',
|
|
623
|
+
prompt: `Style review: check for conventions, naming, structure`,
|
|
624
|
+
files
|
|
625
|
+
}),
|
|
626
|
+
spawnAgent({
|
|
627
|
+
type: 'reviewer',
|
|
628
|
+
prompt: `Accessibility review: check for a11y issues in UI code`,
|
|
629
|
+
files
|
|
630
|
+
})
|
|
631
|
+
]);
|
|
632
|
+
|
|
633
|
+
return {
|
|
634
|
+
security: securityReview,
|
|
635
|
+
performance: performanceReview,
|
|
636
|
+
style: styleReview,
|
|
637
|
+
accessibility: accessibilityReview,
|
|
638
|
+
summary: generateReviewSummary([
|
|
639
|
+
securityReview,
|
|
640
|
+
performanceReview,
|
|
641
|
+
styleReview,
|
|
642
|
+
accessibilityReview
|
|
643
|
+
])
|
|
644
|
+
};
|
|
645
|
+
}
|
|
37
646
|
```
|
|
38
647
|
|
|
39
648
|
## Best Practices
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
-
|
|
649
|
+
|
|
650
|
+
### Do's
|
|
651
|
+
|
|
652
|
+
- **Identify truly independent tasks** before parallelizing
|
|
653
|
+
- **Use specialized agents** for different concerns
|
|
654
|
+
- **Set appropriate timeouts** for each agent
|
|
655
|
+
- **Handle partial failures** gracefully
|
|
656
|
+
- **Aggregate results** meaningfully
|
|
657
|
+
- **Monitor resource usage** when spawning many agents
|
|
658
|
+
- **Use concurrency limits** to avoid overwhelming systems
|
|
659
|
+
- **Document dependencies** between tasks
|
|
660
|
+
|
|
661
|
+
### Don'ts
|
|
662
|
+
|
|
663
|
+
- Don't parallelize tasks that share state
|
|
664
|
+
- Don't spawn unlimited agents
|
|
665
|
+
- Don't ignore failed agent results
|
|
666
|
+
- Don't assume order of completion
|
|
667
|
+
- Don't parallelize tiny tasks (overhead exceeds benefit)
|
|
668
|
+
- Don't forget to clean up agent resources
|
|
669
|
+
- Don't skip the aggregation step
|
|
670
|
+
- Don't parallelize without clear benefit
|
|
671
|
+
|
|
672
|
+
## References
|
|
673
|
+
|
|
674
|
+
- [Concurrency Patterns](https://www.oreilly.com/library/view/concurrency-in-go/9781491941294/)
|
|
675
|
+
- [Parallel Programming](https://en.wikipedia.org/wiki/Parallel_computing)
|
|
676
|
+
- [Actor Model](https://en.wikipedia.org/wiki/Actor_model)
|
|
677
|
+
- [MapReduce Pattern](https://en.wikipedia.org/wiki/MapReduce)
|