Module: Protege::Toolable

Extended by:
ActiveSupport::Concern
Included in:
Agent
Defined in:
app/models/concerns/protege/toolable.rb

Overview

An agent's tools — sourced entirely from the toolkits attached to it. There is no code-declared grant and no per-agent disable list: attaching a toolkit equips the agent with its member tools, and the attachment (+AgentToolkit+) decides who may reach them. Resolution is fail-closed — an agent with no attached toolkit has no tools at all, so even replying (send_email is itself a tool) requires a toolkit that supplies it.

Two questions, two methods. #available_tools is the gate-agnostic union across every attached toolkit — the at-a-glance catalogue for the dashboard. #available_tools_for narrows that to a single run: a tool is offered only when some attached toolkit that contains it admits the run — on a reply the inbound sender must pass that grant's gate; on a scheduled (senderless) run the grant must opt into proactive use (fail-closed by default). Both reconcile against the live registry (via the toolkit's member_tools), so a stale member id — naming a tool since deleted from the code — is simply skipped.

Instance Method Summary collapse

Instance Method Details

#available_tool_idsArray<Symbol>

The ids of #available_tools — a convenience for UI and tests.

Returns:

  • (Array<Symbol>)

    the equipped tool ids



57
58
59
# File 'app/models/concerns/protege/toolable.rb', line 57

def available_tool_ids
  available_tools.map(&:id)
end

#available_tool_ids_for(context:) ⇒ Array<Symbol>

The ids of #available_tools_for — the convenience the dispatch backstop checks.

Parameters:

Returns:

  • (Array<Symbol>)

    the offered tool ids



41
42
43
# File 'app/models/concerns/protege/toolable.rb', line 41

def available_tool_ids_for(context:)
  available_tools_for(context:).map(&:id)
end

#available_toolsArray<Class>

Every tool this agent is equipped with across all attached toolkits, gate-agnostic — the at-a-glance catalogue for the dashboard. Who may actually reach each tool is decided per run by #available_tools_for; this answers only "what could this agent ever use".

Returns:

  • (Array<Class>)

    the union of the attached toolkits' tool classes



50
51
52
# File 'app/models/concerns/protege/toolable.rb', line 50

def available_tools
  tool_classes(attachments)
end

#available_tools_for(context:) ⇒ Array<Class>

The tool classes this agent may use for a specific run — the members of every attached toolkit whose grant admits the run, deduped. This is the single source of truth called by both the advertised catalogue and the dispatch backstop, so what the model is offered and what it is allowed to call can never diverge.

Parameters:

Returns:

  • (Array<Class>)

    the tool classes offered for this run



33
34
35
# File 'app/models/concerns/protege/toolable.rb', line 33

def available_tools_for(context:)
  tool_classes(admitted_grants(context:))
end