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
)

Adding tools

Method: add_tool()

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)

Available tools

WebhookTool

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)

KnowledgeBaseTool

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)

McpServerTool

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)

WhatsappTemplateTool

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)

Built-in tools

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"
))

Example 3: Global help menu

# 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"
))

Tool selection

The LLM automatically selects appropriate tools based on:

  1. Tool descriptions: Always provide clear descriptions
  2. Tool names: Use descriptive, action-oriented names
  3. Prompt guidance: Reference tools in the node prompt
  4. Context: The current conversation state

Guiding tool selection

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

1. Tool naming

# ✅ Good: Clear, action-oriented names
WebhookTool(name="check_inventory", ...)
WebhookTool(name="create_ticket", ...)

# ❌ Bad: Vague or generic names
WebhookTool(name="api1", ...)
WebhookTool(name="webhook", ...)

2. Tool descriptions

# ✅ 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
)

4. Tool organization

# 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