claude_swarm 1.0.9 → 1.0.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (134) hide show
  1. checksums.yaml +4 -4
  2. data/{CHANGELOG.md → CHANGELOG.claude-swarm.md} +10 -0
  3. data/CLAUDE.md +346 -191
  4. data/decisions/2025-11-22-001-global-agent-registry.md +172 -0
  5. data/docs/v2/CHANGELOG.swarm_cli.md +20 -0
  6. data/docs/v2/CHANGELOG.swarm_memory.md +146 -1
  7. data/docs/v2/CHANGELOG.swarm_sdk.md +433 -10
  8. data/docs/v2/README.md +20 -5
  9. data/docs/v2/guides/complete-tutorial.md +95 -9
  10. data/docs/v2/guides/getting-started.md +10 -8
  11. data/docs/v2/guides/memory-adapters.md +41 -0
  12. data/docs/v2/guides/migrating-to-2.x.md +746 -0
  13. data/docs/v2/guides/plugins.md +52 -5
  14. data/docs/v2/guides/rails-integration.md +6 -0
  15. data/docs/v2/guides/snapshots.md +14 -14
  16. data/docs/v2/guides/swarm-memory.md +2 -13
  17. data/docs/v2/reference/architecture-flow.md +3 -3
  18. data/docs/v2/reference/cli.md +0 -1
  19. data/docs/v2/reference/configuration_reference.md +300 -0
  20. data/docs/v2/reference/event_payload_structures.md +27 -5
  21. data/docs/v2/reference/ruby-dsl.md +614 -18
  22. data/docs/v2/reference/swarm_memory_technical_details.md +7 -29
  23. data/docs/v2/reference/yaml.md +172 -54
  24. data/examples/snapshot_demo.rb +2 -2
  25. data/lib/claude_swarm/mcp_generator.rb +8 -21
  26. data/lib/claude_swarm/orchestrator.rb +8 -1
  27. data/lib/claude_swarm/version.rb +1 -1
  28. data/lib/swarm_cli/commands/run.rb +2 -2
  29. data/lib/swarm_cli/config_loader.rb +11 -11
  30. data/lib/swarm_cli/formatters/human_formatter.rb +0 -33
  31. data/lib/swarm_cli/interactive_repl.rb +2 -2
  32. data/lib/swarm_cli/ui/icons.rb +0 -23
  33. data/lib/swarm_cli/version.rb +1 -1
  34. data/lib/swarm_memory/adapters/filesystem_adapter.rb +11 -34
  35. data/lib/swarm_memory/core/semantic_index.rb +10 -2
  36. data/lib/swarm_memory/core/storage.rb +7 -2
  37. data/lib/swarm_memory/dsl/memory_config.rb +37 -0
  38. data/lib/swarm_memory/integration/sdk_plugin.rb +201 -28
  39. data/lib/swarm_memory/optimization/defragmenter.rb +1 -1
  40. data/lib/swarm_memory/prompts/memory_researcher.md.erb +0 -1
  41. data/lib/swarm_memory/tools/load_skill.rb +0 -1
  42. data/lib/swarm_memory/tools/memory_edit.rb +2 -1
  43. data/lib/swarm_memory/tools/memory_read.rb +1 -1
  44. data/lib/swarm_memory/version.rb +1 -1
  45. data/lib/swarm_memory.rb +8 -6
  46. data/lib/swarm_sdk/agent/builder.rb +58 -0
  47. data/lib/swarm_sdk/agent/chat.rb +527 -1061
  48. data/lib/swarm_sdk/agent/{chat → chat_helpers}/context_tracker.rb +13 -88
  49. data/lib/swarm_sdk/agent/chat_helpers/event_emitter.rb +204 -0
  50. data/lib/swarm_sdk/agent/{chat → chat_helpers}/hook_integration.rb +108 -46
  51. data/lib/swarm_sdk/agent/chat_helpers/instrumentation.rb +78 -0
  52. data/lib/swarm_sdk/agent/chat_helpers/llm_configuration.rb +267 -0
  53. data/lib/swarm_sdk/agent/{chat → chat_helpers}/logging_helpers.rb +3 -3
  54. data/lib/swarm_sdk/agent/chat_helpers/serialization.rb +83 -0
  55. data/lib/swarm_sdk/agent/{chat → chat_helpers}/system_reminder_injector.rb +11 -13
  56. data/lib/swarm_sdk/agent/chat_helpers/system_reminders.rb +79 -0
  57. data/lib/swarm_sdk/agent/chat_helpers/token_tracking.rb +146 -0
  58. data/lib/swarm_sdk/agent/context.rb +1 -2
  59. data/lib/swarm_sdk/agent/definition.rb +66 -154
  60. data/lib/swarm_sdk/agent/llm_instrumentation_middleware.rb +4 -2
  61. data/lib/swarm_sdk/agent/system_prompt_builder.rb +161 -0
  62. data/lib/swarm_sdk/agent_registry.rb +146 -0
  63. data/lib/swarm_sdk/builders/base_builder.rb +488 -0
  64. data/lib/swarm_sdk/concerns/cleanupable.rb +39 -0
  65. data/lib/swarm_sdk/concerns/snapshotable.rb +67 -0
  66. data/lib/swarm_sdk/concerns/validatable.rb +55 -0
  67. data/lib/swarm_sdk/config.rb +302 -0
  68. data/lib/swarm_sdk/configuration/parser.rb +373 -0
  69. data/lib/swarm_sdk/configuration/translator.rb +255 -0
  70. data/lib/swarm_sdk/configuration.rb +77 -546
  71. data/lib/swarm_sdk/context_compactor/token_counter.rb +2 -6
  72. data/lib/swarm_sdk/context_compactor.rb +6 -11
  73. data/lib/swarm_sdk/context_management/builder.rb +128 -0
  74. data/lib/swarm_sdk/context_management/context.rb +328 -0
  75. data/lib/swarm_sdk/custom_tool_registry.rb +226 -0
  76. data/lib/swarm_sdk/defaults.rb +196 -0
  77. data/lib/swarm_sdk/events_to_messages.rb +18 -0
  78. data/lib/swarm_sdk/hooks/adapter.rb +3 -3
  79. data/lib/swarm_sdk/hooks/shell_executor.rb +4 -2
  80. data/lib/swarm_sdk/log_collector.rb +179 -29
  81. data/lib/swarm_sdk/log_stream.rb +29 -0
  82. data/lib/swarm_sdk/models.json +4333 -1
  83. data/lib/swarm_sdk/models.rb +43 -2
  84. data/lib/swarm_sdk/node_context.rb +1 -1
  85. data/lib/swarm_sdk/observer/builder.rb +81 -0
  86. data/lib/swarm_sdk/observer/config.rb +45 -0
  87. data/lib/swarm_sdk/observer/manager.rb +236 -0
  88. data/lib/swarm_sdk/patterns/agent_observer.rb +160 -0
  89. data/lib/swarm_sdk/plugin.rb +95 -5
  90. data/lib/swarm_sdk/result.rb +52 -0
  91. data/lib/swarm_sdk/snapshot.rb +6 -6
  92. data/lib/swarm_sdk/snapshot_from_events.rb +13 -2
  93. data/lib/swarm_sdk/state_restorer.rb +136 -151
  94. data/lib/swarm_sdk/state_snapshot.rb +65 -100
  95. data/lib/swarm_sdk/swarm/agent_initializer.rb +181 -137
  96. data/lib/swarm_sdk/swarm/builder.rb +44 -578
  97. data/lib/swarm_sdk/swarm/executor.rb +213 -0
  98. data/lib/swarm_sdk/swarm/hook_triggers.rb +151 -0
  99. data/lib/swarm_sdk/swarm/logging_callbacks.rb +341 -0
  100. data/lib/swarm_sdk/swarm/mcp_configurator.rb +7 -4
  101. data/lib/swarm_sdk/swarm/tool_configurator.rb +58 -140
  102. data/lib/swarm_sdk/swarm.rb +203 -683
  103. data/lib/swarm_sdk/tools/bash.rb +14 -8
  104. data/lib/swarm_sdk/tools/delegate.rb +61 -43
  105. data/lib/swarm_sdk/tools/edit.rb +8 -13
  106. data/lib/swarm_sdk/tools/glob.rb +12 -4
  107. data/lib/swarm_sdk/tools/grep.rb +7 -0
  108. data/lib/swarm_sdk/tools/multi_edit.rb +15 -11
  109. data/lib/swarm_sdk/tools/path_resolver.rb +51 -2
  110. data/lib/swarm_sdk/tools/read.rb +16 -18
  111. data/lib/swarm_sdk/tools/registry.rb +122 -10
  112. data/lib/swarm_sdk/tools/stores/scratchpad_storage.rb +9 -5
  113. data/lib/swarm_sdk/tools/stores/storage.rb +0 -6
  114. data/lib/swarm_sdk/tools/todo_write.rb +7 -0
  115. data/lib/swarm_sdk/tools/web_fetch.rb +20 -17
  116. data/lib/swarm_sdk/tools/write.rb +8 -13
  117. data/lib/swarm_sdk/version.rb +1 -1
  118. data/lib/swarm_sdk/{node → workflow}/agent_config.rb +1 -1
  119. data/lib/swarm_sdk/workflow/builder.rb +192 -0
  120. data/lib/swarm_sdk/workflow/executor.rb +497 -0
  121. data/lib/swarm_sdk/{node/builder.rb → workflow/node_builder.rb} +7 -5
  122. data/lib/swarm_sdk/{node → workflow}/transformer_executor.rb +5 -3
  123. data/lib/swarm_sdk/{node_orchestrator.rb → workflow.rb} +152 -456
  124. data/lib/swarm_sdk.rb +294 -108
  125. data/rubocop/cop/security/no_reflection_methods.rb +1 -1
  126. data/swarm_cli.gemspec +1 -1
  127. data/swarm_memory.gemspec +8 -3
  128. data/swarm_sdk.gemspec +6 -4
  129. data/team_full.yml +124 -320
  130. metadata +42 -14
  131. data/lib/swarm_memory/chat_extension.rb +0 -34
  132. data/lib/swarm_memory/tools/memory_multi_edit.rb +0 -281
  133. data/lib/swarm_sdk/providers/openai_with_responses.rb +0 -589
  134. /data/lib/swarm_memory/{errors.rb → error.rb} +0 -0
@@ -0,0 +1,746 @@
1
+ # Migrating SwarmSDK 2.x
2
+
3
+ This guide covers all breaking changes and migration steps for upgrading between SwarmSDK 2.x versions.
4
+
5
+ ---
6
+
7
+ ## Migrating to v2.4.0
8
+
9
+ ### Overview
10
+
11
+ SwarmSDK v2.4.0 introduces a centralized configuration system that replaces the previous `SwarmSDK.settings` approach.
12
+
13
+ ### Breaking Changes
14
+
15
+ #### 1. Configuration API Change
16
+
17
+ **What Changed:**
18
+ - `SwarmSDK.settings` replaced with `SwarmSDK.config` singleton
19
+ - New `SwarmSDK.configure` block syntax for setting values
20
+ - Lazy ENV loading with thread-safe initialization
21
+ - Auto-proxying of API keys to RubyLLM
22
+
23
+ **Before (v2.3.x):**
24
+ ```ruby
25
+ # Direct property access
26
+ SwarmSDK.settings.openai_api_key = "sk-..."
27
+ SwarmSDK.settings.default_model = "gpt-5"
28
+ SwarmSDK.settings.allow_filesystem_tools = false
29
+
30
+ # Reading values
31
+ model = SwarmSDK.settings.default_model
32
+ ```
33
+
34
+ **After (v2.4.0):**
35
+ ```ruby
36
+ # Block-based configuration
37
+ SwarmSDK.configure do |config|
38
+ config.openai_api_key = "sk-..."
39
+ config.default_model = "gpt-5"
40
+ config.allow_filesystem_tools = false
41
+ end
42
+
43
+ # Reading values
44
+ model = SwarmSDK.config.default_model
45
+ ```
46
+
47
+ **Migration Steps:**
48
+
49
+ 1. **Replace all `SwarmSDK.settings` with `SwarmSDK.config`:**
50
+ ```ruby
51
+ # Before
52
+ timeout = SwarmSDK.settings.agent_request_timeout
53
+
54
+ # After
55
+ timeout = SwarmSDK.config.agent_request_timeout
56
+ ```
57
+
58
+ 2. **Use configure block for setting multiple values:**
59
+ ```ruby
60
+ # Before
61
+ SwarmSDK.settings.openai_api_key = ENV["OPENAI_API_KEY"]
62
+ SwarmSDK.settings.default_model = "claude-sonnet-4"
63
+ SwarmSDK.settings.agent_request_timeout = 600
64
+
65
+ # After
66
+ SwarmSDK.configure do |config|
67
+ config.openai_api_key = ENV["OPENAI_API_KEY"]
68
+ config.default_model = "claude-sonnet-4"
69
+ config.agent_request_timeout = 600
70
+ end
71
+ ```
72
+
73
+ 3. **Update test setup/teardown:**
74
+ ```ruby
75
+ # Before
76
+ def setup
77
+ @original = SwarmSDK.settings.default_model
78
+ SwarmSDK.settings.default_model = "test-model"
79
+ end
80
+
81
+ def teardown
82
+ SwarmSDK.settings.default_model = @original
83
+ end
84
+
85
+ # After
86
+ def setup
87
+ SwarmSDK.reset_config!
88
+ SwarmSDK.configure do |config|
89
+ config.default_model = "test-model"
90
+ end
91
+ end
92
+
93
+ def teardown
94
+ SwarmSDK.reset_config!
95
+ end
96
+ ```
97
+
98
+ #### 2. API Key Auto-Proxying
99
+
100
+ **What Changed:**
101
+ - API keys set via `SwarmSDK.configure` are automatically proxied to `RubyLLM.config`
102
+ - No need to configure both SwarmSDK and RubyLLM separately
103
+
104
+ **Before (v2.3.x):**
105
+ ```ruby
106
+ # Had to configure both
107
+ SwarmSDK.settings.openai_api_key = "sk-..."
108
+ RubyLLM.config.openai_api_key = "sk-..."
109
+ ```
110
+
111
+ **After (v2.4.0):**
112
+ ```ruby
113
+ # Only configure SwarmSDK - auto-proxied to RubyLLM
114
+ SwarmSDK.configure do |config|
115
+ config.openai_api_key = "sk-..."
116
+ end
117
+ # RubyLLM.config.openai_api_key is now also set
118
+ ```
119
+
120
+ #### 3. Configuration Priority
121
+
122
+ Values are resolved in this order:
123
+ 1. **Explicit value** (set via `SwarmSDK.configure`)
124
+ 2. **Environment variable** (e.g., `SWARM_SDK_DEFAULT_MODEL`)
125
+ 3. **Default value** (from `SwarmSDK::Defaults` module)
126
+
127
+ ```ruby
128
+ # ENV has SWARM_SDK_DEFAULT_MODEL=gpt-4o
129
+
130
+ # Without explicit config - uses ENV
131
+ SwarmSDK.config.default_model # => "gpt-4o"
132
+
133
+ # With explicit config - overrides ENV
134
+ SwarmSDK.configure do |config|
135
+ config.default_model = "claude-sonnet-4"
136
+ end
137
+ SwarmSDK.config.default_model # => "claude-sonnet-4"
138
+ ```
139
+
140
+ ### New Features
141
+
142
+ #### Configuration Reference
143
+
144
+ See [Configuration Reference](../reference/configuration_reference.md) for all 45+ configuration options including:
145
+ - API keys for all providers
146
+ - Timeouts and limits
147
+ - WebFetch LLM processing
148
+ - Security settings
149
+
150
+ #### New Helper Methods
151
+
152
+ ```ruby
153
+ # Check if WebFetch LLM processing is enabled
154
+ SwarmSDK.config.webfetch_llm_enabled?
155
+
156
+ # Reset config for testing
157
+ SwarmSDK.reset_config!
158
+ ```
159
+
160
+ ### Testing Your Migration
161
+
162
+ ```ruby
163
+ describe "v2.4.0 Migration" do
164
+ def setup
165
+ SwarmSDK.reset_config!
166
+ end
167
+
168
+ def teardown
169
+ SwarmSDK.reset_config!
170
+ end
171
+
172
+ it "uses new config API" do
173
+ SwarmSDK.configure do |config|
174
+ config.default_model = "test-model"
175
+ end
176
+
177
+ assert_equal "test-model", SwarmSDK.config.default_model
178
+ end
179
+
180
+ it "auto-proxies API keys to RubyLLM" do
181
+ SwarmSDK.configure do |config|
182
+ config.openai_api_key = "test-key"
183
+ end
184
+
185
+ assert_equal "test-key", RubyLLM.config.openai_api_key
186
+ end
187
+ end
188
+ ```
189
+
190
+ ---
191
+
192
+ ## Migrating to v2.3.0
193
+
194
+ ### Overview
195
+
196
+ SwarmSDK v2.3.0 introduces significant architectural improvements:
197
+
198
+ - **Swarm/Workflow API Separation** - Clear distinction between single-swarm and multi-stage workflows
199
+ - **Delegation Tool Rebranding** - `WorkWith*` instead of `DelegateTaskTo*`
200
+ - **Agent::Chat Abstraction Layer** - Improved encapsulation of RubyLLM internals
201
+ - **Snapshot Version 2.1.0** - Plugin state support and metadata restructuring
202
+ - **Observer Module** - Event-driven parallel agent execution (new feature)
203
+ - **Context Management DSL** - Custom context warning handlers (new feature)
204
+ - **Non-blocking Execution** - Async execution with cancellation support (new feature)
205
+
206
+ ---
207
+
208
+ ## Priority: Critical Breaking Changes
209
+
210
+ ### 1. Delegation Tool Rebranding
211
+
212
+ **What Changed:**
213
+ - Tool names: `DelegateTaskTo*` → `WorkWith*`
214
+ - Parameter: `task:` → `message:`
215
+ - Description emphasizes collaboration over task delegation
216
+
217
+ **Before (v2.2.x):**
218
+ ```ruby
219
+ # Tool call
220
+ DelegateTaskToBackend(task: "Build the authentication API")
221
+
222
+ # In agent conversations
223
+ "I'll delegate this to Backend using DelegateTaskToBackend"
224
+ ```
225
+
226
+ **After (v2.3.0):**
227
+ ```ruby
228
+ # Tool call
229
+ WorkWithBackend(message: "Build the authentication API")
230
+
231
+ # In agent conversations
232
+ "I'll work with Backend using WorkWithBackend"
233
+ ```
234
+
235
+ **Migration Steps:**
236
+
237
+ 1. **Update tool references in your code:**
238
+ ```ruby
239
+ # Before
240
+ expect(agent.has_tool?(:DelegateTaskToBackend)).to be true
241
+
242
+ # After
243
+ expect(agent.has_tool?(:WorkWithBackend)).to be true
244
+ ```
245
+
246
+ 2. **Update parameter names:**
247
+ ```ruby
248
+ # Before
249
+ result = DelegateTaskToBackend(task: "Build API")
250
+
251
+ # After
252
+ result = WorkWithBackend(message: "Build API")
253
+ ```
254
+
255
+ 3. **Update documentation and prompts:**
256
+ ```ruby
257
+ # Before - in system prompts
258
+ "Use DelegateTaskToBackend when you need help with APIs"
259
+
260
+ # After
261
+ "Use WorkWithBackend when you need to collaborate on APIs"
262
+ ```
263
+
264
+ 4. **Canonical tool name generation:**
265
+ ```ruby
266
+ # Use the canonical method
267
+ tool_name = SwarmSDK::Tools::Delegate.tool_name_for(:backend)
268
+ # Returns "WorkWithBackend"
269
+ ```
270
+
271
+ ---
272
+
273
+ ### 2. Agent::Chat Abstraction Layer
274
+
275
+ **What Changed:**
276
+ - Chat no longer inherits from RubyLLM::Chat (composition over inheritance)
277
+ - Direct access to `.tools`, `.messages`, `.model` removed
278
+ - New abstraction methods provide controlled access
279
+
280
+ **Before (v2.2.x):**
281
+ ```ruby
282
+ agent = swarm.agent(:backend)
283
+
284
+ # Direct access to RubyLLM internals
285
+ agent.tools.key?(:Read) # Check tool existence
286
+ agent.tools.keys # List all tools
287
+ agent.model.id # Get model ID
288
+ agent.model.provider # Get provider
289
+ agent.messages.count # Count messages
290
+ agent.messages # Access messages array
291
+ ```
292
+
293
+ **After (v2.3.0):**
294
+ ```ruby
295
+ agent = swarm.agent(:backend)
296
+
297
+ # SwarmSDK abstraction API
298
+ agent.has_tool?(:Read) # Check tool existence
299
+ agent.tool_names # List all tools
300
+ agent.model_id # Get model ID
301
+ agent.model_provider # Get provider
302
+ agent.message_count # Count messages
303
+ agent.messages # Safe copy of messages
304
+ ```
305
+
306
+ **Migration Table:**
307
+
308
+ | Old API (v2.2.x) | New API (v2.3.0) |
309
+ |------------------|------------------|
310
+ | `chat.tools.key?(:Read)` | `chat.has_tool?(:Read)` |
311
+ | `chat.tools.keys` | `chat.tool_names` |
312
+ | `chat.tools.count` | `chat.tool_count` |
313
+ | `chat.tools[:Read]` | Not available (use `has_tool?`) |
314
+ | `chat.model.id` | `chat.model_id` |
315
+ | `chat.model.provider` | `chat.model_provider` |
316
+ | `chat.model.context_window` | `chat.model_context_window` |
317
+ | `chat.messages.count` | `chat.message_count` |
318
+ | `chat.messages.any? { \|m\| m.role == :user }` | `chat.has_user_message?` |
319
+ | `chat.messages.last` | `chat.last_assistant_message` |
320
+
321
+ **For Plugin/Internal Code:**
322
+
323
+ If you're writing plugins or internal modules that need direct access:
324
+
325
+ ```ruby
326
+ # Use internal access methods (not for public API consumption)
327
+ agent.internal_messages # Direct array of RubyLLM messages
328
+ agent.internal_tools # Direct hash of tool instances
329
+ agent.internal_model # Direct RubyLLM model object
330
+ ```
331
+
332
+ **Why This Change:**
333
+ - Better encapsulation of LLM library internals
334
+ - Easier future migrations if RubyLLM API changes
335
+ - More consistent and predictable API
336
+ - Prevents accidental mutation of internal state
337
+
338
+ ---
339
+
340
+ ### 3. Swarm vs Workflow API Separation
341
+
342
+ **What Changed:**
343
+ - `SwarmSDK.build` now **ONLY** returns `Swarm`
344
+ - New `SwarmSDK.workflow` method for multi-stage workflows
345
+ - YAML uses explicit `swarm:` or `workflow:` root keys
346
+ - `NodeOrchestrator` class renamed to `Workflow`
347
+
348
+ **Before (v2.2.x):**
349
+ ```ruby
350
+ # Single method returned either Swarm or NodeOrchestrator
351
+ result = SwarmSDK.build do
352
+ # If you used nodes, got NodeOrchestrator
353
+ # If not, got Swarm
354
+ end
355
+ ```
356
+
357
+ **After (v2.3.0):**
358
+ ```ruby
359
+ # Explicit methods for each type
360
+ swarm = SwarmSDK.build do
361
+ name "Development Team"
362
+ lead :backend
363
+ # Cannot use nodes here - raises ConfigurationError
364
+ end
365
+
366
+ workflow = SwarmSDK.workflow do
367
+ name "CI Pipeline"
368
+ start_node :planning
369
+ # Must define nodes here
370
+ end
371
+ ```
372
+
373
+ **Migration for DSL Users:**
374
+
375
+ ```ruby
376
+ # Before - building a workflow
377
+ SwarmSDK.build do
378
+ name "Pipeline"
379
+ agent(:planner) { ... }
380
+ node(:planning) { ... }
381
+ start_node :planning
382
+ end
383
+
384
+ # After
385
+ SwarmSDK.workflow do
386
+ name "Pipeline"
387
+ agent(:planner) { ... }
388
+ node(:planning) { ... }
389
+ start_node :planning
390
+ end
391
+ ```
392
+
393
+ **Migration for YAML Users:**
394
+
395
+ ```yaml
396
+ # Before - workflow config
397
+ version: 2
398
+ swarm:
399
+ name: "Pipeline"
400
+ start_node: planning
401
+ agents: { ... }
402
+ nodes: { ... }
403
+
404
+ # After - explicit workflow key
405
+ version: 2
406
+ workflow:
407
+ name: "Pipeline"
408
+ start_node: planning
409
+ agents: { ... }
410
+ nodes: { ... }
411
+ ```
412
+
413
+ **For Vanilla Swarm Users:**
414
+ No changes needed! Your code continues to work:
415
+
416
+ ```ruby
417
+ # This still works exactly the same
418
+ swarm = SwarmSDK.build do
419
+ name "Team"
420
+ lead :backend
421
+ agent(:backend) { ... }
422
+ end
423
+ ```
424
+
425
+ ```yaml
426
+ # This still works exactly the same
427
+ version: 2
428
+ swarm:
429
+ name: "Team"
430
+ lead: backend
431
+ agents: { ... }
432
+ ```
433
+
434
+ ---
435
+
436
+ ### 4. Snapshot Version 2.1.0
437
+
438
+ **What Changed:**
439
+ - Version bumped from 1.0.0 to 2.1.0
440
+ - New `plugin_states` field for plugin-specific state
441
+ - `swarm:` metadata key renamed to `metadata:`
442
+ - Type field now lowercase: `"swarm"` or `"workflow"`
443
+
444
+ **Old Snapshot Format (v1.0.0):**
445
+ ```json
446
+ {
447
+ "version": "1.0.0",
448
+ "type": "swarm",
449
+ "swarm": {
450
+ "id": "main",
451
+ "parent_id": null,
452
+ "first_message_sent": true
453
+ },
454
+ "agents": { ... },
455
+ "delegation_instances": { ... },
456
+ "read_tracking": { ... },
457
+ "memory_read_tracking": { ... }
458
+ }
459
+ ```
460
+
461
+ **New Snapshot Format (v2.1.0):**
462
+ ```json
463
+ {
464
+ "version": "2.1.0",
465
+ "type": "swarm",
466
+ "snapshot_at": "2025-11-17T10:30:00Z",
467
+ "swarm_sdk_version": "2.3.0",
468
+ "metadata": {
469
+ "id": "main",
470
+ "parent_id": null,
471
+ "name": "Development Team",
472
+ "first_message_sent": true
473
+ },
474
+ "agents": { ... },
475
+ "delegation_instances": { ... },
476
+ "scratchpad": { ... },
477
+ "read_tracking": { ... },
478
+ "plugin_states": {
479
+ "backend": { "read_entries": [...] }
480
+ }
481
+ }
482
+ ```
483
+
484
+ **Migration Steps:**
485
+
486
+ 1. **Cannot restore old snapshots directly** - Create new snapshots after upgrading
487
+ 2. **Manual conversion (if absolutely needed):**
488
+ ```ruby
489
+ def convert_snapshot_1_to_2(old_data)
490
+ {
491
+ version: "2.1.0",
492
+ type: old_data[:type] || "swarm",
493
+ snapshot_at: Time.now.utc.iso8601,
494
+ swarm_sdk_version: SwarmSDK::VERSION,
495
+ metadata: old_data[:swarm] || old_data[:orchestrator],
496
+ agents: old_data[:agents],
497
+ delegation_instances: old_data[:delegation_instances],
498
+ scratchpad: old_data[:scratchpad] || {},
499
+ read_tracking: old_data[:read_tracking],
500
+ plugin_states: convert_memory_tracking(old_data[:memory_read_tracking])
501
+ }
502
+ end
503
+
504
+ def convert_memory_tracking(memory_tracking)
505
+ return {} unless memory_tracking
506
+ memory_tracking.transform_values do |entries|
507
+ { read_entries: entries }
508
+ end
509
+ end
510
+ ```
511
+
512
+ 3. **Event-sourced sessions** - Use `SnapshotFromEvents.reconstruct(events)` which automatically generates v2.1.0 snapshots
513
+
514
+ ---
515
+
516
+ ## Important: Plugin Lifecycle Changes
517
+
518
+ ### Plugin State Persistence
519
+
520
+ **What Changed:**
521
+ - Plugins now have `snapshot_agent_state` and `restore_agent_state` methods
522
+ - SDK no longer has direct knowledge of plugin internals
523
+ - `memory_read_tracking` field replaced by generic `plugin_states`
524
+
525
+ **If You Have Custom Plugins:**
526
+
527
+ ```ruby
528
+ class MyPlugin < SwarmSDK::Plugin
529
+ # NEW - Snapshot your plugin's state
530
+ def snapshot_agent_state(agent_name)
531
+ {
532
+ custom_data: @storage[agent_name]&.to_h || {}
533
+ }
534
+ end
535
+
536
+ # NEW - Restore your plugin's state
537
+ def restore_agent_state(agent_name, state)
538
+ @storage[agent_name]&.restore(state[:custom_data])
539
+ end
540
+
541
+ # NEW - Get digest for change detection hooks
542
+ def get_tool_result_digest(agent_name:, tool_name:, path:)
543
+ return nil unless tool_name == :MyCustomRead
544
+ @storage[agent_name]&.digest_for(path)
545
+ end
546
+ end
547
+ ```
548
+
549
+ ### Plugin Configuration Decoupling
550
+
551
+ **What Changed:**
552
+ - SDK no longer knows about specific plugin configs
553
+ - Plugin configs stored in generic `@plugin_configs` hash
554
+ - Plugins handle their own YAML translation
555
+
556
+ **Agent::Definition Changes:**
557
+
558
+ ```ruby
559
+ # Accessing plugin configuration
560
+ definition.plugin_config(:memory) # Returns memory plugin config
561
+ definition.plugin_config(:custom) # Returns custom plugin config
562
+
563
+ # Generic storage for non-SDK keys
564
+ definition.plugin_configs # Hash of all plugin configs
565
+ ```
566
+
567
+ ---
568
+
569
+ ## New Features (No Migration Required)
570
+
571
+ These are additions that don't break existing code:
572
+
573
+ ### Observer Module
574
+
575
+ ```ruby
576
+ swarm = SwarmSDK.build do
577
+ agent :backend { ... }
578
+ agent :security_monitor { ... }
579
+
580
+ # NEW - Parallel agent execution
581
+ observer :security_monitor do
582
+ on :tool_call do |event|
583
+ next unless event[:tool_name] == "Bash"
584
+ "Check security of: #{event[:arguments][:command]}"
585
+ end
586
+ timeout 30
587
+ end
588
+ end
589
+ ```
590
+
591
+ ### Context Management DSL
592
+
593
+ ```ruby
594
+ agent :backend do
595
+ # NEW - Custom context warning handlers
596
+ context_management do
597
+ on :warning_60 do |ctx|
598
+ ctx.compress_tool_results(keep_recent: 15)
599
+ end
600
+
601
+ on :warning_80 do |ctx|
602
+ ctx.prune_old_messages(keep_recent: 20)
603
+ end
604
+ end
605
+ end
606
+ ```
607
+
608
+ ### Non-blocking Execution
609
+
610
+ ```ruby
611
+ # NEW - Async execution with cancellation
612
+ Sync do
613
+ task = swarm.execute("Build feature", wait: false)
614
+
615
+ # Cancel if needed
616
+ task.stop
617
+
618
+ # Wait for result
619
+ result = task.wait # Returns nil if cancelled
620
+ end
621
+ ```
622
+
623
+ ### Filtered Event Subscriptions
624
+
625
+ ```ruby
626
+ # NEW - Subscribe to specific events
627
+ LogCollector.subscribe(filter: { type: "tool_call", agent: :backend }) do |event|
628
+ puts "Backend called tool: #{event[:tool_name]}"
629
+ end
630
+ ```
631
+
632
+ ---
633
+
634
+ ## Testing Your Migration
635
+
636
+ ### 1. Check for Deprecated APIs
637
+
638
+ ```ruby
639
+ # Run this in your test suite
640
+ describe "Migration compatibility" do
641
+ it "uses new Chat API" do
642
+ agent = swarm.agent(:backend)
643
+
644
+ # These should work
645
+ expect(agent).to respond_to(:has_tool?)
646
+ expect(agent).to respond_to(:tool_names)
647
+ expect(agent).to respond_to(:model_id)
648
+
649
+ # These are gone (don't test for them)
650
+ # agent.tools.key? - removed
651
+ # agent.model.id - removed
652
+ end
653
+
654
+ it "uses new delegation names" do
655
+ expect(agent.has_tool?(:WorkWithDatabase)).to be true
656
+ expect(agent.has_tool?(:DelegateTaskToDatabase)).to be false
657
+ end
658
+ end
659
+ ```
660
+
661
+ ### 2. Verify Workflow Separation
662
+
663
+ ```ruby
664
+ describe "Workflow API" do
665
+ it "uses separate methods" do
666
+ # This should work
667
+ workflow = SwarmSDK.workflow do
668
+ node(:planning) { ... }
669
+ start_node :planning
670
+ end
671
+ expect(workflow).to be_a(SwarmSDK::Workflow)
672
+
673
+ # This should raise
674
+ expect {
675
+ SwarmSDK.build do
676
+ node(:planning) { ... } # ERROR!
677
+ end
678
+ }.to raise_error(SwarmSDK::ConfigurationError)
679
+ end
680
+ end
681
+ ```
682
+
683
+ ### 3. Test Snapshot Compatibility
684
+
685
+ ```ruby
686
+ describe "Snapshot format" do
687
+ it "generates v2.1.0 snapshots" do
688
+ snapshot = swarm.snapshot
689
+ expect(snapshot.version).to eq("2.1.0")
690
+ expect(snapshot.data[:metadata]).to be_present
691
+ expect(snapshot.data[:swarm]).to be_nil # Old key removed
692
+ end
693
+ end
694
+ ```
695
+
696
+ ---
697
+
698
+ ## Deprecation Timeline
699
+
700
+ - **v2.3.0**
701
+ - Swarm/Workflow API separation
702
+ - Delegation tool rebranding
703
+ - Agent::Chat abstraction layer
704
+ - Snapshot format v2.1.0
705
+
706
+ - **v2.4.0** (Current Release)
707
+ - `SwarmSDK.settings` → `SwarmSDK.config`
708
+ - Centralized configuration system
709
+ - API key auto-proxying to RubyLLM
710
+
711
+ - **v2.5.0** (Future)
712
+ - No breaking changes planned
713
+ - Focus on new features
714
+
715
+ ---
716
+
717
+ ## Getting Help
718
+
719
+ If you encounter issues during migration:
720
+
721
+ 1. **Check the CHANGELOG**: `docs/v2/CHANGELOG.swarm_sdk.md` has detailed explanations
722
+ 2. **Run tests**: `bundle exec rake swarm_sdk:test` to catch compatibility issues
723
+ 3. **Review examples**: `test/swarm_sdk/` contains comprehensive usage examples
724
+ 4. **Report issues**: https://github.com/parruda/claude-swarm/issues
725
+
726
+ ---
727
+
728
+ ## Summary Checklist
729
+
730
+ ### v2.4.0 Migration
731
+ - [ ] Replace `SwarmSDK.settings` with `SwarmSDK.config`
732
+ - [ ] Use `SwarmSDK.configure` block for setting values
733
+ - [ ] Update test setup/teardown to use `SwarmSDK.reset_config!`
734
+ - [ ] Remove duplicate RubyLLM API key configuration (auto-proxied now)
735
+
736
+ ### v2.3.0 Migration
737
+ - [ ] Update delegation tool calls: `DelegateTaskTo*` → `WorkWith*`
738
+ - [ ] Update delegation parameters: `task:` → `message:`
739
+ - [ ] Update Chat API usage: `tools.key?` → `has_tool?`, etc.
740
+ - [ ] Separate workflows: `SwarmSDK.build` → `SwarmSDK.workflow` for node-based configs
741
+ - [ ] Update YAML: `swarm:` key for swarms, `workflow:` key for workflows
742
+ - [ ] Regenerate snapshots (v1.0.0 → v2.1.0)
743
+ - [ ] Update custom plugins with new lifecycle methods
744
+
745
+ ### Final Step
746
+ - [ ] Test all changes with `bundle exec rake swarm_sdk:test`