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 DrainJob and communicates with the parent through natural text messages routed by Events::Subscribers::SubagentMessageRouter.
Nickname assignment is handled by the Melete::Runner which runs synchronously at spawn time — the same muse 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, Tools::SubagentPrompts::PROMPT_GUIDELINES
Class Method Summary collapse
- .description ⇒ Object
- .input_schema ⇒ Object
- .prompt_guidelines ⇒ Object
- .prompt_snippet ⇒ Object
- .tool_name ⇒ Object
Instance Method Summary collapse
-
#execute(input) ⇒ String, Hash{Symbol => String}
Creates a child session with a clean context (no parent history), runs Melete to assign a nickname, pins the task as a Goal, and enqueues the task as the child’s first user_message PendingMessage — which kicks the standard inbound pipeline (Melete → (Mneme) → StartProcessing → DrainJob) so the sub-agent self-starts the same way a human-typed message would.
-
#initialize(session:, tool_use_id: nil) ⇒ SpawnSubagent
constructor
A new instance of SpawnSubagent.
Methods inherited from Base
Constructor Details
#initialize(session:, tool_use_id: nil) ⇒ SpawnSubagent
Returns a new instance of SpawnSubagent.
54 55 56 57 |
# File 'lib/tools/spawn_subagent.rb', line 54 def initialize(session:, tool_use_id: nil, **) @session = session @tool_use_id = tool_use_id 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
33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 |
# File 'lib/tools/spawn_subagent.rb', line 33 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: #{Tools::Registry::STANDARD_TOOLS_BY_NAME.keys.join(", ")}" } }, required: %w[task] } end |
.prompt_guidelines ⇒ Object
31 |
# File 'lib/tools/spawn_subagent.rb', line 31 def self.prompt_guidelines = SubagentPrompts::PROMPT_GUIDELINES |
.prompt_snippet ⇒ Object
29 |
# File 'lib/tools/spawn_subagent.rb', line 29 def self.prompt_snippet = "Hand off a sidequest to a sub-agent. Reachable later via @." |
.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 Melete to assign a nickname, pins the task as a Goal, and enqueues the task as the child’s first user_message PendingMessage —which kicks the standard inbound pipeline (Melete → (Mneme) →StartProcessing → DrainJob) so the sub-agent self-starts the same way a human-typed message would. Returns immediately after Melete completes (blocking for ~200ms).
70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 |
# File 'lib/tools/spawn_subagent.rb', line 70 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 |