> ## Documentation Index
> Fetch the complete documentation index at: https://kapso-1adbad2d.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Flow nodes

> Building blocks for WhatsApp workflows

## Node types

### StartNode

Entry point of the flow.

```python theme={null}
from kapso.builder.flows.nodes import StartNode

node = StartNode(id="start_1234")
```

### SendTextNode

Send WhatsApp text messages.

```python theme={null}
from kapso.builder.flows.nodes import SendTextNode
from kapso.builder.ai.field import AIField

# Static message
node = SendTextNode(
    id="send_text_1234",
    message="Hello! How can I help you today?"
)

# AI-generated message
node = SendTextNode(
    id="send_text_5678",
    message=AIField("Personalize greeting based on customer history"),
    provider_model_name="claude-sonnet-4-20250514"
)
```

### WaitForResponseNode

Wait for user input.

```python theme={null}
from kapso.builder.flows.nodes import WaitForResponseNode

node = WaitForResponseNode(
    id="wait_1234"
)
```

### DecideNode

Route flows with AI or custom logic.

```python theme={null}
from kapso.builder.flows.nodes import DecideNode
from kapso.builder.flows.nodes.decide import Condition

# AI-powered: AI interprets user intent
node = DecideNode(
    id="decide_1234",
    decision_type="ai",  # Default, can be omitted
    provider_model_name="claude-sonnet-4-20250514",
    conditions=[
        Condition(label="urgent", description="Customer issue is urgent"),
        Condition(label="general", description="General inquiry or question"),
        Condition(label="billing", description="Billing or payment related")
    ],
    llm_temperature=0.0,
    llm_max_tokens=100
)

# Function: Run your routing logic
node = DecideNode(
    id="decide_5678",
    decision_type="function",
    function_id="7c9e6679-7425-40de-944b-e07fc1f90ae7",  # UUID of deployed function
    conditions=[
        Condition(label="premium", description="Premium tier route"),
        Condition(label="standard", description="Standard tier route"),
        Condition(label="trial", description="Trial user route")
    ]
    # No AI parameters needed for function mode
)
```

**Configuration:**

* **AI mode**: Requires `provider_model_name`, optional `llm_temperature` and `llm_max_tokens`
* **Function mode**: Requires `function_id` (UUID), AI parameters are ignored

Your function receives `execution_context`, `flow_events`, and `available_edges[]`. Run any logic you want (business rules, data checks, API calls) and return `{ next_edge: "label", vars: {...} }`.

### AgentNode

Embedded AI agent with tools.

```python theme={null}
from kapso.builder.flows.nodes import AgentNode
from kapso.builder.flows.nodes.agent import FlowAgentWebhook, FlowAgentMcpServer

webhooks = [
    FlowAgentWebhook(
        name="check_order",
        url="https://api.store.com/orders/{{order_id}}",
        description="Get order status by ID",
        http_method="GET"
    )
]

mcp_servers = [
    FlowAgentMcpServer(
        name="Context Server",
        url="https://mcp.context7.ai/v1",
        description="Documentation and knowledge access",
        headers={"Authorization": "Bearer token123"}
    )
]  # HTTP streamable transport only

node = AgentNode(
    id="agent_1234",
    system_prompt="You are a customer service agent. Help with orders.",
    provider_model_name="claude-sonnet-4-20250514",
    temperature=0.1,
    max_iterations=10,
    max_tokens=2000,
    reasoning_effort="medium",
    webhooks=webhooks,
    mcp_servers=mcp_servers
)

# POST webhook example with request schema
import json

create_ticket = FlowAgentWebhook(
    name="create_support_ticket",
    url="https://api.support.com/tickets",
    http_method="POST",
    description="Create a support ticket with subject and body",
    headers={"Content-Type": "application/json"},
    body={
        "subject": "{{vars.issue_subject}}",
        "body": "{{last_user_input}}",
        "priority": "high",
    },
    body_schema=json.dumps(
        {
            "type": "object",
            "properties": {
                "subject": {"type": "string"},
                "body": {"type": "string"},
                "priority": {"type": "string", "enum": ["low", "medium", "high"]},
            },
            "required": ["subject", "body"],
        }
    ),
    jmespath_query="data.ticket_id",
)

AgentNode(
    id="support_agent",
    system_prompt="Log tickets for users and share the ticket ID.",
    provider_model_name="claude-sonnet-4-20250514",
    webhooks=[create_ticket]
)
```

<Note>
  Use `body_schema` to describe the payload you want the LLM to fill. Supply `body` only when you have fixed values or stored variables you want to send verbatim. Typically you use one or the other—avoid setting both unless you’re intentionally seeding a constant field alongside a schema-generated payload.
</Note>

### SendTemplateNode

WhatsApp template messages.

```python theme={null}
from kapso.builder.flows.nodes import SendTemplateNode
from kapso.builder.ai.field import AIField

node = SendTemplateNode(
    id="template_1234",
    template_id="order_confirmation",
    parameters={
        "1": "{{customer_name}}",
        "2": AIField("Extract order number from conversation")
    },
    provider_model_name="claude-sonnet-4-20250514"  # Required for AIField
)
```

### SendInteractiveNode

Interactive lists and buttons.

```python theme={null}
from kapso.builder.flows.nodes import SendInteractiveNode
from kapso.builder.flows.nodes.send_interactive import (
    InteractiveButton,
    ListRow,
    ListSection,
)
from kapso.builder.ai.field import AIField

# Button message with helper buttons
node = SendInteractiveNode(
    id="interactive_1234",
    interactive_type="button",
    body_text="How can we help you today?",
    header_type="text",
    header_text="Support Menu",
    buttons=[
        InteractiveButton(id="support", title="Support"),
        InteractiveButton(id="sales", title="Sales"),
    ],
)

# List message with AI content
node = SendInteractiveNode(
    id="interactive_5678",
    interactive_type="list",
    body_text=AIField("Create personalized menu options"),
    list_button_text="View options",
    list_sections=[
        ListSection(
            title="Assistance",
            rows=[
                ListRow(id="tech", title="Technical Support"),
                ListRow(id="billing", title="Billing", description="Invoices and payments"),
            ],
        )
    ],
    provider_model_name="claude-sonnet-4-20250514",
)
```

### FunctionNode

Call serverless functions.

```python theme={null}
from kapso.builder.flows.nodes import FunctionNode

node = FunctionNode(
    id="function_1234",
    function_id="func_calculate_shipping_789",
    save_response_to="shipping_cost"
)
```

### HandoffNode

Transfer to human agent.

```python theme={null}
from kapso.builder.flows.nodes import HandoffNode

node = HandoffNode(
    id="handoff_1234"
)
```

## AIField support

These nodes support AIField for dynamic content:

* **SendTextNode**: `message` parameter
* **SendTemplateNode**: `parameters` values
* **SendInteractiveNode**: `body_text`, `header_text`, `footer_text`

When using AIField, always provide `provider_model_name`.
