VEXYL AI

AI brain

The AI brain is the language model side of a call: it receives what the caller said and returns the reply the gateway speaks. The gateway supports two brains, LiteBot and your own HTTP endpoint. This chapter covers how to choose between them, every variable each one reads, and what callers hear when the brain is slow or fails. Speech in and out is covered in Speech recognition and Text to speech; ready-made combinations are in Configuration recipes.

Choosing

Set LLM_PROVIDER to one of the two values below. Always set it explicitly; leaving it unset is not a supported configuration.

LLM_PROVIDER=litebot
Brain (LLM_PROVIDER) Use it when You get
litebot You want a managed bot with prompts, tools and transfers Bots with tools, transfer and hang-up by tool, end-of-call hooks, session cost reconciliation
custom You already have your own backend or model service Full control: you receive the message as JSON and return the reply as JSON

Realtime LiteBot Live is a different mode that replaces the whole speech pipeline; see Realtime mode.

LiteBot

Point the gateway at your LiteBot server and choose a bot.

LLM_PROVIDER=litebot
LITEBOT_API_URL=http://<litebot-host>:3345
LITEBOT_BOT_ID=customer-service
Variable Default What it does
LITEBOT_API_URL http://localhost:3000 Address of the LiteBot server
LITEBOT_BOT_ID customer-service Bot that answers calls
LITEBOT_TIMEOUT 30000 Request timeout in milliseconds
LITEBOT_STREAMING true Speak the answer sentence by sentence as it arrives; false waits for the whole answer
LITEBOT_HANGUP_TOOLS hangupCall Comma-separated tool names that end the call
LITEBOT_TRANSFER_TOOLS empty Comma-separated tool names that trigger a transfer; empty relies on the bot's escalate or transfer flag
LITEBOT_RECONCILE_COST true At hang-up, read LiteBot's session total and correct the per-call cost
LITEBOT_RECONCILE_TIMEOUT_MS 1500 Hard cap on that lookup
LITEBOT_SESSION_END true Tell LiteBot the session ended so end-of-session hooks run now
LITEBOT_SESSION_END_TIMEOUT_MS 5000 Time allowed for that notification
LITEBOT_ERROR_TEXT_GUARD true Never speak an error that LiteBot relays as the reply
LITEBOT_ERROR_TEXT_PATTERN empty Regex override for what counts as a relayed error

Choosing a bot per call

Post a botId in the session metadata for a call and that bot answers instead of LITEBOT_BOT_ID. The id is case-sensitive; an unknown id falls back to the default bot. The metadata request is described in HTTP API.

What the gateway sends

Each turn the gateway sends LiteBot the following.

Field Content
message What the caller said
sessionId Conversation identifier for the call
botId The bot chosen for this call
userId The call UUID
context Language (default en-IN), caller name, caller phone, timestamp, plus any session metadata you posted

Streaming

With LITEBOT_STREAMING on, the first sentence is spoken while the rest is still being written. Bots that call tools deliver their final answer as one block even with streaming on; that is LiteBot's behaviour, not a gateway setting.

Hang-up, transfer and cost

  • A tool named in LITEBOT_HANGUP_TOOLS ends the call after the goodbye is spoken. Add your own tool names, comma-separated.
  • A tool named in LITEBOT_TRANSFER_TOOLS hands the caller to a human. Transfer set-up and what happens when it fails are in Conversation behaviour.
  • Per-turn cost can miss turns that finish after the call ends. With LITEBOT_RECONCILE_COST on, the gateway reads LiteBot's own total at hang-up and only ever raises the recorded cost to match. Where costs go is covered in Webhooks and billing.
  • With LITEBOT_SESSION_END on, the bot's end-of-session hooks (a CRM log, for example) run at hang-up instead of at LiteBot's idle sweep. The call is fire-and-forget and never delays hang-up. An older LiteBot without that route returns 404, which is logged once and is harmless.

When LiteBot relays an error

If LiteBot's own model fails (usually an invalid or expired key on the bot), LiteBot may return the failure as the reply text, starting with Error:. With LITEBOT_ERROR_TEXT_GUARD on, the gateway does not speak it. The caller hears the final-timeout message from When the AI is slow or fails, and the log records that LiteBot returned an upstream error as the reply. Fix the cause on the LiteBot side. LITEBOT_ERROR_TEXT_PATTERN replaces the default match, a reply beginning with error: in any case.

Custom HTTP endpoint

The gateway POSTs each turn to your URL and speaks the text in the JSON you return.

LLM_PROVIDER=custom
CUSTOM_LLM_URL=https://your-server.example.com/chat
CUSTOM_LLM_AUTH_TYPE=bearer
CUSTOM_LLM_AUTH_TOKEN=your-secret-token
Variable Default What it does
CUSTOM_LLM_URL none Required. Your HTTP endpoint
CUSTOM_LLM_TIMEOUT 30000 Request timeout in milliseconds
CUSTOM_LLM_AUTH_TYPE none none, bearer or header
CUSTOM_LLM_AUTH_TOKEN empty Token for bearer or header authentication
CUSTOM_LLM_AUTH_HEADER empty Header name to carry the token when the type is header
CUSTOM_LLM_RESPONSE_FIELD empty Dot path to the reply text when your JSON is not an auto-detected shape, for example data.output.message
CUSTOM_LLM_SESSION_FIELD empty Dot path to your session id in the reply

Request

Your endpoint receives a POST with this JSON body.

{
  "message": "Hello, I need help with my order",
  "sessionId": "custom-session-1706234567890-abc123xyz",
  "history": [
    { "role": "user", "content": "Hi" },
    { "role": "assistant", "content": "Hello! How can I help you today?" }
  ],
  "context": {
    "userId": "550e8400-e29b-41d4-a716-446655440000",
    "callerName": "John Doe",
    "callerPhone": "+9198xxxxxxxx",
    "language": "en-IN",
    "timestamp": "2024-01-25T10:30:00.000Z",
    "custom_field_1": "value1",
    "custom_field_2": "value2"
  }
}
Field Type Description
message string The caller's words as text
sessionId string Identifier for conversation continuity
history array Earlier messages (optional)
context.userId string Unique call UUID
context.callerName string Caller's name, from session metadata
context.callerPhone string Caller's phone number
context.language string Language code, such as en-IN or hi-IN
context.timestamp string ISO 8601 time of the turn
context.* any Any other metadata you posted for the call

Response

Return JSON. The recommended shape:

{
  "response": "I'd be happy to help you with your order. Can you please provide your order number?",
  "sessionId": "your-session-id-123",
  "shouldEscalate": false,
  "shouldHangup": false
}

The gateway also finds the reply text under any of these field names.

{ "response": "..." }
{ "text": "..." }
{ "message": "..." }
{ "output": "..." }
{ "result": "..." }
{ "answer": "..." }
{ "reply": "..." }
{ "content": "..." }

Nested formats also work:
{ "data": { "response": "..." } }
{ "data": { "text": "..." } }
{ "data": { "message": "..." } }

If your JSON uses another shape, set CUSTOM_LLM_RESPONSE_FIELD.

Flags

All four flags are optional booleans. They are also accepted nested under metadata or data.

Flag Effect
shouldEscalate Transfer the call to a human
shouldHangup End the call after the reply is spoken
shouldWaitForMore The caller's sentence seems unfinished; the gateway says nothing and waits for more speech
shouldGiveTime The caller is thinking; wait without speaking

shouldWaitForMore and shouldGiveTime only take effect when ENABLE_INCOMPLETE_TURN_DETECTION=true.

To transfer, return:

{
  "response": "I'll connect you with a customer service representative right away.",
  "shouldEscalate": true
}

To end the call, return:

{
  "response": "Thank you for calling! Have a great day. Goodbye!",
  "shouldHangup": true
}

A transfer that fails or is not configured plays a message and ends the call; see Conversation behaviour.

When the AI is slow or fails

Two messages cover a struggling brain. They play only when the brain is slow or fails.

Variable Default What it does
TIMEOUT_MESSAGE_ENABLED false When true, a slow reply makes the gateway speak the timeout message while it keeps waiting
LLM_TIMEOUT_MESSAGE built-in English The slow-reply message
LLM_TIMEOUT_MESSAGE_ML built-in English The slow-reply message for Malayalam calls
LLM_FINAL_TIMEOUT_MESSAGE built-in English Spoken on hard failure
LLM_FINAL_TIMEOUT_MESSAGE_ML built-in English Hard-failure message for Malayalam calls

Only the _ML variants exist, and they apply only to Malayalam (ml-IN) calls. Every other language uses the base message.

  • Slow-reply default: "I'm experiencing some technical difficulties. Please hold on while I try to process your request."
  • Hard-failure default: "I'm sorry, I'm having trouble processing your request right now. Please try again in a moment."

The hard-failure message is spoken on a request error, a final timeout, or an error text relayed by LiteBot.

Processing sound

A short filler sound can play while the brain thinks, so the line is not silent.

Variable Default What it does
PROCESSING_SOUND_ENABLED false Turn the filler on
PROCESSING_SOUND_TYPE chime Built-in sound to use
PROCESSING_SOUND_FILE empty Your own file, absolute or relative to the install directory
PROCESSING_SOUND_VOLUME 0.3 Playback volume
PROCESSING_SOUND_START_DELAY 2000 Milliseconds of waiting before the sound starts
PROCESSING_SOUND_LOOP false Repeat the sound while waiting
PROCESSING_SOUND_LOOP_DELAY 2000 Milliseconds between repeats
PROCESSING_SOUND_HARD_CUT true Cut the filler the instant speech is ready; false lets the phrase finish