Class: Tools::Registry
- Inherits:
-
Object
- Object
- Tools::Registry
- Defined in:
- lib/tools/registry.rb
Overview
Constant Summary collapse
- STANDARD_TOOLS =
Standard tools available to every session unless filtered out by Session#granted_tools.
[Tools::Bash, Tools::Read, Tools::Write, Tools::Edit, Tools::WebGet, Tools::Think, Tools::ViewMessages, Tools::SearchMessages].freeze
- ALWAYS_GRANTED_TOOLS =
Tools that bypass Session#granted_tools filtering — the agent’s reasoning depends on them regardless of task scope.
[Tools::Think].freeze
- STANDARD_TOOLS_BY_NAME =
Name-to-class mapping for granted-tools filtering.
STANDARD_TOOLS.index_by(&:tool_name).freeze
Instance Attribute Summary collapse
-
#tools ⇒ Hash{String => Class, Object}
readonly
Registered tools keyed by name.
Class Method Summary collapse
-
.build(session:, shell_session:) ⇒ Registry
Builds a registry appropriate for the given session: standard tools filtered through Session#granted_tools, plus spawn tools for main sessions or
mark_goal_completedfor sub-agents, plus any tools exposed by configured MCP servers. -
.tool_classes_for(session) ⇒ Array<Class<Tools::Base>>
Resolves the ordered tool-class list for a session: granted standard tools (or all of them when
granted_toolsis nil), plus spawn tools for main sessions ormark_goal_completedfor sub-agents.
Instance Method Summary collapse
-
#any? ⇒ Boolean
Whether any tools are registered.
-
#execute(name, input, tool_use_id: nil) ⇒ String, Hash
Execute a tool by name.
-
#initialize(context: {}) ⇒ Registry
constructor
A new instance of Registry.
-
#register(tool) ⇒ void
Register a tool class or instance.
-
#registered?(name) ⇒ Boolean
Whether a tool with the given name is registered.
-
#schemas ⇒ Array<Hash>
Returns tool schemas for the Anthropic API.
-
#truncation_threshold(name) ⇒ Integer?
Returns the truncation threshold for a tool, or
nilif the tool opts out of truncation (e.g. read_file tool has its own pagination).
Constructor Details
#initialize(context: {}) ⇒ Registry
Returns a new instance of Registry.
91 92 93 94 |
# File 'lib/tools/registry.rb', line 91 def initialize(context: {}) @tools = {} @context = context end |
Instance Attribute Details
#tools ⇒ Hash{String => Class, Object} (readonly)
Returns registered tools keyed by name.
88 89 90 |
# File 'lib/tools/registry.rb', line 88 def tools @tools end |
Class Method Details
.build(session:, shell_session:) ⇒ Registry
Builds a registry appropriate for the given session: standard tools filtered through Session#granted_tools, plus spawn tools for main sessions or mark_goal_completed for sub-agents, plus any tools exposed by configured MCP servers.
MCP registration warnings are emitted as system messages so both the user (in verbose mode) and the LLM see them.
40 41 42 43 44 45 46 47 48 49 50 |
# File 'lib/tools/registry.rb', line 40 def build(session:, shell_session:) registry = new(context: {shell_session: shell_session, session: session}) tool_classes_for(session).each { |tool| registry.register(tool) } Mcp::ClientManager.shared.register_tools(registry).each do || Events::Bus.emit(Events::SystemMessage.new(content: , session_id: session.id)) end registry end |
.tool_classes_for(session) ⇒ Array<Class<Tools::Base>>
Resolves the ordered tool-class list for a session: granted standard tools (or all of them when granted_tools is nil), plus spawn tools for main sessions or mark_goal_completed for sub-agents. MCP tools are excluded — they are dynamic and registered separately by build. Single source of truth for build, Session#tool_schemas, and the system-prompt section assemblers.
61 62 63 64 65 66 67 68 69 70 71 |
# File 'lib/tools/registry.rb', line 61 def tool_classes_for(session) tools = granted_standard_tools(session).dup if session.sub_agent? tools.push(Tools::MarkGoalCompleted) else tools.push(Tools::SpawnSubagent, Tools::SpawnSpecialist, Tools::OpenIssue) end tools end |
Instance Method Details
#any? ⇒ Boolean
Returns whether any tools are registered.
161 162 163 |
# File 'lib/tools/registry.rb', line 161 def any? @tools.any? end |
#execute(name, input, tool_use_id: nil) ⇒ String, Hash
Execute a tool by name. Classes are instantiated with the registry’s context; instances are called directly. The enclosing tool_use_id is merged into the context when provided so tools that need to reference their own invoking tool_call (e.g. SpawnSubagent persisting spawn_tool_use_id on the child session) can read it via a named kwarg in their initializer.
134 135 136 137 138 139 |
# File 'lib/tools/registry.rb', line 134 def execute(name, input, tool_use_id: nil) tool = @tools.fetch(name) { raise UnknownToolError, "Unknown tool: #{name}" } context = tool_use_id ? @context.merge(tool_use_id: tool_use_id) : @context instance = tool.is_a?(Class) ? tool.new(**context) : tool instance.execute(input) end |
#register(tool) ⇒ void
This method returns an undefined value.
Register a tool class or instance. Must respond to tool_name and schema.
99 100 101 |
# File 'lib/tools/registry.rb', line 99 def register(tool) @tools[tool.tool_name] = tool end |
#registered?(name) ⇒ Boolean
Returns whether a tool with the given name is registered.
156 157 158 |
# File 'lib/tools/registry.rb', line 156 def registered?(name) @tools.key?(name) end |
#schemas ⇒ Array<Hash>
Returns tool schemas for the Anthropic API. The last schema is annotated with cache_control so the API caches the entire tools prefix (tools are evaluated first in cache prefix order).
114 115 116 117 118 119 |
# File 'lib/tools/registry.rb', line 114 def schemas default = Anima::Settings.tool_timeout result = @tools.values.map { |tool| inject_timeout(resolve_schema(tool), default) } result.last[:cache_control] = {type: "ephemeral"} result end |
#truncation_threshold(name) ⇒ Integer?
Returns the truncation threshold for a tool, or nil if the tool opts out of truncation (e.g. read_file tool has its own pagination). MCP tools and other duck-typed instances use the default threshold.
147 148 149 150 151 152 |
# File 'lib/tools/registry.rb', line 147 def truncation_threshold(name) tool = @tools[name] return tool.truncation_threshold if tool&.respond_to?(:truncation_threshold) Anima::Settings.max_tool_response_chars end |