The Supervisor and Tool Caller system
The Supervisor and Tool Caller is the execution layer that detects when the ConvoAgent commits to an action and triggers the corresponding backend operation. After each conversational turn, the system analyzes the agent's latest response against a set of available tools, determines which tools need to be called, resolves conflicts between competing tools, and executes the required actions. This article is the definitive developer reference for the Tool Caller's architecture, condition detection logic, conflict resolution, and execution pipeline.
Architecture overview
The CANewoToolCaller flow runs after each conversational turn, triggered by the same broadcast_analyze_conversation event that activates the Observer. While the Observer generates thoughts about what to do next, the Tool Caller detects what the agent has already committed to and makes it happen.
ConvoAgent generates response: "I'll send you an SMS with the details"
│
▼
broadcast_analyze_conversation event
│
├──► CAObserverFlow (thoughts generation)
├──► CAThoughtsFlow (directive generation)
│
└──► CANewoToolCaller
├── compile_tools_object (merge NAF + custom tools)
├── get_tools_to_call (condition analysis via LLM)
├── rerank_conflict (resolve competing tools)
└── handle_*_action (execute tools)
The flow contains 21 skills organized into four categories: tool compilation, condition detection, conflict resolution, and action execution.
AnalyzeConversation orchestrator
The AnalyzeConversation skill is the entry point and orchestrator for the entire Tool Caller flow. It runs the following sequence:
- Compile tools — Calls
compile_tools_objectto merge NAF and custom tools. - Group tools — Separates tools into two groups: those that need full conversation history and those that only need the latest agent answer.
- Evaluate tools without history — Calls
get_tools_to_callwith only<LatestConvoAgentAnswer>, passing tools that haveuseConversationHistory: false. - Evaluate tools with history — Calls
get_tools_to_callwith the full<Conversation>block, passing tools that haveuseConversationHistory: true. - Identify conflicts — Groups selected tools by their
conflictPolicy.tag. - Resolve conflicts — For each tag group with multiple candidates, calls
rerank_conflictto select the winner. - Execute tools — Runs the action handler for each selected tool.
- Update follow-up timer — Adjusts the follow-up delay based on channel (voice channels get shorter delays than chat).
- Set conversation state — Marks that tools were called during this turn.
:::
🗒️ NOTE
The webcall channel is mapped to phone for tool evaluation purposes. The skill normalizes webcall → phone at the start of execution so that phone-only tools (like transfer_call_tool) are available on web call sessions too.
:::
Tool compilation
At runtime, the system assembles the complete set of available tools by merging built-in NAF tools with any custom tools defined by the customer.
compile_tools_object
The skill reads NAF-defined tools and merges any custom tools defined in project_attributes_settings_newo_tools into a single tools object that the condition detection step operates on.
Each tool definition follows a standard schema:
{
"tool_name": {
"description": "What this tool does",
"conditions": {
"condition_name": {
"type": "boolean",
"description": "When this condition is true"
}
},
"useConversationHistory": true,
"conflictPolicy": {
"tag": "conflict_group_tag"
},
"action": {
"type": "send_event",
"options": {}
},
"after_actions": []
}
}| Field | Description |
|---|---|
description | Plain-text description of the tool's purpose. |
conditions | Object of named boolean conditions that must all be true for the tool to be called. |
useConversationHistory | When true, the full conversation history is passed to the LLM during condition evaluation. When false, only the latest agent answer is analyzed. |
conflictPolicy | Optional. Groups tools by tag — tools with the same tag are mutually exclusive. |
action | The action to execute: send_event, send_webhook, or send_urgent_message. |
after_actions | Optional post-execution actions (e.g., set_persona_attribute, set_prompt_section). |
Tool activation attributes
Each built-in tool is gated by a boolean project attribute:
| Attribute | Tool enabled |
|---|---|
project_attributes_setting_booking_check_availability_enabled | check_availability_tool |
project_attributes_setting_booking_enabled | create_booking_tool, search_booking_tool |
project_attributes_setting_booking_cancellation_enabled | cancel_booking_tool (when type is endpoint or project) |
project_attributes_setting_sms_send_information_enabled | send_sms_tool |
project_attributes_setting_email_send_information_enabled | send_email_tool |
project_attributes_setting_transfer_call_enabled | transfer_call_tool (phone channel only) |
project_attributes_setting_calendar_event_integration | create_meeting_tool (when set to google_integration) |
project_attributes_setting_products_and_services_background_check_location_enabled | check_zip_code_served_tool |
project_attributes_setting_products_and_services_background_check_availability_enabled | check_product_or_service_availability |
The end_conversation_tool is always available regardless of attribute settings.
Condition detection
The get_tools_to_call skill is the analytical core. It uses an LLM to evaluate the agent's latest response against each tool's conditions, applying strict rules to prevent false positives.
Analysis prompt structure
The skill formats each tool into a markdown description and passes it with the conversation context.
Critical exclusion rules
The condition detection enforces five rules to prevent false tool activations:
| Rule | Description | Example ignored |
|---|---|---|
| In-progress exclusion | Actions already started are not re-triggered. | "I'm still checking..." |
| Completed exclusion | Past actions are not re-triggered. | "I've sent it", "I already checked" |
| Future step exclusion | Actions described as future steps in a sequence are not triggered. | "I need to ask X, and then I will..." |
| Offer exclusion | Suggestions or conditional phrasing are not triggered. | "I can...", "Would you like me to...?" |
| Subject-verb check | Only triggers when the Agent is the grammatical subject. | "You will receive an SMS" (user is subject) |
Conflict resolution
When multiple tools share the same conflictPolicy.tag, they are mutually exclusive — only one can execute per turn. The rerank_conflict skill resolves this.
Conflict resolution flow
The AnalyzeConversation orchestrator handles conflicts as follows:
For each tool selected by get_tools_to_call:
If tool has conflictPolicy.tag AND other selected tools share that tag:
Add to rerank_candidates[tag]
Else:
Execute immediately
For each conflict group in rerank_candidates:
If only 1 candidate: execute it
Else: call rerank_conflict → LLM selects the most relevant tool
Conflict tags
| Tag | Competing tools |
|---|---|
sms | send_sms_tool, send_manage_booking_url_tool |
availability | check_availability_tool, check_product_or_service_availability |
The rerank_conflict skill uses the same prompt structure as get_tools_to_call but asks the LLM to rank and select the single most relevant tool from the competing set.
Tool execution pipeline
Once tools are selected and conflicts resolved, the AnalyzeConversation orchestrator groups tools by conversation history requirement, executes them, and processes post-execution actions.
Execution grouping
Tools are split into two groups for efficiency:
- Tools without conversation history (
useConversationHistory: false) — Evaluated first, using only the latest agent answer. - Tools with conversation history (
useConversationHistory: true) — Evaluated second, with the full conversation context.
Action handlers
Each tool's action.type routes to a specific handler:
| Handler | Action type | Description |
|---|---|---|
handle_send_event_action | send_event | Fires a SendSystemEvent with the tool name as event IDN. The target flow picks up the event and executes the action (e.g., CACheckingAvailabilityFlow, CAScheduleFlow). |
handle_send_webhook_action | send_webhook | Sends an HTTP request to a configured URL. Generates query parameters, body, and headers from conversation data using generate_object_by_schema. |
handle_send_urgent_message_after_action | send_urgent_message | Sends an urgent message event with optional prefix, used for injecting immediate instructions. |
handle_set_persona_attribute_after_action | set_persona_attribute | Sets a persona attribute value, with optional LLM processing of the input. |
handle_set_prompt_section_after_action | set_prompt_section | Updates a prompt section (custom user data) via system event. |
send_event handler
The most common handler — fires a system event that triggers the corresponding execution flow:
send_webhook handler
Used for custom tools that call external APIs:
Custom tool registration
Custom tools are defined in the project_attributes_settings_newo_tools customer attribute as a JSON object:
{
"tools": {
"my_custom_tool": {
"description": "What this tool does",
"conditions": {
"agentPromised": {
"type": "boolean",
"description": "The agent explicitly states they will perform this action"
}
},
"useConversationHistory": false,
"action": {
"type": "send_webhook",
"options": {
"url": "https://api.example.com/action",
"method": "POST",
"body": {
"type": "object",
"properties": {
"customer_name": {
"type": "string",
"description": "The customer's full name"
}
}
}
}
},
"after_actions": [
{
"type": "send_urgent_message",
"options": {
"prefix": "Action result"
}
}
]
}
}
}Custom tools are merged with NAF tools at runtime by compile_tools_object and go through the same condition detection, conflict resolution, and execution pipeline.
End-to-end example
Here is a complete walkthrough of what happens when the ConvoAgent says "I'll send you an SMS with the reservation details":
-
Event fires:
broadcast_analyze_conversationtriggers the CANewoToolCaller flow. -
Tool compilation:
compile_tools_objectmerges NAF tools (includingsend_sms_toolsinceproject_attributes_setting_sms_send_information_enabledis"True") with any custom tools. -
Tools grouped:
send_sms_toolhasuseConversationHistory: false, so it goes in the first evaluation group. -
Condition detection:
get_tools_to_callanalyzes the latest agent answer:- Subject check: "I" (Agent) is the subject — passes.
- Tense check: "I'll send" — present commitment, not past or future step — passes.
- Keyword check: "SMS" appears in the answer — passes.
agentPromisedcondition: met.notRelatedToExistingBookingcondition: met (not about managing an existing booking).- Result:
send_sms_toolselected.
-
Conflict check:
send_sms_toolhasconflictPolicy.tag: "sms". No other SMS-tagged tool was selected, so no conflict resolution needed. -
Execution:
handle_send_event_actionfires:SendSystemEvent(eventIdn="send_sms_tool", connectorIdn="system", ...) -
SMS delivery: The
CAActionSendSMSInformationFlowreceives the event and processes the SMS delivery through the SmsWorker agent.
Changelog
The Supervisor and Tool Caller system: initial publication
Published developer reference covering the Tool Caller's runtime tool compilation, condition detection with exclusion rules, conflict resolution via reranking, action execution pipeline (send_event, send_webhook, send_urgent_message), custom tool registration, and end-to-end execution walkthrough.
Updated 2 days ago
