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.
- checksums.yaml +4 -4
- data/{CHANGELOG.md → CHANGELOG.claude-swarm.md} +10 -0
- data/CLAUDE.md +346 -191
- data/decisions/2025-11-22-001-global-agent-registry.md +172 -0
- data/docs/v2/CHANGELOG.swarm_cli.md +20 -0
- data/docs/v2/CHANGELOG.swarm_memory.md +146 -1
- data/docs/v2/CHANGELOG.swarm_sdk.md +433 -10
- data/docs/v2/README.md +20 -5
- data/docs/v2/guides/complete-tutorial.md +95 -9
- data/docs/v2/guides/getting-started.md +10 -8
- data/docs/v2/guides/memory-adapters.md +41 -0
- data/docs/v2/guides/migrating-to-2.x.md +746 -0
- data/docs/v2/guides/plugins.md +52 -5
- data/docs/v2/guides/rails-integration.md +6 -0
- data/docs/v2/guides/snapshots.md +14 -14
- data/docs/v2/guides/swarm-memory.md +2 -13
- data/docs/v2/reference/architecture-flow.md +3 -3
- data/docs/v2/reference/cli.md +0 -1
- data/docs/v2/reference/configuration_reference.md +300 -0
- data/docs/v2/reference/event_payload_structures.md +27 -5
- data/docs/v2/reference/ruby-dsl.md +614 -18
- data/docs/v2/reference/swarm_memory_technical_details.md +7 -29
- data/docs/v2/reference/yaml.md +172 -54
- data/examples/snapshot_demo.rb +2 -2
- data/lib/claude_swarm/mcp_generator.rb +8 -21
- data/lib/claude_swarm/orchestrator.rb +8 -1
- data/lib/claude_swarm/version.rb +1 -1
- data/lib/swarm_cli/commands/run.rb +2 -2
- data/lib/swarm_cli/config_loader.rb +11 -11
- data/lib/swarm_cli/formatters/human_formatter.rb +0 -33
- data/lib/swarm_cli/interactive_repl.rb +2 -2
- data/lib/swarm_cli/ui/icons.rb +0 -23
- data/lib/swarm_cli/version.rb +1 -1
- data/lib/swarm_memory/adapters/filesystem_adapter.rb +11 -34
- data/lib/swarm_memory/core/semantic_index.rb +10 -2
- data/lib/swarm_memory/core/storage.rb +7 -2
- data/lib/swarm_memory/dsl/memory_config.rb +37 -0
- data/lib/swarm_memory/integration/sdk_plugin.rb +201 -28
- data/lib/swarm_memory/optimization/defragmenter.rb +1 -1
- data/lib/swarm_memory/prompts/memory_researcher.md.erb +0 -1
- data/lib/swarm_memory/tools/load_skill.rb +0 -1
- data/lib/swarm_memory/tools/memory_edit.rb +2 -1
- data/lib/swarm_memory/tools/memory_read.rb +1 -1
- data/lib/swarm_memory/version.rb +1 -1
- data/lib/swarm_memory.rb +8 -6
- data/lib/swarm_sdk/agent/builder.rb +58 -0
- data/lib/swarm_sdk/agent/chat.rb +527 -1061
- data/lib/swarm_sdk/agent/{chat → chat_helpers}/context_tracker.rb +13 -88
- data/lib/swarm_sdk/agent/chat_helpers/event_emitter.rb +204 -0
- data/lib/swarm_sdk/agent/{chat → chat_helpers}/hook_integration.rb +108 -46
- data/lib/swarm_sdk/agent/chat_helpers/instrumentation.rb +78 -0
- data/lib/swarm_sdk/agent/chat_helpers/llm_configuration.rb +267 -0
- data/lib/swarm_sdk/agent/{chat → chat_helpers}/logging_helpers.rb +3 -3
- data/lib/swarm_sdk/agent/chat_helpers/serialization.rb +83 -0
- data/lib/swarm_sdk/agent/{chat → chat_helpers}/system_reminder_injector.rb +11 -13
- data/lib/swarm_sdk/agent/chat_helpers/system_reminders.rb +79 -0
- data/lib/swarm_sdk/agent/chat_helpers/token_tracking.rb +146 -0
- data/lib/swarm_sdk/agent/context.rb +1 -2
- data/lib/swarm_sdk/agent/definition.rb +66 -154
- data/lib/swarm_sdk/agent/llm_instrumentation_middleware.rb +4 -2
- data/lib/swarm_sdk/agent/system_prompt_builder.rb +161 -0
- data/lib/swarm_sdk/agent_registry.rb +146 -0
- data/lib/swarm_sdk/builders/base_builder.rb +488 -0
- data/lib/swarm_sdk/concerns/cleanupable.rb +39 -0
- data/lib/swarm_sdk/concerns/snapshotable.rb +67 -0
- data/lib/swarm_sdk/concerns/validatable.rb +55 -0
- data/lib/swarm_sdk/config.rb +302 -0
- data/lib/swarm_sdk/configuration/parser.rb +373 -0
- data/lib/swarm_sdk/configuration/translator.rb +255 -0
- data/lib/swarm_sdk/configuration.rb +77 -546
- data/lib/swarm_sdk/context_compactor/token_counter.rb +2 -6
- data/lib/swarm_sdk/context_compactor.rb +6 -11
- data/lib/swarm_sdk/context_management/builder.rb +128 -0
- data/lib/swarm_sdk/context_management/context.rb +328 -0
- data/lib/swarm_sdk/custom_tool_registry.rb +226 -0
- data/lib/swarm_sdk/defaults.rb +196 -0
- data/lib/swarm_sdk/events_to_messages.rb +18 -0
- data/lib/swarm_sdk/hooks/adapter.rb +3 -3
- data/lib/swarm_sdk/hooks/shell_executor.rb +4 -2
- data/lib/swarm_sdk/log_collector.rb +179 -29
- data/lib/swarm_sdk/log_stream.rb +29 -0
- data/lib/swarm_sdk/models.json +4333 -1
- data/lib/swarm_sdk/models.rb +43 -2
- data/lib/swarm_sdk/node_context.rb +1 -1
- data/lib/swarm_sdk/observer/builder.rb +81 -0
- data/lib/swarm_sdk/observer/config.rb +45 -0
- data/lib/swarm_sdk/observer/manager.rb +236 -0
- data/lib/swarm_sdk/patterns/agent_observer.rb +160 -0
- data/lib/swarm_sdk/plugin.rb +95 -5
- data/lib/swarm_sdk/result.rb +52 -0
- data/lib/swarm_sdk/snapshot.rb +6 -6
- data/lib/swarm_sdk/snapshot_from_events.rb +13 -2
- data/lib/swarm_sdk/state_restorer.rb +136 -151
- data/lib/swarm_sdk/state_snapshot.rb +65 -100
- data/lib/swarm_sdk/swarm/agent_initializer.rb +181 -137
- data/lib/swarm_sdk/swarm/builder.rb +44 -578
- data/lib/swarm_sdk/swarm/executor.rb +213 -0
- data/lib/swarm_sdk/swarm/hook_triggers.rb +151 -0
- data/lib/swarm_sdk/swarm/logging_callbacks.rb +341 -0
- data/lib/swarm_sdk/swarm/mcp_configurator.rb +7 -4
- data/lib/swarm_sdk/swarm/tool_configurator.rb +58 -140
- data/lib/swarm_sdk/swarm.rb +203 -683
- data/lib/swarm_sdk/tools/bash.rb +14 -8
- data/lib/swarm_sdk/tools/delegate.rb +61 -43
- data/lib/swarm_sdk/tools/edit.rb +8 -13
- data/lib/swarm_sdk/tools/glob.rb +12 -4
- data/lib/swarm_sdk/tools/grep.rb +7 -0
- data/lib/swarm_sdk/tools/multi_edit.rb +15 -11
- data/lib/swarm_sdk/tools/path_resolver.rb +51 -2
- data/lib/swarm_sdk/tools/read.rb +16 -18
- data/lib/swarm_sdk/tools/registry.rb +122 -10
- data/lib/swarm_sdk/tools/stores/scratchpad_storage.rb +9 -5
- data/lib/swarm_sdk/tools/stores/storage.rb +0 -6
- data/lib/swarm_sdk/tools/todo_write.rb +7 -0
- data/lib/swarm_sdk/tools/web_fetch.rb +20 -17
- data/lib/swarm_sdk/tools/write.rb +8 -13
- data/lib/swarm_sdk/version.rb +1 -1
- data/lib/swarm_sdk/{node → workflow}/agent_config.rb +1 -1
- data/lib/swarm_sdk/workflow/builder.rb +192 -0
- data/lib/swarm_sdk/workflow/executor.rb +497 -0
- data/lib/swarm_sdk/{node/builder.rb → workflow/node_builder.rb} +7 -5
- data/lib/swarm_sdk/{node → workflow}/transformer_executor.rb +5 -3
- data/lib/swarm_sdk/{node_orchestrator.rb → workflow.rb} +152 -456
- data/lib/swarm_sdk.rb +294 -108
- data/rubocop/cop/security/no_reflection_methods.rb +1 -1
- data/swarm_cli.gemspec +1 -1
- data/swarm_memory.gemspec +8 -3
- data/swarm_sdk.gemspec +6 -4
- data/team_full.yml +124 -320
- metadata +42 -14
- data/lib/swarm_memory/chat_extension.rb +0 -34
- data/lib/swarm_memory/tools/memory_multi_edit.rb +0 -281
- data/lib/swarm_sdk/providers/openai_with_responses.rb +0 -589
- /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`
|