@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.
Files changed (134) hide show
  1. package/README.md +245 -897
  2. package/dist/agents.d.ts +13 -0
  3. package/dist/agents.d.ts.map +1 -0
  4. package/dist/agents.js +70 -0
  5. package/dist/agents.js.map +1 -0
  6. package/dist/assessor/assessor.d.ts +9 -2
  7. package/dist/assessor/assessor.d.ts.map +1 -1
  8. package/dist/assessor/assessor.js +71 -52
  9. package/dist/assessor/assessor.js.map +1 -1
  10. package/dist/assessor/role-matcher.d.ts +6 -24
  11. package/dist/assessor/role-matcher.d.ts.map +1 -1
  12. package/dist/assessor/role-matcher.js +9 -37
  13. package/dist/assessor/role-matcher.js.map +1 -1
  14. package/dist/base-coordinator.d.ts +117 -0
  15. package/dist/base-coordinator.d.ts.map +1 -0
  16. package/dist/base-coordinator.js +455 -0
  17. package/dist/base-coordinator.js.map +1 -0
  18. package/dist/communication/blackboard.d.ts +34 -4
  19. package/dist/communication/blackboard.d.ts.map +1 -1
  20. package/dist/communication/blackboard.js +81 -46
  21. package/dist/communication/blackboard.js.map +1 -1
  22. package/dist/communication/event-emitter.d.ts.map +1 -1
  23. package/dist/communication/event-emitter.js +6 -17
  24. package/dist/communication/event-emitter.js.map +1 -1
  25. package/dist/communication/index.d.ts +2 -2
  26. package/dist/communication/index.d.ts.map +1 -1
  27. package/dist/communication/index.js +2 -2
  28. package/dist/communication/index.js.map +1 -1
  29. package/dist/communication/message-bus.d.ts +48 -5
  30. package/dist/communication/message-bus.d.ts.map +1 -1
  31. package/dist/communication/message-bus.js +135 -50
  32. package/dist/communication/message-bus.js.map +1 -1
  33. package/dist/communication/redis-blackboard.d.ts +11 -5
  34. package/dist/communication/redis-blackboard.d.ts.map +1 -1
  35. package/dist/communication/redis-blackboard.js +159 -116
  36. package/dist/communication/redis-blackboard.js.map +1 -1
  37. package/dist/communication/redis-event-emitter.d.ts +12 -0
  38. package/dist/communication/redis-event-emitter.d.ts.map +1 -1
  39. package/dist/communication/redis-event-emitter.js +96 -54
  40. package/dist/communication/redis-event-emitter.js.map +1 -1
  41. package/dist/communication/redis-message-bus.d.ts +11 -6
  42. package/dist/communication/redis-message-bus.d.ts.map +1 -1
  43. package/dist/communication/redis-message-bus.js +88 -77
  44. package/dist/communication/redis-message-bus.js.map +1 -1
  45. package/dist/coordinator.d.ts +7 -41
  46. package/dist/coordinator.d.ts.map +1 -1
  47. package/dist/coordinator.js +17 -340
  48. package/dist/coordinator.js.map +1 -1
  49. package/dist/distributed/distributed-coordinator.d.ts +54 -51
  50. package/dist/distributed/distributed-coordinator.d.ts.map +1 -1
  51. package/dist/distributed/distributed-coordinator.js +166 -284
  52. package/dist/distributed/distributed-coordinator.js.map +1 -1
  53. package/dist/distributed/index.d.ts +1 -1
  54. package/dist/distributed/index.d.ts.map +1 -1
  55. package/dist/distributed/index.js +1 -1
  56. package/dist/distributed/index.js.map +1 -1
  57. package/dist/index.d.ts +4 -3
  58. package/dist/index.d.ts.map +1 -1
  59. package/dist/index.js +4 -3
  60. package/dist/index.js.map +1 -1
  61. package/dist/resources/circuit-breaker.d.ts.map +1 -1
  62. package/dist/resources/circuit-breaker.js +3 -4
  63. package/dist/resources/circuit-breaker.js.map +1 -1
  64. package/dist/shared/hierarchy.d.ts +21 -0
  65. package/dist/shared/hierarchy.d.ts.map +1 -0
  66. package/dist/shared/hierarchy.js +27 -0
  67. package/dist/shared/hierarchy.js.map +1 -0
  68. package/dist/shared/negotiation.d.ts +27 -0
  69. package/dist/shared/negotiation.d.ts.map +1 -0
  70. package/dist/shared/negotiation.js +55 -0
  71. package/dist/shared/negotiation.js.map +1 -0
  72. package/dist/shared/voting.d.ts +6 -0
  73. package/dist/shared/voting.d.ts.map +1 -0
  74. package/dist/shared/voting.js +13 -0
  75. package/dist/shared/voting.js.map +1 -0
  76. package/dist/strategies/consensus.d.ts +12 -0
  77. package/dist/strategies/consensus.d.ts.map +1 -1
  78. package/dist/strategies/consensus.js +75 -47
  79. package/dist/strategies/consensus.js.map +1 -1
  80. package/dist/strategies/debate.d.ts.map +1 -1
  81. package/dist/strategies/debate.js +18 -8
  82. package/dist/strategies/debate.js.map +1 -1
  83. package/dist/strategies/hierarchical.d.ts.map +1 -1
  84. package/dist/strategies/hierarchical.js +29 -14
  85. package/dist/strategies/hierarchical.js.map +1 -1
  86. package/dist/strategies/negotiation/approval.d.ts.map +1 -1
  87. package/dist/strategies/negotiation/approval.js +22 -19
  88. package/dist/strategies/negotiation/approval.js.map +1 -1
  89. package/dist/strategies/negotiation-strategy.d.ts +24 -2
  90. package/dist/strategies/negotiation-strategy.d.ts.map +1 -1
  91. package/dist/strategies/negotiation-strategy.js +276 -141
  92. package/dist/strategies/negotiation-strategy.js.map +1 -1
  93. package/dist/strategies/pipeline.js +6 -6
  94. package/dist/strategies/pipeline.js.map +1 -1
  95. package/dist/swarm.d.ts +25 -11
  96. package/dist/swarm.d.ts.map +1 -1
  97. package/dist/swarm.js +195 -121
  98. package/dist/swarm.js.map +1 -1
  99. package/dist/tools/blackboard.d.ts +1 -1
  100. package/dist/tools/blackboard.d.ts.map +1 -1
  101. package/dist/tools/blackboard.js +26 -12
  102. package/dist/tools/blackboard.js.map +1 -1
  103. package/dist/tools/delegation.d.ts +17 -4
  104. package/dist/tools/delegation.d.ts.map +1 -1
  105. package/dist/tools/delegation.js +95 -88
  106. package/dist/tools/delegation.js.map +1 -1
  107. package/dist/tools/index.d.ts +3 -1
  108. package/dist/tools/index.d.ts.map +1 -1
  109. package/dist/tools/index.js +9 -4
  110. package/dist/tools/index.js.map +1 -1
  111. package/dist/tools/messaging.d.ts +38 -6
  112. package/dist/tools/messaging.d.ts.map +1 -1
  113. package/dist/tools/messaging.js +118 -41
  114. package/dist/tools/messaging.js.map +1 -1
  115. package/dist/tools/negotiation.d.ts +8 -4
  116. package/dist/tools/negotiation.d.ts.map +1 -1
  117. package/dist/tools/negotiation.js +138 -115
  118. package/dist/tools/negotiation.js.map +1 -1
  119. package/dist/tools/voting.d.ts +3 -0
  120. package/dist/tools/voting.d.ts.map +1 -1
  121. package/dist/tools/voting.js +13 -12
  122. package/dist/tools/voting.js.map +1 -1
  123. package/dist/utils/concurrency.d.ts +10 -0
  124. package/dist/utils/concurrency.d.ts.map +1 -0
  125. package/dist/utils/concurrency.js +28 -0
  126. package/dist/utils/concurrency.js.map +1 -0
  127. package/dist/utils/invoke.d.ts +2 -0
  128. package/dist/utils/invoke.d.ts.map +1 -0
  129. package/dist/utils/invoke.js +19 -0
  130. package/dist/utils/invoke.js.map +1 -0
  131. package/dist/workflow/swarm-node.d.ts.map +1 -1
  132. package/dist/workflow/swarm-node.js +55 -98
  133. package/dist/workflow/swarm-node.js.map +1 -1
  134. 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 various collaboration strategies, automatic model selection, built-in communication primitives, and workflow integration.
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: 'gpt-4o' });
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** - Hierarchical, round-robin, consensus, pipeline, debate, auction, negotiation
38
- - **Automatic Model Selection** - SwarmAssessor matches optimal models to agent roles
39
- - **Agent Communication** - Message bus and shared blackboard
40
- - **Built-in Tools** - Messaging, delegation, voting, and blackboard tools for agents
41
- - **Workflow Integration** - Use swarms as nodes in DAG workflows
42
- - **Resource Tracking** - Monitor tokens, costs, and time budgets
43
- - **Circuit Breaker** - Prevent cascading failures in swarm execution
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
- Supervisor delegates tasks to workers:
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
- new Agent({
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
- maxDelegations: 5,
71
- requireApproval: false,
72
- parallelExecution: true,
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
- ### Round-Robin
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
- Load-balanced rotation across agents:
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
- maxRounds: 10,
95
- skipUnavailable: true,
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
- Voting-based decisions with multiple agents:
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
- votingMethod: 'majority',
114
- minVotes: 2,
115
- timeout: 30000,
116
- tieBreaker: 'random',
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
- { agent: new Agent({ name: 'researcher', instructions: 'Research the topic' }) },
131
- { agent: new Agent({ name: 'writer', instructions: 'Write the content' }) },
132
- { agent: new Agent({ name: 'editor', instructions: 'Edit and refine' }) },
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
- stopOnError: true,
136
- passContext: true,
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
- new Agent({ name: 'optimist', instructions: 'Present positive aspects' }),
150
- new Agent({ name: 'skeptic', instructions: 'Challenge assumptions' }),
151
- new Agent({ name: 'pragmatist', instructions: 'Focus on practicality' }),
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
- biddingRounds: 2,
181
- selectionCriteria: 'lowest',
182
- allowNegotiation: true,
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
- Multi-party negotiation with offers, counter-offers, and coalitions:
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: 10,
201
- convergenceThreshold: 0.8,
202
- allowCoalitions: true,
203
- timeoutPerRound: 30000,
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
- ## SwarmAssessor (Automatic Model Selection)
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
- SwarmAssessor automatically analyzes tasks and matches optimal models to agent roles based on capabilities, cost, and availability.
202
+ ---
213
203
 
214
- ### Basic Usage
204
+ ## Running Swarms
215
205
 
216
206
  ```typescript
217
- import { SwarmBuilder, createAssessor } from '@cogitator-ai/swarms';
218
-
219
- const swarm = new SwarmBuilder('smart-team')
220
- .strategy('hierarchical')
221
- .supervisor(new Agent({ name: 'lead', instructions: '...' }))
222
- .workers([
223
- new Agent({ name: 'coder', instructions: '...' }),
224
- new Agent({ name: 'analyst', instructions: '...' }),
225
- ])
226
- .withAssessor({
227
- mode: 'rules',
228
- preferLocal: true,
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
- ### Dry Run (Preview Assignments)
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 assessment = await swarm.dryRun({
246
- input: 'Build a recommendation engine',
247
- });
226
+ const running = swarm.run({ input: 'Long task' });
248
227
 
249
- console.log('Task complexity:', assessment.taskAnalysis.complexity);
250
- console.log('Estimated cost:', assessment.totalEstimatedCost);
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
- for (const assignment of assessment.assignments) {
253
- console.log(`${assignment.agentName}: ${assignment.assignedModel} (score: ${assignment.score})`);
254
- }
232
+ await running.catch(() => {});
233
+ await swarm.reset(); // clears abort state, budgets, messages and blackboard
255
234
  ```
256
235
 
257
- ### Assessor Configuration
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
- ### Model Suggestions
238
+ ## Error Handling and Limits
276
239
 
277
240
  ```typescript
278
- const candidates = await assessor.suggestModels({
279
- capabilities: ['code', 'reasoning'],
280
- complexity: 'complex',
281
- contextLength: 8000,
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
- for (const model of candidates) {
285
- console.log(`${model.modelId} (${model.provider}): score ${model.score}`);
286
- }
260
+ const usage = swarm.getResourceUsage();
287
261
  ```
288
262
 
289
- ### Assessor Components
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
- import { InMemoryMessageBus, createMessagingTools } from '@cogitator-ai/swarms';
308
-
309
- const messageBus = new InMemoryMessageBus();
310
-
311
- // Create tools for an agent
312
- const tools = createMessagingTools(messageBus, 'agent-1');
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
- ### Blackboard (Shared State)
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
- ### Swarm Configuration with Communication
283
+ ### Blackboard
341
284
 
342
285
  ```typescript
343
286
  const swarm = new SwarmBuilder('research-team')
344
287
  .strategy('hierarchical')
345
- .supervisor(supervisorAgent)
346
- .workers([researcher1, researcher2])
347
- .messaging({
348
- enabled: true,
349
- historySize: 100,
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: 'my-agent',
378
- agentWeight: 1,
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 tools = createSwarmTools(context);
382
- // Returns 16 tools: messaging (4) + blackboard (5) + delegation (4) + voting (4)
314
+ const allTools = createSwarmTools(context); // messaging, blackboard, delegation, voting, negotiation
315
+ const hierarchicalTools = createStrategyTools('hierarchical', context);
383
316
  ```
384
317
 
385
- ### Strategy-Specific Tools
386
-
387
- ```typescript
388
- import { createStrategyTools } from '@cogitator-ai/swarms';
389
-
390
- // Get tools appropriate for the strategy
391
- const tools = createStrategyTools('hierarchical', context);
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
- ### Voting Tools (Consensus/Debate)
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
- ## Workflow Integration
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('budget-conscious')
333
+ const swarm = new SwarmBuilder('smart-team')
503
334
  .strategy('hierarchical')
504
335
  .supervisor(lead)
505
- .workers(workers)
506
- .resources({
507
- tokenBudget: 100000,
508
- costLimit: 5.0,
509
- timeout: 300000,
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
- // Check budget
529
- console.log('Within budget:', tracker.isWithinBudget());
530
- console.log('Remaining:', tracker.getRemainingBudget());
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
- // Per-agent usage
539
- const agentUsage = tracker.getAgentUsage('agent-1');
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
- ### Swarm Resource Usage
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
- ## Circuit Breaker
560
-
561
- Prevent cascading failures in swarm execution.
360
+ ## Workflow Integration
562
361
 
563
362
  ```typescript
564
- import { CircuitBreaker } from '@cogitator-ai/swarms';
363
+ import { WorkflowBuilder, WorkflowExecutor } from '@cogitator-ai/workflows';
364
+ import { swarmNode, parallelSwarmsNode } from '@cogitator-ai/swarms';
565
365
 
566
- const breaker = new CircuitBreaker({
567
- threshold: 5,
568
- resetTimeout: 30000,
569
- successThreshold: 2,
570
- });
571
-
572
- // Check before execution
573
- if (breaker.canExecute()) {
574
- try {
575
- const result = await runTask();
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
- // Monitor state changes
586
- breaker.onStateChange((state) => {
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
- ### Swarm Error Handling Configuration
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
- const swarm = new SwarmBuilder('monitored-team')
621
- .strategy('hierarchical')
622
- .supervisor(lead)
623
- .workers(workers)
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
- ### Event Types
659
-
660
- | Event | Description |
661
- | ------------------- | ---------------------------- |
662
- | `swarm:start` | Swarm execution started |
663
- | `swarm:complete` | Swarm execution completed |
664
- | `swarm:error` | Error during swarm execution |
665
- | `swarm:paused` | Swarm paused |
666
- | `swarm:resumed` | Swarm resumed |
667
- | `swarm:aborted` | Swarm aborted |
668
- | `swarm:reset` | Swarm reset |
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
- Run swarm agents across multiple workers using Redis-backed communication and BullMQ job queues. Each agent executes as a separate job, enabling horizontal scaling and parallel processing.
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('hierarchical')
693
- .supervisor(new Agent({ name: 'lead', instructions: 'Coordinate the team' }))
694
- .workers([
695
- new Agent({ name: 'analyst-1', instructions: 'Analyze data' }),
696
- new Agent({ name: 'analyst-2', instructions: 'Analyze data' }),
697
- new Agent({ name: 'analyst-3', instructions: 'Analyze data' }),
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: 300000,
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
- ### Distributed Configuration Options
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 { RedisMessageBus, RedisBlackboard, RedisSwarmEventEmitter } from '@cogitator-ai/swarms';
749
- import Redis from 'ioredis';
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
- ### Setting Up Workers
777
-
778
- Workers process distributed swarm jobs. Use with `@cogitator-ai/worker`:
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
- redis: {
786
- host: 'localhost',
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 pool.start();
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
- ### Architecture
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