Class: SwarmSDK::Agent::ToolRegistry
- Inherits:
-
Object
- Object
- SwarmSDK::Agent::ToolRegistry
- Defined in:
- lib/swarm_sdk/agent/tool_registry.rb
Overview
Per-agent tool registry managing available and active tools
Architecture
- Available tools: All tool instances the agent CAN use (registry)
- Active tools: Subset sent to LLM based on skill state
Thread Safety
Registry access is protected by Async::Semaphore for fiber-safe operations.
Defined Under Namespace
Classes: ToolEntry
Instance Attribute Summary collapse
-
#base_instance ⇒ Object
readonly
Unwrapped tool instance (for skill permission override).
-
#instance ⇒ Object
readonly
Tool instance (possibly wrapped with permissions).
-
#metadata ⇒ Object
readonly
Source-specific metadata.
-
#removable ⇒ Object
readonly
Can be deactivated by skills.
-
#source ⇒ Object
readonly
Tool source (:builtin, :delegation, :mcp, :plugin, :custom).
Instance Method Summary collapse
-
#active_tools(skill_state: nil, tool_configurator: nil, agent_definition: nil) ⇒ Hash{String => RubyLLM::Tool}
Get active tools based on skill state.
-
#get(name) ⇒ ToolEntry?
Get tool entry with metadata.
-
#has_tool?(name) ⇒ Boolean
Check if tool exists in registry.
-
#initialize ⇒ ToolRegistry
constructor
A new instance of ToolRegistry.
-
#non_removable_tool_names ⇒ Array<String>
Get all non-removable tool names.
-
#register(tool, base_tool: nil, source:, metadata: {}) ⇒ void
Register a tool in the available tools registry.
-
#tool_names ⇒ Array<String>
Get all available tool names.
-
#unregister(name) ⇒ ToolEntry?
Unregister a tool (for testing/cleanup).
Constructor Details
#initialize ⇒ ToolRegistry
Returns a new instance of ToolRegistry.
43 44 45 46 |
# File 'lib/swarm_sdk/agent/tool_registry.rb', line 43 def initialize @available_tools = {} # String name => ToolEntry @mutex = Async::Semaphore.new(1) # Fiber-safe mutex end |
Instance Attribute Details
#base_instance ⇒ Object (readonly)
Unwrapped tool instance (for skill permission override)
41 |
# File 'lib/swarm_sdk/agent/tool_registry.rb', line 41 ToolEntry = Data.define(:instance, :base_instance, :removable, :source, :metadata) |
#instance ⇒ Object (readonly)
Tool instance (possibly wrapped with permissions)
41 |
# File 'lib/swarm_sdk/agent/tool_registry.rb', line 41 ToolEntry = Data.define(:instance, :base_instance, :removable, :source, :metadata) |
#metadata ⇒ Object (readonly)
Source-specific metadata
41 |
# File 'lib/swarm_sdk/agent/tool_registry.rb', line 41 ToolEntry = Data.define(:instance, :base_instance, :removable, :source, :metadata) |
#removable ⇒ Object (readonly)
Can be deactivated by skills
41 |
# File 'lib/swarm_sdk/agent/tool_registry.rb', line 41 ToolEntry = Data.define(:instance, :base_instance, :removable, :source, :metadata) |
#source ⇒ Object (readonly)
Tool source (:builtin, :delegation, :mcp, :plugin, :custom)
41 |
# File 'lib/swarm_sdk/agent/tool_registry.rb', line 41 ToolEntry = Data.define(:instance, :base_instance, :removable, :source, :metadata) |
Instance Method Details
#active_tools(skill_state: nil, tool_configurator: nil, agent_definition: nil) ⇒ Hash{String => RubyLLM::Tool}
Get active tools based on skill state
Returns Hash of tool instances ready for RubyLLM::Chat.
Logic:
- If skill_state is nil: Return ALL available tools
- If skill_state restricts tools: Return skill's tools + non-removable tools
- Skill permissions are applied during activation (wrapping base_instance)
115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 |
# File 'lib/swarm_sdk/agent/tool_registry.rb', line 115 def active_tools(skill_state: nil, tool_configurator: nil, agent_definition: nil) @mutex.acquire do result = if skill_state&.restricts_tools? # Skill loaded with tool restriction - only skill's tools + non-removable filtered = {} # Always include non-removable tools (use wrapped instance) @available_tools.each do |name, entry| filtered[name] = entry.instance unless entry.removable end # Add requested tools from skill skill_state.tools.each do |name| entry = @available_tools[name.to_s] next unless entry # Check if skill has custom permissions for this tool = skill_state.(name) if && tool_configurator && agent_definition # Skill overrides permissions - wrap the BASE instance wrapped = tool_configurator.( entry.base_instance, , agent_definition, ) filtered[name.to_s] = wrapped else # No skill permission override - use registered instance filtered[name.to_s] = entry.instance end end filtered else # No skill OR skill doesn't restrict tools - all available tools @available_tools.transform_values(&:instance) end result end end |
#get(name) ⇒ ToolEntry?
Get tool entry with metadata
177 178 179 |
# File 'lib/swarm_sdk/agent/tool_registry.rb', line 177 def get(name) @available_tools[name.to_s] end |
#has_tool?(name) ⇒ Boolean
Check if tool exists in registry
162 163 164 |
# File 'lib/swarm_sdk/agent/tool_registry.rb', line 162 def has_tool?(name) @available_tools.key?(name.to_s) end |
#non_removable_tool_names ⇒ Array<String>
Get all non-removable tool names
184 185 186 |
# File 'lib/swarm_sdk/agent/tool_registry.rb', line 184 def non_removable_tool_names @available_tools.select { |_name, entry| !entry.removable }.keys end |
#register(tool, base_tool: nil, source:, metadata: {}) ⇒ void
This method returns an undefined value.
Register a tool in the available tools registry
68 69 70 71 72 73 74 75 76 77 78 79 80 81 |
# File 'lib/swarm_sdk/agent/tool_registry.rb', line 68 def register(tool, base_tool: nil, source:, metadata: {}) @mutex.acquire do # Infer removability from tool class removable = tool.respond_to?(:removable?) ? tool.removable? : true @available_tools[tool.name] = ToolEntry.new( instance: tool, base_instance: base_tool || tool, # If no base, use same instance removable: removable, source: source, metadata: , ) end end |
#tool_names ⇒ Array<String>
Get all available tool names
169 170 171 |
# File 'lib/swarm_sdk/agent/tool_registry.rb', line 169 def tool_names @available_tools.keys end |
#unregister(name) ⇒ ToolEntry?
Unregister a tool (for testing/cleanup)
87 88 89 90 91 |
# File 'lib/swarm_sdk/agent/tool_registry.rb', line 87 def unregister(name) @mutex.acquire do @available_tools.delete(name.to_s) end end |