Overview
SubagentNode is the recommended node type for most use cases. It’s a composite node that can contain multiple tools (webhooks, knowledge bases, MCP servers, WhatsApp templates) and intelligently decides which tool to use based on the conversation context.
Why use SubagentNode?
- Flexibility: Add multiple tools without creating separate nodes
- Intelligence: The LLM automatically selects appropriate tools
- Simplicity: Reduces graph complexity by consolidating functionality
- Extensibility: Easy to add new tools without changing the graph
Import and basic usage
from kapso.builder.nodes import SubagentNode
from kapso.builder.nodes.subagent import (
WebhookTool,
KnowledgeBaseTool,
McpServerTool,
WhatsappTemplateTool,
JmespathQuery
)
# Create a SubagentNode
node = SubagentNode(
name="assistant",
prompt="You are a helpful assistant. Use the available tools to help users.",
global_=False,
global_condition=None
)
Constructor parameters
SubagentNode(
name: str, # Required: unique identifier
prompt: str = None, # Optional: instructions for the LLM
global_: bool = False, # Optional: make globally accessible
global_condition: str = None # Required if global_=True
)
node.add_tool(tool: Tool) -> None
Add any supported tool to the SubagentNode:
# Add a webhook tool
api_tool = WebhookTool(name="weather", url="https://api.weather.com/current")
node.add_tool(api_tool)
# Add a knowledge base tool
kb_tool = KnowledgeBaseTool(name="docs", knowledge_base_text="...")
node.add_tool(kb_tool)
Make HTTP requests to external APIs:
from kapso.builder.nodes.subagent import WebhookTool
tool = WebhookTool(
name="order_api", # Required: tool identifier
url="https://api.example.com/orders", # Required: API endpoint
http_method="POST", # Optional: GET, POST, PUT, PATCH, DELETE
headers={ # Optional: request headers
"Authorization": "Bearer {{api_key}}",
"Content-Type": "application/json"
},
body={ # Optional: request body
"order_id": "{{order_id}}",
"action": "status"
},
body_schema={ # Optional: JSON Schema validation
"type": "object",
"properties": {
"order_id": {"type": "string"},
"action": {"type": "string"}
},
"required": ["order_id"]
},
jmespath_query="data.status", # Optional: extract specific data
mock_response={"status": "shipped"}, # Optional: for testing
mock_response_enabled=True, # Optional: enable mock
description="Check order status" # Optional but recommended
)
node.add_tool(tool)
Access and search through knowledge sources:
from kapso.builder.nodes.subagent import KnowledgeBaseTool
# From text
tool = KnowledgeBaseTool(
name="policies",
knowledge_base_text="""
Return Policy:
- 30-day returns for unopened items
- 14-day returns for opened items
- No returns on sale items
""",
description="Company policies and procedures"
)
# From file
tool = KnowledgeBaseTool.from_file(
name="manual",
file_path="docs/user_manual.pdf",
description="Product user manual"
)
node.add_tool(tool)
Connect to Model Context Protocol servers:
from kapso.builder.nodes.subagent import McpServerTool, JmespathQuery
tool = McpServerTool(
name="calculator",
url="https://mcp.example.com/math",
transport_kind="sse", # or "streamable_http"
jmespath_queries=[
JmespathQuery(
tool_name="basic_math",
jmespath_query="tools[?category=='arithmetic']"
),
JmespathQuery(
tool_name="advanced_math",
jmespath_query="tools[?category=='scientific']"
)
],
description="Mathematical calculations"
)
node.add_tool(tool)
Send WhatsApp template messages:
from kapso.builder.nodes.subagent import WhatsappTemplateTool
tool = WhatsappTemplateTool(
name="order_confirmation",
template_name="order_confirm_v2", # Meta-approved template
phone_number="{{customer_phone}}", # Recipient
template_parameters={ # Template variables
"1": "{{customer_name}}",
"2": "{{order_number}}",
"3": "{{delivery_date}}"
},
wait_for_response=True, # Wait for user reply
whatsapp_config_id="prod_config", # WhatsApp configuration
whatsapp_template_id="template_123", # Template ID
description="Send order confirmation message"
)
node.add_tool(tool)
SubagentNode includes all DefaultNode tools plus:
- kb_retrieval: Automatically available if knowledge base tools are added
- SendWhatsappTemplateMessage: Available if WhatsApp template tools are added
Complete examples
Example 1: Customer service assistant
from kapso.builder.nodes import SubagentNode
from kapso.builder.nodes.subagent import (
WebhookTool,
KnowledgeBaseTool,
WhatsappTemplateTool
)
# Create the main subagent
subagent = SubagentNode(
name="customer_service",
prompt="""You are a customer service assistant.
Help customers with:
- Order inquiries (use order_status tool)
- Product questions (use product_info tool)
- Policy questions (use policies tool)
- Send confirmations when needed (use send_confirmation tool)
"""
)
# Order status API
subagent.add_tool(WebhookTool(
name="order_status",
url="https://api.store.com/orders/{{order_id}}",
http_method="GET",
headers={"Authorization": "Bearer {{api_key}}"},
jmespath_query="data.{status: status, tracking: tracking_number}",
description="Get order status and tracking information"
))
# Product knowledge base
subagent.add_tool(KnowledgeBaseTool(
name="product_info",
knowledge_base_file="products/catalog.pdf",
description="Product catalog with specs and pricing"
))
# Company policies
subagent.add_tool(KnowledgeBaseTool(
name="policies",
knowledge_base_text="""
Shipping: Free on orders over $50
Returns: 30 days for most items
Warranty: 1 year manufacturer warranty
""",
description="Company policies"
))
# WhatsApp confirmation
subagent.add_tool(WhatsappTemplateTool(
name="send_confirmation",
template_name="order_update",
phone_number="{{phone}}",
template_parameters={"1": "{{order_id}}", "2": "{{status}}"},
description="Send order update via WhatsApp"
))
Example 2: Technical support bot
# Create technical support subagent
tech_support = SubagentNode(
name="tech_support",
prompt="Provide technical support using available tools and documentation."
)
# API health check
tech_support.add_tool(WebhookTool(
name="system_status",
url="https://status.example.com/api/health",
http_method="GET",
mock_response={"status": "operational", "uptime": "99.9%"},
mock_response_enabled=True,
description="Check system status"
))
# Troubleshooting guide
tech_support.add_tool(KnowledgeBaseTool(
name="troubleshooting",
knowledge_base_text="""
Common Issues:
1. Login problems: Clear cache and cookies
2. Slow performance: Check internet connection
3. Error 500: Contact support
""",
description="Troubleshooting guide"
))
# Calculator for technical calculations
tech_support.add_tool(McpServerTool(
name="tech_calc",
url="https://mcp.tools.com/calculator",
transport_kind="sse",
description="Technical calculations"
))
# Global help subagent available from anywhere
help_menu = SubagentNode(
name="help_assistant",
prompt="Show available options and guide users",
global_=True,
global_condition="user asks for help, menu, or options"
)
# Add navigation knowledge
help_menu.add_tool(KnowledgeBaseTool(
name="navigation",
knowledge_base_text="""
Available Options:
1. Check order status
2. Browse products
3. Technical support
4. Talk to human agent
5. Company policies
""",
description="Navigation help"
))
The LLM automatically selects appropriate tools based on:
- Tool descriptions: Always provide clear descriptions
- Tool names: Use descriptive, action-oriented names
- Prompt guidance: Reference tools in the node prompt
- Context: The current conversation state
node = SubagentNode(
name="assistant",
prompt="""When users ask about:
- Orders: Use the 'check_order' tool
- Weather: Use the 'weather_api' tool
- Policies: Use the 'company_policies' knowledge base
- Calculations: Use the 'calculator' MCP server
"""
)
Best practices
# ✅ Good: Clear, action-oriented names
WebhookTool(name="check_inventory", ...)
WebhookTool(name="create_ticket", ...)
# ❌ Bad: Vague or generic names
WebhookTool(name="api1", ...)
WebhookTool(name="webhook", ...)
# ✅ Good: Specific and helpful
WebhookTool(
name="weather",
description="Get current weather conditions for any city"
)
# ❌ Bad: Too vague
WebhookTool(
name="weather",
description="Weather tool"
)
3. Error handling
# Use mock responses during development
tool = WebhookTool(
name="api",
url="https://api.example.com",
mock_response={"error": "Not found"},
mock_response_enabled=True # Toggle for dev/prod
)
# Group related tools in one SubagentNode
customer_tools = SubagentNode(name="customer_tools")
customer_tools.add_tool(order_api)
customer_tools.add_tool(customer_kb)
customer_tools.add_tool(notification_tool)
# Rather than separate nodes for each tool
Limitations
- Tools are only available within the specific SubagentNode
- Cannot share tools between different SubagentNodes
- Tool execution order is determined by the LLM
- All tools must complete before moving to next node
Migration from individual nodes
Replace multiple specialized nodes with a single SubagentNode:
# Before: Multiple nodes
webhook_node = WebhookNode(name="api", url="...")
kb_node = KnowledgeBaseNode(name="docs", ...)
agent.add_edge("router", "api", condition="needs api")
agent.add_edge("router", "docs", condition="needs docs")
# After: Single SubagentNode
subagent = SubagentNode(name="assistant")
subagent.add_tool(WebhookTool(name="api", url="..."))
subagent.add_tool(KnowledgeBaseTool(name="docs", ...))
agent.add_edge("router", "assistant")
Complete example
from kapso.builder import Agent
from kapso.builder.nodes import SubagentNode
from kapso.builder.nodes.subagent import (
WebhookTool, KnowledgeBaseTool, McpServerTool, WhatsappTemplateTool
)
from kapso.builder.agent.constants import START_NODE, END_NODE
# Create agent
agent = Agent(name="multi_tool_assistant")
agent.add_node(START_NODE)
agent.add_node(END_NODE)
# Create SubagentNode with multiple tools
subagent = SubagentNode(
name="main_assistant",
prompt="""You are a helpful assistant with access to multiple tools.
Use the appropriate tool based on the user's request:
- Use order_api for order inquiries
- Use weather_api for weather information
- Use knowledge_base for general questions
- Send confirmations via WhatsApp when requested"""
)
# Add API tools
subagent.add_tool(WebhookTool(
name="order_api",
url="https://api.example.com/orders/{{order_id}}",
http_method="GET",
headers={"Authorization": "Bearer {{api_key}}"},
description="Retrieve order information by ID"
))
subagent.add_tool(WebhookTool(
name="weather_api",
url="https://api.weather.com/current?city={{city}}",
http_method="GET",
jmespath_query="data.current",
description="Get current weather for a city"
))
# Add knowledge base
subagent.add_tool(KnowledgeBaseTool(
name="company_docs",
knowledge_base_text="""Return Policy: Items can be returned within 30 days.
Shipping: Free shipping on orders over $50.
Business Hours: Monday-Friday 9AM-5PM EST.""",
description="Search company policies and information"
))
# Add WhatsApp template
subagent.add_tool(WhatsappTemplateTool(
name="order_confirmation",
template_name="order_confirmed",
phone_number="{{customer_phone}}",
template_variables={
"1": "{{order_id}}",
"2": "{{delivery_date}}"
},
description="Send order confirmation via WhatsApp"
))
# Add node to agent
agent.add_node(subagent)
# Simple flow
agent.add_edge(START_NODE, "main_assistant")
agent.add_edge("main_assistant", END_NODE)
# The subagent will automatically:
# - Understand user intent
# - Select the appropriate tool(s)
# - Execute them in the right order
# - Provide coherent responses