claude_swarm 1.0.9 → 1.0.10

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 (107) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +7 -0
  3. data/CLAUDE.md +347 -191
  4. data/docs/v2/CHANGELOG.swarm_cli.md +8 -0
  5. data/docs/v2/CHANGELOG.swarm_memory.md +7 -1
  6. data/docs/v2/CHANGELOG.swarm_sdk.md +184 -9
  7. data/docs/v2/README.md +6 -1
  8. data/docs/v2/guides/complete-tutorial.md +2 -2
  9. data/docs/v2/guides/getting-started.md +7 -7
  10. data/docs/v2/guides/migrating-to-2.3.md +541 -0
  11. data/docs/v2/guides/snapshots.md +14 -14
  12. data/docs/v2/reference/architecture-flow.md +3 -3
  13. data/docs/v2/reference/event_payload_structures.md +1 -1
  14. data/docs/v2/reference/ruby-dsl.md +157 -14
  15. data/docs/v2/reference/yaml.md +170 -52
  16. data/examples/snapshot_demo.rb +2 -2
  17. data/lib/claude_swarm/mcp_generator.rb +7 -20
  18. data/lib/claude_swarm/version.rb +1 -1
  19. data/lib/swarm_cli/commands/run.rb +2 -2
  20. data/lib/swarm_cli/config_loader.rb +11 -11
  21. data/lib/swarm_cli/formatters/human_formatter.rb +0 -33
  22. data/lib/swarm_cli/interactive_repl.rb +2 -2
  23. data/lib/swarm_cli/ui/icons.rb +0 -23
  24. data/lib/swarm_cli/version.rb +1 -1
  25. data/lib/swarm_memory/adapters/filesystem_adapter.rb +11 -34
  26. data/lib/swarm_memory/integration/sdk_plugin.rb +87 -7
  27. data/lib/swarm_memory/version.rb +1 -1
  28. data/lib/swarm_memory.rb +1 -1
  29. data/lib/swarm_sdk/agent/builder.rb +58 -0
  30. data/lib/swarm_sdk/agent/chat.rb +527 -1061
  31. data/lib/swarm_sdk/agent/{chat → chat_helpers}/context_tracker.rb +9 -88
  32. data/lib/swarm_sdk/agent/chat_helpers/event_emitter.rb +204 -0
  33. data/lib/swarm_sdk/agent/{chat → chat_helpers}/hook_integration.rb +108 -46
  34. data/lib/swarm_sdk/agent/chat_helpers/instrumentation.rb +78 -0
  35. data/lib/swarm_sdk/agent/chat_helpers/llm_configuration.rb +233 -0
  36. data/lib/swarm_sdk/agent/{chat → chat_helpers}/logging_helpers.rb +1 -1
  37. data/lib/swarm_sdk/agent/chat_helpers/serialization.rb +83 -0
  38. data/lib/swarm_sdk/agent/{chat → chat_helpers}/system_reminder_injector.rb +12 -12
  39. data/lib/swarm_sdk/agent/chat_helpers/system_reminders.rb +79 -0
  40. data/lib/swarm_sdk/agent/chat_helpers/token_tracking.rb +98 -0
  41. data/lib/swarm_sdk/agent/context.rb +2 -2
  42. data/lib/swarm_sdk/agent/definition.rb +66 -154
  43. data/lib/swarm_sdk/agent/llm_instrumentation_middleware.rb +4 -2
  44. data/lib/swarm_sdk/agent/system_prompt_builder.rb +161 -0
  45. data/lib/swarm_sdk/builders/base_builder.rb +409 -0
  46. data/lib/swarm_sdk/concerns/cleanupable.rb +39 -0
  47. data/lib/swarm_sdk/concerns/snapshotable.rb +67 -0
  48. data/lib/swarm_sdk/concerns/validatable.rb +55 -0
  49. data/lib/swarm_sdk/configuration/parser.rb +353 -0
  50. data/lib/swarm_sdk/configuration/translator.rb +255 -0
  51. data/lib/swarm_sdk/configuration.rb +65 -543
  52. data/lib/swarm_sdk/context_compactor/token_counter.rb +3 -3
  53. data/lib/swarm_sdk/context_compactor.rb +6 -11
  54. data/lib/swarm_sdk/context_management/builder.rb +128 -0
  55. data/lib/swarm_sdk/context_management/context.rb +328 -0
  56. data/lib/swarm_sdk/defaults.rb +196 -0
  57. data/lib/swarm_sdk/events_to_messages.rb +18 -0
  58. data/lib/swarm_sdk/hooks/shell_executor.rb +2 -1
  59. data/lib/swarm_sdk/log_collector.rb +179 -29
  60. data/lib/swarm_sdk/log_stream.rb +29 -0
  61. data/lib/swarm_sdk/node_context.rb +1 -1
  62. data/lib/swarm_sdk/observer/builder.rb +81 -0
  63. data/lib/swarm_sdk/observer/config.rb +45 -0
  64. data/lib/swarm_sdk/observer/manager.rb +236 -0
  65. data/lib/swarm_sdk/patterns/agent_observer.rb +160 -0
  66. data/lib/swarm_sdk/plugin.rb +93 -3
  67. data/lib/swarm_sdk/snapshot.rb +6 -6
  68. data/lib/swarm_sdk/snapshot_from_events.rb +13 -2
  69. data/lib/swarm_sdk/state_restorer.rb +136 -151
  70. data/lib/swarm_sdk/state_snapshot.rb +65 -100
  71. data/lib/swarm_sdk/swarm/agent_initializer.rb +180 -136
  72. data/lib/swarm_sdk/swarm/builder.rb +44 -578
  73. data/lib/swarm_sdk/swarm/executor.rb +213 -0
  74. data/lib/swarm_sdk/swarm/hook_triggers.rb +150 -0
  75. data/lib/swarm_sdk/swarm/logging_callbacks.rb +340 -0
  76. data/lib/swarm_sdk/swarm/mcp_configurator.rb +7 -4
  77. data/lib/swarm_sdk/swarm/tool_configurator.rb +42 -138
  78. data/lib/swarm_sdk/swarm.rb +137 -680
  79. data/lib/swarm_sdk/tools/bash.rb +11 -3
  80. data/lib/swarm_sdk/tools/delegate.rb +61 -43
  81. data/lib/swarm_sdk/tools/edit.rb +8 -13
  82. data/lib/swarm_sdk/tools/glob.rb +9 -1
  83. data/lib/swarm_sdk/tools/grep.rb +7 -0
  84. data/lib/swarm_sdk/tools/multi_edit.rb +15 -11
  85. data/lib/swarm_sdk/tools/path_resolver.rb +51 -2
  86. data/lib/swarm_sdk/tools/read.rb +11 -13
  87. data/lib/swarm_sdk/tools/registry.rb +122 -10
  88. data/lib/swarm_sdk/tools/stores/scratchpad_storage.rb +8 -5
  89. data/lib/swarm_sdk/tools/stores/storage.rb +0 -6
  90. data/lib/swarm_sdk/tools/todo_write.rb +7 -0
  91. data/lib/swarm_sdk/tools/web_fetch.rb +3 -2
  92. data/lib/swarm_sdk/tools/write.rb +8 -13
  93. data/lib/swarm_sdk/version.rb +1 -1
  94. data/lib/swarm_sdk/{node → workflow}/agent_config.rb +1 -1
  95. data/lib/swarm_sdk/workflow/builder.rb +143 -0
  96. data/lib/swarm_sdk/workflow/executor.rb +497 -0
  97. data/lib/swarm_sdk/{node/builder.rb → workflow/node_builder.rb} +3 -3
  98. data/lib/swarm_sdk/{node → workflow}/transformer_executor.rb +3 -2
  99. data/lib/swarm_sdk/{node_orchestrator.rb → workflow.rb} +152 -456
  100. data/lib/swarm_sdk.rb +33 -3
  101. data/rubocop/cop/security/no_reflection_methods.rb +1 -1
  102. data/swarm_memory.gemspec +1 -1
  103. data/swarm_sdk.gemspec +4 -2
  104. data/team_full.yml +24 -24
  105. metadata +35 -11
  106. data/lib/swarm_memory/chat_extension.rb +0 -34
  107. data/lib/swarm_sdk/providers/openai_with_responses.rb +0 -589
@@ -0,0 +1,541 @@
1
+ # Migrating to SwarmSDK v2.3.0
2
+
3
+ This guide covers all breaking changes and migration steps for upgrading from SwarmSDK v2.2.x to v2.3.0.
4
+
5
+ ## Overview
6
+
7
+ SwarmSDK v2.3.0 introduces significant architectural improvements:
8
+
9
+ - **Swarm/Workflow API Separation** - Clear distinction between single-swarm and multi-stage workflows
10
+ - **Delegation Tool Rebranding** - `WorkWith*` instead of `DelegateTaskTo*`
11
+ - **Agent::Chat Abstraction Layer** - Improved encapsulation of RubyLLM internals
12
+ - **Snapshot Version 2.1.0** - Plugin state support and metadata restructuring
13
+ - **Observer Module** - Event-driven parallel agent execution (new feature)
14
+ - **Context Management DSL** - Custom context warning handlers (new feature)
15
+ - **Non-blocking Execution** - Async execution with cancellation support (new feature)
16
+
17
+ ---
18
+
19
+ ## Priority: Critical Breaking Changes
20
+
21
+ ### 1. Delegation Tool Rebranding
22
+
23
+ **What Changed:**
24
+ - Tool names: `DelegateTaskTo*` → `WorkWith*`
25
+ - Parameter: `task:` → `message:`
26
+ - Description emphasizes collaboration over task delegation
27
+
28
+ **Before (v2.2.x):**
29
+ ```ruby
30
+ # Tool call
31
+ DelegateTaskToBackend(task: "Build the authentication API")
32
+
33
+ # In agent conversations
34
+ "I'll delegate this to Backend using DelegateTaskToBackend"
35
+ ```
36
+
37
+ **After (v2.3.0):**
38
+ ```ruby
39
+ # Tool call
40
+ WorkWithBackend(message: "Build the authentication API")
41
+
42
+ # In agent conversations
43
+ "I'll work with Backend using WorkWithBackend"
44
+ ```
45
+
46
+ **Migration Steps:**
47
+
48
+ 1. **Update tool references in your code:**
49
+ ```ruby
50
+ # Before
51
+ expect(agent.has_tool?(:DelegateTaskToBackend)).to be true
52
+
53
+ # After
54
+ expect(agent.has_tool?(:WorkWithBackend)).to be true
55
+ ```
56
+
57
+ 2. **Update parameter names:**
58
+ ```ruby
59
+ # Before
60
+ result = DelegateTaskToBackend(task: "Build API")
61
+
62
+ # After
63
+ result = WorkWithBackend(message: "Build API")
64
+ ```
65
+
66
+ 3. **Update documentation and prompts:**
67
+ ```ruby
68
+ # Before - in system prompts
69
+ "Use DelegateTaskToBackend when you need help with APIs"
70
+
71
+ # After
72
+ "Use WorkWithBackend when you need to collaborate on APIs"
73
+ ```
74
+
75
+ 4. **Canonical tool name generation:**
76
+ ```ruby
77
+ # Use the canonical method
78
+ tool_name = SwarmSDK::Tools::Delegate.tool_name_for(:backend)
79
+ # Returns "WorkWithBackend"
80
+ ```
81
+
82
+ ---
83
+
84
+ ### 2. Agent::Chat Abstraction Layer
85
+
86
+ **What Changed:**
87
+ - Chat no longer inherits from RubyLLM::Chat (composition over inheritance)
88
+ - Direct access to `.tools`, `.messages`, `.model` removed
89
+ - New abstraction methods provide controlled access
90
+
91
+ **Before (v2.2.x):**
92
+ ```ruby
93
+ agent = swarm.agent(:backend)
94
+
95
+ # Direct access to RubyLLM internals
96
+ agent.tools.key?(:Read) # Check tool existence
97
+ agent.tools.keys # List all tools
98
+ agent.model.id # Get model ID
99
+ agent.model.provider # Get provider
100
+ agent.messages.count # Count messages
101
+ agent.messages # Access messages array
102
+ ```
103
+
104
+ **After (v2.3.0):**
105
+ ```ruby
106
+ agent = swarm.agent(:backend)
107
+
108
+ # SwarmSDK abstraction API
109
+ agent.has_tool?(:Read) # Check tool existence
110
+ agent.tool_names # List all tools
111
+ agent.model_id # Get model ID
112
+ agent.model_provider # Get provider
113
+ agent.message_count # Count messages
114
+ agent.messages # Safe copy of messages
115
+ ```
116
+
117
+ **Migration Table:**
118
+
119
+ | Old API (v2.2.x) | New API (v2.3.0) |
120
+ |------------------|------------------|
121
+ | `chat.tools.key?(:Read)` | `chat.has_tool?(:Read)` |
122
+ | `chat.tools.keys` | `chat.tool_names` |
123
+ | `chat.tools.count` | `chat.tool_count` |
124
+ | `chat.tools[:Read]` | Not available (use `has_tool?`) |
125
+ | `chat.model.id` | `chat.model_id` |
126
+ | `chat.model.provider` | `chat.model_provider` |
127
+ | `chat.model.context_window` | `chat.model_context_window` |
128
+ | `chat.messages.count` | `chat.message_count` |
129
+ | `chat.messages.any? { \|m\| m.role == :user }` | `chat.has_user_message?` |
130
+ | `chat.messages.last` | `chat.last_assistant_message` |
131
+
132
+ **For Plugin/Internal Code:**
133
+
134
+ If you're writing plugins or internal modules that need direct access:
135
+
136
+ ```ruby
137
+ # Use internal access methods (not for public API consumption)
138
+ agent.internal_messages # Direct array of RubyLLM messages
139
+ agent.internal_tools # Direct hash of tool instances
140
+ agent.internal_model # Direct RubyLLM model object
141
+ ```
142
+
143
+ **Why This Change:**
144
+ - Better encapsulation of LLM library internals
145
+ - Easier future migrations if RubyLLM API changes
146
+ - More consistent and predictable API
147
+ - Prevents accidental mutation of internal state
148
+
149
+ ---
150
+
151
+ ### 3. Swarm vs Workflow API Separation
152
+
153
+ **What Changed:**
154
+ - `SwarmSDK.build` now **ONLY** returns `Swarm`
155
+ - New `SwarmSDK.workflow` method for multi-stage workflows
156
+ - YAML uses explicit `swarm:` or `workflow:` root keys
157
+ - `NodeOrchestrator` class renamed to `Workflow`
158
+
159
+ **Before (v2.2.x):**
160
+ ```ruby
161
+ # Single method returned either Swarm or NodeOrchestrator
162
+ result = SwarmSDK.build do
163
+ # If you used nodes, got NodeOrchestrator
164
+ # If not, got Swarm
165
+ end
166
+ ```
167
+
168
+ **After (v2.3.0):**
169
+ ```ruby
170
+ # Explicit methods for each type
171
+ swarm = SwarmSDK.build do
172
+ name "Development Team"
173
+ lead :backend
174
+ # Cannot use nodes here - raises ConfigurationError
175
+ end
176
+
177
+ workflow = SwarmSDK.workflow do
178
+ name "CI Pipeline"
179
+ start_node :planning
180
+ # Must define nodes here
181
+ end
182
+ ```
183
+
184
+ **Migration for DSL Users:**
185
+
186
+ ```ruby
187
+ # Before - building a workflow
188
+ SwarmSDK.build do
189
+ name "Pipeline"
190
+ agent(:planner) { ... }
191
+ node(:planning) { ... }
192
+ start_node :planning
193
+ end
194
+
195
+ # After
196
+ SwarmSDK.workflow do
197
+ name "Pipeline"
198
+ agent(:planner) { ... }
199
+ node(:planning) { ... }
200
+ start_node :planning
201
+ end
202
+ ```
203
+
204
+ **Migration for YAML Users:**
205
+
206
+ ```yaml
207
+ # Before - workflow config
208
+ version: 2
209
+ swarm:
210
+ name: "Pipeline"
211
+ start_node: planning
212
+ agents: { ... }
213
+ nodes: { ... }
214
+
215
+ # After - explicit workflow key
216
+ version: 2
217
+ workflow:
218
+ name: "Pipeline"
219
+ start_node: planning
220
+ agents: { ... }
221
+ nodes: { ... }
222
+ ```
223
+
224
+ **For Vanilla Swarm Users:**
225
+ No changes needed! Your code continues to work:
226
+
227
+ ```ruby
228
+ # This still works exactly the same
229
+ swarm = SwarmSDK.build do
230
+ name "Team"
231
+ lead :backend
232
+ agent(:backend) { ... }
233
+ end
234
+ ```
235
+
236
+ ```yaml
237
+ # This still works exactly the same
238
+ version: 2
239
+ swarm:
240
+ name: "Team"
241
+ lead: backend
242
+ agents: { ... }
243
+ ```
244
+
245
+ ---
246
+
247
+ ### 4. Snapshot Version 2.1.0
248
+
249
+ **What Changed:**
250
+ - Version bumped from 1.0.0 to 2.1.0
251
+ - New `plugin_states` field for plugin-specific state
252
+ - `swarm:` metadata key renamed to `metadata:`
253
+ - Type field now lowercase: `"swarm"` or `"workflow"`
254
+
255
+ **Old Snapshot Format (v1.0.0):**
256
+ ```json
257
+ {
258
+ "version": "1.0.0",
259
+ "type": "swarm",
260
+ "swarm": {
261
+ "id": "main",
262
+ "parent_id": null,
263
+ "first_message_sent": true
264
+ },
265
+ "agents": { ... },
266
+ "delegation_instances": { ... },
267
+ "read_tracking": { ... },
268
+ "memory_read_tracking": { ... }
269
+ }
270
+ ```
271
+
272
+ **New Snapshot Format (v2.1.0):**
273
+ ```json
274
+ {
275
+ "version": "2.1.0",
276
+ "type": "swarm",
277
+ "snapshot_at": "2025-11-17T10:30:00Z",
278
+ "swarm_sdk_version": "2.3.0",
279
+ "metadata": {
280
+ "id": "main",
281
+ "parent_id": null,
282
+ "name": "Development Team",
283
+ "first_message_sent": true
284
+ },
285
+ "agents": { ... },
286
+ "delegation_instances": { ... },
287
+ "scratchpad": { ... },
288
+ "read_tracking": { ... },
289
+ "plugin_states": {
290
+ "backend": { "read_entries": [...] }
291
+ }
292
+ }
293
+ ```
294
+
295
+ **Migration Steps:**
296
+
297
+ 1. **Cannot restore old snapshots directly** - Create new snapshots after upgrading
298
+ 2. **Manual conversion (if absolutely needed):**
299
+ ```ruby
300
+ def convert_snapshot_1_to_2(old_data)
301
+ {
302
+ version: "2.1.0",
303
+ type: old_data[:type] || "swarm",
304
+ snapshot_at: Time.now.utc.iso8601,
305
+ swarm_sdk_version: SwarmSDK::VERSION,
306
+ metadata: old_data[:swarm] || old_data[:orchestrator],
307
+ agents: old_data[:agents],
308
+ delegation_instances: old_data[:delegation_instances],
309
+ scratchpad: old_data[:scratchpad] || {},
310
+ read_tracking: old_data[:read_tracking],
311
+ plugin_states: convert_memory_tracking(old_data[:memory_read_tracking])
312
+ }
313
+ end
314
+
315
+ def convert_memory_tracking(memory_tracking)
316
+ return {} unless memory_tracking
317
+ memory_tracking.transform_values do |entries|
318
+ { read_entries: entries }
319
+ end
320
+ end
321
+ ```
322
+
323
+ 3. **Event-sourced sessions** - Use `SnapshotFromEvents.reconstruct(events)` which automatically generates v2.1.0 snapshots
324
+
325
+ ---
326
+
327
+ ## Important: Plugin Lifecycle Changes
328
+
329
+ ### Plugin State Persistence
330
+
331
+ **What Changed:**
332
+ - Plugins now have `snapshot_agent_state` and `restore_agent_state` methods
333
+ - SDK no longer has direct knowledge of plugin internals
334
+ - `memory_read_tracking` field replaced by generic `plugin_states`
335
+
336
+ **If You Have Custom Plugins:**
337
+
338
+ ```ruby
339
+ class MyPlugin < SwarmSDK::Plugin
340
+ # NEW - Snapshot your plugin's state
341
+ def snapshot_agent_state(agent_name)
342
+ {
343
+ custom_data: @storage[agent_name]&.to_h || {}
344
+ }
345
+ end
346
+
347
+ # NEW - Restore your plugin's state
348
+ def restore_agent_state(agent_name, state)
349
+ @storage[agent_name]&.restore(state[:custom_data])
350
+ end
351
+
352
+ # NEW - Get digest for change detection hooks
353
+ def get_tool_result_digest(agent_name:, tool_name:, path:)
354
+ return nil unless tool_name == :MyCustomRead
355
+ @storage[agent_name]&.digest_for(path)
356
+ end
357
+ end
358
+ ```
359
+
360
+ ### Plugin Configuration Decoupling
361
+
362
+ **What Changed:**
363
+ - SDK no longer knows about specific plugin configs
364
+ - Plugin configs stored in generic `@plugin_configs` hash
365
+ - Plugins handle their own YAML translation
366
+
367
+ **Agent::Definition Changes:**
368
+
369
+ ```ruby
370
+ # Accessing plugin configuration
371
+ definition.plugin_config(:memory) # Returns memory plugin config
372
+ definition.plugin_config(:custom) # Returns custom plugin config
373
+
374
+ # Generic storage for non-SDK keys
375
+ definition.plugin_configs # Hash of all plugin configs
376
+ ```
377
+
378
+ ---
379
+
380
+ ## New Features (No Migration Required)
381
+
382
+ These are additions that don't break existing code:
383
+
384
+ ### Observer Module
385
+
386
+ ```ruby
387
+ swarm = SwarmSDK.build do
388
+ agent :backend { ... }
389
+ agent :security_monitor { ... }
390
+
391
+ # NEW - Parallel agent execution
392
+ observer :security_monitor do
393
+ on :tool_call do |event|
394
+ next unless event[:tool_name] == "Bash"
395
+ "Check security of: #{event[:arguments][:command]}"
396
+ end
397
+ timeout 30
398
+ end
399
+ end
400
+ ```
401
+
402
+ ### Context Management DSL
403
+
404
+ ```ruby
405
+ agent :backend do
406
+ # NEW - Custom context warning handlers
407
+ context_management do
408
+ on :warning_60 do |ctx|
409
+ ctx.compress_tool_results(keep_recent: 15)
410
+ end
411
+
412
+ on :warning_80 do |ctx|
413
+ ctx.prune_old_messages(keep_recent: 20)
414
+ end
415
+ end
416
+ end
417
+ ```
418
+
419
+ ### Non-blocking Execution
420
+
421
+ ```ruby
422
+ # NEW - Async execution with cancellation
423
+ Sync do
424
+ task = swarm.execute("Build feature", wait: false)
425
+
426
+ # Cancel if needed
427
+ task.stop
428
+
429
+ # Wait for result
430
+ result = task.wait # Returns nil if cancelled
431
+ end
432
+ ```
433
+
434
+ ### Filtered Event Subscriptions
435
+
436
+ ```ruby
437
+ # NEW - Subscribe to specific events
438
+ LogCollector.subscribe(filter: { type: "tool_call", agent: :backend }) do |event|
439
+ puts "Backend called tool: #{event[:tool_name]}"
440
+ end
441
+ ```
442
+
443
+ ---
444
+
445
+ ## Testing Your Migration
446
+
447
+ ### 1. Check for Deprecated APIs
448
+
449
+ ```ruby
450
+ # Run this in your test suite
451
+ describe "Migration compatibility" do
452
+ it "uses new Chat API" do
453
+ agent = swarm.agent(:backend)
454
+
455
+ # These should work
456
+ expect(agent).to respond_to(:has_tool?)
457
+ expect(agent).to respond_to(:tool_names)
458
+ expect(agent).to respond_to(:model_id)
459
+
460
+ # These are gone (don't test for them)
461
+ # agent.tools.key? - removed
462
+ # agent.model.id - removed
463
+ end
464
+
465
+ it "uses new delegation names" do
466
+ expect(agent.has_tool?(:WorkWithDatabase)).to be true
467
+ expect(agent.has_tool?(:DelegateTaskToDatabase)).to be false
468
+ end
469
+ end
470
+ ```
471
+
472
+ ### 2. Verify Workflow Separation
473
+
474
+ ```ruby
475
+ describe "Workflow API" do
476
+ it "uses separate methods" do
477
+ # This should work
478
+ workflow = SwarmSDK.workflow do
479
+ node(:planning) { ... }
480
+ start_node :planning
481
+ end
482
+ expect(workflow).to be_a(SwarmSDK::Workflow)
483
+
484
+ # This should raise
485
+ expect {
486
+ SwarmSDK.build do
487
+ node(:planning) { ... } # ERROR!
488
+ end
489
+ }.to raise_error(SwarmSDK::ConfigurationError)
490
+ end
491
+ end
492
+ ```
493
+
494
+ ### 3. Test Snapshot Compatibility
495
+
496
+ ```ruby
497
+ describe "Snapshot format" do
498
+ it "generates v2.1.0 snapshots" do
499
+ snapshot = swarm.snapshot
500
+ expect(snapshot.version).to eq("2.1.0")
501
+ expect(snapshot.data[:metadata]).to be_present
502
+ expect(snapshot.data[:swarm]).to be_nil # Old key removed
503
+ end
504
+ end
505
+ ```
506
+
507
+ ---
508
+
509
+ ## Deprecation Timeline
510
+
511
+ - **v2.3.0** (This Release)
512
+ - Old APIs removed (no deprecation warnings)
513
+ - Migration required immediately
514
+
515
+ - **v2.4.0** (Future)
516
+ - No further breaking changes planned
517
+ - Focus on new features
518
+
519
+ ---
520
+
521
+ ## Getting Help
522
+
523
+ If you encounter issues during migration:
524
+
525
+ 1. **Check the CHANGELOG**: `docs/v2/CHANGELOG.swarm_sdk.md` has detailed explanations
526
+ 2. **Run tests**: `bundle exec rake swarm_sdk:test` to catch compatibility issues
527
+ 3. **Review examples**: `test/swarm_sdk/` contains comprehensive usage examples
528
+ 4. **Report issues**: https://github.com/parruda/claude-swarm/issues
529
+
530
+ ---
531
+
532
+ ## Summary Checklist
533
+
534
+ - [ ] Update delegation tool calls: `DelegateTaskTo*` → `WorkWith*`
535
+ - [ ] Update delegation parameters: `task:` → `message:`
536
+ - [ ] Update Chat API usage: `tools.key?` → `has_tool?`, etc.
537
+ - [ ] Separate workflows: `SwarmSDK.build` → `SwarmSDK.workflow` for node-based configs
538
+ - [ ] Update YAML: `swarm:` key for swarms, `workflow:` key for workflows
539
+ - [ ] Regenerate snapshots (v1.0.0 → v2.1.0)
540
+ - [ ] Update custom plugins with new lifecycle methods
541
+ - [ ] Test all changes with `bundle exec rake swarm_sdk:test`
@@ -112,8 +112,8 @@ snapshot.write_to_file("session.json")
112
112
  snapshot.write_to_file("session.json", pretty: false)
113
113
 
114
114
  # Access metadata
115
- snapshot.version # => "1.0.0"
116
- snapshot.type # => "swarm" or "node_orchestrator"
115
+ snapshot.version: 2.0.0"
116
+ snapshot.type # => "swarm" or "workflow"
117
117
  snapshot.snapshot_at # => "2025-01-03T14:30:00Z"
118
118
  snapshot.swarm_sdk_version # => "2.1.3"
119
119
  snapshot.agent_names # => ["backend", "database"]
@@ -121,7 +121,7 @@ snapshot.delegation_instance_names # => ["database@backend"]
121
121
 
122
122
  # Type checks
123
123
  snapshot.swarm? # => true
124
- snapshot.node_orchestrator? # => false
124
+ snapshot.workflow? # => false
125
125
  ```
126
126
 
127
127
  ### Loading Snapshots
@@ -137,7 +137,7 @@ json_string = redis.get("session:#{user_id}")
137
137
  snapshot = SwarmSDK::Snapshot.from_json(json_string)
138
138
 
139
139
  # From hash
140
- hash = { version: "1.0.0", type: "swarm", ... }
140
+ hash = { version: 2.0.0", type: "swarm", ... }
141
141
  snapshot = SwarmSDK::Snapshot.from_hash(hash)
142
142
  ```
143
143
 
@@ -616,7 +616,7 @@ result = swarm.restore(hash)
616
616
  result = swarm.restore(json_string)
617
617
  ```
618
618
 
619
- ### NodeOrchestrator Methods
619
+ ### Workflow Methods
620
620
 
621
621
  Same API as Swarm:
622
622
 
@@ -639,8 +639,8 @@ Snapshot.from_json(json_string) # => Snapshot
639
639
  Snapshot.from_hash(hash) # => Snapshot
640
640
 
641
641
  # Metadata accessors
642
- snapshot.version # => "1.0.0"
643
- snapshot.type # => "swarm" | "node_orchestrator"
642
+ snapshot.version: 2.0.0"
643
+ snapshot.type # => "swarm" | "workflow"
644
644
  snapshot.snapshot_at # => "2025-01-03T14:30:00Z"
645
645
  snapshot.swarm_sdk_version # => "2.1.3"
646
646
  snapshot.agent_names # => ["agent1", "agent2"]
@@ -648,7 +648,7 @@ snapshot.delegation_instance_names # => ["agent2@agent1"]
648
648
 
649
649
  # Type checks
650
650
  snapshot.swarm? # => true | false
651
- snapshot.node_orchestrator? # => true | false
651
+ snapshot.workflow? # => true | false
652
652
  ```
653
653
 
654
654
  ### SnapshotFromEvents Class
@@ -799,10 +799,10 @@ swarm.restore(snapshot)
799
799
  result = swarm.execute("Implement API endpoints using different pattern")
800
800
  ```
801
801
 
802
- ### NodeOrchestrator Workflows
802
+ ### Workflow Workflows
803
803
 
804
804
  ```ruby
805
- orchestrator = SwarmSDK::NodeOrchestrator.new(
805
+ orchestrator = SwarmSDK::Workflow.new(
806
806
  swarm_name: "Dev Workflow",
807
807
  agent_definitions: { planner: planner_def, coder: coder_def },
808
808
  nodes: { planning: planning_node, coding: coding_node },
@@ -819,7 +819,7 @@ snapshot.write_to_file("workflow_session.json")
819
819
  # === Later, new process ===
820
820
 
821
821
  # Restore and continue
822
- orchestrator = SwarmSDK::NodeOrchestrator.new(...) # Same config
822
+ orchestrator = SwarmSDK::Workflow.new(...) # Same config
823
823
  snapshot = SwarmSDK::Snapshot.from_file("workflow_session.json")
824
824
  orchestrator.restore(snapshot)
825
825
 
@@ -1283,7 +1283,7 @@ swarm2.execute("Read scratchpad://tasks/auth.md")
1283
1283
  # => Agent sees content from previous session
1284
1284
  ```
1285
1285
 
1286
- **Note**: NodeOrchestrator doesn't snapshot scratchpad because each node creates its own fresh scratchpad.
1286
+ **Note**: Workflow doesn't snapshot scratchpad because each node creates its own fresh scratchpad.
1287
1287
 
1288
1288
  ## Troubleshooting
1289
1289
 
@@ -1340,9 +1340,9 @@ result = swarm.restore(snapshot)
1340
1340
 
1341
1341
  ### Type Mismatch
1342
1342
 
1343
- **Problem**: `Snapshot type 'swarm' doesn't match orchestration type 'node_orchestrator'`
1343
+ **Problem**: `Snapshot type 'swarm' doesn't match orchestration type 'workflow'`
1344
1344
 
1345
- **Cause**: Trying to restore swarm snapshot into NodeOrchestrator (or vice versa)
1345
+ **Cause**: Trying to restore swarm snapshot into Workflow (or vice versa)
1346
1346
 
1347
1347
  **Solution**: Use correct orchestration type that matches snapshot
1348
1348
 
@@ -93,7 +93,7 @@ flowchart TB
93
93
  end
94
94
 
95
95
  subgraph "Node Workflows"
96
- NODE_ORCH["NodeOrchestrator<br/>(multi-stage execution)"]
96
+ NODE_ORCH["Workflow<br/>(multi-stage execution)"]
97
97
  NODE_CTX["NodeContext<br/>(goto_node, halt_workflow, skip_execution)"]
98
98
  TRANSFORMERS["Bash/Ruby Transformers<br/>(input/output transformation)"]
99
99
  MINI_SWARMS["Mini-Swarms<br/>(one per node)"]
@@ -318,7 +318,7 @@ Event occurs →
318
318
 
319
319
  ### 9. Node Workflow Flow
320
320
  ```
321
- NodeOrchestrator.execute →
321
+ Workflow.execute →
322
322
  Build execution order (topological sort) →
323
323
  For each node:
324
324
  Input transformer (Bash/Ruby) →
@@ -339,7 +339,7 @@ NodeOrchestrator.execute →
339
339
  - **AgentInitializer**: Complex 5-pass initialization (tools, MCP, delegation, hooks)
340
340
  - **ToolConfigurator**: Tool registration, creation, permissions wrapping
341
341
  - **McpConfigurator**: MCP client management, external tool integration
342
- - **NodeOrchestrator**: Multi-stage workflows with transformers
342
+ - **Workflow**: Multi-stage workflows with transformers
343
343
  - **Plugin System**: Extensibility framework (SwarmMemory uses this)
344
344
 
345
345
  ### SwarmCLI
@@ -100,7 +100,7 @@ Emitted once per agent when agents are initialized (lazy initialization).
100
100
  provider: "openai", # Provider name
101
101
  directory: "./backend", # Working directory
102
102
  system_prompt: "You are a backend dev...", # Full system prompt
103
- tools: [:Read, :Edit, :Bash, :DelegateTaskToFrontend], # Array of tool names
103
+ tools: [:Read, :Edit, :Bash, :WorkWithFrontend], # Array of tool names
104
104
  delegates_to: [:frontend], # Array of delegate agent names
105
105
  plugin_storages: { # Plugin storage info (optional)
106
106
  memory: {