Ai knowledge and logicHelpers

hand_off_conversation

Hand off the conversation to a human agent from within an action.

hand_off_conversation(context: dict, reason: str = None, phone_destination: str = None) -> dict

Hands off the conversation to a human agent. Once handed off, the bot stops responding and a human takes over.

This is the programmatic equivalent of the built-in transferConversation action — use it when the handoff decision depends on logic inside your action rather than the workflow instructions.


Parameters

NameTypeDescription
contextdictThe context object passed to your action
reasonstr or NoneOptional reason for the handoff (max 500 characters)
phone_destinationstr or NoneOptional phone number to forward a live phone call to (E.164 format, e.g. +15551234567). Silently ignored outside the phone channel.

Returns

dict{"success": bool, "message": str}

Behavior

  • Once handed off, the bot will not respond to further messages in this conversation.
  • If the conversation is already handed off, the operation succeeds without changes.
  • Skipped in test/mock environments.
  • On the phone channel, providing phone_destination transfers the live call to that number instead of performing a standard handoff. The bot stops talking once the transfer fires.
  • Outside the phone channel, phone_destination is silently ignored — the call falls through to a normal handoff. This means the same action code can be reused across channels.
  • When a phone transfer fires, the action's return value is ignored (the bot won't see it because the call has been handed off). It is still fine and normal to return a regular {"success": True} shape — keep the return shape consistent so the same action behaves correctly when it runs outside a phone call (e.g. on chat) or when no transfer is attempted (e.g. outside business hours).

Examples

Hand off when an API call reveals a complex case

def execute_action(context):
    order = fetch_order(context["args"]["orderId"])

    if order.get("hasFraudFlag"):
        hand_off_conversation(context, "Order flagged for fraud review")
        return {"handedOff": True, "reason": "fraud_flag"}

    return order

Hand off with context about what was attempted

def execute_action(context):
    try:
        result = process_cancellation(context["args"]["orderId"])
        return result
    except Exception as e:
        hand_off_conversation(
            context,
            f"Automatic cancellation failed: {str(e)}"
        )
        return {"handedOff": True, "error": str(e)}

Transfer a phone call during business hours, fall back to a regular handoff otherwise

from datetime import datetime
from zoneinfo import ZoneInfo

def execute_action(context):
    now_et = datetime.now(ZoneInfo("America/New_York"))
    within_hours = now_et.weekday() <= 5 and 9 <= now_et.hour < 20

    if within_hours:
        hand_off_conversation(context, phone_destination="+15551234567")
        # Ignored when a phone transfer fires; useful on other channels.
        return {"success": True}

    hand_off_conversation(context)
    return {
        "success": False,
        "message": (
            "It's currently outside business hours (Mon–Sat 9 AM–8 PM ET). "
            "Let the customer know an agent will follow up within ~24 hours, "
            "and invite them to leave any details for the agent."
        ),
    }

On this page