Module: Protege::ToolScoped
- Extended by:
- ActiveSupport::Concern
- Included in:
- Persona
- Defined in:
- app/models/concerns/protege/tool_scoped.rb
Overview
Per-persona tool scoping — mixed into Persona to bound which tools an agent may use.
A persona's effective tools are the code-declared grant (the ceiling, set by the ClassMethods#tools
macro) minus the operator's disabled_tool_ids override, and never wider than the grant. Two layers,
deliberately different in reach:
- The grant lives on a
class_attributeso it survives Active Record's schema-loading reloads (the same reasonPersona._display_nameis one). Unlike the resolver chains — per-subclass +@ivar+s that never inherit — the grant inherits down the STI tree, so a base persona narrows a whole family's ceiling unless a subclass declares its own. A nil grant means "every registered tool", so an unconfigured persona keeps the full catalogue (the pre-scoping behaviour). disabled_tool_idsis a dashboard-editable JSON array on the row (text column; SQLite has no native JSON type), normalised to a clean string array so it is never nil. It can only subtract from the grant, never add to it.
#available_tools resolves both layers against the live registry, so a stale grant or disabled id — naming a tool since deleted from the code — is simply skipped rather than conjuring or breaking a tool.
Instance Method Summary collapse
-
#available_tool_ids ⇒ Array<Symbol>
The ids of this persona's effective tools — a convenience over #available_tools for UI and tests.
-
#available_tools ⇒ Array<Class>
Return the tool classes this persona may currently use — its effective, scoped catalogue.
Instance Method Details
#available_tool_ids ⇒ Array<Symbol>
The ids of this persona's effective tools — a convenience over #available_tools for UI and tests.
74 75 76 |
# File 'app/models/concerns/protege/tool_scoped.rb', line 74 def available_tool_ids available_tools.map(&:id) end |
#available_tools ⇒ Array<Class>
Return the tool classes this persona may currently use — its effective, scoped catalogue.
Computed as one filter over the live registry (+ToolMixin.registered+): drop anything the operator
has switched off in disabled_tool_ids, then keep only what the subclass's grant permits (or
everything, when the grant is nil). Iterating the registry rather than the grant means a grant id
with no matching registered tool is simply skipped — a stale scope can never conjure or break a tool.
62 63 64 65 66 67 68 69 |
# File 'app/models/concerns/protege/tool_scoped.rb', line 62 def available_tools disabled = disabled_tool_ids.map(&:to_sym) grant = self.class.tool_grant ToolMixin.registered .reject { |tool| disabled.include?(tool.id) } .select { |tool| grant.nil? || grant.include?(tool.id) } end |