Class: Insika::Tools::Subagent
- Inherits:
-
RubyLLM::Tool
- Object
- RubyLLM::Tool
- Insika::Tools::Subagent
- Defined in:
- lib/insika/tools/subagent.rb
Overview
In-process delegation to a CHILD agent (RFC-0010, item 21) — the Flue
session.task() primitive. A system tool (like remember/load_skill): wired
by the ChatBuilder ONLY when profile.subagents is present, so require "ruby_llm" stays in this file (loaded lazily in create_chat). NOT enveloped
(system tool) — in the synchronous mode the child lives in the parent's
envelope and re-runs on the parent's resume (RFC-0010 §6).
It holds no delegation logic itself: execute reads the parent TurnState
(the subagents allowlist + resolved model for inheritance + depth) and hands
off to Executor#run_subagent, which spawns the isolated child turn and
returns its result. The child result = its text + the linked child session
id (§4.3 R3).
Instance Method Summary collapse
-
#description ⇒ Object
The parent's allowlist is per-TURN data, so it is named per instance: the ids go into the description AND as an
enumonagent. -
#execute(agent:, message:, async: false) ⇒ Object
The child result is returned to the model as the tool result.
-
#initialize(runner:, state:) ⇒ Subagent
constructor
A new instance of Subagent.
-
#name ⇒ Object
otherwise RubyLLM derives "insika--tools--subagent" from the class name.
- #params_schema ⇒ Object
Constructor Details
#initialize(runner:, state:) ⇒ Subagent
Returns a new instance of Subagent.
35 36 37 38 39 40 |
# File 'lib/insika/tools/subagent.rb', line 35 def initialize(runner:, state:) @runner = runner @state = state @allowed = Array(state.profile.subagents).map(&:to_s) super() end |
Instance Method Details
#description ⇒ Object
The parent's allowlist is per-TURN data, so it is named per instance: the
ids go into the description AND as an enum on agent. Measured, not
guessed — with only "must be one this agent may spawn" in the schema, a
real provider answered "let me check which agents are available" and then
did the work itself instead of delegating. A model cannot call what it
cannot name.
48 49 50 51 52 |
# File 'lib/insika/tools/subagent.rb', line 48 def description return super if @allowed.empty? "#{super} Agents you may spawn: #{@allowed.join(', ')}." end |
#execute(agent:, message:, async: false) ⇒ Object
The child result is returned to the model as the tool result. On error we
return { error: } (never raise) — a bad agent/depth/child failure is a
message to the model, not a turn-killer (parity with A2ARemote).
61 62 63 64 65 66 67 68 69 70 71 72 |
# File 'lib/insika/tools/subagent.rb', line 61 def execute(agent:, message:, async: false) result = @runner.run_subagent(agent: agent.to_s, message: .to_s, parent_state: @state, async: async == true) return { error: result[:error] } if result[:error] # async dispatch: the ack (the child result arrives later as a new turn). return { dispatched: true, agent: result[:agent], session_id: result[:session_id] } if result[:dispatched] # sync: link the child session id alongside the text so a multi-step parent # can reference it and the transcript stays auditable (§4.3 R3 / §7). { text: result[:text], session_id: result[:session_id] } end |
#name ⇒ Object
otherwise RubyLLM derives "insika--tools--subagent" from the class name.
33 |
# File 'lib/insika/tools/subagent.rb', line 33 def name = "spawn_subagent" |