Class: Tools::SpawnSpecialist
- Includes:
- SubagentPrompts
- Defined in:
- lib/tools/spawn_specialist.rb
Overview
Spawns a named specialist sub-agent from the agent registry. The specialist has a predefined system prompt and tool set defined in its Markdown definition file under agents/.
Nickname assignment is handled by the AnalyticalBrain::Runner which runs synchronously at spawn time, generating a unique nickname based on the task — same as generic sub-agents.
Results are delivered through natural text messages routed by Events::Subscribers::SubagentMessageRouter.
Constant Summary
Constants included from SubagentPrompts
Tools::SubagentPrompts::COMMUNICATION_INSTRUCTION, Tools::SubagentPrompts::FORK_FRAMING_MESSAGE, Tools::SubagentPrompts::IDENTITY_TEMPLATE
Class Method Summary collapse
-
.description ⇒ Object
Builds description dynamically to include available specialists.
-
.input_schema ⇒ Object
Builds input schema dynamically to include named agent enum.
- .tool_name ⇒ Object
Instance Method Summary collapse
-
#execute(input) ⇒ String, Hash{Symbol => String}
Creates a child session with the specialist’s predefined prompt and tools, persists the task as a user message, and queues background processing.
-
#initialize(session:, agent_registry: nil) ⇒ SpawnSpecialist
constructor
A new instance of SpawnSpecialist.
Methods inherited from Base
Constructor Details
#initialize(session:, agent_registry: nil) ⇒ SpawnSpecialist
Returns a new instance of SpawnSpecialist.
62 63 64 65 |
# File 'lib/tools/spawn_specialist.rb', line 62 def initialize(session:, agent_registry: nil, **) @session = session @agent_registry = agent_registry || Agents::Registry.instance end |
Class Method Details
.description ⇒ Object
Builds description dynamically to include available specialists.
23 24 25 26 27 28 29 30 31 32 33 |
# File 'lib/tools/spawn_specialist.rb', line 23 def self.description base = "Need a specific skill set for the job? Bring in a specialist. " \ "Its messages appear in yours; any message containing " \ "@nickname is forwarded — even casual mentions will wake it." registry = Agents::Registry.instance return base unless registry.any? specialist_list = registry.catalog.map { |name, desc| "- #{name}: #{desc}" }.join("\n") "#{base}\n\nAvailable specialists:\n#{specialist_list}" end |
.input_schema ⇒ Object
Builds input schema dynamically to include named agent enum.
36 37 38 39 40 41 42 43 44 45 |
# File 'lib/tools/spawn_specialist.rb', line 36 def self.input_schema { type: "object", properties: { name: name_property, task: {type: "string", description: "State the goal — the specialist knows its method."} }, required: %w[name task] } end |
.tool_name ⇒ Object
20 |
# File 'lib/tools/spawn_specialist.rb', line 20 def self.tool_name = "spawn_specialist" |
Instance Method Details
#execute(input) ⇒ String, Hash{Symbol => String}
Creates a child session with the specialist’s predefined prompt and tools, persists the task as a user message, and queues background processing. Returns immediately (non-blocking).
74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 |
# File 'lib/tools/spawn_specialist.rb', line 74 def execute(input) task = input["task"].to_s.strip name = input["name"].to_s.strip return {error: "Name cannot be blank"} if name.empty? return {error: "Task cannot be blank"} if task.empty? definition = @agent_registry.get(name) return {error: "Unknown agent: #{name}"} unless definition child = spawn_child(definition, task) nickname = child.name "Specialist @#{nickname} spawned (session #{child.id}). " \ "Its messages will appear in your conversation. " \ "Reply with @#{nickname} to send it instructions — " \ "any message mentioning @#{nickname} is forwarded, even in narration." end |