@cogitator-ai/swarms 0.4.20 → 0.5.1
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/README.md +245 -897
- package/dist/agents.d.ts +13 -0
- package/dist/agents.d.ts.map +1 -0
- package/dist/agents.js +70 -0
- package/dist/agents.js.map +1 -0
- package/dist/assessor/assessor.d.ts +9 -2
- package/dist/assessor/assessor.d.ts.map +1 -1
- package/dist/assessor/assessor.js +71 -52
- package/dist/assessor/assessor.js.map +1 -1
- package/dist/assessor/role-matcher.d.ts +6 -24
- package/dist/assessor/role-matcher.d.ts.map +1 -1
- package/dist/assessor/role-matcher.js +9 -37
- package/dist/assessor/role-matcher.js.map +1 -1
- package/dist/base-coordinator.d.ts +117 -0
- package/dist/base-coordinator.d.ts.map +1 -0
- package/dist/base-coordinator.js +455 -0
- package/dist/base-coordinator.js.map +1 -0
- package/dist/communication/blackboard.d.ts +34 -4
- package/dist/communication/blackboard.d.ts.map +1 -1
- package/dist/communication/blackboard.js +81 -46
- package/dist/communication/blackboard.js.map +1 -1
- package/dist/communication/event-emitter.d.ts.map +1 -1
- package/dist/communication/event-emitter.js +6 -17
- package/dist/communication/event-emitter.js.map +1 -1
- package/dist/communication/index.d.ts +2 -2
- package/dist/communication/index.d.ts.map +1 -1
- package/dist/communication/index.js +2 -2
- package/dist/communication/index.js.map +1 -1
- package/dist/communication/message-bus.d.ts +48 -5
- package/dist/communication/message-bus.d.ts.map +1 -1
- package/dist/communication/message-bus.js +135 -50
- package/dist/communication/message-bus.js.map +1 -1
- package/dist/communication/redis-blackboard.d.ts +11 -5
- package/dist/communication/redis-blackboard.d.ts.map +1 -1
- package/dist/communication/redis-blackboard.js +159 -116
- package/dist/communication/redis-blackboard.js.map +1 -1
- package/dist/communication/redis-event-emitter.d.ts +12 -0
- package/dist/communication/redis-event-emitter.d.ts.map +1 -1
- package/dist/communication/redis-event-emitter.js +96 -54
- package/dist/communication/redis-event-emitter.js.map +1 -1
- package/dist/communication/redis-message-bus.d.ts +11 -6
- package/dist/communication/redis-message-bus.d.ts.map +1 -1
- package/dist/communication/redis-message-bus.js +88 -77
- package/dist/communication/redis-message-bus.js.map +1 -1
- package/dist/coordinator.d.ts +7 -41
- package/dist/coordinator.d.ts.map +1 -1
- package/dist/coordinator.js +17 -340
- package/dist/coordinator.js.map +1 -1
- package/dist/distributed/distributed-coordinator.d.ts +54 -51
- package/dist/distributed/distributed-coordinator.d.ts.map +1 -1
- package/dist/distributed/distributed-coordinator.js +166 -284
- package/dist/distributed/distributed-coordinator.js.map +1 -1
- package/dist/distributed/index.d.ts +1 -1
- package/dist/distributed/index.d.ts.map +1 -1
- package/dist/distributed/index.js +1 -1
- package/dist/distributed/index.js.map +1 -1
- package/dist/index.d.ts +4 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -3
- package/dist/index.js.map +1 -1
- package/dist/resources/circuit-breaker.d.ts.map +1 -1
- package/dist/resources/circuit-breaker.js +3 -4
- package/dist/resources/circuit-breaker.js.map +1 -1
- package/dist/shared/hierarchy.d.ts +21 -0
- package/dist/shared/hierarchy.d.ts.map +1 -0
- package/dist/shared/hierarchy.js +27 -0
- package/dist/shared/hierarchy.js.map +1 -0
- package/dist/shared/negotiation.d.ts +27 -0
- package/dist/shared/negotiation.d.ts.map +1 -0
- package/dist/shared/negotiation.js +55 -0
- package/dist/shared/negotiation.js.map +1 -0
- package/dist/shared/voting.d.ts +6 -0
- package/dist/shared/voting.d.ts.map +1 -0
- package/dist/shared/voting.js +13 -0
- package/dist/shared/voting.js.map +1 -0
- package/dist/strategies/consensus.d.ts +12 -0
- package/dist/strategies/consensus.d.ts.map +1 -1
- package/dist/strategies/consensus.js +75 -47
- package/dist/strategies/consensus.js.map +1 -1
- package/dist/strategies/debate.d.ts.map +1 -1
- package/dist/strategies/debate.js +18 -8
- package/dist/strategies/debate.js.map +1 -1
- package/dist/strategies/hierarchical.d.ts.map +1 -1
- package/dist/strategies/hierarchical.js +29 -14
- package/dist/strategies/hierarchical.js.map +1 -1
- package/dist/strategies/negotiation/approval.d.ts.map +1 -1
- package/dist/strategies/negotiation/approval.js +22 -19
- package/dist/strategies/negotiation/approval.js.map +1 -1
- package/dist/strategies/negotiation-strategy.d.ts +24 -2
- package/dist/strategies/negotiation-strategy.d.ts.map +1 -1
- package/dist/strategies/negotiation-strategy.js +276 -141
- package/dist/strategies/negotiation-strategy.js.map +1 -1
- package/dist/strategies/pipeline.js +6 -6
- package/dist/strategies/pipeline.js.map +1 -1
- package/dist/swarm.d.ts +25 -11
- package/dist/swarm.d.ts.map +1 -1
- package/dist/swarm.js +195 -121
- package/dist/swarm.js.map +1 -1
- package/dist/tools/blackboard.d.ts +1 -1
- package/dist/tools/blackboard.d.ts.map +1 -1
- package/dist/tools/blackboard.js +26 -12
- package/dist/tools/blackboard.js.map +1 -1
- package/dist/tools/delegation.d.ts +17 -4
- package/dist/tools/delegation.d.ts.map +1 -1
- package/dist/tools/delegation.js +95 -88
- package/dist/tools/delegation.js.map +1 -1
- package/dist/tools/index.d.ts +3 -1
- package/dist/tools/index.d.ts.map +1 -1
- package/dist/tools/index.js +9 -4
- package/dist/tools/index.js.map +1 -1
- package/dist/tools/messaging.d.ts +38 -6
- package/dist/tools/messaging.d.ts.map +1 -1
- package/dist/tools/messaging.js +118 -41
- package/dist/tools/messaging.js.map +1 -1
- package/dist/tools/negotiation.d.ts +8 -4
- package/dist/tools/negotiation.d.ts.map +1 -1
- package/dist/tools/negotiation.js +138 -115
- package/dist/tools/negotiation.js.map +1 -1
- package/dist/tools/voting.d.ts +3 -0
- package/dist/tools/voting.d.ts.map +1 -1
- package/dist/tools/voting.js +13 -12
- package/dist/tools/voting.js.map +1 -1
- package/dist/utils/concurrency.d.ts +10 -0
- package/dist/utils/concurrency.d.ts.map +1 -0
- package/dist/utils/concurrency.js +28 -0
- package/dist/utils/concurrency.js.map +1 -0
- package/dist/utils/invoke.d.ts +2 -0
- package/dist/utils/invoke.d.ts.map +1 -0
- package/dist/utils/invoke.js +19 -0
- package/dist/utils/invoke.js.map +1 -0
- package/dist/workflow/swarm-node.d.ts.map +1 -1
- package/dist/workflow/swarm-node.js +55 -98
- package/dist/workflow/swarm-node.js.map +1 -1
- package/package.json +6 -6
package/README.md
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
# @cogitator-ai/swarms
|
|
2
2
|
|
|
3
|
-
Multi-agent swarm coordination for Cogitator. Orchestrate teams of AI agents with
|
|
3
|
+
Multi-agent swarm coordination for Cogitator. Orchestrate teams of AI agents with seven collaboration strategies, automatic model selection, shared communication primitives, workflow integration and Redis-backed distributed execution.
|
|
4
4
|
|
|
5
5
|
## Installation
|
|
6
6
|
|
|
7
7
|
```bash
|
|
8
|
-
pnpm add @cogitator-ai/swarms
|
|
8
|
+
pnpm add @cogitator-ai/swarms @cogitator-ai/core
|
|
9
9
|
```
|
|
10
10
|
|
|
11
11
|
## Quick Start
|
|
@@ -14,33 +14,55 @@ pnpm add @cogitator-ai/swarms
|
|
|
14
14
|
import { Cogitator, Agent } from '@cogitator-ai/core';
|
|
15
15
|
import { SwarmBuilder } from '@cogitator-ai/swarms';
|
|
16
16
|
|
|
17
|
-
const cogitator = new Cogitator({ defaultModel: '
|
|
17
|
+
const cogitator = new Cogitator({ llm: { defaultModel: 'ollama/llama3.2' } });
|
|
18
|
+
const model = 'ollama/llama3.2';
|
|
18
19
|
|
|
19
20
|
const swarm = new SwarmBuilder('dev-team')
|
|
20
21
|
.strategy('hierarchical')
|
|
21
|
-
.supervisor(new Agent({ name: 'lead', instructions: 'Coordinate the team' }))
|
|
22
|
+
.supervisor(new Agent({ name: 'lead', model, instructions: 'Coordinate the team' }))
|
|
22
23
|
.workers([
|
|
23
|
-
new Agent({ name: 'coder', instructions: 'Write code' }),
|
|
24
|
-
new Agent({ name: 'tester', instructions: 'Test code' }),
|
|
24
|
+
new Agent({ name: 'coder', model, instructions: 'Write code' }),
|
|
25
|
+
new Agent({ name: 'tester', model, instructions: 'Test code' }),
|
|
25
26
|
])
|
|
26
27
|
.build(cogitator);
|
|
27
28
|
|
|
28
|
-
const result = await swarm.run({
|
|
29
|
-
input: 'Build a REST API for user management',
|
|
30
|
-
});
|
|
31
|
-
|
|
29
|
+
const result = await swarm.run({ input: 'Build a REST API for user management' });
|
|
32
30
|
console.log(result.output);
|
|
33
31
|
```
|
|
34
32
|
|
|
33
|
+
Strategies equip agents with the tools they need: the hierarchical supervisor receives `delegate_task`, `check_progress`, `request_revision` and `list_workers`; negotiating agents receive the negotiation tools. Tools an agent already defines with the same name are kept.
|
|
34
|
+
|
|
35
35
|
## Features
|
|
36
36
|
|
|
37
|
-
- **7 Coordination Strategies**
|
|
38
|
-
- **Automatic Model Selection**
|
|
39
|
-
- **Agent Communication**
|
|
40
|
-
- **Built-in Tools**
|
|
41
|
-
- **
|
|
42
|
-
- **
|
|
43
|
-
- **
|
|
37
|
+
- **7 Coordination Strategies** — hierarchical, round-robin, consensus, auction, pipeline, debate, negotiation
|
|
38
|
+
- **Automatic Model Selection** — `SwarmAssessor` matches models to agent roles
|
|
39
|
+
- **Agent Communication** — message bus with read tracking, shared blackboard, `message:*` / `blackboard:write` events
|
|
40
|
+
- **Built-in Tools** — messaging, blackboard, delegation, voting and negotiation tools
|
|
41
|
+
- **Run Control** — per-run timeout, thread ids, lifecycle callbacks, pause/resume/abort with cancellation of in-flight LLM calls
|
|
42
|
+
- **Resilience** — retry with backoff, failover chains, skip, partial results, circuit breaker
|
|
43
|
+
- **Resource Limits** — per-run token/cost/time budgets and per-agent caps
|
|
44
|
+
- **Workflow Integration** — run swarms as DAG workflow nodes
|
|
45
|
+
- **Distributed Execution** — Redis-backed state and worker nodes from `@cogitator-ai/worker`
|
|
46
|
+
|
|
47
|
+
---
|
|
48
|
+
|
|
49
|
+
## Agent Roles and Metadata
|
|
50
|
+
|
|
51
|
+
Agents keep their swarm metadata (role, expertise, weight, model lock) in `agentMetadata`, keyed by agent name. Slot defaults apply automatically: `supervisor` → `role: 'supervisor'`, `workers` → `role: 'worker'`, `moderator` → `role: 'moderator'`, `router` → `role: 'router'`.
|
|
52
|
+
|
|
53
|
+
```typescript
|
|
54
|
+
const swarm = new SwarmBuilder('debate-club')
|
|
55
|
+
.strategy('debate')
|
|
56
|
+
.agents([pro, con])
|
|
57
|
+
.agentMetadata({
|
|
58
|
+
pro: { role: 'advocate', expertise: ['economics'] },
|
|
59
|
+
con: { role: 'critic', weight: 2 },
|
|
60
|
+
})
|
|
61
|
+
.debate({ rounds: 2 })
|
|
62
|
+
.build(cogitator);
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
Agent names must be unique within a swarm.
|
|
44
66
|
|
|
45
67
|
---
|
|
46
68
|
|
|
@@ -48,252 +70,197 @@ console.log(result.output);
|
|
|
48
70
|
|
|
49
71
|
### Hierarchical
|
|
50
72
|
|
|
51
|
-
|
|
73
|
+
A supervisor delegates tasks to workers through the `delegate_task` tool.
|
|
52
74
|
|
|
53
75
|
```typescript
|
|
54
|
-
import { SwarmBuilder, Swarm } from '@cogitator-ai/swarms';
|
|
55
|
-
|
|
56
76
|
const swarm = new SwarmBuilder('dev-team')
|
|
57
77
|
.strategy('hierarchical')
|
|
58
|
-
.supervisor(
|
|
59
|
-
|
|
60
|
-
name: 'tech-lead',
|
|
61
|
-
instructions: 'Break down tasks and delegate to workers',
|
|
62
|
-
})
|
|
63
|
-
)
|
|
64
|
-
.workers([
|
|
65
|
-
new Agent({ name: 'frontend-dev', instructions: 'Build UI components' }),
|
|
66
|
-
new Agent({ name: 'backend-dev', instructions: 'Build API endpoints' }),
|
|
67
|
-
new Agent({ name: 'tester', instructions: 'Write and run tests' }),
|
|
68
|
-
])
|
|
78
|
+
.supervisor(lead)
|
|
79
|
+
.workers([frontend, backend, tester])
|
|
69
80
|
.hierarchical({
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
81
|
+
maxDelegationDepth: 2, // workers may re-delegate once
|
|
82
|
+
workerCommunication: false, // workers can only message the supervisor
|
|
83
|
+
routeThrough: 'supervisor',
|
|
84
|
+
visibility: 'summary', // supervisor sees the first 500 chars of worker output
|
|
73
85
|
})
|
|
74
86
|
.build(cogitator);
|
|
75
|
-
|
|
76
|
-
const result = await swarm.run({
|
|
77
|
-
input: 'Build a user authentication system',
|
|
78
|
-
});
|
|
79
87
|
```
|
|
80
88
|
|
|
81
|
-
|
|
89
|
+
Workers that ran during the supervisor turn are included in `result.agentResults`. Delegating to yourself or to the supervisor is refused.
|
|
82
90
|
|
|
83
|
-
|
|
91
|
+
### Round-Robin
|
|
84
92
|
|
|
85
93
|
```typescript
|
|
86
94
|
const swarm = new SwarmBuilder('support-team')
|
|
87
95
|
.strategy('round-robin')
|
|
88
|
-
.agents([
|
|
89
|
-
new Agent({ name: 'support-1', instructions: 'Handle customer queries' }),
|
|
90
|
-
new Agent({ name: 'support-2', instructions: 'Handle customer queries' }),
|
|
91
|
-
new Agent({ name: 'support-3', instructions: 'Handle customer queries' }),
|
|
92
|
-
])
|
|
96
|
+
.agents([support1, support2, support3])
|
|
93
97
|
.roundRobin({
|
|
94
|
-
|
|
95
|
-
|
|
98
|
+
rotation: 'sequential',
|
|
99
|
+
sticky: true,
|
|
100
|
+
stickyKey: (input) => String(input).slice(0, 20),
|
|
96
101
|
})
|
|
97
102
|
.build(cogitator);
|
|
98
103
|
```
|
|
99
104
|
|
|
100
105
|
### Consensus
|
|
101
106
|
|
|
102
|
-
|
|
107
|
+
Agents vote (`VOTE: <decision>` in their answer or the `cast_vote` tool). A decision wins when its share of **all eligible voters** reaches the threshold and it is not tied; abstentions count against it.
|
|
103
108
|
|
|
104
109
|
```typescript
|
|
105
110
|
const swarm = new SwarmBuilder('review-board')
|
|
106
111
|
.strategy('consensus')
|
|
107
|
-
.agents([
|
|
108
|
-
new Agent({ name: 'reviewer-1', instructions: 'Review from security perspective' }),
|
|
109
|
-
new Agent({ name: 'reviewer-2', instructions: 'Review from performance perspective' }),
|
|
110
|
-
new Agent({ name: 'reviewer-3', instructions: 'Review from UX perspective' }),
|
|
111
|
-
])
|
|
112
|
+
.agents([security, performance, ux])
|
|
112
113
|
.consensus({
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
114
|
+
threshold: 0.66,
|
|
115
|
+
maxRounds: 3,
|
|
116
|
+
resolution: 'weighted', // 'majority' | 'unanimous' | 'weighted'
|
|
117
|
+
weights: { security: 2 },
|
|
118
|
+
onNoConsensus: 'escalate', // 'fail' | 'supervisor-decides' | 'escalate'
|
|
117
119
|
})
|
|
118
120
|
.build(cogitator);
|
|
121
|
+
|
|
122
|
+
const result = await swarm.run({ input: 'Approve the new caching layer?' });
|
|
123
|
+
console.log(result.votes);
|
|
119
124
|
```
|
|
120
125
|
|
|
121
126
|
### Pipeline
|
|
122
127
|
|
|
123
|
-
Sequential processing stages:
|
|
124
|
-
|
|
125
128
|
```typescript
|
|
126
129
|
const swarm = new SwarmBuilder('content-pipeline')
|
|
127
130
|
.strategy('pipeline')
|
|
128
131
|
.pipeline({
|
|
129
132
|
stages: [
|
|
130
|
-
{
|
|
131
|
-
{
|
|
132
|
-
{
|
|
133
|
-
{ agent: new Agent({ name: 'reviewer', instructions: 'Final review' }) },
|
|
133
|
+
{ name: 'research', agent: researcher },
|
|
134
|
+
{ name: 'draft', agent: writer, gate: true },
|
|
135
|
+
{ name: 'edit', agent: editor },
|
|
134
136
|
],
|
|
135
|
-
|
|
136
|
-
|
|
137
|
+
gates: {
|
|
138
|
+
draft: {
|
|
139
|
+
condition: (output) => String(output).length > 200,
|
|
140
|
+
onFail: 'retry-previous', // 'abort' | 'skip' | 'goto:<stage>'
|
|
141
|
+
maxRetries: 2,
|
|
142
|
+
},
|
|
143
|
+
},
|
|
137
144
|
})
|
|
138
145
|
.build(cogitator);
|
|
146
|
+
|
|
147
|
+
const result = await swarm.run({ input: 'Write about vector databases' });
|
|
148
|
+
console.log(result.pipelineOutputs);
|
|
139
149
|
```
|
|
140
150
|
|
|
141
151
|
### Debate
|
|
142
152
|
|
|
143
|
-
Multiple perspectives with synthesis:
|
|
144
|
-
|
|
145
153
|
```typescript
|
|
146
154
|
const swarm = new SwarmBuilder('analysis-team')
|
|
147
155
|
.strategy('debate')
|
|
148
|
-
.agents([
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
])
|
|
153
|
-
.moderator(
|
|
154
|
-
new Agent({
|
|
155
|
-
name: 'moderator',
|
|
156
|
-
instructions: 'Guide discussion and synthesize conclusions',
|
|
157
|
-
})
|
|
158
|
-
)
|
|
159
|
-
.debate({
|
|
160
|
-
rounds: 3,
|
|
161
|
-
requireSynthesis: true,
|
|
162
|
-
maxTurnsPerRound: 2,
|
|
163
|
-
})
|
|
156
|
+
.agents([optimist, skeptic])
|
|
157
|
+
.agentMetadata({ optimist: { role: 'advocate' }, skeptic: { role: 'critic' } })
|
|
158
|
+
.moderator(moderator)
|
|
159
|
+
.debate({ rounds: 3, format: 'structured', maxTokensPerTurn: 400 })
|
|
164
160
|
.build(cogitator);
|
|
165
161
|
```
|
|
166
162
|
|
|
167
163
|
### Auction
|
|
168
164
|
|
|
169
|
-
Bidding-based task assignment:
|
|
170
|
-
|
|
171
165
|
```typescript
|
|
172
166
|
const swarm = new SwarmBuilder('contractor-pool')
|
|
173
167
|
.strategy('auction')
|
|
174
|
-
.agents([
|
|
175
|
-
new Agent({ name: 'contractor-1', instructions: 'Bid based on expertise' }),
|
|
176
|
-
new Agent({ name: 'contractor-2', instructions: 'Bid based on expertise' }),
|
|
177
|
-
new Agent({ name: 'contractor-3', instructions: 'Bid based on expertise' }),
|
|
178
|
-
])
|
|
168
|
+
.agents([contractorA, contractorB])
|
|
179
169
|
.auction({
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
170
|
+
bidding: 'capability-match', // agents bid via LLM; or 'custom' with bidFunction
|
|
171
|
+
selection: 'highest-bid', // or 'weighted-random'
|
|
172
|
+
minBid: 0.3,
|
|
183
173
|
})
|
|
184
174
|
.build(cogitator);
|
|
185
175
|
```
|
|
186
176
|
|
|
187
177
|
### Negotiation
|
|
188
178
|
|
|
189
|
-
|
|
179
|
+
Agents negotiate with structured offers through the negotiation tools (`make_offer`, `counter_offer`, `accept_offer`, `reject_offer`, coalitions, interests). An offer becomes an agreement once **every recipient** accepted it.
|
|
190
180
|
|
|
191
181
|
```typescript
|
|
192
182
|
const swarm = new SwarmBuilder('deal-makers')
|
|
193
183
|
.strategy('negotiation')
|
|
194
|
-
.agents([
|
|
195
|
-
new Agent({ name: 'buyer', instructions: 'Negotiate best purchase terms' }),
|
|
196
|
-
new Agent({ name: 'seller', instructions: 'Maximize sale value' }),
|
|
197
|
-
new Agent({ name: 'mediator', instructions: 'Facilitate fair agreement' }),
|
|
198
|
-
])
|
|
184
|
+
.agents([buyer, seller])
|
|
199
185
|
.negotiation({
|
|
200
|
-
maxRounds:
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
186
|
+
maxRounds: 6,
|
|
187
|
+
onDeadlock: 'arbitrate', // 'escalate' | 'supervisor-decides' | 'majority-rules' | 'arbitrate' | 'fail'
|
|
188
|
+
maxOffersPerRound: 2,
|
|
189
|
+
offerTimeout: 120_000,
|
|
190
|
+
turnTimeout: 60_000,
|
|
191
|
+
allowCoalitions: false,
|
|
192
|
+
quorum: 1, // all parties must be part of the agreement
|
|
204
193
|
})
|
|
205
194
|
.build(cogitator);
|
|
206
|
-
```
|
|
207
195
|
|
|
208
|
-
|
|
196
|
+
const result = await swarm.run({ input: 'Agree on price and delivery date' });
|
|
197
|
+
console.log(result.negotiationResult?.agreement);
|
|
198
|
+
```
|
|
209
199
|
|
|
210
|
-
|
|
200
|
+
When stagnation is detected, the strategy proposes a mediated compromise as an offer from `mediator`; agents accept it with `accept_offer`.
|
|
211
201
|
|
|
212
|
-
|
|
202
|
+
---
|
|
213
203
|
|
|
214
|
-
|
|
204
|
+
## Running Swarms
|
|
215
205
|
|
|
216
206
|
```typescript
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
.
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
minCapabilityMatch: 0.3,
|
|
230
|
-
maxCostPerRun: 0.5,
|
|
231
|
-
})
|
|
232
|
-
.build(cogitator);
|
|
233
|
-
|
|
234
|
-
// Models are automatically selected based on task requirements
|
|
235
|
-
const result = await swarm.run({ input: 'Complex coding task' });
|
|
236
|
-
|
|
237
|
-
// View what models were assigned
|
|
238
|
-
const assessment = swarm.getLastAssessment();
|
|
239
|
-
console.log(assessment?.assignments);
|
|
207
|
+
const result = await swarm.run({
|
|
208
|
+
input: 'Plan the release',
|
|
209
|
+
threadId: 'release-42', // each agent uses thread `release-42:<agent>`
|
|
210
|
+
timeout: 120_000, // rejects with SwarmTimeoutError and cancels in-flight calls
|
|
211
|
+
saveHistory: false,
|
|
212
|
+
context: { project: 'cogitator' },
|
|
213
|
+
onAgentStart: (agent) => console.log('start', agent),
|
|
214
|
+
onAgentComplete: (agent, run) => console.log('done', agent, run.usage.totalTokens),
|
|
215
|
+
onAgentError: (agent, error) => console.error(agent, error.message),
|
|
216
|
+
onMessage: (message) => console.log(`${message.from} → ${message.to}`),
|
|
217
|
+
onEvent: (event) => console.log(event.type),
|
|
218
|
+
});
|
|
240
219
|
```
|
|
241
220
|
|
|
242
|
-
|
|
221
|
+
A `Swarm` instance runs one task at a time; create separate instances for concurrent runs.
|
|
222
|
+
|
|
223
|
+
### Pause, Resume, Abort, Reset
|
|
243
224
|
|
|
244
225
|
```typescript
|
|
245
|
-
const
|
|
246
|
-
input: 'Build a recommendation engine',
|
|
247
|
-
});
|
|
226
|
+
const running = swarm.run({ input: 'Long task' });
|
|
248
227
|
|
|
249
|
-
|
|
250
|
-
|
|
228
|
+
swarm.pause(); // agents wait before their next turn
|
|
229
|
+
swarm.resume();
|
|
230
|
+
swarm.abort(); // rejects pending turns and cancels in-flight LLM calls
|
|
251
231
|
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
}
|
|
232
|
+
await running.catch(() => {});
|
|
233
|
+
await swarm.reset(); // clears abort state, budgets, messages and blackboard
|
|
255
234
|
```
|
|
256
235
|
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
```typescript
|
|
260
|
-
import { createAssessor, SwarmAssessor } from '@cogitator-ai/swarms';
|
|
261
|
-
|
|
262
|
-
const assessor = createAssessor({
|
|
263
|
-
mode: 'rules',
|
|
264
|
-
assessorModel: 'gpt-4o-mini',
|
|
265
|
-
preferLocal: true,
|
|
266
|
-
minCapabilityMatch: 0.3,
|
|
267
|
-
ollamaUrl: 'http://localhost:11434',
|
|
268
|
-
enabledProviders: ['ollama', 'openai', 'anthropic', 'google'],
|
|
269
|
-
cacheAssessments: true,
|
|
270
|
-
cacheTTL: 5 * 60 * 1000,
|
|
271
|
-
maxCostPerRun: 1.0,
|
|
272
|
-
});
|
|
273
|
-
```
|
|
236
|
+
---
|
|
274
237
|
|
|
275
|
-
|
|
238
|
+
## Error Handling and Limits
|
|
276
239
|
|
|
277
240
|
```typescript
|
|
278
|
-
const
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
241
|
+
const swarm = new SwarmBuilder('resilient-team')
|
|
242
|
+
.strategy('round-robin')
|
|
243
|
+
.agents([primary, backup])
|
|
244
|
+
.errorHandling({
|
|
245
|
+
onAgentFailure: 'failover', // 'retry' | 'failover' | 'skip' | 'abort'
|
|
246
|
+
failover: { primary: 'backup' },
|
|
247
|
+
retry: { maxRetries: 3, backoff: 'exponential', initialDelay: 500, maxDelay: 10_000 },
|
|
248
|
+
circuitBreaker: { enabled: true, threshold: 5, resetTimeout: 30_000 },
|
|
249
|
+
partialResults: true, // parallel phases return the agents that succeeded
|
|
250
|
+
})
|
|
251
|
+
.resources({
|
|
252
|
+
maxConcurrency: 4,
|
|
253
|
+
tokenBudget: 100_000, // per run
|
|
254
|
+
costLimit: 5,
|
|
255
|
+
timeout: 300_000,
|
|
256
|
+
perAgent: { maxTokens: 2_000, maxIterations: 5, timeout: 60_000 },
|
|
257
|
+
})
|
|
258
|
+
.build(cogitator);
|
|
283
259
|
|
|
284
|
-
|
|
285
|
-
console.log(`${model.modelId} (${model.provider}): score ${model.score}`);
|
|
286
|
-
}
|
|
260
|
+
const usage = swarm.getResourceUsage();
|
|
287
261
|
```
|
|
288
262
|
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
| Component | Description |
|
|
292
|
-
| ---------------- | --------------------------------------------- |
|
|
293
|
-
| `TaskAnalyzer` | Analyzes task complexity and requirements |
|
|
294
|
-
| `ModelDiscovery` | Discovers available models from all providers |
|
|
295
|
-
| `ModelScorer` | Scores models against role requirements |
|
|
296
|
-
| `RoleMatcher` | Matches agents to optimal models |
|
|
263
|
+
`CircuitBreaker` and `ResourceTracker` are exported for standalone use.
|
|
297
264
|
|
|
298
265
|
---
|
|
299
266
|
|
|
@@ -301,808 +268,189 @@ for (const model of candidates) {
|
|
|
301
268
|
|
|
302
269
|
### Message Bus
|
|
303
270
|
|
|
304
|
-
Agents can send direct messages and broadcasts:
|
|
305
|
-
|
|
306
271
|
```typescript
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
// Tools available:
|
|
315
|
-
// - send_message: Send to specific agent
|
|
316
|
-
// - read_messages: Read incoming messages
|
|
317
|
-
// - broadcast_message: Send to all agents
|
|
318
|
-
// - reply_to_message: Reply to a specific message
|
|
272
|
+
await swarm.messageBus.send({
|
|
273
|
+
swarmId: swarm.id,
|
|
274
|
+
from: 'operator',
|
|
275
|
+
to: 'coder',
|
|
276
|
+
type: 'notification',
|
|
277
|
+
content: 'Use TypeScript strict mode',
|
|
278
|
+
});
|
|
319
279
|
```
|
|
320
280
|
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
Agents can read/write shared state:
|
|
324
|
-
|
|
325
|
-
```typescript
|
|
326
|
-
import { InMemoryBlackboard, createBlackboardTools } from '@cogitator-ai/swarms';
|
|
327
|
-
|
|
328
|
-
const blackboard = new InMemoryBlackboard();
|
|
329
|
-
|
|
330
|
-
const tools = createBlackboardTools(blackboard, 'agent-1');
|
|
331
|
-
|
|
332
|
-
// Tools available:
|
|
333
|
-
// - read_blackboard: Read a section
|
|
334
|
-
// - write_blackboard: Write to a section
|
|
335
|
-
// - append_blackboard: Append to array section
|
|
336
|
-
// - list_blackboard_sections: List all sections
|
|
337
|
-
// - get_blackboard_history: Get change history
|
|
338
|
-
```
|
|
281
|
+
Unread messages are injected into the recipient's next turn exactly once (`message:received` event). `maxMessagesPerTurn` limits how many messages an agent may send per turn.
|
|
339
282
|
|
|
340
|
-
###
|
|
283
|
+
### Blackboard
|
|
341
284
|
|
|
342
285
|
```typescript
|
|
343
286
|
const swarm = new SwarmBuilder('research-team')
|
|
344
287
|
.strategy('hierarchical')
|
|
345
|
-
.supervisor(
|
|
346
|
-
.workers([
|
|
347
|
-
.messaging({
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
channels: ['findings', 'questions', 'progress'],
|
|
351
|
-
})
|
|
352
|
-
.blackboardConfig({
|
|
353
|
-
enabled: true,
|
|
354
|
-
sections: {
|
|
355
|
-
findings: [],
|
|
356
|
-
sources: [],
|
|
357
|
-
conclusions: '',
|
|
358
|
-
},
|
|
359
|
-
})
|
|
288
|
+
.supervisor(lead)
|
|
289
|
+
.workers([researcher])
|
|
290
|
+
.messaging({ enabled: true, protocol: 'direct', maxMessagesPerTurn: 5 })
|
|
291
|
+
.blackboardConfig({ enabled: true, sections: { findings: [] }, trackHistory: true })
|
|
292
|
+
.observability({ messageLogging: true, blackboardLogging: true })
|
|
360
293
|
.build(cogitator);
|
|
294
|
+
|
|
295
|
+
swarm.blackboard.subscribe('findings', (data, writer) => console.log(writer, data));
|
|
361
296
|
```
|
|
362
297
|
|
|
363
298
|
---
|
|
364
299
|
|
|
365
300
|
## Built-in Swarm Tools
|
|
366
301
|
|
|
367
|
-
### All Tools at Once
|
|
368
|
-
|
|
369
302
|
```typescript
|
|
370
|
-
import { createSwarmTools, SwarmToolContext } from '@cogitator-ai/swarms';
|
|
303
|
+
import { createSwarmTools, createStrategyTools, type SwarmToolContext } from '@cogitator-ai/swarms';
|
|
371
304
|
|
|
372
305
|
const context: SwarmToolContext = {
|
|
373
|
-
coordinator,
|
|
374
|
-
blackboard,
|
|
375
|
-
messageBus,
|
|
376
|
-
events,
|
|
377
|
-
agentName: '
|
|
378
|
-
|
|
306
|
+
coordinator, // the swarm coordinator (SwarmCoordinatorInterface)
|
|
307
|
+
blackboard: swarm.blackboard,
|
|
308
|
+
messageBus: swarm.messageBus,
|
|
309
|
+
events: swarm.events,
|
|
310
|
+
agentName: 'coder',
|
|
311
|
+
swarmId: swarm.id,
|
|
379
312
|
};
|
|
380
313
|
|
|
381
|
-
const
|
|
382
|
-
|
|
314
|
+
const allTools = createSwarmTools(context); // messaging, blackboard, delegation, voting, negotiation
|
|
315
|
+
const hierarchicalTools = createStrategyTools('hierarchical', context);
|
|
383
316
|
```
|
|
384
317
|
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
// Returns: messaging + blackboard + delegation tools
|
|
393
|
-
|
|
394
|
-
const debateTools = createStrategyTools('debate', context);
|
|
395
|
-
// Returns: messaging + blackboard + voting tools
|
|
396
|
-
```
|
|
397
|
-
|
|
398
|
-
### Delegation Tools (Hierarchical)
|
|
399
|
-
|
|
400
|
-
```typescript
|
|
401
|
-
import { createDelegationTools } from '@cogitator-ai/swarms';
|
|
402
|
-
|
|
403
|
-
const tools = createDelegationTools(coordinator, blackboard, 'supervisor');
|
|
404
|
-
|
|
405
|
-
// delegate_task - Assign work to a worker
|
|
406
|
-
// check_progress - Monitor worker status
|
|
407
|
-
// request_revision - Ask for corrections
|
|
408
|
-
// list_workers - See available workers
|
|
409
|
-
```
|
|
318
|
+
| Factory | Tools |
|
|
319
|
+
| ------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
320
|
+
| `createMessagingTools` | `send_message` (optional `waitForReply`), `read_messages` (marks returned messages read), `broadcast_message`, `reply_to_message` |
|
|
321
|
+
| `createBlackboardTools` | `read_blackboard`, `write_blackboard` (`merge` extends arrays / merges objects), `append_blackboard`, `list_blackboard_sections`, `get_blackboard_history` |
|
|
322
|
+
| `createDelegationTools` | `delegate_task`, `check_progress`, `request_revision`, `list_workers` |
|
|
323
|
+
| `createVotingTools` | `cast_vote`, `get_votes`, `change_vote`, `get_consensus_status` |
|
|
324
|
+
| `createNegotiationTools` | `make_offer`, `counter_offer`, `accept_offer`, `reject_offer`, `get_negotiation_status`, `get_current_offers`, `propose_coalition`, `join_coalition`, `declare_interests` |
|
|
410
325
|
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
```typescript
|
|
414
|
-
import { createVotingTools } from '@cogitator-ai/swarms';
|
|
415
|
-
|
|
416
|
-
const tools = createVotingTools(blackboard, events, 'voter-1', 1.0);
|
|
417
|
-
|
|
418
|
-
// cast_vote - Submit a vote
|
|
419
|
-
// get_votes - See current votes
|
|
420
|
-
// change_vote - Modify your vote
|
|
421
|
-
// get_consensus_status - Check if consensus reached
|
|
422
|
-
```
|
|
326
|
+
Messaging tools created through `createSwarmTools`/`createStrategyTools` enforce the hierarchical communication policy (`createHierarchyMessageAuthorizer`).
|
|
423
327
|
|
|
424
328
|
---
|
|
425
329
|
|
|
426
|
-
##
|
|
427
|
-
|
|
428
|
-
Use swarms as nodes in DAG workflows.
|
|
429
|
-
|
|
430
|
-
### Basic Swarm Node
|
|
431
|
-
|
|
432
|
-
```typescript
|
|
433
|
-
import { WorkflowBuilder } from '@cogitator-ai/workflows';
|
|
434
|
-
import { swarmNode, SwarmNodeContext } from '@cogitator-ai/swarms';
|
|
435
|
-
|
|
436
|
-
const analysisSwarm = new SwarmBuilder('analysis')
|
|
437
|
-
.strategy('debate')
|
|
438
|
-
.agents([...])
|
|
439
|
-
.build(cogitator);
|
|
440
|
-
|
|
441
|
-
const workflow = new WorkflowBuilder('analysis-flow')
|
|
442
|
-
.addNode('analyze', swarmNode(analysisSwarm, {
|
|
443
|
-
inputMapper: (state) => state.document,
|
|
444
|
-
stateMapper: (result) => ({ analysis: result.output }),
|
|
445
|
-
}))
|
|
446
|
-
.build();
|
|
447
|
-
|
|
448
|
-
const result = await workflow.run({
|
|
449
|
-
cogitator,
|
|
450
|
-
input: { document: 'Analyze this document...' },
|
|
451
|
-
});
|
|
452
|
-
```
|
|
453
|
-
|
|
454
|
-
### Conditional Swarm Node
|
|
455
|
-
|
|
456
|
-
```typescript
|
|
457
|
-
import { conditionalSwarmNode } from '@cogitator-ai/swarms';
|
|
458
|
-
|
|
459
|
-
const workflow = new WorkflowBuilder('conditional-flow')
|
|
460
|
-
.addNode(
|
|
461
|
-
'expert-review',
|
|
462
|
-
conditionalSwarmNode(expertSwarm, (state) => state.needsExpertReview, {
|
|
463
|
-
stateMapper: (result) => ({ expertOpinion: result.output }),
|
|
464
|
-
})
|
|
465
|
-
)
|
|
466
|
-
.build();
|
|
467
|
-
```
|
|
468
|
-
|
|
469
|
-
### Parallel Swarms Node
|
|
470
|
-
|
|
471
|
-
```typescript
|
|
472
|
-
import { parallelSwarmsNode } from '@cogitator-ai/swarms';
|
|
473
|
-
|
|
474
|
-
const workflow = new WorkflowBuilder('parallel-analysis')
|
|
475
|
-
.addNode(
|
|
476
|
-
'multi-analyze',
|
|
477
|
-
parallelSwarmsNode(
|
|
478
|
-
[
|
|
479
|
-
{ swarm: technicalSwarm, key: 'technical' },
|
|
480
|
-
{ swarm: businessSwarm, key: 'business' },
|
|
481
|
-
{ swarm: legalSwarm, key: 'legal' },
|
|
482
|
-
],
|
|
483
|
-
(results) => ({
|
|
484
|
-
technicalAnalysis: results.technical.output,
|
|
485
|
-
businessAnalysis: results.business.output,
|
|
486
|
-
legalAnalysis: results.legal.output,
|
|
487
|
-
})
|
|
488
|
-
)
|
|
489
|
-
)
|
|
490
|
-
.build();
|
|
491
|
-
```
|
|
492
|
-
|
|
493
|
-
---
|
|
494
|
-
|
|
495
|
-
## Resource Tracking
|
|
496
|
-
|
|
497
|
-
Monitor and limit resource usage during swarm execution.
|
|
498
|
-
|
|
499
|
-
### Configuration
|
|
330
|
+
## SwarmAssessor (Automatic Model Selection)
|
|
500
331
|
|
|
501
332
|
```typescript
|
|
502
|
-
const swarm = new SwarmBuilder('
|
|
333
|
+
const swarm = new SwarmBuilder('smart-team')
|
|
503
334
|
.strategy('hierarchical')
|
|
504
335
|
.supervisor(lead)
|
|
505
|
-
.workers(
|
|
506
|
-
.
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
336
|
+
.workers([coder, analyst])
|
|
337
|
+
.agentMetadata({ lead: { locked: true }, coder: { expertise: ['code'] } })
|
|
338
|
+
.withAssessor({
|
|
339
|
+
mode: 'rules',
|
|
340
|
+
preferLocal: true,
|
|
341
|
+
minCapabilityMatch: 0.3,
|
|
342
|
+
maxCostPerRun: 0.5,
|
|
343
|
+
enabledProviders: ['ollama', 'openai'],
|
|
510
344
|
})
|
|
511
345
|
.build(cogitator);
|
|
512
|
-
```
|
|
513
|
-
|
|
514
|
-
### ResourceTracker API
|
|
515
|
-
|
|
516
|
-
```typescript
|
|
517
|
-
import { ResourceTracker } from '@cogitator-ai/swarms';
|
|
518
|
-
|
|
519
|
-
const tracker = new ResourceTracker({
|
|
520
|
-
tokenBudget: 50000,
|
|
521
|
-
costLimit: 2.0,
|
|
522
|
-
timeout: 60000,
|
|
523
|
-
});
|
|
524
|
-
|
|
525
|
-
// Track agent runs
|
|
526
|
-
tracker.trackAgentRun('agent-1', runResult);
|
|
527
346
|
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
console.log(
|
|
531
|
-
|
|
532
|
-
// Get usage stats
|
|
533
|
-
const usage = tracker.getUsage();
|
|
534
|
-
console.log('Total tokens:', usage.totalTokens);
|
|
535
|
-
console.log('Total cost:', usage.totalCost);
|
|
536
|
-
console.log('Elapsed time:', usage.elapsedTime);
|
|
347
|
+
const preview = await swarm.dryRun({ input: 'Build a recommendation engine' });
|
|
348
|
+
for (const a of preview.assignments) {
|
|
349
|
+
console.log(`${a.agentName}: ${a.assignedModel} (score ${a.score})`);
|
|
350
|
+
}
|
|
537
351
|
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
console.log('Agent tokens:', agentUsage?.tokens);
|
|
352
|
+
await swarm.run({ input: 'Build a recommendation engine' });
|
|
353
|
+
console.log(swarm.getLastAssessment()?.assignments);
|
|
541
354
|
```
|
|
542
355
|
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
```typescript
|
|
546
|
-
const result = await swarm.run({ input: 'Task...' });
|
|
547
|
-
|
|
548
|
-
const usage = swarm.getResourceUsage();
|
|
549
|
-
console.log('Total tokens:', usage.totalTokens);
|
|
550
|
-
console.log('Total cost:', usage.totalCost);
|
|
551
|
-
|
|
552
|
-
for (const [agent, stats] of usage.agentUsage) {
|
|
553
|
-
console.log(`${agent}: ${stats.tokens} tokens, ${stats.runs} runs`);
|
|
554
|
-
}
|
|
555
|
-
```
|
|
356
|
+
Assigned models are provider-qualified (e.g. `ollama/llama3.2:3b`). Unlocked agents are replaced by clones running the assigned model; locked agents keep theirs.
|
|
556
357
|
|
|
557
358
|
---
|
|
558
359
|
|
|
559
|
-
##
|
|
560
|
-
|
|
561
|
-
Prevent cascading failures in swarm execution.
|
|
360
|
+
## Workflow Integration
|
|
562
361
|
|
|
563
362
|
```typescript
|
|
564
|
-
import {
|
|
363
|
+
import { WorkflowBuilder, WorkflowExecutor } from '@cogitator-ai/workflows';
|
|
364
|
+
import { swarmNode, parallelSwarmsNode } from '@cogitator-ai/swarms';
|
|
565
365
|
|
|
566
|
-
const
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
breaker.recordSuccess();
|
|
577
|
-
} catch (error) {
|
|
578
|
-
breaker.recordFailure();
|
|
579
|
-
throw error;
|
|
580
|
-
}
|
|
581
|
-
} else {
|
|
582
|
-
console.log('Circuit is open, skipping execution');
|
|
583
|
-
}
|
|
366
|
+
const workflow = new WorkflowBuilder<{ document: string; analysis?: unknown }>('analysis-flow')
|
|
367
|
+
.initialState({ document: '' })
|
|
368
|
+
.addNode(
|
|
369
|
+
'analyze',
|
|
370
|
+
swarmNode(analysisSwarm, {
|
|
371
|
+
inputMapper: (state) => state.document,
|
|
372
|
+
stateMapper: (result) => ({ analysis: result.output }),
|
|
373
|
+
})
|
|
374
|
+
)
|
|
375
|
+
.build();
|
|
584
376
|
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
console.log('Circuit state:', state); // 'closed' | 'open' | 'half-open'
|
|
377
|
+
const result = await new WorkflowExecutor(cogitator).execute(workflow, {
|
|
378
|
+
document: 'Analyze this...',
|
|
588
379
|
});
|
|
589
|
-
|
|
590
|
-
// Reset manually
|
|
591
|
-
breaker.reset();
|
|
592
380
|
```
|
|
593
381
|
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
```typescript
|
|
597
|
-
const swarm = new SwarmBuilder('resilient-team')
|
|
598
|
-
.strategy('hierarchical')
|
|
599
|
-
.supervisor(lead)
|
|
600
|
-
.workers(workers)
|
|
601
|
-
.errorHandling({
|
|
602
|
-
retryCount: 3,
|
|
603
|
-
retryDelay: 1000,
|
|
604
|
-
circuitBreaker: {
|
|
605
|
-
threshold: 5,
|
|
606
|
-
resetTimeout: 30000,
|
|
607
|
-
},
|
|
608
|
-
fallbackAgent: fallbackAgent,
|
|
609
|
-
})
|
|
610
|
-
.build(cogitator);
|
|
611
|
-
```
|
|
382
|
+
`conditionalSwarmNode(swarm, condition, options)` and `parallelSwarmsNode([{ swarm, key }], merge)` are also available. Pass a `SwarmConfig` instead of a `Swarm` to create (and close) a fresh swarm per execution.
|
|
612
383
|
|
|
613
384
|
---
|
|
614
385
|
|
|
615
386
|
## Swarm Events
|
|
616
387
|
|
|
617
|
-
Subscribe to swarm lifecycle events.
|
|
618
|
-
|
|
619
388
|
```typescript
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
.build(cogitator);
|
|
625
|
-
|
|
626
|
-
// Subscribe to specific events
|
|
627
|
-
swarm.on('swarm:start', (event) => {
|
|
628
|
-
console.log('Swarm started:', event.swarmId);
|
|
629
|
-
});
|
|
630
|
-
|
|
631
|
-
swarm.on('agent:start', (event) => {
|
|
632
|
-
console.log(`Agent ${event.agentName} started`);
|
|
633
|
-
});
|
|
634
|
-
|
|
635
|
-
swarm.on('agent:complete', (event) => {
|
|
636
|
-
console.log(`Agent ${event.agentName} completed`);
|
|
637
|
-
});
|
|
638
|
-
|
|
639
|
-
swarm.on('swarm:complete', (event) => {
|
|
640
|
-
console.log('Swarm completed, agents used:', event.agentCount);
|
|
641
|
-
});
|
|
642
|
-
|
|
643
|
-
swarm.on('swarm:error', (event) => {
|
|
644
|
-
console.error('Swarm error:', event.error);
|
|
645
|
-
});
|
|
646
|
-
|
|
647
|
-
// Subscribe to all events
|
|
648
|
-
swarm.on('*', (event) => {
|
|
649
|
-
console.log('Event:', event);
|
|
650
|
-
});
|
|
651
|
-
|
|
652
|
-
// One-time subscription
|
|
653
|
-
swarm.once('swarm:complete', (event) => {
|
|
654
|
-
console.log('Finished!');
|
|
655
|
-
});
|
|
389
|
+
swarm.on('agent:complete', (event) => console.log(event.agentName));
|
|
390
|
+
swarm.once('swarm:complete', () => console.log('done'));
|
|
391
|
+
const unsubscribe = swarm.on('*', (event) => console.log(event.type));
|
|
392
|
+
unsubscribe();
|
|
656
393
|
```
|
|
657
394
|
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
| Event
|
|
661
|
-
|
|
|
662
|
-
| `swarm:start`
|
|
663
|
-
| `swarm:
|
|
664
|
-
| `
|
|
665
|
-
| `
|
|
666
|
-
| `
|
|
667
|
-
| `
|
|
668
|
-
| `
|
|
669
|
-
| `agent:start` | Agent started execution |
|
|
670
|
-
| `agent:complete` | Agent completed execution |
|
|
671
|
-
| `agent:error` | Agent encountered error |
|
|
672
|
-
| `assessor:complete` | Model assessment completed |
|
|
673
|
-
| `message:sent` | Message sent between agents |
|
|
674
|
-
| `blackboard:write` | Blackboard updated |
|
|
675
|
-
| `vote:cast` | Vote cast in consensus |
|
|
395
|
+
Subscriptions survive the coordinator rebuild that happens after model assessment.
|
|
396
|
+
|
|
397
|
+
| Event | Description |
|
|
398
|
+
| --------------------------------------------------------------------------------------------- | ------------------------------------------------ |
|
|
399
|
+
| `swarm:start` / `swarm:complete` / `swarm:error` | Run lifecycle |
|
|
400
|
+
| `swarm:paused` / `swarm:resumed` / `swarm:aborted` / `swarm:reset` | Control actions |
|
|
401
|
+
| `agent:start` / `agent:complete` / `agent:error` | Agent turns |
|
|
402
|
+
| `message:sent` / `message:received` | Bus messages sent / delivered to an agent's turn |
|
|
403
|
+
| `blackboard:write` | Section written or deleted |
|
|
404
|
+
| `assessor:complete` | Model assessment finished |
|
|
405
|
+
| `consensus:*`, `debate:*`, `auction:*`, `pipeline:*`, `round-robin:assigned`, `negotiation:*` | Strategy progress |
|
|
676
406
|
|
|
677
407
|
---
|
|
678
408
|
|
|
679
409
|
## Distributed Execution
|
|
680
410
|
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
### Basic Distributed Swarm
|
|
411
|
+
With `distributed.enabled`, the swarm keeps its message bus, blackboard and events in Redis and dispatches every agent turn as a job. Worker nodes from `@cogitator-ai/worker` execute the turns and publish results back.
|
|
684
412
|
|
|
685
413
|
```typescript
|
|
686
|
-
import { Cogitator, Agent } from '@cogitator-ai/core';
|
|
687
|
-
import { SwarmBuilder } from '@cogitator-ai/swarms';
|
|
688
|
-
|
|
689
|
-
const cogitator = new Cogitator({ defaultModel: 'gpt-4o' });
|
|
690
|
-
|
|
691
414
|
const swarm = new SwarmBuilder('distributed-team')
|
|
692
|
-
.strategy('
|
|
693
|
-
.
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
415
|
+
.strategy('pipeline')
|
|
416
|
+
.pipeline({
|
|
417
|
+
stages: [
|
|
418
|
+
{ name: 'draft', agent: writer },
|
|
419
|
+
{ name: 'review', agent: reviewer },
|
|
420
|
+
],
|
|
421
|
+
})
|
|
699
422
|
.distributed({
|
|
700
423
|
enabled: true,
|
|
701
424
|
queue: 'swarm-agent-jobs',
|
|
702
|
-
timeout:
|
|
703
|
-
redis: {
|
|
704
|
-
host: 'localhost',
|
|
705
|
-
port: 6379,
|
|
706
|
-
},
|
|
425
|
+
timeout: 300_000,
|
|
426
|
+
redis: { host: 'localhost', port: 6379, keyPrefix: 'swarm' },
|
|
707
427
|
})
|
|
708
428
|
.build(cogitator);
|
|
709
429
|
|
|
710
|
-
const result = await swarm.run({
|
|
711
|
-
input: 'Analyze Q4 sales data across all regions',
|
|
712
|
-
});
|
|
713
|
-
|
|
714
|
-
// Cleanup Redis connections when done
|
|
430
|
+
const result = await swarm.run({ input: 'Write release notes' });
|
|
715
431
|
await swarm.close();
|
|
716
432
|
```
|
|
717
433
|
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
```typescript
|
|
721
|
-
interface DistributedSwarmConfig {
|
|
722
|
-
enabled: boolean;
|
|
723
|
-
queue?: string; // Job queue name (default: 'swarm-agent-jobs')
|
|
724
|
-
workerConcurrency?: number; // Workers per process (default: 4)
|
|
725
|
-
timeout?: number; // Job timeout in ms (default: 300000)
|
|
726
|
-
redis?: {
|
|
727
|
-
host?: string; // Redis host (default: 'localhost')
|
|
728
|
-
port?: number; // Redis port (default: 6379)
|
|
729
|
-
password?: string; // Redis password
|
|
730
|
-
keyPrefix?: string; // Key prefix (default: 'swarm')
|
|
731
|
-
db?: number; // Redis database (default: 0)
|
|
732
|
-
};
|
|
733
|
-
retry?: {
|
|
734
|
-
maxRetries?: number; // Max retry attempts
|
|
735
|
-
backoff?: 'constant' | 'linear' | 'exponential';
|
|
736
|
-
initialDelay?: number; // Initial delay in ms
|
|
737
|
-
maxDelay?: number; // Max delay in ms
|
|
738
|
-
};
|
|
739
|
-
cleanupAfter?: number; // Cleanup keys after ms
|
|
740
|
-
}
|
|
741
|
-
```
|
|
742
|
-
|
|
743
|
-
### Redis-Backed Communication
|
|
744
|
-
|
|
745
|
-
Distributed swarms use Redis for shared state synchronization:
|
|
434
|
+
Worker node:
|
|
746
435
|
|
|
747
436
|
```typescript
|
|
748
|
-
import {
|
|
749
|
-
import
|
|
750
|
-
|
|
751
|
-
const redis = new Redis({ host: 'localhost', port: 6379 });
|
|
752
|
-
|
|
753
|
-
// Message bus for agent-to-agent communication
|
|
754
|
-
const messageBus = new RedisMessageBus(
|
|
755
|
-
{ enabled: true, protocol: 'direct' },
|
|
756
|
-
{ redis, swarmId: 'my-swarm', keyPrefix: 'swarm' }
|
|
757
|
-
);
|
|
758
|
-
await messageBus.initialize();
|
|
759
|
-
|
|
760
|
-
// Shared blackboard for state
|
|
761
|
-
const blackboard = new RedisBlackboard(
|
|
762
|
-
{ enabled: true, sections: { results: [] }, trackHistory: true },
|
|
763
|
-
{ redis, swarmId: 'my-swarm', keyPrefix: 'swarm' }
|
|
764
|
-
);
|
|
765
|
-
await blackboard.initialize();
|
|
766
|
-
|
|
767
|
-
// Event emitter for cross-worker events
|
|
768
|
-
const events = new RedisSwarmEventEmitter({
|
|
769
|
-
redis,
|
|
770
|
-
swarmId: 'my-swarm',
|
|
771
|
-
keyPrefix: 'swarm',
|
|
772
|
-
});
|
|
773
|
-
await events.initialize();
|
|
774
|
-
```
|
|
437
|
+
import { Cogitator } from '@cogitator-ai/core';
|
|
438
|
+
import { DistributedSwarmWorker } from '@cogitator-ai/worker';
|
|
775
439
|
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
```typescript
|
|
781
|
-
import { WorkerPool } from '@cogitator-ai/worker';
|
|
782
|
-
|
|
783
|
-
const pool = new WorkerPool({
|
|
440
|
+
const worker = new DistributedSwarmWorker({
|
|
441
|
+
redis: { host: 'localhost', port: 6379 },
|
|
442
|
+
keyPrefix: 'swarm', // must match distributed.redis.keyPrefix
|
|
443
|
+
queue: 'swarm-agent-jobs', // must match distributed.queue
|
|
784
444
|
concurrency: 4,
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
port: 6379,
|
|
788
|
-
},
|
|
789
|
-
queues: ['swarm-agent-jobs'],
|
|
445
|
+
cogitator: new Cogitator({ llm: { defaultModel: 'ollama/llama3.2' } }),
|
|
446
|
+
tools: [searchTool, calculatorTool], // implementations of tools the agents reference
|
|
790
447
|
});
|
|
791
448
|
|
|
792
|
-
await
|
|
793
|
-
|
|
794
|
-
// Workers automatically process swarm-agent jobs
|
|
795
|
-
// Each job runs a single agent and publishes results back to Redis
|
|
449
|
+
await worker.start();
|
|
450
|
+
process.on('SIGTERM', () => void worker.stop());
|
|
796
451
|
```
|
|
797
452
|
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
```
|
|
801
|
-
┌─────────────────────────────────────────────────────────────┐
|
|
802
|
-
│ Swarm.run() │
|
|
803
|
-
│ distributed: true → DistributedSwarmCoordinator │
|
|
804
|
-
│ distributed: false → SwarmCoordinator (in-memory) │
|
|
805
|
-
└─────────────────────────────────────────────────────────────┘
|
|
806
|
-
│
|
|
807
|
-
┌───────────────┴───────────────┐
|
|
808
|
-
▼ ▼
|
|
809
|
-
┌─────────────────────────┐ ┌─────────────────────────────┐
|
|
810
|
-
│ DistributedCoordinator │ │ Redis (Shared State) │
|
|
811
|
-
│ - dispatches agent jobs│────▶│ - swarm:{id}:blackboard │
|
|
812
|
-
│ - subscribes to results│ │ - swarm:{id}:messages │
|
|
813
|
-
│ - coordinates strategy │ │ - swarm:{id}:results │
|
|
814
|
-
└─────────────────────────┘ └─────────────────────────────┘
|
|
815
|
-
│ ▲
|
|
816
|
-
│ job queue │
|
|
817
|
-
▼ │
|
|
818
|
-
┌─────────────────────────┐ │
|
|
819
|
-
│ BullMQ Queue │ │
|
|
820
|
-
│ swarm-agent-jobs │ │
|
|
821
|
-
└─────────────────────────┘ │
|
|
822
|
-
│ │
|
|
823
|
-
┌─────────┼─────────┐ │
|
|
824
|
-
▼ ▼ ▼ │
|
|
825
|
-
┌───────┐ ┌───────┐ ┌───────┐ │
|
|
826
|
-
│Worker1│ │Worker2│ │Worker3│ ───────────────┘
|
|
827
|
-
│ Agent │ │ Agent │ │ Agent │ publish results
|
|
828
|
-
└───────┘ └───────┘ └───────┘
|
|
829
|
-
```
|
|
830
|
-
|
|
831
|
-
### Local vs Distributed
|
|
832
|
-
|
|
833
|
-
The same swarm works in both modes with identical API:
|
|
834
|
-
|
|
835
|
-
```typescript
|
|
836
|
-
// Local execution (in-process)
|
|
837
|
-
const localSwarm = new SwarmBuilder('local-team')
|
|
838
|
-
.strategy('consensus')
|
|
839
|
-
.agents([agent1, agent2, agent3])
|
|
840
|
-
.consensus({ threshold: 0.6, maxRounds: 3, resolution: 'majority', onNoConsensus: 'fail' })
|
|
841
|
-
.build(cogitator);
|
|
842
|
-
|
|
843
|
-
// Distributed execution (across workers)
|
|
844
|
-
const distributedSwarm = new SwarmBuilder('distributed-team')
|
|
845
|
-
.strategy('consensus')
|
|
846
|
-
.agents([agent1, agent2, agent3])
|
|
847
|
-
.consensus({ threshold: 0.6, maxRounds: 3, resolution: 'majority', onNoConsensus: 'fail' })
|
|
848
|
-
.distributed({ enabled: true, redis: { host: 'redis.example.com' } })
|
|
849
|
-
.build(cogitator);
|
|
850
|
-
|
|
851
|
-
// Same API for both
|
|
852
|
-
const localResult = await localSwarm.run({ input: 'Task...' });
|
|
853
|
-
const distributedResult = await distributedSwarm.run({ input: 'Task...' });
|
|
854
|
-
```
|
|
855
|
-
|
|
856
|
-
---
|
|
857
|
-
|
|
858
|
-
## Swarm Control
|
|
859
|
-
|
|
860
|
-
### Pause and Resume
|
|
861
|
-
|
|
862
|
-
```typescript
|
|
863
|
-
const swarm = new SwarmBuilder('controllable')
|
|
864
|
-
.strategy('pipeline')
|
|
865
|
-
.pipeline({ stages: [...] })
|
|
866
|
-
.build(cogitator);
|
|
867
|
-
|
|
868
|
-
// Start execution
|
|
869
|
-
const resultPromise = swarm.run({ input: 'Process this...' });
|
|
870
|
-
|
|
871
|
-
// Pause mid-execution
|
|
872
|
-
setTimeout(() => {
|
|
873
|
-
swarm.pause();
|
|
874
|
-
console.log('Paused:', swarm.isPaused());
|
|
875
|
-
|
|
876
|
-
// Resume later
|
|
877
|
-
setTimeout(() => {
|
|
878
|
-
swarm.resume();
|
|
879
|
-
}, 5000);
|
|
880
|
-
}, 2000);
|
|
881
|
-
|
|
882
|
-
const result = await resultPromise;
|
|
883
|
-
```
|
|
884
|
-
|
|
885
|
-
### Abort
|
|
886
|
-
|
|
887
|
-
```typescript
|
|
888
|
-
const timeoutId = setTimeout(() => {
|
|
889
|
-
if (!swarm.isAborted()) {
|
|
890
|
-
swarm.abort();
|
|
891
|
-
console.log('Swarm aborted due to timeout');
|
|
892
|
-
}
|
|
893
|
-
}, 60000);
|
|
894
|
-
|
|
895
|
-
try {
|
|
896
|
-
const result = await swarm.run({ input: 'Task...' });
|
|
897
|
-
clearTimeout(timeoutId);
|
|
898
|
-
} catch (error) {
|
|
899
|
-
if (swarm.isAborted()) {
|
|
900
|
-
console.log('Task was aborted');
|
|
901
|
-
}
|
|
902
|
-
}
|
|
903
|
-
```
|
|
904
|
-
|
|
905
|
-
### Reset
|
|
906
|
-
|
|
907
|
-
```typescript
|
|
908
|
-
// Reset swarm state for a new run
|
|
909
|
-
swarm.reset();
|
|
910
|
-
|
|
911
|
-
// Run again with fresh state
|
|
912
|
-
const result = await swarm.run({ input: 'New task...' });
|
|
913
|
-
```
|
|
914
|
-
|
|
915
|
-
---
|
|
916
|
-
|
|
917
|
-
## Type Reference
|
|
918
|
-
|
|
919
|
-
### Core Types
|
|
920
|
-
|
|
921
|
-
```typescript
|
|
922
|
-
import type {
|
|
923
|
-
SwarmConfig,
|
|
924
|
-
SwarmRunOptions,
|
|
925
|
-
SwarmAgent,
|
|
926
|
-
SwarmAgentMetadata,
|
|
927
|
-
SwarmAgentState,
|
|
928
|
-
StrategyResult,
|
|
929
|
-
SwarmStrategy,
|
|
930
|
-
} from '@cogitator-ai/swarms';
|
|
931
|
-
```
|
|
932
|
-
|
|
933
|
-
### Strategy Types
|
|
934
|
-
|
|
935
|
-
```typescript
|
|
936
|
-
import type {
|
|
937
|
-
HierarchicalConfig,
|
|
938
|
-
RoundRobinConfig,
|
|
939
|
-
ConsensusConfig,
|
|
940
|
-
AuctionConfig,
|
|
941
|
-
PipelineConfig,
|
|
942
|
-
PipelineStage,
|
|
943
|
-
DebateConfig,
|
|
944
|
-
} from '@cogitator-ai/swarms';
|
|
945
|
-
```
|
|
946
|
-
|
|
947
|
-
### Communication Types
|
|
948
|
-
|
|
949
|
-
```typescript
|
|
950
|
-
import type {
|
|
951
|
-
MessageBus,
|
|
952
|
-
MessageBusConfig,
|
|
953
|
-
Blackboard,
|
|
954
|
-
BlackboardConfig,
|
|
955
|
-
BlackboardEntry,
|
|
956
|
-
SwarmMessage,
|
|
957
|
-
SwarmMessageType,
|
|
958
|
-
} from '@cogitator-ai/swarms';
|
|
959
|
-
```
|
|
960
|
-
|
|
961
|
-
### Assessor Types
|
|
962
|
-
|
|
963
|
-
```typescript
|
|
964
|
-
import type {
|
|
965
|
-
AssessorConfig,
|
|
966
|
-
AssessmentResult,
|
|
967
|
-
TaskRequirements,
|
|
968
|
-
RoleRequirements,
|
|
969
|
-
ModelAssignment,
|
|
970
|
-
ModelCandidate,
|
|
971
|
-
DiscoveredModel,
|
|
972
|
-
ScoredModel,
|
|
973
|
-
} from '@cogitator-ai/swarms';
|
|
974
|
-
```
|
|
975
|
-
|
|
976
|
-
### Event Types
|
|
977
|
-
|
|
978
|
-
```typescript
|
|
979
|
-
import type {
|
|
980
|
-
SwarmEventEmitter,
|
|
981
|
-
SwarmEventType,
|
|
982
|
-
SwarmEvent,
|
|
983
|
-
SwarmEventHandler,
|
|
984
|
-
} from '@cogitator-ai/swarms';
|
|
985
|
-
```
|
|
986
|
-
|
|
987
|
-
### Distributed Types
|
|
988
|
-
|
|
989
|
-
```typescript
|
|
990
|
-
import type { DistributedSwarmConfig } from '@cogitator-ai/types';
|
|
991
|
-
|
|
992
|
-
import {
|
|
993
|
-
RedisMessageBus,
|
|
994
|
-
RedisBlackboard,
|
|
995
|
-
RedisSwarmEventEmitter,
|
|
996
|
-
DistributedSwarmCoordinator,
|
|
997
|
-
} from '@cogitator-ai/swarms';
|
|
998
|
-
```
|
|
999
|
-
|
|
1000
|
-
---
|
|
1001
|
-
|
|
1002
|
-
## Examples
|
|
1003
|
-
|
|
1004
|
-
### Research Team with Shared Knowledge
|
|
1005
|
-
|
|
1006
|
-
```typescript
|
|
1007
|
-
const swarm = new SwarmBuilder('research-team')
|
|
1008
|
-
.strategy('hierarchical')
|
|
1009
|
-
.supervisor(
|
|
1010
|
-
new Agent({
|
|
1011
|
-
name: 'lead-researcher',
|
|
1012
|
-
instructions: 'Coordinate research and synthesize findings',
|
|
1013
|
-
})
|
|
1014
|
-
)
|
|
1015
|
-
.workers([
|
|
1016
|
-
new Agent({
|
|
1017
|
-
name: 'web-researcher',
|
|
1018
|
-
instructions: 'Search and analyze web sources',
|
|
1019
|
-
tools: [webSearchTool],
|
|
1020
|
-
}),
|
|
1021
|
-
new Agent({
|
|
1022
|
-
name: 'data-analyst',
|
|
1023
|
-
instructions: 'Analyze data and statistics',
|
|
1024
|
-
tools: [calculatorTool],
|
|
1025
|
-
}),
|
|
1026
|
-
new Agent({
|
|
1027
|
-
name: 'writer',
|
|
1028
|
-
instructions: 'Write clear summaries',
|
|
1029
|
-
}),
|
|
1030
|
-
])
|
|
1031
|
-
.messaging({ enabled: true })
|
|
1032
|
-
.blackboardConfig({
|
|
1033
|
-
enabled: true,
|
|
1034
|
-
sections: { findings: [], sources: [], draft: '' },
|
|
1035
|
-
})
|
|
1036
|
-
.withAssessor({ preferLocal: true })
|
|
1037
|
-
.build(cogitator);
|
|
1038
|
-
|
|
1039
|
-
const result = await swarm.run({
|
|
1040
|
-
input: 'Research the impact of AI on job markets',
|
|
1041
|
-
});
|
|
1042
|
-
```
|
|
1043
|
-
|
|
1044
|
-
### Code Review Pipeline
|
|
1045
|
-
|
|
1046
|
-
```typescript
|
|
1047
|
-
const swarm = new SwarmBuilder('code-review')
|
|
1048
|
-
.strategy('pipeline')
|
|
1049
|
-
.pipeline({
|
|
1050
|
-
stages: [
|
|
1051
|
-
{
|
|
1052
|
-
agent: new Agent({
|
|
1053
|
-
name: 'syntax-checker',
|
|
1054
|
-
instructions: 'Check for syntax errors and style issues',
|
|
1055
|
-
}),
|
|
1056
|
-
},
|
|
1057
|
-
{
|
|
1058
|
-
agent: new Agent({
|
|
1059
|
-
name: 'security-reviewer',
|
|
1060
|
-
instructions: 'Check for security vulnerabilities',
|
|
1061
|
-
}),
|
|
1062
|
-
},
|
|
1063
|
-
{
|
|
1064
|
-
agent: new Agent({
|
|
1065
|
-
name: 'performance-reviewer',
|
|
1066
|
-
instructions: 'Check for performance issues',
|
|
1067
|
-
}),
|
|
1068
|
-
},
|
|
1069
|
-
{
|
|
1070
|
-
agent: new Agent({
|
|
1071
|
-
name: 'summarizer',
|
|
1072
|
-
instructions: 'Summarize all findings',
|
|
1073
|
-
}),
|
|
1074
|
-
},
|
|
1075
|
-
],
|
|
1076
|
-
stopOnError: false,
|
|
1077
|
-
passContext: true,
|
|
1078
|
-
})
|
|
1079
|
-
.build(cogitator);
|
|
1080
|
-
```
|
|
1081
|
-
|
|
1082
|
-
### Decision Making with Consensus
|
|
1083
|
-
|
|
1084
|
-
```typescript
|
|
1085
|
-
const swarm = new SwarmBuilder('investment-committee')
|
|
1086
|
-
.strategy('consensus')
|
|
1087
|
-
.agents([
|
|
1088
|
-
new Agent({ name: 'risk-analyst', instructions: 'Evaluate risks' }),
|
|
1089
|
-
new Agent({ name: 'growth-analyst', instructions: 'Evaluate growth potential' }),
|
|
1090
|
-
new Agent({ name: 'market-analyst', instructions: 'Evaluate market conditions' }),
|
|
1091
|
-
])
|
|
1092
|
-
.consensus({
|
|
1093
|
-
votingMethod: 'weighted',
|
|
1094
|
-
minVotes: 3,
|
|
1095
|
-
weights: { 'risk-analyst': 1.5, 'growth-analyst': 1.0, 'market-analyst': 1.0 },
|
|
1096
|
-
})
|
|
1097
|
-
.build(cogitator);
|
|
1098
|
-
|
|
1099
|
-
const result = await swarm.run({
|
|
1100
|
-
input: 'Should we invest in Company X?',
|
|
1101
|
-
});
|
|
1102
|
-
|
|
1103
|
-
console.log('Decision:', result.output);
|
|
1104
|
-
console.log('Vote breakdown:', result.metadata?.votes);
|
|
1105
|
-
```
|
|
453
|
+
Retry, failover, budgets and circuit breaking work the same as for local swarms. `RedisMessageBus`, `RedisBlackboard` and `RedisSwarmEventEmitter` are exported for direct use.
|
|
1106
454
|
|
|
1107
455
|
---
|
|
1108
456
|
|