Class: Rubino::Tools::Registry
- Inherits:
-
Object
- Object
- Rubino::Tools::Registry
- Defined in:
- lib/rubino/tools/registry.rb
Overview
Singleton registry for all available tools. Tools register themselves and can be looked up by name.
Class Method Summary collapse
-
.all ⇒ Object
Returns all registered tools.
-
.enabled_tools ⇒ Object
Returns only enabled tools based on configuration AND the active mode (Modes.current).
-
.find(name) ⇒ Object
Finds a tool by name.
-
.instance ⇒ Object
Returns the singleton instance.
-
.register(tool) ⇒ Object
Registers a tool instance.
-
.register_defaults! ⇒ Object
Registers all default tools.
-
.reset! ⇒ Object
Clears all registered tools (useful for testing).
-
.tool_definitions ⇒ Object
Returns tool definitions for LLM registration.
-
.unregister(name) ⇒ Object
Removes a tool by name (#182): stopping an MCP server must also drop its MCPToolWrapper instances, or the model keeps seeing tools whose client is gone and every call fails.
Class Method Details
.all ⇒ Object
Returns all registered tools
34 35 36 |
# File 'lib/rubino/tools/registry.rb', line 34 def all @tools.values end |
.enabled_tools ⇒ Object
Returns only enabled tools based on configuration AND the active mode (Modes.current). Plan mode pares the registry down to its read-only whitelist so the model literally has no ‘edit`/`shell`/ `git` definition in the request — it can’t even propose a mutating tool call. Yolo and default leave everything through; their difference is on the approval path, not the registry.
44 45 46 47 48 49 50 51 52 53 54 |
# File 'lib/rubino/tools/registry.rb', line 44 def enabled_tools config = Rubino.configuration disabled = config.agent_disabled_toolsets @tools.values.reject do |tool| disabled.include?(tool.name) || !tool_enabled_in_config?(tool, config) || !Rubino::Modes.allows_tool?(tool.name) || !aux_dependency_satisfied?(tool, config) end end |
.find(name) ⇒ Object
Finds a tool by name
22 23 24 |
# File 'lib/rubino/tools/registry.rb', line 22 def find(name) @tools[name.to_s] end |
.instance ⇒ Object
Returns the singleton instance
12 13 14 |
# File 'lib/rubino/tools/registry.rb', line 12 def instance self end |
.register(tool) ⇒ Object
Registers a tool instance
17 18 19 |
# File 'lib/rubino/tools/registry.rb', line 17 def register(tool) @tools[tool.name] = tool end |
.register_defaults! ⇒ Object
Registers all default tools
67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 |
# File 'lib/rubino/tools/registry.rb', line 67 def register_defaults! register(Rubino::Tools::ReadTool.new) register(Rubino::Tools::SummarizeFileTool.new) register(Rubino::Tools::WriteTool.new) register(Rubino::Tools::EditTool.new) register(Rubino::Tools::MultiEditTool.new) register(Rubino::Tools::GrepTool.new) register(Rubino::Tools::GlobTool.new) register(Rubino::Tools::GitTool.new) register(Rubino::Tools::GitHubTool.new) register(Rubino::Tools::ShellTool.new) register(Rubino::Tools::ShellOutputTool.new) register(Rubino::Tools::ShellTailTool.new) register(Rubino::Tools::ShellInputTool.new) register(Rubino::Tools::ShellKillTool.new) register(Rubino::Tools::RubyTool.new) # Structured test-runner (issue #101): auto-detects rspec/minitest/ # rake, prefers `bundle exec` (falls back when the bundle is broken), # and returns pass/fail counts + parsed failing examples instead of # the raw toolchain firehose the `shell` tool would dump. register(Rubino::Tools::TestTool.new) register(Rubino::Tools::PatchTool.new) register(Rubino::Tools::WebFetchTool.new) register(Rubino::Tools::WebSearchTool.new) register(Rubino::Tools::QuestionTool.new) register(Rubino::Tools::TodoTool.new) register(Rubino::Tools::MemoryTool.new) register(Rubino::Tools::SessionSearchTool.new) register(Rubino::Tools::AttachFileTool.new) # Gated, on-demand attachment reader (#6): converts a document to # Markdown IN-PROCESS (Rubino::Documents) and frames it as untrusted # data, so attachment bytes enter context only when the model asks. register(Rubino::Tools::ReadAttachmentTool.new) register(Rubino::Tools::VisionTool.new) # Skills tool: loads a skill body (Level 2) and bundled files # (Level 3) on demand. Gated like any tool via `tools.skill`. register(Rubino::Skills::SkillTool.new) # Delegation tool: lets the model spawn an isolated subagent run. # Gated like any other tool (tools.task in config). Subagents now KEEP # it (scoped nesting, S1) — a subagent can spawn its own subagents, # bounded by the depth / fan-out / global caps in BackgroundTasks#reserve. register(Rubino::Tools::TaskTool.new) # Companion poll/stop tools for background subagents (the default # path of `task`). Mirror the shell_output/shell_kill trio. Gated by # the same tools.task key — disabling delegation disables these too. register(Rubino::Tools::TaskResultTool.new) register(Rubino::Tools::TaskStopTool.new) # ask_parent: the child->parent escalation tool. Registered globally # (gated by the same tools.task key), but Definition#resolved_tools # exposes it ONLY to subagents — a top-level agent has no parent to ask. register(Rubino::Tools::AskParentTool.new) # steer / probe (S2/S3): the MODEL-callable parent->child channels, # registered for ALL agents and AUTHORIZED by ownership at call time # (a node with no children just gets a "not your child" error). NOT on # any strip list — scoping happens inside the tool, not in the registry. register(Rubino::Tools::SteerTool.new) register(Rubino::Tools::ProbeTool.new) # answer_child (S4): the MODEL-callable answer to a child's ask_parent, # the agent-parent twin of the human /reply. Registered for ALL agents # and AUTHORIZED by ownership at call time (like steer/probe). NOT on # any strip list — a node with no waiting child just gets a not-waiting # / not-yours error. register(Rubino::Tools::AnswerChildTool.new) end |
.reset! ⇒ Object
Clears all registered tools (useful for testing)
62 63 64 |
# File 'lib/rubino/tools/registry.rb', line 62 def reset! @tools = {} end |
.tool_definitions ⇒ Object
Returns tool definitions for LLM registration
57 58 59 |
# File 'lib/rubino/tools/registry.rb', line 57 def tool_definitions enabled_tools.map(&:to_tool_definition) end |
.unregister(name) ⇒ Object
Removes a tool by name (#182): stopping an MCP server must also drop its MCPToolWrapper instances, or the model keeps seeing tools whose client is gone and every call fails.
29 30 31 |
# File 'lib/rubino/tools/registry.rb', line 29 def unregister(name) @tools.delete(name.to_s) end |