claude_swarm 1.0.6 → 1.0.7
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.
- checksums.yaml +4 -4
- data/.ruby-version +1 -1
- data/CHANGELOG.md +14 -0
- data/README.md +336 -1037
- data/docs/V1_TO_V2_MIGRATION_GUIDE.md +1120 -0
- data/docs/v1/README.md +1195 -0
- data/docs/v2/CHANGELOG.swarm_cli.md +22 -0
- data/docs/v2/CHANGELOG.swarm_memory.md +20 -0
- data/docs/v2/CHANGELOG.swarm_sdk.md +287 -10
- data/docs/v2/README.md +32 -6
- data/docs/v2/guides/complete-tutorial.md +133 -37
- data/docs/v2/guides/composable-swarms.md +1178 -0
- data/docs/v2/guides/getting-started.md +42 -1
- data/docs/v2/guides/snapshots.md +1498 -0
- data/docs/v2/reference/architecture-flow.md +5 -3
- data/docs/v2/reference/event_payload_structures.md +249 -12
- data/docs/v2/reference/execution-flow.md +1 -1
- data/docs/v2/reference/ruby-dsl.md +368 -22
- data/docs/v2/reference/yaml.md +314 -63
- data/examples/snapshot_demo.rb +119 -0
- data/examples/v2/dsl/01_basic.rb +0 -2
- data/examples/v2/dsl/02_core_parameters.rb +0 -2
- data/examples/v2/dsl/03_capabilities.rb +0 -2
- data/examples/v2/dsl/04_llm_parameters.rb +0 -2
- data/examples/v2/dsl/05_advanced_flags.rb +0 -3
- data/examples/v2/dsl/06_permissions.rb +0 -4
- data/examples/v2/dsl/07_mcp_server.rb +0 -2
- data/examples/v2/dsl/08_swarm_hooks.rb +0 -2
- data/examples/v2/dsl/09_agent_hooks.rb +0 -2
- data/examples/v2/dsl/10_all_agents_hooks.rb +0 -3
- data/examples/v2/dsl/11_delegation.rb +0 -2
- data/examples/v2/dsl/12_complete_integration.rb +2 -6
- data/examples/v2/node_context_demo.rb +1 -1
- data/examples/v2/node_workflow.rb +2 -4
- data/examples/v2/plan_and_execute.rb +157 -0
- data/lib/claude_swarm/configuration.rb +28 -4
- data/lib/claude_swarm/version.rb +1 -1
- data/lib/swarm_cli/formatters/human_formatter.rb +103 -0
- data/lib/swarm_cli/interactive_repl.rb +9 -3
- data/lib/swarm_cli/version.rb +1 -1
- data/lib/swarm_memory/core/storage_read_tracker.rb +51 -14
- data/lib/swarm_memory/integration/cli_registration.rb +3 -2
- data/lib/swarm_memory/integration/sdk_plugin.rb +11 -5
- data/lib/swarm_memory/tools/memory_edit.rb +2 -2
- data/lib/swarm_memory/tools/memory_multi_edit.rb +2 -2
- data/lib/swarm_memory/tools/memory_read.rb +3 -3
- data/lib/swarm_memory/version.rb +1 -1
- data/lib/swarm_memory.rb +5 -0
- data/lib/swarm_sdk/agent/builder.rb +33 -0
- data/lib/swarm_sdk/agent/chat/context_tracker.rb +33 -0
- data/lib/swarm_sdk/agent/chat/hook_integration.rb +49 -3
- data/lib/swarm_sdk/agent/chat/system_reminder_injector.rb +11 -27
- data/lib/swarm_sdk/agent/chat.rb +200 -51
- data/lib/swarm_sdk/agent/context.rb +6 -2
- data/lib/swarm_sdk/agent/context_manager.rb +6 -0
- data/lib/swarm_sdk/agent/definition.rb +14 -2
- data/lib/swarm_sdk/agent/llm_instrumentation_middleware.rb +180 -0
- data/lib/swarm_sdk/configuration.rb +387 -94
- data/lib/swarm_sdk/events_to_messages.rb +181 -0
- data/lib/swarm_sdk/log_collector.rb +31 -5
- data/lib/swarm_sdk/log_stream.rb +37 -8
- data/lib/swarm_sdk/model_aliases.json +4 -1
- data/lib/swarm_sdk/node/agent_config.rb +33 -8
- data/lib/swarm_sdk/node/builder.rb +39 -18
- data/lib/swarm_sdk/node_orchestrator.rb +293 -26
- data/lib/swarm_sdk/proc_helpers.rb +53 -0
- data/lib/swarm_sdk/providers/openai_with_responses.rb +22 -15
- data/lib/swarm_sdk/restore_result.rb +65 -0
- data/lib/swarm_sdk/snapshot.rb +156 -0
- data/lib/swarm_sdk/snapshot_from_events.rb +386 -0
- data/lib/swarm_sdk/state_restorer.rb +491 -0
- data/lib/swarm_sdk/state_snapshot.rb +369 -0
- data/lib/swarm_sdk/swarm/agent_initializer.rb +360 -55
- data/lib/swarm_sdk/swarm/all_agents_builder.rb +28 -1
- data/lib/swarm_sdk/swarm/builder.rb +208 -12
- data/lib/swarm_sdk/swarm/swarm_registry_builder.rb +67 -0
- data/lib/swarm_sdk/swarm/tool_configurator.rb +46 -11
- data/lib/swarm_sdk/swarm.rb +338 -42
- data/lib/swarm_sdk/swarm_loader.rb +145 -0
- data/lib/swarm_sdk/swarm_registry.rb +136 -0
- data/lib/swarm_sdk/tools/delegate.rb +92 -7
- data/lib/swarm_sdk/tools/read.rb +17 -5
- data/lib/swarm_sdk/tools/stores/read_tracker.rb +47 -12
- data/lib/swarm_sdk/tools/stores/scratchpad_storage.rb +45 -0
- data/lib/swarm_sdk/utils.rb +18 -0
- data/lib/swarm_sdk/validation_result.rb +33 -0
- data/lib/swarm_sdk/version.rb +1 -1
- data/lib/swarm_sdk.rb +40 -8
- data/swarm_cli.gemspec +1 -1
- data/swarm_memory.gemspec +2 -2
- data/swarm_sdk.gemspec +2 -2
- metadata +21 -13
- data/examples/learning-assistant/assistant.md +0 -7
- data/examples/learning-assistant/example-memories/concept-example.md +0 -90
- data/examples/learning-assistant/example-memories/experience-example.md +0 -66
- data/examples/learning-assistant/example-memories/fact-example.md +0 -76
- data/examples/learning-assistant/example-memories/memory-index.md +0 -78
- data/examples/learning-assistant/example-memories/skill-example.md +0 -168
- data/examples/learning-assistant/learning_assistant.rb +0 -34
- data/examples/learning-assistant/learning_assistant.yml +0 -20
- data/lib/swarm_sdk/mcp.rb +0 -16
- data/llm.v2.txt +0 -13407
- /data/docs/v2/guides/{MEMORY_DEFRAG_GUIDE.md → memory-defrag-guide.md} +0 -0
- /data/{llms.txt → llms.claude-swarm.txt} +0 -0
|
@@ -0,0 +1,1178 @@
|
|
|
1
|
+
# Composable Swarms Guide
|
|
2
|
+
|
|
3
|
+
Build reusable AI agent teams that can be composed together like building blocks.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Overview
|
|
8
|
+
|
|
9
|
+
Composable swarms enable you to:
|
|
10
|
+
- **Build once, use anywhere**: Create specialized swarm teams and reuse them
|
|
11
|
+
- **Hierarchical composition**: Swarms can contain other swarms, unlimited nesting
|
|
12
|
+
- **Transparent delegation**: Delegate to swarms just like agents
|
|
13
|
+
- **No configuration merging**: Each swarm maintains isolated scope
|
|
14
|
+
- **Multiple sources**: Load from files, YAML strings, or define inline
|
|
15
|
+
|
|
16
|
+
**Key principle:** **A swarm IS an agent** - delegating to a child swarm is identical to delegating to an agent. The child swarm's lead agent serves as its public interface.
|
|
17
|
+
|
|
18
|
+
---
|
|
19
|
+
|
|
20
|
+
## Quick Start
|
|
21
|
+
|
|
22
|
+
### Ruby DSL
|
|
23
|
+
|
|
24
|
+
```ruby
|
|
25
|
+
# Define a reusable code review swarm (in ./swarms/code_review.rb)
|
|
26
|
+
SwarmSDK.build do
|
|
27
|
+
id "code_review_team"
|
|
28
|
+
name "Code Review Team"
|
|
29
|
+
lead :lead_reviewer
|
|
30
|
+
|
|
31
|
+
agent :lead_reviewer do
|
|
32
|
+
model "claude-3-5-sonnet"
|
|
33
|
+
description "Lead code reviewer"
|
|
34
|
+
system "Coordinate security, style, and performance reviews"
|
|
35
|
+
delegates_to "security", "style", "performance"
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
agent :security do
|
|
39
|
+
model "gpt-4o"
|
|
40
|
+
system "Security expert - analyze for vulnerabilities"
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
agent :style do
|
|
44
|
+
model "gpt-4o-mini"
|
|
45
|
+
system "Code style expert - enforce best practices"
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
agent :performance do
|
|
49
|
+
model "gpt-4o"
|
|
50
|
+
system "Performance expert - optimize code efficiency"
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
# Use it in your main swarm
|
|
55
|
+
SwarmSDK.build do
|
|
56
|
+
id "development_team"
|
|
57
|
+
name "Development Team"
|
|
58
|
+
lead :lead_dev
|
|
59
|
+
|
|
60
|
+
swarms do
|
|
61
|
+
register "code_review", file: "./swarms/code_review.rb"
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
agent :lead_dev do
|
|
65
|
+
system "Lead developer coordinating the team"
|
|
66
|
+
delegates_to "backend", "code_review" # Delegate to swarm!
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
agent :backend do
|
|
70
|
+
system "Backend developer"
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
# Execute
|
|
75
|
+
swarm.execute("Review the authentication module")
|
|
76
|
+
# lead_dev → code_review swarm → lead_reviewer → security/style/performance
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
### YAML
|
|
80
|
+
|
|
81
|
+
```yaml
|
|
82
|
+
# File: config.yml
|
|
83
|
+
version: 2
|
|
84
|
+
swarm:
|
|
85
|
+
id: development_team
|
|
86
|
+
name: "Development Team"
|
|
87
|
+
lead: lead_dev
|
|
88
|
+
|
|
89
|
+
swarms:
|
|
90
|
+
code_review:
|
|
91
|
+
file: "./swarms/code_review.yml"
|
|
92
|
+
keep_context: true
|
|
93
|
+
|
|
94
|
+
agents:
|
|
95
|
+
lead_dev:
|
|
96
|
+
description: "Lead developer"
|
|
97
|
+
system: "Coordinate the team"
|
|
98
|
+
delegates_to:
|
|
99
|
+
- backend
|
|
100
|
+
- code_review # Delegate to swarm!
|
|
101
|
+
|
|
102
|
+
backend:
|
|
103
|
+
description: "Backend developer"
|
|
104
|
+
system: "Build APIs"
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
---
|
|
108
|
+
|
|
109
|
+
## Registration Methods
|
|
110
|
+
|
|
111
|
+
Composable swarms support three ways to register sub-swarms:
|
|
112
|
+
|
|
113
|
+
### 1. File Path
|
|
114
|
+
|
|
115
|
+
Load swarms from .rb (Ruby DSL) or .yml (YAML) files.
|
|
116
|
+
|
|
117
|
+
**When to use:**
|
|
118
|
+
- Swarm is complex and deserves its own file
|
|
119
|
+
- Swarm is reused across multiple parent swarms
|
|
120
|
+
- Team collaboration on swarm definition
|
|
121
|
+
- Version control separate swarm components
|
|
122
|
+
|
|
123
|
+
**Ruby DSL:**
|
|
124
|
+
```ruby
|
|
125
|
+
swarms do
|
|
126
|
+
register "code_review", file: "./swarms/code_review.rb"
|
|
127
|
+
register "testing", file: "./swarms/testing.yml", keep_context: false
|
|
128
|
+
end
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
**YAML:**
|
|
132
|
+
```yaml
|
|
133
|
+
swarms:
|
|
134
|
+
code_review:
|
|
135
|
+
file: "./swarms/code_review.rb"
|
|
136
|
+
keep_context: true
|
|
137
|
+
testing:
|
|
138
|
+
file: "./swarms/testing.yml"
|
|
139
|
+
keep_context: false
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
### 2. YAML String
|
|
143
|
+
|
|
144
|
+
Pass YAML content directly as a string.
|
|
145
|
+
|
|
146
|
+
**When to use:**
|
|
147
|
+
- Loading swarms from APIs or databases
|
|
148
|
+
- Dynamic swarm selection based on runtime conditions
|
|
149
|
+
- Configuration management systems
|
|
150
|
+
- Remote swarm repositories
|
|
151
|
+
|
|
152
|
+
**Ruby DSL:**
|
|
153
|
+
```ruby
|
|
154
|
+
# Fetch from API
|
|
155
|
+
yaml_content = HTTP.get("https://api.example.com/swarms/testing.yml").body
|
|
156
|
+
|
|
157
|
+
# Or from database
|
|
158
|
+
yaml_content = SwarmConfig.find_by(name: "testing").yaml_content
|
|
159
|
+
|
|
160
|
+
# Or from environment variable
|
|
161
|
+
yaml_content = ENV["TESTING_SWARM_CONFIG"]
|
|
162
|
+
|
|
163
|
+
swarms do
|
|
164
|
+
register "testing", yaml: yaml_content, keep_context: false
|
|
165
|
+
end
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
**YAML:**
|
|
169
|
+
Not supported in YAML format (use inline definition instead).
|
|
170
|
+
|
|
171
|
+
### 3. Inline Block (DSL Only)
|
|
172
|
+
|
|
173
|
+
Define swarms inline without separate files.
|
|
174
|
+
|
|
175
|
+
**When to use:**
|
|
176
|
+
- Simple, single-use sub-swarms
|
|
177
|
+
- Testing and development
|
|
178
|
+
- Self-contained gems (no external files)
|
|
179
|
+
- Dynamically generated swarms from templates
|
|
180
|
+
- Co-locating swarm with usage makes sense
|
|
181
|
+
|
|
182
|
+
**Ruby DSL:**
|
|
183
|
+
```ruby
|
|
184
|
+
swarms do
|
|
185
|
+
register "testing", keep_context: false do
|
|
186
|
+
id "testing_team"
|
|
187
|
+
name "Testing Team"
|
|
188
|
+
lead :tester
|
|
189
|
+
|
|
190
|
+
agent :tester do
|
|
191
|
+
model "gpt-4o-mini"
|
|
192
|
+
description "Test specialist"
|
|
193
|
+
system "You write and run comprehensive tests"
|
|
194
|
+
tools :Think, :Bash
|
|
195
|
+
end
|
|
196
|
+
|
|
197
|
+
agent :qa do
|
|
198
|
+
model "gpt-4o"
|
|
199
|
+
description "QA specialist"
|
|
200
|
+
system "You validate quality and user experience"
|
|
201
|
+
end
|
|
202
|
+
end
|
|
203
|
+
end
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
### 4. Inline Definition (YAML Only)
|
|
207
|
+
|
|
208
|
+
Define swarms inline within YAML configuration.
|
|
209
|
+
|
|
210
|
+
**When to use:**
|
|
211
|
+
- Want everything in one YAML file
|
|
212
|
+
- Simple sub-swarms that don't need separate files
|
|
213
|
+
- Deployment simplicity (single config file)
|
|
214
|
+
|
|
215
|
+
**YAML:**
|
|
216
|
+
```yaml
|
|
217
|
+
swarms:
|
|
218
|
+
testing:
|
|
219
|
+
keep_context: false
|
|
220
|
+
swarm: # Inline swarm definition
|
|
221
|
+
id: testing_team
|
|
222
|
+
name: "Testing Team"
|
|
223
|
+
lead: tester
|
|
224
|
+
agents:
|
|
225
|
+
tester:
|
|
226
|
+
description: "Test specialist"
|
|
227
|
+
model: gpt-4o-mini
|
|
228
|
+
system: "You write tests"
|
|
229
|
+
tools:
|
|
230
|
+
- Think
|
|
231
|
+
- Bash
|
|
232
|
+
```
|
|
233
|
+
|
|
234
|
+
---
|
|
235
|
+
|
|
236
|
+
## Hierarchical Swarm IDs
|
|
237
|
+
|
|
238
|
+
Sub-swarms automatically get hierarchical IDs based on parent ID and registration name.
|
|
239
|
+
|
|
240
|
+
**Pattern:** `"#{parent_swarm_id}/#{registration_name}"`
|
|
241
|
+
|
|
242
|
+
```ruby
|
|
243
|
+
SwarmSDK.build do
|
|
244
|
+
id "main_app" # Parent swarm ID
|
|
245
|
+
|
|
246
|
+
swarms do
|
|
247
|
+
register "code_review", file: "./swarms/code_review.rb"
|
|
248
|
+
# Loaded swarm gets: swarm_id = "main_app/code_review"
|
|
249
|
+
|
|
250
|
+
register "testing", file: "./swarms/testing.rb"
|
|
251
|
+
# Loaded swarm gets: swarm_id = "main_app/testing"
|
|
252
|
+
end
|
|
253
|
+
end
|
|
254
|
+
```
|
|
255
|
+
|
|
256
|
+
**Hierarchy example:**
|
|
257
|
+
```
|
|
258
|
+
main_app (root swarm)
|
|
259
|
+
├── main_app/code_review (sub-swarm)
|
|
260
|
+
│ └── main_app/code_review/security (nested sub-swarm)
|
|
261
|
+
├── main_app/testing (sub-swarm)
|
|
262
|
+
└── main_app/deployment (sub-swarm)
|
|
263
|
+
```
|
|
264
|
+
|
|
265
|
+
**Event tracking:**
|
|
266
|
+
All events include `swarm_id` and `parent_swarm_id` for complete hierarchy tracking:
|
|
267
|
+
|
|
268
|
+
```ruby
|
|
269
|
+
{
|
|
270
|
+
type: "agent_delegation",
|
|
271
|
+
swarm_id: "main_app",
|
|
272
|
+
parent_swarm_id: nil,
|
|
273
|
+
agent: "lead_dev",
|
|
274
|
+
delegate_to: "code_review"
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
{
|
|
278
|
+
type: "agent_step",
|
|
279
|
+
swarm_id: "main_app/code_review",
|
|
280
|
+
parent_swarm_id: "main_app",
|
|
281
|
+
agent: "lead_reviewer"
|
|
282
|
+
}
|
|
283
|
+
```
|
|
284
|
+
|
|
285
|
+
---
|
|
286
|
+
|
|
287
|
+
## Context Control
|
|
288
|
+
|
|
289
|
+
Control whether sub-swarms maintain conversation history between delegations.
|
|
290
|
+
|
|
291
|
+
### keep_context: true (default)
|
|
292
|
+
|
|
293
|
+
Swarm maintains conversation history across delegations.
|
|
294
|
+
|
|
295
|
+
**Use cases:**
|
|
296
|
+
- Iterative work (multiple rounds of refinement)
|
|
297
|
+
- Stateful processes (building up knowledge)
|
|
298
|
+
- Collaborative sessions (back-and-forth discussion)
|
|
299
|
+
|
|
300
|
+
**Example:**
|
|
301
|
+
```ruby
|
|
302
|
+
swarms do
|
|
303
|
+
register "code_review", file: "./swarms/code_review.rb", keep_context: true
|
|
304
|
+
end
|
|
305
|
+
|
|
306
|
+
# First delegation
|
|
307
|
+
swarm.agent(:backend).ask("Review the auth module")
|
|
308
|
+
# code_review swarm: conversation history = [user: "Review auth module", assistant: "Found 3 issues..."]
|
|
309
|
+
|
|
310
|
+
# Second delegation
|
|
311
|
+
swarm.agent(:backend).ask("Fix the issues you found")
|
|
312
|
+
# code_review swarm: remembers previous review, can reference "the 3 issues"
|
|
313
|
+
```
|
|
314
|
+
|
|
315
|
+
### keep_context: false
|
|
316
|
+
|
|
317
|
+
Swarm context is reset after each delegation completes.
|
|
318
|
+
|
|
319
|
+
**Use cases:**
|
|
320
|
+
- Stateless operations (each task independent)
|
|
321
|
+
- Preventing context pollution
|
|
322
|
+
- Enforcing fresh starts
|
|
323
|
+
- Memory management for long-running swarms
|
|
324
|
+
|
|
325
|
+
**Example:**
|
|
326
|
+
```ruby
|
|
327
|
+
swarms do
|
|
328
|
+
register "testing", file: "./swarms/testing.rb", keep_context: false
|
|
329
|
+
end
|
|
330
|
+
|
|
331
|
+
# First delegation
|
|
332
|
+
swarm.agent(:backend).ask("Test the login endpoint")
|
|
333
|
+
# testing swarm: conversation history = [user: "Test login endpoint", assistant: "Tests passed"]
|
|
334
|
+
|
|
335
|
+
# After delegation completes, context is reset
|
|
336
|
+
|
|
337
|
+
# Second delegation
|
|
338
|
+
swarm.agent(:backend).ask("Test the signup endpoint")
|
|
339
|
+
# testing swarm: conversation history = [user: "Test signup endpoint", ...] (no memory of login test)
|
|
340
|
+
```
|
|
341
|
+
|
|
342
|
+
---
|
|
343
|
+
|
|
344
|
+
## Transparent Delegation
|
|
345
|
+
|
|
346
|
+
Delegating to a swarm is identical to delegating to an agent. The swarm's lead agent serves as the entry point.
|
|
347
|
+
|
|
348
|
+
```ruby
|
|
349
|
+
agent :backend do
|
|
350
|
+
# Mix local agents and registered swarms in delegates_to
|
|
351
|
+
delegates_to "database", # Local agent
|
|
352
|
+
"code_review", # Registered swarm
|
|
353
|
+
"testing" # Registered swarm
|
|
354
|
+
end
|
|
355
|
+
```
|
|
356
|
+
|
|
357
|
+
**Resolution order:**
|
|
358
|
+
When delegating to target "code_review":
|
|
359
|
+
1. Check local agents (`@swarm.agents["code_review"]`)
|
|
360
|
+
2. Check delegation instances (`@swarm.delegation_instances["code_review@backend"]`)
|
|
361
|
+
3. Check registered swarms (`@swarm.swarm_registry.registered?("code_review")`)
|
|
362
|
+
4. Raise error if not found
|
|
363
|
+
|
|
364
|
+
**This means:**
|
|
365
|
+
- Local agents take precedence over swarms with same name
|
|
366
|
+
- Clear error messages when target not found
|
|
367
|
+
- No ambiguity in delegation resolution
|
|
368
|
+
|
|
369
|
+
---
|
|
370
|
+
|
|
371
|
+
## Circular Dependency Detection
|
|
372
|
+
|
|
373
|
+
Runtime detection prevents infinite delegation loops.
|
|
374
|
+
|
|
375
|
+
### Within Swarm
|
|
376
|
+
|
|
377
|
+
Detects circular delegation within a single swarm:
|
|
378
|
+
|
|
379
|
+
```ruby
|
|
380
|
+
SwarmSDK.build do
|
|
381
|
+
id "team"
|
|
382
|
+
|
|
383
|
+
agent :agent_a do
|
|
384
|
+
delegates_to "agent_b"
|
|
385
|
+
end
|
|
386
|
+
|
|
387
|
+
agent :agent_b do
|
|
388
|
+
delegates_to "agent_a" # Circular!
|
|
389
|
+
end
|
|
390
|
+
end
|
|
391
|
+
|
|
392
|
+
# Execution: agent_a → agent_b → agent_a (BLOCKED)
|
|
393
|
+
# Event emitted: delegation_circular_dependency
|
|
394
|
+
# LLM receives: "Error: Circular delegation detected: agent_a -> agent_b -> agent_a"
|
|
395
|
+
```
|
|
396
|
+
|
|
397
|
+
### Across Swarms
|
|
398
|
+
|
|
399
|
+
Each swarm has an isolated call stack, so false positives are avoided:
|
|
400
|
+
|
|
401
|
+
```ruby
|
|
402
|
+
# Parent swarm
|
|
403
|
+
SwarmSDK.build do
|
|
404
|
+
id "main"
|
|
405
|
+
|
|
406
|
+
swarms do
|
|
407
|
+
register "child_swarm" do
|
|
408
|
+
id "child"
|
|
409
|
+
agent :agent_a do
|
|
410
|
+
delegates_to "agent_b" # This is ALLOWED
|
|
411
|
+
end
|
|
412
|
+
end
|
|
413
|
+
end
|
|
414
|
+
|
|
415
|
+
agent :agent_a do
|
|
416
|
+
delegates_to "child_swarm"
|
|
417
|
+
end
|
|
418
|
+
end
|
|
419
|
+
|
|
420
|
+
# Execution: main.agent_a → child_swarm → child.agent_a
|
|
421
|
+
# NOT circular because they're in different swarms (isolated contexts)
|
|
422
|
+
```
|
|
423
|
+
|
|
424
|
+
---
|
|
425
|
+
|
|
426
|
+
## Deep Nesting
|
|
427
|
+
|
|
428
|
+
Swarms can be nested unlimited levels deep.
|
|
429
|
+
|
|
430
|
+
```ruby
|
|
431
|
+
# File: ./swarms/security/scanner.rb
|
|
432
|
+
SwarmSDK.build do
|
|
433
|
+
id "vulnerability_scanner"
|
|
434
|
+
# ...
|
|
435
|
+
end
|
|
436
|
+
|
|
437
|
+
# File: ./swarms/security/audit.rb
|
|
438
|
+
SwarmSDK.build do
|
|
439
|
+
id "security_audit"
|
|
440
|
+
|
|
441
|
+
swarms do
|
|
442
|
+
register "scanner", file: "./scanner.rb"
|
|
443
|
+
end
|
|
444
|
+
|
|
445
|
+
agent :auditor do
|
|
446
|
+
delegates_to "scanner"
|
|
447
|
+
end
|
|
448
|
+
end
|
|
449
|
+
|
|
450
|
+
# File: ./swarms/code_review.rb
|
|
451
|
+
SwarmSDK.build do
|
|
452
|
+
id "code_review_team"
|
|
453
|
+
|
|
454
|
+
swarms do
|
|
455
|
+
register "security", file: "./security/audit.rb"
|
|
456
|
+
end
|
|
457
|
+
|
|
458
|
+
agent :reviewer do
|
|
459
|
+
delegates_to "security"
|
|
460
|
+
end
|
|
461
|
+
end
|
|
462
|
+
|
|
463
|
+
# File: main.rb
|
|
464
|
+
SwarmSDK.build do
|
|
465
|
+
id "main"
|
|
466
|
+
|
|
467
|
+
swarms do
|
|
468
|
+
register "code_review", file: "./swarms/code_review.rb"
|
|
469
|
+
end
|
|
470
|
+
|
|
471
|
+
agent :lead do
|
|
472
|
+
delegates_to "code_review"
|
|
473
|
+
end
|
|
474
|
+
end
|
|
475
|
+
|
|
476
|
+
# Hierarchy:
|
|
477
|
+
# main
|
|
478
|
+
# └── main/code_review
|
|
479
|
+
# └── main/code_review/security
|
|
480
|
+
# └── main/code_review/security/scanner
|
|
481
|
+
```
|
|
482
|
+
|
|
483
|
+
All events properly tagged at each level with hierarchical swarm_id!
|
|
484
|
+
|
|
485
|
+
---
|
|
486
|
+
|
|
487
|
+
## Use Cases
|
|
488
|
+
|
|
489
|
+
### 1. Specialized Teams
|
|
490
|
+
|
|
491
|
+
Create expert teams for specific domains:
|
|
492
|
+
|
|
493
|
+
```ruby
|
|
494
|
+
swarms do
|
|
495
|
+
# Each team is a self-contained swarm
|
|
496
|
+
register "security_team" do
|
|
497
|
+
id "security"
|
|
498
|
+
name "Security Team"
|
|
499
|
+
lead :security_lead
|
|
500
|
+
|
|
501
|
+
agent :security_lead do
|
|
502
|
+
delegates_to "owasp_expert", "crypto_expert", "auth_expert"
|
|
503
|
+
end
|
|
504
|
+
|
|
505
|
+
agent :owasp_expert { system "OWASP Top 10 specialist" }
|
|
506
|
+
agent :crypto_expert { system "Cryptography specialist" }
|
|
507
|
+
agent :auth_expert { system "Authentication specialist" }
|
|
508
|
+
end
|
|
509
|
+
|
|
510
|
+
register "performance_team" do
|
|
511
|
+
id "performance"
|
|
512
|
+
name "Performance Team"
|
|
513
|
+
lead :perf_lead
|
|
514
|
+
|
|
515
|
+
agent :perf_lead do
|
|
516
|
+
delegates_to "profiling", "optimization", "caching"
|
|
517
|
+
end
|
|
518
|
+
|
|
519
|
+
agent :profiling { system "Profiling specialist" }
|
|
520
|
+
agent :optimization { system "Code optimization specialist" }
|
|
521
|
+
agent :caching { system "Caching strategies specialist" }
|
|
522
|
+
end
|
|
523
|
+
end
|
|
524
|
+
```
|
|
525
|
+
|
|
526
|
+
### 2. Dynamic Swarm Loading
|
|
527
|
+
|
|
528
|
+
Load swarms from different sources based on runtime conditions:
|
|
529
|
+
|
|
530
|
+
```ruby
|
|
531
|
+
# Environment-specific configurations
|
|
532
|
+
testing_config = case ENV["RAILS_ENV"]
|
|
533
|
+
when "production"
|
|
534
|
+
# Load strict production testing from API
|
|
535
|
+
yaml: fetch_swarm_from_api("production_testing")
|
|
536
|
+
when "staging"
|
|
537
|
+
# Load from file
|
|
538
|
+
file: "./swarms/staging_testing.yml"
|
|
539
|
+
else
|
|
540
|
+
# Define inline for dev
|
|
541
|
+
proc do
|
|
542
|
+
id "dev_testing"
|
|
543
|
+
name "Dev Testing"
|
|
544
|
+
lead :quick_tester
|
|
545
|
+
agent :quick_tester do
|
|
546
|
+
model "gpt-4o-mini"
|
|
547
|
+
system "Quick smoke tests only"
|
|
548
|
+
end
|
|
549
|
+
end
|
|
550
|
+
end
|
|
551
|
+
|
|
552
|
+
SwarmSDK.build do
|
|
553
|
+
id "app_#{ENV['RAILS_ENV']}"
|
|
554
|
+
|
|
555
|
+
swarms do
|
|
556
|
+
if testing_config[:yaml]
|
|
557
|
+
register "testing", yaml: testing_config[:yaml]
|
|
558
|
+
elsif testing_config[:file]
|
|
559
|
+
register "testing", file: testing_config[:file]
|
|
560
|
+
else
|
|
561
|
+
register "testing", &testing_config
|
|
562
|
+
end
|
|
563
|
+
end
|
|
564
|
+
end
|
|
565
|
+
```
|
|
566
|
+
|
|
567
|
+
### 3. Embedded Swarms in Gems
|
|
568
|
+
|
|
569
|
+
Create gems with embedded swarm teams (no external files needed):
|
|
570
|
+
|
|
571
|
+
```ruby
|
|
572
|
+
# In your gem
|
|
573
|
+
module MyGem
|
|
574
|
+
def self.create_analyzer
|
|
575
|
+
SwarmSDK.build do
|
|
576
|
+
id "code_analyzer"
|
|
577
|
+
name "Code Analyzer"
|
|
578
|
+
lead :coordinator
|
|
579
|
+
|
|
580
|
+
swarms do
|
|
581
|
+
# Embed all sub-swarms in gem code
|
|
582
|
+
register "security_audit" do
|
|
583
|
+
id "security"
|
|
584
|
+
name "Security Auditor"
|
|
585
|
+
lead :security_expert
|
|
586
|
+
|
|
587
|
+
agent :security_expert do
|
|
588
|
+
model "claude-3-5-sonnet"
|
|
589
|
+
system <<~PROMPT
|
|
590
|
+
You are a security expert specializing in vulnerability detection.
|
|
591
|
+
Analyze code for OWASP Top 10 vulnerabilities, authentication issues,
|
|
592
|
+
and data validation problems.
|
|
593
|
+
PROMPT
|
|
594
|
+
tools :Read, :Grep, :Bash
|
|
595
|
+
end
|
|
596
|
+
end
|
|
597
|
+
|
|
598
|
+
register "code_quality" do
|
|
599
|
+
id "quality"
|
|
600
|
+
name "Quality Checker"
|
|
601
|
+
lead :quality_expert
|
|
602
|
+
|
|
603
|
+
agent :quality_expert do
|
|
604
|
+
model "gpt-4o"
|
|
605
|
+
system "Analyze code quality, maintainability, and best practices"
|
|
606
|
+
tools :Read, :Grep
|
|
607
|
+
end
|
|
608
|
+
end
|
|
609
|
+
|
|
610
|
+
register "performance" do
|
|
611
|
+
id "performance"
|
|
612
|
+
name "Performance Analyzer"
|
|
613
|
+
lead :perf_expert
|
|
614
|
+
|
|
615
|
+
agent :perf_expert do
|
|
616
|
+
model "gpt-4o"
|
|
617
|
+
system "Analyze performance bottlenecks and optimization opportunities"
|
|
618
|
+
tools :Read, :Bash
|
|
619
|
+
end
|
|
620
|
+
end
|
|
621
|
+
end
|
|
622
|
+
|
|
623
|
+
agent :coordinator do
|
|
624
|
+
model "claude-3-5-sonnet"
|
|
625
|
+
system "Coordinate comprehensive code analysis across security, quality, and performance"
|
|
626
|
+
delegates_to "security_audit", "code_quality", "performance"
|
|
627
|
+
end
|
|
628
|
+
end
|
|
629
|
+
end
|
|
630
|
+
end
|
|
631
|
+
|
|
632
|
+
# Users of your gem
|
|
633
|
+
require "my_gem"
|
|
634
|
+
|
|
635
|
+
analyzer = MyGem.create_analyzer
|
|
636
|
+
result = analyzer.execute("Analyze this codebase for issues")
|
|
637
|
+
```
|
|
638
|
+
|
|
639
|
+
### 4. Template-Based Swarm Generation
|
|
640
|
+
|
|
641
|
+
Generate swarms programmatically from templates:
|
|
642
|
+
|
|
643
|
+
```ruby
|
|
644
|
+
# Template function
|
|
645
|
+
def specialist_swarm(domain:, model:, expertise:)
|
|
646
|
+
proc do
|
|
647
|
+
id "#{domain}_specialist"
|
|
648
|
+
name "#{domain.capitalize} Specialist"
|
|
649
|
+
lead :expert
|
|
650
|
+
|
|
651
|
+
agent :expert do
|
|
652
|
+
model model
|
|
653
|
+
description "#{domain} expert"
|
|
654
|
+
system expertise
|
|
655
|
+
tools :Read, :Write, :Bash
|
|
656
|
+
end
|
|
657
|
+
end
|
|
658
|
+
end
|
|
659
|
+
|
|
660
|
+
# Use template to generate swarms
|
|
661
|
+
SwarmSDK.build do
|
|
662
|
+
id "multi_domain_team"
|
|
663
|
+
name "Multi-Domain Team"
|
|
664
|
+
lead :coordinator
|
|
665
|
+
|
|
666
|
+
swarms do
|
|
667
|
+
# Generate swarms from template
|
|
668
|
+
register "security", &specialist_swarm(
|
|
669
|
+
domain: "security",
|
|
670
|
+
model: "claude-3-5-sonnet",
|
|
671
|
+
expertise: "You are a security expert specializing in vulnerability detection..."
|
|
672
|
+
)
|
|
673
|
+
|
|
674
|
+
register "performance", &specialist_swarm(
|
|
675
|
+
domain: "performance",
|
|
676
|
+
model: "gpt-4o",
|
|
677
|
+
expertise: "You are a performance expert specializing in optimization..."
|
|
678
|
+
)
|
|
679
|
+
|
|
680
|
+
register "accessibility", &specialist_swarm(
|
|
681
|
+
domain: "accessibility",
|
|
682
|
+
model: "gpt-4o",
|
|
683
|
+
expertise: "You are an accessibility expert ensuring WCAG compliance..."
|
|
684
|
+
)
|
|
685
|
+
end
|
|
686
|
+
|
|
687
|
+
agent :coordinator do
|
|
688
|
+
model "claude-3-5-sonnet"
|
|
689
|
+
system "Coordinate analysis across all specialist domains"
|
|
690
|
+
delegates_to "security", "performance", "accessibility"
|
|
691
|
+
end
|
|
692
|
+
end
|
|
693
|
+
```
|
|
694
|
+
|
|
695
|
+
### 5. Testing with Inline Swarms
|
|
696
|
+
|
|
697
|
+
Create test swarms without managing files:
|
|
698
|
+
|
|
699
|
+
```ruby
|
|
700
|
+
# In your test suite
|
|
701
|
+
def create_test_swarm
|
|
702
|
+
SwarmSDK.build do
|
|
703
|
+
id "test_main"
|
|
704
|
+
name "Test Main"
|
|
705
|
+
lead :main
|
|
706
|
+
|
|
707
|
+
swarms do
|
|
708
|
+
# Mock service swarm - inline definition
|
|
709
|
+
register "mock_api" do
|
|
710
|
+
id "mock"
|
|
711
|
+
name "Mock API Service"
|
|
712
|
+
lead :mocker
|
|
713
|
+
|
|
714
|
+
agent :mocker do
|
|
715
|
+
model "gpt-4o-mini"
|
|
716
|
+
system "Return mock API responses: { status: 'ok', data: [...] }"
|
|
717
|
+
tools :Think
|
|
718
|
+
end
|
|
719
|
+
end
|
|
720
|
+
|
|
721
|
+
# Mock database swarm - inline definition
|
|
722
|
+
register "mock_db" do
|
|
723
|
+
id "mock_db"
|
|
724
|
+
name "Mock Database"
|
|
725
|
+
lead :db
|
|
726
|
+
|
|
727
|
+
agent :db do
|
|
728
|
+
model "gpt-4o-mini"
|
|
729
|
+
system "Return mock database query results"
|
|
730
|
+
tools :Think
|
|
731
|
+
end
|
|
732
|
+
end
|
|
733
|
+
end
|
|
734
|
+
|
|
735
|
+
agent :main do
|
|
736
|
+
system "Main agent under test"
|
|
737
|
+
delegates_to "mock_api", "mock_db"
|
|
738
|
+
end
|
|
739
|
+
end
|
|
740
|
+
end
|
|
741
|
+
|
|
742
|
+
# Test with mocked dependencies
|
|
743
|
+
swarm = create_test_swarm
|
|
744
|
+
result = swarm.execute("Fetch user data from API and save to DB")
|
|
745
|
+
```
|
|
746
|
+
|
|
747
|
+
---
|
|
748
|
+
|
|
749
|
+
## Best Practices
|
|
750
|
+
|
|
751
|
+
### 1. ID Naming Conventions
|
|
752
|
+
|
|
753
|
+
Use descriptive, hierarchical IDs:
|
|
754
|
+
|
|
755
|
+
```ruby
|
|
756
|
+
# Good
|
|
757
|
+
id "main_application"
|
|
758
|
+
id "code_review_team_v2"
|
|
759
|
+
id "security_audit_strict"
|
|
760
|
+
|
|
761
|
+
# Avoid
|
|
762
|
+
id "team"
|
|
763
|
+
id "cr"
|
|
764
|
+
id "x"
|
|
765
|
+
```
|
|
766
|
+
|
|
767
|
+
### 2. Swarm Granularity
|
|
768
|
+
|
|
769
|
+
**Too granular:**
|
|
770
|
+
```ruby
|
|
771
|
+
swarms do
|
|
772
|
+
register "read_files" do # Too simple - should be an agent
|
|
773
|
+
agent :reader do
|
|
774
|
+
system "Read files"
|
|
775
|
+
end
|
|
776
|
+
end
|
|
777
|
+
end
|
|
778
|
+
```
|
|
779
|
+
|
|
780
|
+
**Too coarse:**
|
|
781
|
+
```ruby
|
|
782
|
+
swarms do
|
|
783
|
+
register "entire_application" do # Too large - hard to reuse
|
|
784
|
+
# 20+ agents doing everything
|
|
785
|
+
end
|
|
786
|
+
end
|
|
787
|
+
```
|
|
788
|
+
|
|
789
|
+
**Just right:**
|
|
790
|
+
```ruby
|
|
791
|
+
swarms do
|
|
792
|
+
register "code_review" do # Focused, reusable team
|
|
793
|
+
agent :lead_reviewer do
|
|
794
|
+
delegates_to "security", "style", "performance"
|
|
795
|
+
end
|
|
796
|
+
# 3-5 specialized agents
|
|
797
|
+
end
|
|
798
|
+
end
|
|
799
|
+
```
|
|
800
|
+
|
|
801
|
+
### 3. keep_context Guidelines
|
|
802
|
+
|
|
803
|
+
**Use `keep_context: true` (default) when:**
|
|
804
|
+
- Sub-swarm performs iterative work
|
|
805
|
+
- Multiple delegations build on previous work
|
|
806
|
+
- Conversation context improves results
|
|
807
|
+
|
|
808
|
+
**Use `keep_context: false` when:**
|
|
809
|
+
- Each delegation is independent
|
|
810
|
+
- Want fresh perspective each time
|
|
811
|
+
- Preventing context pollution matters
|
|
812
|
+
- Managing memory in long-running swarms
|
|
813
|
+
|
|
814
|
+
```ruby
|
|
815
|
+
swarms do
|
|
816
|
+
# Stateful - remembers previous reviews
|
|
817
|
+
register "code_review", file: "./code_review.rb", keep_context: true
|
|
818
|
+
|
|
819
|
+
# Stateless - fresh tests each time
|
|
820
|
+
register "testing", file: "./testing.rb", keep_context: false
|
|
821
|
+
end
|
|
822
|
+
```
|
|
823
|
+
|
|
824
|
+
### 4. Mixing Local Agents and Swarms
|
|
825
|
+
|
|
826
|
+
```ruby
|
|
827
|
+
agent :backend do
|
|
828
|
+
# Best practice: List local agents first, then swarms
|
|
829
|
+
delegates_to "database", # Local agent (fast, same swarm)
|
|
830
|
+
"cache", # Local agent
|
|
831
|
+
"code_review", # External swarm (more expensive)
|
|
832
|
+
"deployment" # External swarm
|
|
833
|
+
end
|
|
834
|
+
```
|
|
835
|
+
|
|
836
|
+
---
|
|
837
|
+
|
|
838
|
+
## Advanced Patterns
|
|
839
|
+
|
|
840
|
+
### Pattern 1: Swarm Pipeline
|
|
841
|
+
|
|
842
|
+
Chain swarms for multi-stage processing:
|
|
843
|
+
|
|
844
|
+
```ruby
|
|
845
|
+
SwarmSDK.build do
|
|
846
|
+
id "pipeline"
|
|
847
|
+
|
|
848
|
+
swarms do
|
|
849
|
+
register "analysis", file: "./swarms/analysis.rb"
|
|
850
|
+
register "refactoring", file: "./swarms/refactoring.rb"
|
|
851
|
+
register "testing", file: "./swarms/testing.rb"
|
|
852
|
+
end
|
|
853
|
+
|
|
854
|
+
agent :coordinator do
|
|
855
|
+
system <<~PROMPT
|
|
856
|
+
Process code through pipeline:
|
|
857
|
+
1. Delegate to analysis for code review
|
|
858
|
+
2. Based on analysis, delegate to refactoring if needed
|
|
859
|
+
3. After changes, delegate to testing for validation
|
|
860
|
+
PROMPT
|
|
861
|
+
delegates_to "analysis", "refactoring", "testing"
|
|
862
|
+
end
|
|
863
|
+
end
|
|
864
|
+
```
|
|
865
|
+
|
|
866
|
+
### Pattern 2: Conditional Swarm Loading
|
|
867
|
+
|
|
868
|
+
Load different swarms based on project type:
|
|
869
|
+
|
|
870
|
+
```ruby
|
|
871
|
+
# Detect project type
|
|
872
|
+
project_type = detect_project_type # => :rails, :nodejs, :python
|
|
873
|
+
|
|
874
|
+
swarms do
|
|
875
|
+
case project_type
|
|
876
|
+
when :rails
|
|
877
|
+
register "testing", file: "./swarms/rails_testing.rb"
|
|
878
|
+
register "deployment", file: "./swarms/rails_deployment.rb"
|
|
879
|
+
when :nodejs
|
|
880
|
+
register "testing", file: "./swarms/nodejs_testing.rb"
|
|
881
|
+
register "deployment", file: "./swarms/nodejs_deployment.rb"
|
|
882
|
+
when :python
|
|
883
|
+
register "testing", file: "./swarms/python_testing.rb"
|
|
884
|
+
register "deployment", file: "./swarms/python_deployment.rb"
|
|
885
|
+
end
|
|
886
|
+
end
|
|
887
|
+
```
|
|
888
|
+
|
|
889
|
+
### Pattern 3: Feature Flags for Swarms
|
|
890
|
+
|
|
891
|
+
Enable/disable swarms based on configuration:
|
|
892
|
+
|
|
893
|
+
```ruby
|
|
894
|
+
swarms do
|
|
895
|
+
# Always available
|
|
896
|
+
register "code_review", file: "./swarms/code_review.rb"
|
|
897
|
+
|
|
898
|
+
# Optional features
|
|
899
|
+
if ENV["ENABLE_SECURITY_AUDIT"]
|
|
900
|
+
register "security", file: "./swarms/security_audit.rb"
|
|
901
|
+
end
|
|
902
|
+
|
|
903
|
+
if ENV["ENABLE_PERFORMANCE_ANALYSIS"]
|
|
904
|
+
register "performance", file: "./swarms/performance.rb"
|
|
905
|
+
end
|
|
906
|
+
end
|
|
907
|
+
|
|
908
|
+
agent :lead do
|
|
909
|
+
delegates = ["code_review"]
|
|
910
|
+
delegates << "security" if ENV["ENABLE_SECURITY_AUDIT"]
|
|
911
|
+
delegates << "performance" if ENV["ENABLE_PERFORMANCE_ANALYSIS"]
|
|
912
|
+
|
|
913
|
+
delegates_to(*delegates)
|
|
914
|
+
end
|
|
915
|
+
```
|
|
916
|
+
|
|
917
|
+
---
|
|
918
|
+
|
|
919
|
+
## Troubleshooting
|
|
920
|
+
|
|
921
|
+
### Error: "Swarm id must be set using id(...) when using composable swarms"
|
|
922
|
+
|
|
923
|
+
**Cause:** Using `swarms {}` block without setting swarm ID.
|
|
924
|
+
|
|
925
|
+
**Solution:**
|
|
926
|
+
```ruby
|
|
927
|
+
SwarmSDK.build do
|
|
928
|
+
id "main_app" # Add this!
|
|
929
|
+
|
|
930
|
+
swarms do
|
|
931
|
+
register "team", file: "./team.rb"
|
|
932
|
+
end
|
|
933
|
+
end
|
|
934
|
+
```
|
|
935
|
+
|
|
936
|
+
### Error: "register 'name' requires either file:, yaml:, or a block"
|
|
937
|
+
|
|
938
|
+
**Cause:** Calling `register` without providing a source.
|
|
939
|
+
|
|
940
|
+
**Solution:**
|
|
941
|
+
```ruby
|
|
942
|
+
# Wrong
|
|
943
|
+
register "team"
|
|
944
|
+
|
|
945
|
+
# Right - pick one
|
|
946
|
+
register "team", file: "./team.rb"
|
|
947
|
+
register "team", yaml: yaml_string
|
|
948
|
+
register "team" do
|
|
949
|
+
# ...
|
|
950
|
+
end
|
|
951
|
+
```
|
|
952
|
+
|
|
953
|
+
### Error: "register 'name' accepts only one of: file:, yaml:, or block (got 2)"
|
|
954
|
+
|
|
955
|
+
**Cause:** Providing multiple sources to `register`.
|
|
956
|
+
|
|
957
|
+
**Solution:**
|
|
958
|
+
```ruby
|
|
959
|
+
# Wrong
|
|
960
|
+
register "team", file: "./team.rb" do
|
|
961
|
+
# ...
|
|
962
|
+
end
|
|
963
|
+
|
|
964
|
+
# Right - pick one
|
|
965
|
+
register "team", file: "./team.rb"
|
|
966
|
+
# OR
|
|
967
|
+
register "team" do
|
|
968
|
+
# ...
|
|
969
|
+
end
|
|
970
|
+
```
|
|
971
|
+
|
|
972
|
+
### Error: "Circular delegation detected: agent_a -> agent_b -> agent_a"
|
|
973
|
+
|
|
974
|
+
**Cause:** Agents delegating in a circle, creating infinite loop.
|
|
975
|
+
|
|
976
|
+
**Solution:**
|
|
977
|
+
Restructure delegation to avoid cycles:
|
|
978
|
+
```ruby
|
|
979
|
+
# Wrong
|
|
980
|
+
agent :a do
|
|
981
|
+
delegates_to "b"
|
|
982
|
+
end
|
|
983
|
+
|
|
984
|
+
agent :b do
|
|
985
|
+
delegates_to "a" # Circular!
|
|
986
|
+
end
|
|
987
|
+
|
|
988
|
+
# Right - use intermediary or rethink architecture
|
|
989
|
+
agent :coordinator do
|
|
990
|
+
delegates_to "a", "b"
|
|
991
|
+
end
|
|
992
|
+
|
|
993
|
+
agent :a do
|
|
994
|
+
# No delegation to b
|
|
995
|
+
end
|
|
996
|
+
|
|
997
|
+
agent :b do
|
|
998
|
+
# No delegation to a
|
|
999
|
+
end
|
|
1000
|
+
```
|
|
1001
|
+
|
|
1002
|
+
### Error: "Agent 'backend' delegates to unknown target 'code_review'"
|
|
1003
|
+
|
|
1004
|
+
**Cause:** Referencing a swarm that isn't registered.
|
|
1005
|
+
|
|
1006
|
+
**Solution:**
|
|
1007
|
+
```ruby
|
|
1008
|
+
swarms do
|
|
1009
|
+
register "code_review", file: "./swarms/code_review.rb" # Add this!
|
|
1010
|
+
end
|
|
1011
|
+
|
|
1012
|
+
agent :backend do
|
|
1013
|
+
delegates_to "code_review"
|
|
1014
|
+
end
|
|
1015
|
+
```
|
|
1016
|
+
|
|
1017
|
+
---
|
|
1018
|
+
|
|
1019
|
+
## Performance Considerations
|
|
1020
|
+
|
|
1021
|
+
### Lazy Loading
|
|
1022
|
+
|
|
1023
|
+
Sub-swarms are only loaded when first accessed:
|
|
1024
|
+
|
|
1025
|
+
```ruby
|
|
1026
|
+
swarms do
|
|
1027
|
+
register "heavy_swarm", file: "./heavy.rb" # Not loaded yet
|
|
1028
|
+
end
|
|
1029
|
+
|
|
1030
|
+
# First delegation triggers load
|
|
1031
|
+
swarm.agent(:main).ask("Use heavy_swarm") # Loads now
|
|
1032
|
+
|
|
1033
|
+
# Subsequent delegations use cached instance
|
|
1034
|
+
swarm.agent(:main).ask("Use heavy_swarm again") # Uses cache
|
|
1035
|
+
```
|
|
1036
|
+
|
|
1037
|
+
### Memory Management
|
|
1038
|
+
|
|
1039
|
+
```ruby
|
|
1040
|
+
swarms do
|
|
1041
|
+
# Stateless swarms reset after each use (better memory)
|
|
1042
|
+
register "testing", file: "./testing.rb", keep_context: false
|
|
1043
|
+
|
|
1044
|
+
# Stateful swarms accumulate conversation (uses more memory)
|
|
1045
|
+
register "code_review", file: "./code_review.rb", keep_context: true
|
|
1046
|
+
end
|
|
1047
|
+
```
|
|
1048
|
+
|
|
1049
|
+
### Cleanup
|
|
1050
|
+
|
|
1051
|
+
All sub-swarms are automatically cleaned up when parent swarm completes:
|
|
1052
|
+
|
|
1053
|
+
```ruby
|
|
1054
|
+
swarm = SwarmSDK.build do
|
|
1055
|
+
swarms do
|
|
1056
|
+
register "child", file: "./child.rb"
|
|
1057
|
+
end
|
|
1058
|
+
end
|
|
1059
|
+
|
|
1060
|
+
swarm.execute("Task")
|
|
1061
|
+
# After execution:
|
|
1062
|
+
# - swarm.cleanup is called
|
|
1063
|
+
# - Cascades to child swarm
|
|
1064
|
+
# - All MCP clients stopped
|
|
1065
|
+
# - Resources released
|
|
1066
|
+
```
|
|
1067
|
+
|
|
1068
|
+
---
|
|
1069
|
+
|
|
1070
|
+
## API Reference
|
|
1071
|
+
|
|
1072
|
+
Quick reference for composable swarms methods.
|
|
1073
|
+
|
|
1074
|
+
### Ruby DSL
|
|
1075
|
+
|
|
1076
|
+
```ruby
|
|
1077
|
+
# Swarm-level
|
|
1078
|
+
id "swarm_id" # Set swarm ID
|
|
1079
|
+
swarms { } # Register sub-swarms
|
|
1080
|
+
|
|
1081
|
+
# Inside swarms {}
|
|
1082
|
+
register "name", file: "path" # From file
|
|
1083
|
+
register "name", yaml: "yaml_string", keep_context: false # From YAML
|
|
1084
|
+
register "name", keep_context: false do ... end # Inline block
|
|
1085
|
+
```
|
|
1086
|
+
|
|
1087
|
+
### YAML
|
|
1088
|
+
|
|
1089
|
+
```yaml
|
|
1090
|
+
swarm:
|
|
1091
|
+
id: swarm_id
|
|
1092
|
+
swarms:
|
|
1093
|
+
name:
|
|
1094
|
+
file: "./path/to/swarm.rb"
|
|
1095
|
+
keep_context: true
|
|
1096
|
+
name2:
|
|
1097
|
+
swarm: # Inline definition
|
|
1098
|
+
id: team_id
|
|
1099
|
+
# ... full swarm config
|
|
1100
|
+
```
|
|
1101
|
+
|
|
1102
|
+
### Events
|
|
1103
|
+
|
|
1104
|
+
All events include:
|
|
1105
|
+
- `swarm_id`: Current swarm ID
|
|
1106
|
+
- `parent_swarm_id`: Parent swarm ID (null for root)
|
|
1107
|
+
|
|
1108
|
+
New event:
|
|
1109
|
+
- `delegation_circular_dependency`: Emitted when circular delegation detected
|
|
1110
|
+
|
|
1111
|
+
---
|
|
1112
|
+
|
|
1113
|
+
## Migration Guide
|
|
1114
|
+
|
|
1115
|
+
### From Monolithic to Composable
|
|
1116
|
+
|
|
1117
|
+
**Before:**
|
|
1118
|
+
```ruby
|
|
1119
|
+
SwarmSDK.build do
|
|
1120
|
+
name "Development Team"
|
|
1121
|
+
lead :lead_dev
|
|
1122
|
+
|
|
1123
|
+
# Everything in one swarm
|
|
1124
|
+
agent :lead_dev { delegates_to "backend", "security", "style", "performance" }
|
|
1125
|
+
agent :backend { }
|
|
1126
|
+
agent :security { }
|
|
1127
|
+
agent :style { }
|
|
1128
|
+
agent :performance { }
|
|
1129
|
+
end
|
|
1130
|
+
```
|
|
1131
|
+
|
|
1132
|
+
**After:**
|
|
1133
|
+
```ruby
|
|
1134
|
+
# Extract specialized teams
|
|
1135
|
+
# File: ./swarms/code_review.rb
|
|
1136
|
+
SwarmSDK.build do
|
|
1137
|
+
id "code_review_team"
|
|
1138
|
+
name "Code Review Team"
|
|
1139
|
+
lead :reviewer
|
|
1140
|
+
agent :reviewer { delegates_to "security", "style", "performance" }
|
|
1141
|
+
agent :security { }
|
|
1142
|
+
agent :style { }
|
|
1143
|
+
agent :performance { }
|
|
1144
|
+
end
|
|
1145
|
+
|
|
1146
|
+
# Main swarm
|
|
1147
|
+
SwarmSDK.build do
|
|
1148
|
+
id "development_team"
|
|
1149
|
+
name "Development Team"
|
|
1150
|
+
lead :lead_dev
|
|
1151
|
+
|
|
1152
|
+
swarms do
|
|
1153
|
+
register "code_review", file: "./swarms/code_review.rb"
|
|
1154
|
+
end
|
|
1155
|
+
|
|
1156
|
+
agent :lead_dev { delegates_to "backend", "code_review" }
|
|
1157
|
+
agent :backend { }
|
|
1158
|
+
end
|
|
1159
|
+
```
|
|
1160
|
+
|
|
1161
|
+
**Benefits:**
|
|
1162
|
+
- Code review team is now reusable
|
|
1163
|
+
- Cleaner main swarm configuration
|
|
1164
|
+
- Easier to test and maintain
|
|
1165
|
+
- Can be shared across projects
|
|
1166
|
+
|
|
1167
|
+
---
|
|
1168
|
+
|
|
1169
|
+
## See Also
|
|
1170
|
+
|
|
1171
|
+
- [Ruby DSL Reference - swarms](../reference/ruby-dsl.md#swarms)
|
|
1172
|
+
- [Ruby DSL Reference - swarms.register](../reference/ruby-dsl.md#swarmsregister)
|
|
1173
|
+
- [YAML Reference - swarms](../reference/yaml.md#swarms)
|
|
1174
|
+
- [Event Payloads - delegation_circular_dependency](../reference/event_payload_structures.md#12a-delegation_circular_dependency)
|
|
1175
|
+
|
|
1176
|
+
---
|
|
1177
|
+
|
|
1178
|
+
*Guide last updated: 2025-11-02*
|