Class: Tools::SpawnSubagent
- Includes:
- SubagentPrompts
- Defined in:
- lib/tools/spawn_subagent.rb
Overview
Spawns a generic child session that works on a task autonomously. The sub-agent starts clean — no parent conversation history — with only a system prompt, a Goal, and the task as its first user message. Runs via AgentRequestJob and communicates with the parent through natural text messages routed by Events::Subscribers::SubagentMessageRouter.
Nickname assignment is handled by the AnalyticalBrain::Runner which runs synchronously at spawn time — the same brain that manages skills, goals, and workflows for the main session.
For named specialists with predefined prompts and tools, see SpawnSpecialist.
Constant Summary collapse
- GENERIC_PROMPT =
"#{COMMUNICATION_INSTRUCTION}\n"
Constants included from SubagentPrompts
Tools::SubagentPrompts::COMMUNICATION_INSTRUCTION, Tools::SubagentPrompts::IDENTITY_TEMPLATE
Class Method Summary collapse
Instance Method Summary collapse
-
#execute(input) ⇒ String, Hash{Symbol => String}
Creates a child session with a clean context (no parent history), runs the analytical brain to assign a nickname, persists the task as a pinned user message, and queues background processing.
-
#initialize(session:, shell_session:) ⇒ SpawnSubagent
constructor
A new instance of SpawnSubagent.
Methods inherited from Base
Constructor Details
#initialize(session:, shell_session:) ⇒ SpawnSubagent
Returns a new instance of SpawnSubagent.
48 49 50 51 |
# File 'lib/tools/spawn_subagent.rb', line 48 def initialize(session:, shell_session:, **) @session = session @shell_session = shell_session end |
Class Method Details
.description ⇒ Object
22 23 24 25 26 27 |
# File 'lib/tools/spawn_subagent.rb', line 22 def self.description "Task feels like a sidequest or a context-switch? Hand it off. " \ "Starts clean with just the task — include all relevant context in the task description. " \ "Its messages appear as tool responses in your conversation. " \ "Prefix its nickname with @ to send instructions." end |
.input_schema ⇒ Object
29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 |
# File 'lib/tools/spawn_subagent.rb', line 29 def self.input_schema { type: "object", properties: { task: {type: "string"}, tools: { type: "array", items: {type: "string"}, description: "Tool names to grant the sub-agent. " \ "Omit for all standard tools. Empty array for pure reasoning. " \ "Valid tools: #{AgentLoop::STANDARD_TOOLS_BY_NAME.keys.join(", ")}" } }, required: %w[task] } end |
.tool_name ⇒ Object
20 |
# File 'lib/tools/spawn_subagent.rb', line 20 def self.tool_name = "spawn_subagent" |
Instance Method Details
#execute(input) ⇒ String, Hash{Symbol => String}
Creates a child session with a clean context (no parent history), runs the analytical brain to assign a nickname, persists the task as a pinned user message, and queues background processing. Returns immediately after brain completes (blocking for ~200ms).
61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 |
# File 'lib/tools/spawn_subagent.rb', line 61 def execute(input) task = input["task"].to_s.strip return {error: "Task cannot be blank"} if task.empty? tools = normalize_tools(input["tools"]) error = validate_tools(tools) return error if error child = spawn_child(task, tools) nickname = child.name "Sub-agent #{nickname} spawned (session #{child.id}). " \ "Its messages will appear in your conversation. " \ "To address it, prefix its name with @ in your message." end |