claude_swarm 1.0.10 → 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} +3 -0
- data/CLAUDE.md +0 -1
- data/decisions/2025-11-22-001-global-agent-registry.md +172 -0
- data/docs/v2/CHANGELOG.swarm_cli.md +12 -0
- data/docs/v2/CHANGELOG.swarm_memory.md +139 -0
- data/docs/v2/CHANGELOG.swarm_sdk.md +249 -1
- data/docs/v2/README.md +15 -5
- data/docs/v2/guides/complete-tutorial.md +93 -7
- data/docs/v2/guides/getting-started.md +3 -1
- data/docs/v2/guides/memory-adapters.md +41 -0
- data/docs/v2/guides/{migrating-to-2.3.md → migrating-to-2.x.md} +213 -8
- data/docs/v2/guides/plugins.md +52 -5
- data/docs/v2/guides/rails-integration.md +6 -0
- data/docs/v2/guides/swarm-memory.md +2 -13
- 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 +26 -4
- data/docs/v2/reference/ruby-dsl.md +457 -4
- data/docs/v2/reference/swarm_memory_technical_details.md +7 -29
- data/docs/v2/reference/yaml.md +2 -2
- data/lib/claude_swarm/mcp_generator.rb +1 -1
- data/lib/claude_swarm/orchestrator.rb +8 -1
- data/lib/claude_swarm/version.rb +1 -1
- data/lib/swarm_cli/version.rb +1 -1
- 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 +120 -27
- 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 +7 -5
- data/lib/swarm_sdk/agent/chat.rb +1 -1
- data/lib/swarm_sdk/agent/chat_helpers/context_tracker.rb +4 -0
- data/lib/swarm_sdk/agent/chat_helpers/hook_integration.rb +1 -1
- data/lib/swarm_sdk/agent/chat_helpers/llm_configuration.rb +38 -4
- data/lib/swarm_sdk/agent/chat_helpers/logging_helpers.rb +2 -2
- data/lib/swarm_sdk/agent/chat_helpers/system_reminder_injector.rb +3 -5
- data/lib/swarm_sdk/agent/chat_helpers/token_tracking.rb +48 -0
- data/lib/swarm_sdk/agent/context.rb +1 -2
- data/lib/swarm_sdk/agent/definition.rb +3 -3
- data/lib/swarm_sdk/agent/system_prompt_builder.rb +1 -1
- data/lib/swarm_sdk/agent_registry.rb +146 -0
- data/lib/swarm_sdk/builders/base_builder.rb +91 -12
- data/lib/swarm_sdk/config.rb +302 -0
- data/lib/swarm_sdk/configuration/parser.rb +22 -2
- data/lib/swarm_sdk/configuration.rb +13 -4
- data/lib/swarm_sdk/context_compactor/token_counter.rb +2 -6
- data/lib/swarm_sdk/custom_tool_registry.rb +226 -0
- data/lib/swarm_sdk/hooks/adapter.rb +3 -3
- data/lib/swarm_sdk/hooks/shell_executor.rb +4 -3
- data/lib/swarm_sdk/models.json +4333 -1
- data/lib/swarm_sdk/models.rb +43 -2
- data/lib/swarm_sdk/plugin.rb +2 -2
- data/lib/swarm_sdk/result.rb +52 -0
- data/lib/swarm_sdk/swarm/agent_initializer.rb +1 -1
- data/lib/swarm_sdk/swarm/hook_triggers.rb +1 -0
- data/lib/swarm_sdk/swarm/logging_callbacks.rb +1 -0
- data/lib/swarm_sdk/swarm/tool_configurator.rb +18 -4
- data/lib/swarm_sdk/swarm.rb +76 -13
- data/lib/swarm_sdk/tools/bash.rb +7 -9
- data/lib/swarm_sdk/tools/glob.rb +5 -5
- data/lib/swarm_sdk/tools/read.rb +8 -8
- data/lib/swarm_sdk/tools/stores/scratchpad_storage.rb +4 -3
- data/lib/swarm_sdk/tools/web_fetch.rb +20 -18
- data/lib/swarm_sdk/version.rb +1 -1
- data/lib/swarm_sdk/workflow/builder.rb +49 -0
- data/lib/swarm_sdk/workflow/node_builder.rb +4 -2
- data/lib/swarm_sdk/workflow/transformer_executor.rb +4 -3
- data/lib/swarm_sdk.rb +261 -105
- data/swarm_cli.gemspec +1 -1
- data/swarm_memory.gemspec +8 -3
- data/swarm_sdk.gemspec +4 -4
- data/team_full.yml +104 -300
- metadata +9 -5
- data/lib/swarm_memory/tools/memory_multi_edit.rb +0 -281
- /data/lib/swarm_memory/{errors.rb → error.rb} +0 -0
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: f29b35b5b6dadfd9638907704a3bc204ebd35ba3c7e95c4bfafb0ff7ed1f44ed
|
|
4
|
+
data.tar.gz: e6e005f4dc472961daaa02f094c8d044a76018628a0e7d07ea6ed55ab0d830b6
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 0bd8988be66a9514cc80732a5d66b52fc737f44f67b1949271230fbb083e3a8fcc95a515b1bc5fd2688b51449cc04e5e162c70f66de14531075f4f6606bd2002
|
|
7
|
+
data.tar.gz: 5aa8a44f9dc5bd935b380ab59654e2e382726a977ea404ebe8c20401df29536425f50619857ae87a6b3ee4674377b83fa3a211b73fc232bc2ff1ce7af61df128
|
data/CLAUDE.md
CHANGED
|
@@ -146,7 +146,6 @@ swarm = SwarmSDK.load_file("swarm.yml")
|
|
|
146
146
|
- **MemoryWrite** - Create/update memory entries with semantic indexing
|
|
147
147
|
- **MemoryRead** - Retrieve memory entries with optional semantic search
|
|
148
148
|
- **MemoryEdit** - Edit specific memory entries
|
|
149
|
-
- **MemoryMultiEdit** - Batch edit multiple entries
|
|
150
149
|
- **MemoryDelete** - Remove memory entries
|
|
151
150
|
- **MemoryGrep** - Search memory content with regex
|
|
152
151
|
- **MemoryGlob** - Find memory entries by pattern
|
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
# Decision: Global Agent Registry for SwarmSDK
|
|
2
|
+
|
|
3
|
+
**Date:** 2025-11-22
|
|
4
|
+
**Status:** Implemented
|
|
5
|
+
|
|
6
|
+
## Context
|
|
7
|
+
|
|
8
|
+
Users wanted the ability to declare agents in separate files and reference them by name in swarm definitions. This promotes:
|
|
9
|
+
- Code reuse across multiple swarms
|
|
10
|
+
- Separation of concerns (agent definitions vs swarm composition)
|
|
11
|
+
- Cleaner organization for large projects
|
|
12
|
+
|
|
13
|
+
## Decision
|
|
14
|
+
|
|
15
|
+
Implement a global `AgentRegistry` that stores agent configuration blocks and allows referencing them in `SwarmSDK.build` and `SwarmSDK.workflow` definitions.
|
|
16
|
+
|
|
17
|
+
### API Design
|
|
18
|
+
|
|
19
|
+
```ruby
|
|
20
|
+
# Register agent in separate file (e.g., agents/backend.rb)
|
|
21
|
+
SwarmSDK.agent :backend do
|
|
22
|
+
model "claude-sonnet-4"
|
|
23
|
+
description "Backend developer"
|
|
24
|
+
system_prompt "You build APIs"
|
|
25
|
+
tools :Read, :Edit, :Bash
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
# Reference in swarm definition
|
|
29
|
+
SwarmSDK.build do
|
|
30
|
+
name "Dev Team"
|
|
31
|
+
lead :backend
|
|
32
|
+
|
|
33
|
+
agent :backend # Lookup from registry
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
# Extend with overrides
|
|
37
|
+
SwarmSDK.build do
|
|
38
|
+
name "Extended Team"
|
|
39
|
+
lead :backend
|
|
40
|
+
|
|
41
|
+
agent :backend do
|
|
42
|
+
tools :CustomTool # Adds to registry tools
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
### Key Design Decisions
|
|
48
|
+
|
|
49
|
+
1. **Proc Storage (not Lambda)**
|
|
50
|
+
- Procs work naturally with `instance_eval` DSL semantics
|
|
51
|
+
- Flexible arity handling suits DSL blocks
|
|
52
|
+
- Blocks passed to methods are already Procs
|
|
53
|
+
|
|
54
|
+
2. **Class with Class Methods (not Singleton)**
|
|
55
|
+
- Simpler than full Singleton pattern
|
|
56
|
+
- Easier to test with `AgentRegistry.clear`
|
|
57
|
+
- Class methods feel natural for global registry
|
|
58
|
+
|
|
59
|
+
3. **Duplicate Registration Error**
|
|
60
|
+
- Raises `ArgumentError` if registering same name twice
|
|
61
|
+
- Prevents accidental overwrites across files
|
|
62
|
+
- User must call `SwarmSDK.clear_agent_registry!` to reset
|
|
63
|
+
|
|
64
|
+
4. **Registry Takes Precedence**
|
|
65
|
+
- When `agent :name do ... end` is called and agent is registered:
|
|
66
|
+
- Registry config is applied first
|
|
67
|
+
- Block becomes overrides (additive)
|
|
68
|
+
- Promotes DRY principle - registry is source of truth
|
|
69
|
+
|
|
70
|
+
5. **No Thread Safety**
|
|
71
|
+
- SwarmSDK uses fiber-based concurrency (Async gem)
|
|
72
|
+
- Single-threaded execution means no race conditions
|
|
73
|
+
- Documented limitation for multi-threaded environments
|
|
74
|
+
|
|
75
|
+
6. **Delegation is Swarm-Specific (Best Practice)**
|
|
76
|
+
- Don't set `delegates_to` in registry agent definitions
|
|
77
|
+
- Delegation targets depend on which agents exist in each swarm
|
|
78
|
+
- Set `delegates_to` as an override when referencing the agent in a swarm
|
|
79
|
+
- This makes agents truly reusable across different swarm compositions
|
|
80
|
+
|
|
81
|
+
## Implementation
|
|
82
|
+
|
|
83
|
+
### New Files
|
|
84
|
+
- `lib/swarm_sdk/agent_registry.rb` - AgentRegistry class
|
|
85
|
+
|
|
86
|
+
### Modified Files
|
|
87
|
+
- `lib/swarm_sdk.rb` - Added `SwarmSDK.agent` and `SwarmSDK.clear_agent_registry!`
|
|
88
|
+
- `lib/swarm_sdk/builders/base_builder.rb` - Added registry lookup to `#agent` method
|
|
89
|
+
|
|
90
|
+
### Test Coverage
|
|
91
|
+
- 26 tests covering:
|
|
92
|
+
- Registry class methods (register, get, registered?, names, clear)
|
|
93
|
+
- Module methods (agent, clear_agent_registry!)
|
|
94
|
+
- Registry lookup in Swarm and Workflow builders
|
|
95
|
+
- Registry + overrides behavior
|
|
96
|
+
- Multiple swarms sharing registry
|
|
97
|
+
- Error handling
|
|
98
|
+
- Edge cases
|
|
99
|
+
|
|
100
|
+
## Alternatives Considered
|
|
101
|
+
|
|
102
|
+
1. **Explicit Syntax (`agent :name, from: :registry`)**
|
|
103
|
+
- Rejected: Too verbose for common use case
|
|
104
|
+
- Current behavior is intuitive (no args = lookup)
|
|
105
|
+
|
|
106
|
+
2. **Warning on Shadow**
|
|
107
|
+
- Rejected: Too noisy, users might ignore
|
|
108
|
+
- Error-free operation preferred
|
|
109
|
+
|
|
110
|
+
3. **Thread-Safe Implementation**
|
|
111
|
+
- Rejected: Unnecessary complexity for fiber-based model
|
|
112
|
+
- The definitions should be eager loaded in the app that is using the SDK
|
|
113
|
+
- Documented limitation acceptable
|
|
114
|
+
|
|
115
|
+
## Enhancement: Workflow Node Registry Fallback
|
|
116
|
+
|
|
117
|
+
Added automatic agent resolution in workflow nodes. When `agent(:name)` is called inside a node:
|
|
118
|
+
|
|
119
|
+
1. First checks if agent is defined at workflow level
|
|
120
|
+
2. If not found, checks the global AgentRegistry
|
|
121
|
+
3. If still not found, raises ConfigurationError
|
|
122
|
+
|
|
123
|
+
This allows powerful patterns like:
|
|
124
|
+
|
|
125
|
+
```ruby
|
|
126
|
+
# agents/shared.rb
|
|
127
|
+
SwarmSDK.agent :shared_analyzer do
|
|
128
|
+
model "claude-sonnet-4"
|
|
129
|
+
description "Shared analyzer"
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
# workflow.rb
|
|
133
|
+
SwarmSDK.workflow do
|
|
134
|
+
name "Pipeline"
|
|
135
|
+
start_node :analyze
|
|
136
|
+
|
|
137
|
+
# No need to define shared_analyzer here!
|
|
138
|
+
|
|
139
|
+
node :analyze do
|
|
140
|
+
agent(:shared_analyzer) # Auto-resolved from registry
|
|
141
|
+
end
|
|
142
|
+
end
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
The fallback also resolves delegation targets:
|
|
146
|
+
|
|
147
|
+
```ruby
|
|
148
|
+
node :process do
|
|
149
|
+
agent(:main_agent).delegates_to(:helper_agent)
|
|
150
|
+
# Both resolved from registry
|
|
151
|
+
end
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
### Implementation
|
|
155
|
+
- Modified `Workflow::Builder#build_workflow` to call `resolve_missing_agents_from_registry`
|
|
156
|
+
- Added `collect_referenced_agents` to gather all agents from nodes (including delegates_to)
|
|
157
|
+
- Resolution happens at build time before agent definitions are built
|
|
158
|
+
|
|
159
|
+
## Consequences
|
|
160
|
+
|
|
161
|
+
### Positive
|
|
162
|
+
- Clean separation of agent definitions from swarm composition
|
|
163
|
+
- Easy code reuse across swarms
|
|
164
|
+
- Intuitive API that matches existing DSL patterns
|
|
165
|
+
- Works with both Swarm and Workflow builders
|
|
166
|
+
- Workflow nodes automatically resolve agents from registry
|
|
167
|
+
- Delegation targets also auto-resolve from registry
|
|
168
|
+
|
|
169
|
+
### Negative
|
|
170
|
+
- Global state (mitigated by clear method for testing)
|
|
171
|
+
- Not thread-safe (documented limitation)
|
|
172
|
+
- Must require agent files before building swarms
|
|
@@ -5,6 +5,18 @@ All notable changes to SwarmCLI will be documented in this file.
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
+
## [2.1.7]
|
|
9
|
+
|
|
10
|
+
### Dependencies
|
|
11
|
+
|
|
12
|
+
- Updated `swarm_sdk` to `~> 2.5.1`
|
|
13
|
+
|
|
14
|
+
## [2.1.6]
|
|
15
|
+
- Bump SDK and memory gem versions
|
|
16
|
+
|
|
17
|
+
## [2.1.5]
|
|
18
|
+
- Bump SDK gem version
|
|
19
|
+
|
|
8
20
|
## [2.1.4]
|
|
9
21
|
|
|
10
22
|
### Changed
|
|
@@ -5,6 +5,145 @@ All notable changes to SwarmMemory will be documented in this file.
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
+
## [2.2.3]
|
|
9
|
+
|
|
10
|
+
### Fixed
|
|
11
|
+
|
|
12
|
+
- **Hybrid search weight configuration**: Fixed bug where `semantic_weight` and `keyword_weight` from config weren't being passed to SemanticIndex
|
|
13
|
+
- **Issue**: SDK plugin extracted weights from config but didn't pass them to Storage/SemanticIndex
|
|
14
|
+
- **Fix**: Storage now accepts and passes weight parameters through to SemanticIndex
|
|
15
|
+
- **Impact**: Per-agent weight configuration now works correctly (was only used for logging before)
|
|
16
|
+
- **Files**: `lib/swarm_memory/core/storage.rb:23-35`, `lib/swarm_memory/integration/sdk_plugin.rb:130-150`
|
|
17
|
+
|
|
18
|
+
- **YAML config with string keys**: Fixed bug where Hash configs with string keys would fail adapter initialization
|
|
19
|
+
- **Issue**: Adapters expect symbol keyword arguments, but YAML configs have string keys
|
|
20
|
+
- **Fix**: Symbolize adapter option keys in create_storage for Hash configs
|
|
21
|
+
- **Impact**: YAML configurations now work correctly with all adapters
|
|
22
|
+
- **Files**: `lib/swarm_memory/integration/sdk_plugin.rb:113-118`
|
|
23
|
+
|
|
24
|
+
### Added
|
|
25
|
+
|
|
26
|
+
- **DSL methods for weights**: Added `semantic_weight()` and `keyword_weight()` methods to MemoryConfig
|
|
27
|
+
- **Before**: `option(:semantic_weight, 0.8)`
|
|
28
|
+
- **After**: `semantic_weight(0.8)` (cleaner syntax, consistent with `directory()` and `mode()`)
|
|
29
|
+
- **Backward compatible**: `option()` method still works
|
|
30
|
+
- **Files**: `lib/swarm_memory/dsl/memory_config.rb:87-122`
|
|
31
|
+
|
|
32
|
+
### Changed
|
|
33
|
+
|
|
34
|
+
- **Automatic semantic fallback**: Hybrid search now falls back to pure semantic scoring when keyword_score is 0
|
|
35
|
+
- **Before**: semantic=0.92, keyword=0.0 → final=0.46 (penalized by 50/50 weights)
|
|
36
|
+
- **After**: semantic=0.92, keyword=0.0 → final=0.92 (no penalty when no tag matches)
|
|
37
|
+
- **Rationale**: Prevents excellent semantic matches from being penalized when there's no keyword/tag overlap
|
|
38
|
+
- **Impact**: Improved recall for queries with no tag matches
|
|
39
|
+
- **Files**: `lib/swarm_memory/core/semantic_index.rb:195-201`
|
|
40
|
+
|
|
41
|
+
## [2.2.2]
|
|
42
|
+
|
|
43
|
+
### Dependencies
|
|
44
|
+
|
|
45
|
+
- Updated `swarm_sdk` to `~> 2.5.1`
|
|
46
|
+
|
|
47
|
+
## [2.2.1]
|
|
48
|
+
|
|
49
|
+
### Fixed
|
|
50
|
+
|
|
51
|
+
- **MemoryEdit metadata preservation**: MemoryEdit now preserves all metadata when updating entry content
|
|
52
|
+
- **Issue**: MemoryEdit was only preserving title, losing tags, confidence, domain, and other metadata
|
|
53
|
+
- **Fix**: Pass `metadata: entry.metadata` to storage.write to preserve all existing metadata
|
|
54
|
+
- **Impact**: Prevents metadata loss when editing memory entries
|
|
55
|
+
- **Files**: `lib/swarm_memory/tools/memory_edit.rb:169`
|
|
56
|
+
|
|
57
|
+
## [2.2.0]
|
|
58
|
+
|
|
59
|
+
### Added
|
|
60
|
+
|
|
61
|
+
- **Per-Adapter Threshold Configuration**: Semantic search thresholds can now be configured per-adapter in YAML
|
|
62
|
+
- **Fallback chain**: `adapter_config → ENV var → hardcoded_default` (config wins over ENV)
|
|
63
|
+
- **Supported threshold keys**:
|
|
64
|
+
- `discovery_threshold` (default: 0.35) - Main similarity threshold for normal queries
|
|
65
|
+
- `discovery_threshold_short` (default: 0.25) - Threshold for queries with <10 words
|
|
66
|
+
- `adaptive_word_cutoff` (default: 10) - Word count to switch between thresholds
|
|
67
|
+
- `semantic_weight` (default: 0.5) - Hybrid search semantic weight
|
|
68
|
+
- `keyword_weight` (default: 0.5) - Hybrid search keyword weight
|
|
69
|
+
- **Use cases**: Per-agent threshold tuning, adapter-specific optimization (pgvector vs FAISS), multi-tenant customization
|
|
70
|
+
- **Backward compatible**: ENV vars still work as deployment-level override
|
|
71
|
+
- **Zero config required**: Sensible defaults work out of the box
|
|
72
|
+
- **Example**:
|
|
73
|
+
```yaml
|
|
74
|
+
memory:
|
|
75
|
+
adapter: multi_bank_postgres
|
|
76
|
+
agent_id: researcher
|
|
77
|
+
discovery_threshold: 0.5
|
|
78
|
+
discovery_threshold_short: 0.3
|
|
79
|
+
semantic_weight: 0.6
|
|
80
|
+
```
|
|
81
|
+
- **Files**: `lib/swarm_memory/integration/sdk_plugin.rb`
|
|
82
|
+
- **Tests**: 4 new tests validating threshold extraction and fallback behavior
|
|
83
|
+
|
|
84
|
+
- **Custom Adapter Support**: SwarmMemory now fully supports custom storage adapters
|
|
85
|
+
- **Custom adapter options pass-through**: All YAML config keys (except `directory`, `adapter`, `mode`) are now passed to adapter constructor
|
|
86
|
+
- **Example configuration**:
|
|
87
|
+
```yaml
|
|
88
|
+
memory:
|
|
89
|
+
adapter: multi_bank_postgres
|
|
90
|
+
agent_id: business_consultant
|
|
91
|
+
default_bank: working
|
|
92
|
+
banks:
|
|
93
|
+
working: { max_size: 10485760 }
|
|
94
|
+
long_term: { max_size: 52428800 }
|
|
95
|
+
bank_access:
|
|
96
|
+
archive: read_only
|
|
97
|
+
```
|
|
98
|
+
- **Enables**: PostgreSQL, MySQL, Redis, S3, and any custom storage backend
|
|
99
|
+
- **Files**: `lib/swarm_memory/integration/sdk_plugin.rb:290-310`
|
|
100
|
+
- **Tests**: 2 new tests for custom adapter option pass-through
|
|
101
|
+
|
|
102
|
+
### Changed
|
|
103
|
+
|
|
104
|
+
- **BREAKING: `storage_enabled?` renamed to `memory_configured?`** in SDKPlugin
|
|
105
|
+
- **Improved logic**: Filesystem adapter requires `directory`, custom adapters can use any configuration keys
|
|
106
|
+
- **Better validation**: Custom adapters are recognized as valid even without `directory` key
|
|
107
|
+
- **Adapter validation**: Each adapter validates its own requirements during initialization
|
|
108
|
+
- **No backward compatibility**: `storage_enabled?` method removed entirely (breaking change)
|
|
109
|
+
- **Migration**: Update any code calling `plugin.storage_enabled?()` to use `plugin.memory_configured?()`
|
|
110
|
+
- **Files**: `lib/swarm_memory/integration/sdk_plugin.rb:202-235`
|
|
111
|
+
- **Tests**: 3 new tests for custom adapter recognition
|
|
112
|
+
|
|
113
|
+
### Removed
|
|
114
|
+
|
|
115
|
+
- **MemoryMultiEdit tool**: Removed in favor of simpler MemoryEdit tool
|
|
116
|
+
- **Rationale**: Memory entries are small (typically < 100 lines), making batch edits unnecessary
|
|
117
|
+
- **Alternative**: Use multiple `MemoryEdit` calls for sequential edits
|
|
118
|
+
- **Simplification**: Reduces API complexity and LLM error surface (JSON parameter was error-prone)
|
|
119
|
+
- **Files removed**: `lib/swarm_memory/tools/memory_multi_edit.rb`
|
|
120
|
+
- **Tool count**: Memory tools reduced from 8 to 7 (MemoryWrite, MemoryRead, MemoryEdit, MemoryDelete, MemoryGlob, MemoryGrep, MemoryDefrag)
|
|
121
|
+
|
|
122
|
+
### Benefits
|
|
123
|
+
|
|
124
|
+
- ✅ **Eliminates need for monkey patches** when building custom adapters
|
|
125
|
+
- ✅ **Makes SwarmMemory fully extensible** for any storage backend
|
|
126
|
+
- ✅ **Per-agent threshold tuning** for optimal semantic search accuracy
|
|
127
|
+
- ✅ **Multi-tenant customization** with per-adapter configuration
|
|
128
|
+
- ✅ **Clearer semantics** (memory vs storage terminology)
|
|
129
|
+
- ✅ **Better error messages** (adapters validate themselves)
|
|
130
|
+
|
|
131
|
+
## [2.1.7]
|
|
132
|
+
|
|
133
|
+
### Dependencies
|
|
134
|
+
|
|
135
|
+
- Updated `ruby_llm_swarm` to `~> 1.9.5`
|
|
136
|
+
|
|
137
|
+
## [2.1.6]
|
|
138
|
+
- Fix files included in the gem
|
|
139
|
+
|
|
140
|
+
## [2.1.5]
|
|
141
|
+
|
|
142
|
+
### Fixed
|
|
143
|
+
- **Fixed Zeitwerk naming convention**: Renamed `lib/swarm_memory/errors.rb` to `lib/swarm_memory/error.rb` to match the `SwarmMemory::Error` constant it defines
|
|
144
|
+
- Fixes `Zeitwerk::Loader.eager_load_all` failures with "uninitialized constant SwarmMemory::Errors" errors
|
|
145
|
+
- Properly follows Zeitwerk file naming conventions where `error.rb` defines `Error` class
|
|
146
|
+
|
|
8
147
|
## [2.1.4]
|
|
9
148
|
|
|
10
149
|
### Changed
|
|
@@ -5,6 +5,254 @@ All notable changes to SwarmSDK will be documented in this file.
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
+
## [2.5.1]
|
|
9
|
+
|
|
10
|
+
### Dependencies
|
|
11
|
+
|
|
12
|
+
- Updated `ruby_llm_swarm-mcp` to `~> 0.8.1`
|
|
13
|
+
|
|
14
|
+
## [2.5.0]
|
|
15
|
+
|
|
16
|
+
### Added
|
|
17
|
+
|
|
18
|
+
- **Custom Tool Registration**: Simple API for registering custom tools without creating full plugins
|
|
19
|
+
- **`SwarmSDK.register_tool(ToolClass)`**: Register with inferred name (e.g., `WeatherTool` → `:Weather`)
|
|
20
|
+
- **`SwarmSDK.register_tool(:Name, ToolClass)`**: Register with explicit name
|
|
21
|
+
- **`SwarmSDK.custom_tool_registered?(:Name)`**: Check if tool is registered
|
|
22
|
+
- **`SwarmSDK.custom_tools`**: List all registered custom tool names
|
|
23
|
+
- **`SwarmSDK.unregister_tool(:Name)`**: Remove a registered tool
|
|
24
|
+
- **`SwarmSDK.clear_custom_tools!`**: Clear all registered tools (useful for testing)
|
|
25
|
+
- **Tool lookup order**: Plugin tools → Custom tools → Built-in tools
|
|
26
|
+
- **Context support**: Tools can declare `creation_requirements` for agent context (`:agent_name`, `:directory`)
|
|
27
|
+
- **Name consistency**: `NamedToolWrapper` ensures registered name is used for tool lookup
|
|
28
|
+
- **Validation**: Prevents overriding built-in tools or plugin tools
|
|
29
|
+
- **Use case**: Simple, stateless tools that don't need plugin lifecycle hooks or storage
|
|
30
|
+
- **Example**:
|
|
31
|
+
```ruby
|
|
32
|
+
class WeatherTool < RubyLLM::Tool
|
|
33
|
+
description "Get weather for a city"
|
|
34
|
+
param :city, type: "string", required: true
|
|
35
|
+
|
|
36
|
+
def execute(city:)
|
|
37
|
+
"Weather in #{city}: Sunny"
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
SwarmSDK.register_tool(WeatherTool)
|
|
42
|
+
|
|
43
|
+
SwarmSDK.build do
|
|
44
|
+
name "Assistant"
|
|
45
|
+
lead :helper
|
|
46
|
+
|
|
47
|
+
agent :helper do
|
|
48
|
+
model "claude-sonnet-4"
|
|
49
|
+
description "Weather assistant"
|
|
50
|
+
system_prompt "You help with weather"
|
|
51
|
+
tools :Weather # Use the registered tool
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
```
|
|
55
|
+
- **Files**: `lib/swarm_sdk/custom_tool_registry.rb`, `lib/swarm_sdk.rb`, `lib/swarm_sdk/swarm/tool_configurator.rb`
|
|
56
|
+
- **Tests**: 32 comprehensive tests (unit + integration)
|
|
57
|
+
|
|
58
|
+
### Changed
|
|
59
|
+
|
|
60
|
+
- **BREAKING: Plugin API method renamed**: `storage_enabled?` → `memory_configured?` in Plugin base class
|
|
61
|
+
- **Rationale**: "memory" is the user-facing concept, "storage" is internal implementation detail
|
|
62
|
+
- **Better semantics**: "Is memory configured?" vs "Is storage enabled?"
|
|
63
|
+
- **No backward compatibility**: `storage_enabled?` method removed entirely (breaking change)
|
|
64
|
+
- **Impact**: Custom plugins implementing `storage_enabled?` must rename to `memory_configured?`
|
|
65
|
+
- **Migration**: Update plugin classes to implement `memory_configured?` instead of `storage_enabled?`
|
|
66
|
+
- **Files**: `lib/swarm_sdk/plugin.rb:142-148`
|
|
67
|
+
- **Updated callers**:
|
|
68
|
+
- `lib/swarm_sdk/swarm/agent_initializer.rb:572`
|
|
69
|
+
- `lib/swarm_sdk/agent/system_prompt_builder.rb:151`
|
|
70
|
+
- `lib/swarm_sdk/swarm/tool_configurator.rb:270`
|
|
71
|
+
- **Tests**: All plugin-related tests updated
|
|
72
|
+
|
|
73
|
+
## [2.4.6]
|
|
74
|
+
- Use a fork of ruby_llm-mcp that requires ruby_llm_swarm instead of ruby_llm
|
|
75
|
+
|
|
76
|
+
## [2.4.5]
|
|
77
|
+
|
|
78
|
+
### Fixed
|
|
79
|
+
|
|
80
|
+
- **Context Window Tracking Bug**: Fixed model lookup using wrong source for context window data
|
|
81
|
+
- **Issue**: Changes to `models.json` had no effect on context window tracking - SDK always returned 0%
|
|
82
|
+
- **Root cause**: `fetch_real_model_info` was using `RubyLLM.models.find()` instead of `SwarmSDK::Models.find()`
|
|
83
|
+
- **Fix**: Changed model lookup to use `SwarmSDK::Models.find()` first, falling back to `RubyLLM.models.find()`
|
|
84
|
+
- **Impact**: Context window percentage now correctly calculated from SwarmSDK's models.json
|
|
85
|
+
- **Files**: `lib/swarm_sdk/agent/chat_helpers/llm_configuration.rb`
|
|
86
|
+
|
|
87
|
+
### Added
|
|
88
|
+
|
|
89
|
+
- **Per-Agent Context Breakdown**: Real-time and historical context usage metrics per agent
|
|
90
|
+
- **`Swarm#context_breakdown`**: Returns live context metrics for all agents including:
|
|
91
|
+
- Token counts: `input_tokens`, `output_tokens`, `total_tokens`, `cached_tokens`, `cache_creation_tokens`, `effective_input_tokens`
|
|
92
|
+
- Context limits: `context_limit`, `usage_percentage`, `tokens_remaining`
|
|
93
|
+
- Cost metrics: `input_cost`, `output_cost`, `total_cost`
|
|
94
|
+
- **`Result#per_agent_usage`**: Extracts per-agent usage from execution logs (for historical analysis)
|
|
95
|
+
- **`swarm_stop` event enhancement**: Now includes `per_agent_usage` field with complete breakdown
|
|
96
|
+
- **Use cases**: Monitor token consumption, track costs per agent, identify context-heavy agents
|
|
97
|
+
- **Example**:
|
|
98
|
+
```ruby
|
|
99
|
+
breakdown = swarm.context_breakdown
|
|
100
|
+
breakdown[:backend]
|
|
101
|
+
# => {
|
|
102
|
+
# input_tokens: 15000,
|
|
103
|
+
# output_tokens: 5000,
|
|
104
|
+
# total_tokens: 20000,
|
|
105
|
+
# cached_tokens: 2000,
|
|
106
|
+
# context_limit: 200000,
|
|
107
|
+
# usage_percentage: 10.0,
|
|
108
|
+
# tokens_remaining: 180000,
|
|
109
|
+
# input_cost: 0.045,
|
|
110
|
+
# output_cost: 0.075,
|
|
111
|
+
# total_cost: 0.12
|
|
112
|
+
# }
|
|
113
|
+
```
|
|
114
|
+
- **Files**: `lib/swarm_sdk/swarm.rb`, `lib/swarm_sdk/result.rb`, `lib/swarm_sdk/swarm/hook_triggers.rb`, `lib/swarm_sdk/swarm/logging_callbacks.rb`
|
|
115
|
+
|
|
116
|
+
- **Cumulative Cost Tracking in TokenTracking**: New methods for calculating conversation costs
|
|
117
|
+
- **`cumulative_input_cost`**: Calculate total input cost based on tokens and model pricing
|
|
118
|
+
- **`cumulative_output_cost`**: Calculate total output cost based on tokens and model pricing
|
|
119
|
+
- **`cumulative_total_cost`**: Sum of input and output costs
|
|
120
|
+
- **Pricing source**: Uses `@real_model_info.pricing` from SwarmSDK's models.json
|
|
121
|
+
- **Files**: `lib/swarm_sdk/agent/chat_helpers/token_tracking.rb`
|
|
122
|
+
|
|
123
|
+
- **ModelInfo Class**: Wrapper class for model data with method access
|
|
124
|
+
- **`SwarmSDK::Models::ModelInfo`**: Replaces raw Hash returns from `Models.find()`
|
|
125
|
+
- **Attributes**: `id`, `name`, `provider`, `family`, `context_window`, `max_output_tokens`, `knowledge_cutoff`, `modalities`, `capabilities`, `pricing`, `metadata`
|
|
126
|
+
- **Files**: `lib/swarm_sdk/models.rb`
|
|
127
|
+
|
|
128
|
+
### Tests
|
|
129
|
+
|
|
130
|
+
- **28 new tests** covering:
|
|
131
|
+
- `TokenTracking` cost methods (24 tests): context_limit, cumulative costs, pricing edge cases
|
|
132
|
+
- `Swarm#context_breakdown` (5 tests): structure, metrics, delegation instances, lazy initialization
|
|
133
|
+
|
|
134
|
+
## [2.4.4]
|
|
135
|
+
|
|
136
|
+
### Added
|
|
137
|
+
|
|
138
|
+
- **Environment Variable Interpolation Control**: New `env_interpolation` setting to disable YAML variable interpolation
|
|
139
|
+
- **Global config**: `SwarmSDK.configure { |c| c.env_interpolation = false }`
|
|
140
|
+
- **Environment variable**: `SWARM_SDK_ENV_INTERPOLATION=false`
|
|
141
|
+
- **Per-load override**: `SwarmSDK.load(yaml, env_interpolation: false)` or `SwarmSDK.load_file(path, env_interpolation: false)`
|
|
142
|
+
- **Priority order**: per-load parameter > global config > environment variable > default (true)
|
|
143
|
+
- **Use cases**:
|
|
144
|
+
- Testing YAML files without setting environment variables
|
|
145
|
+
- Loading configs where `${...}` syntax should be preserved literally
|
|
146
|
+
- Security: preventing accidental environment variable exposure
|
|
147
|
+
- **Example**:
|
|
148
|
+
```ruby
|
|
149
|
+
# Disable globally
|
|
150
|
+
SwarmSDK.configure do |config|
|
|
151
|
+
config.env_interpolation = false
|
|
152
|
+
end
|
|
153
|
+
|
|
154
|
+
# Disable for specific load
|
|
155
|
+
swarm = SwarmSDK.load_file("config.yml", env_interpolation: false)
|
|
156
|
+
```
|
|
157
|
+
- **Files**: `lib/swarm_sdk/config.rb`, `lib/swarm_sdk/configuration.rb`, `lib/swarm_sdk/configuration/parser.rb`, `lib/swarm_sdk.rb`
|
|
158
|
+
- **Tests**: Comprehensive tests in `config_test.rb` and `configuration_test.rb`
|
|
159
|
+
|
|
160
|
+
## [2.4.3]
|
|
161
|
+
|
|
162
|
+
### Added
|
|
163
|
+
|
|
164
|
+
- **Global Agent Registry**: Declare agents in separate files and reference them by name across swarms
|
|
165
|
+
- **`SwarmSDK.agent(:name) { ... }`**: Register agents globally for reuse across multiple swarms
|
|
166
|
+
- **`SwarmSDK.clear_agent_registry!`**: Clear all registrations (useful for testing)
|
|
167
|
+
- **Registry lookup in builders**: `agent :name` (no block) fetches from global registry
|
|
168
|
+
- **Registry + overrides**: `agent :name do ... end` applies registry config then override block
|
|
169
|
+
- **Duplicate registration error**: Raises `ArgumentError` if registering same name twice
|
|
170
|
+
- **Workflow node auto-resolution**: Agents referenced in nodes automatically resolve from registry
|
|
171
|
+
- Checks workflow-level definitions first, then falls back to global registry
|
|
172
|
+
- Includes delegation targets (`delegates_to`) in auto-resolution
|
|
173
|
+
- **Best practice**: Don't set `delegates_to` in registry—delegation is swarm-specific. Set it as an override in each swarm.
|
|
174
|
+
- **Use case**: Define agents once in separate files, compose into multiple swarms without duplication
|
|
175
|
+
- **Example**:
|
|
176
|
+
```ruby
|
|
177
|
+
# agents/backend.rb
|
|
178
|
+
SwarmSDK.agent :backend do
|
|
179
|
+
model "claude-sonnet-4"
|
|
180
|
+
description "Backend developer"
|
|
181
|
+
tools :Read, :Edit, :Bash
|
|
182
|
+
end
|
|
183
|
+
|
|
184
|
+
# swarm.rb
|
|
185
|
+
SwarmSDK.build do
|
|
186
|
+
name "Dev Team"
|
|
187
|
+
lead :backend
|
|
188
|
+
agent :backend # Pulls from registry
|
|
189
|
+
end
|
|
190
|
+
|
|
191
|
+
# workflow.rb - agents auto-resolve in nodes
|
|
192
|
+
SwarmSDK.workflow do
|
|
193
|
+
name "Pipeline"
|
|
194
|
+
start_node :build
|
|
195
|
+
node(:build) { agent(:backend) } # Auto-resolved from registry
|
|
196
|
+
end
|
|
197
|
+
```
|
|
198
|
+
- **Files**: `lib/swarm_sdk/agent_registry.rb`, `lib/swarm_sdk.rb`, `lib/swarm_sdk/builders/base_builder.rb`, `lib/swarm_sdk/workflow/builder.rb`
|
|
199
|
+
- **Tests**: 32 comprehensive tests in `test/swarm_sdk/agent_registry_test.rb`
|
|
200
|
+
|
|
201
|
+
## [2.4.2]
|
|
202
|
+
|
|
203
|
+
### Fixed
|
|
204
|
+
|
|
205
|
+
- **Duplicate event emission bug**: Fixed agent_stop and agent_step events being emitted twice
|
|
206
|
+
- Root cause: `setup_logging` was being called twice during agent initialization
|
|
207
|
+
- First call in `agent_initializer.rb` when `LogStream.emitter` was set
|
|
208
|
+
- Second call in `emit_retroactive_agent_start_events` via `setup_logging_for_all_agents`
|
|
209
|
+
- Fix: Made `ContextTracker#setup_logging` idempotent with `@logging_setup` guard
|
|
210
|
+
- Prevents duplicate callback registration on `on_end_message`, `on_tool_result`, and `on_tool_call`
|
|
211
|
+
|
|
212
|
+
### Added
|
|
213
|
+
|
|
214
|
+
- **Event deduplication tests**: Comprehensive test suite to prevent regression
|
|
215
|
+
- `test_agent_stop_event_not_duplicated` - Ensures agent_stop emitted exactly once
|
|
216
|
+
- `test_agent_step_event_not_duplicated` - Ensures agent_step emitted exactly once per tool response
|
|
217
|
+
- `test_tool_call_event_not_duplicated` - Ensures tool_call emitted exactly once per invocation
|
|
218
|
+
- `test_tool_result_event_not_duplicated` - Ensures tool_result emitted exactly once
|
|
219
|
+
- `test_setup_logging_idempotency` - Verifies idempotent behavior across multiple executions
|
|
220
|
+
- `test_comprehensive_event_counts_*` - Validates exact event counts for various scenarios
|
|
221
|
+
|
|
222
|
+
### Dependencies
|
|
223
|
+
|
|
224
|
+
- Updated `ruby_llm_swarm` to `~> 1.9.5`
|
|
225
|
+
- Added `openssl` (`~> 3.3.2`) dependency
|
|
226
|
+
|
|
227
|
+
## [2.4.1]
|
|
228
|
+
- Fix gemspec issues
|
|
229
|
+
|
|
230
|
+
## [2.4.0]
|
|
231
|
+
|
|
232
|
+
### Breaking Changes
|
|
233
|
+
|
|
234
|
+
- **Centralized Configuration System**: Unified all configuration into `SwarmSDK::Config`
|
|
235
|
+
- **New API**: `SwarmSDK.config` replaces `SwarmSDK.settings`
|
|
236
|
+
- **Removed**: `SwarmSDK::Settings` class removed entirely
|
|
237
|
+
- **Removed**: `SwarmSDK.settings` method removed
|
|
238
|
+
- **Removed**: `SwarmSDK.reset_settings!` → use `SwarmSDK.reset_config!`
|
|
239
|
+
- **Removed**: Tool constants (DEFAULT_TIMEOUT_MS, MAX_OUTPUT_LENGTH, etc.)
|
|
240
|
+
- **API key proxying**: All API keys automatically proxy to `RubyLLM.config`
|
|
241
|
+
- **Override all defaults**: Every constant in Defaults module can now be overridden at runtime
|
|
242
|
+
- **Priority**: explicit value → ENV variable → Defaults module constant
|
|
243
|
+
- **Lazy ENV loading**: Thread-safe with double-check locking
|
|
244
|
+
- **Migration**:
|
|
245
|
+
- `SwarmSDK.settings.allow_filesystem_tools` → `SwarmSDK.config.allow_filesystem_tools`
|
|
246
|
+
- `SwarmSDK.reset_settings!` → `SwarmSDK.reset_config!`
|
|
247
|
+
- Tool constants → `SwarmSDK.config.*` methods (e.g., `SwarmSDK.config.bash_command_timeout`)
|
|
248
|
+
|
|
249
|
+
### Fixed
|
|
250
|
+
|
|
251
|
+
- **Base URL Configuration Bug**: Custom provider contexts now properly use configured API keys
|
|
252
|
+
- Previously: `configure_provider_base_url` read ENV directly, ignoring `RubyLLM.config`
|
|
253
|
+
- Now: Uses `SwarmSDK.config.openai_api_key` and other configured values
|
|
254
|
+
- Better error messages when API keys are missing for non-local endpoints
|
|
255
|
+
|
|
8
256
|
## [2.3.0]
|
|
9
257
|
|
|
10
258
|
### Breaking Changes
|
|
@@ -271,7 +519,7 @@ old[:metadata] = old.delete(:swarm)
|
|
|
271
519
|
- **Documentation**: Complete guide in `docs/v2/guides/snapshots.md` with examples and comparisons
|
|
272
520
|
|
|
273
521
|
- **System-Wide Filesystem Tools Control**: Global security setting to disable filesystem tools across all agents
|
|
274
|
-
- **`SwarmSDK.
|
|
522
|
+
- **`SwarmSDK.config.allow_filesystem_tools`** - Global setting to enable/disable filesystem tools (default: true)
|
|
275
523
|
- **Environment variable**: `SWARM_SDK_ALLOW_FILESYSTEM_TOOLS` - Set via environment for production deployments
|
|
276
524
|
- **Parameter override**: `allow_filesystem_tools:` parameter in `SwarmSDK.build`, `load`, and `load_file`
|
|
277
525
|
- **Filesystem tools**: Read, Write, Edit, MultiEdit, Grep, Glob, Bash
|