Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.getpatter.com/llms.txt

Use this file to discover all available pages before exploring further.

Patter conducts the call (speech-to-text, the voice agent, text-to-speech, and the carrier). The consult tool gives that in-call agent an on-demand bridge back to your own agent — reachable over HTTP — for deeper reasoning, fresh information, or an action beyond the call. This is the dispatch + consult pattern: your orchestrator (or any HTTP endpoint you host) stays off the per-turn path. It is consulted only when the in-call agent decides it needs help, so ordinary turns keep their low latency while hard turns can reach your full reasoning stack.

When to use it

  • The caller asks something the in-call agent can’t answer from its prompt (order status, account details, a policy lookup).
  • You already run an agent (e.g. an internal assistant) and want phone calls to tap into it without putting it on every conversational turn.
If instead you want your LLM to drive every turn, that is a different (“brain-on-the-line”) mode — consult is the lighter, lower-latency default.

Quickstart

from getpatter import Patter, ConsultConfig

phone = Patter(carrier=...)

agent = phone.agent(
    system_prompt="You are front-desk support. If you can't answer directly, "
                  "consult your back-office agent.",
    stt=...,            # any Patter STT (pipeline) — or use a Realtime engine
    tts=...,
    consult=ConsultConfig(
        url="https://my-orchestrator.example.com/consult",
        headers={"Authorization": "Bearer ${ORCHESTRATOR_TOKEN}"},
        timeout_s=30.0,
    ),
)

phone.serve(agent)
When consult is set, Patter auto-injects a consult_agent tool into the agent (Realtime and Pipeline modes). The model calls it with a single request string when it needs help.

The HTTP contract

Patter POSTs JSON to your url:
{
  "request": "When does order 4815 ship?",
  "call_id": "CA0000000000000000000000000000a001",
  "caller": "+15555550100",
  "callee": "+15555550199"
}
Your endpoint returns JSON with a reply (or response / text / result / answer / message) string, which the agent speaks:
{ "reply": "Order 4815 ships Tuesday by end of day." }
Plain text and other JSON shapes are accepted too (the raw body is spoken / serialized as a fallback).

ConsultConfig

FieldDefaultNotes
url— (required)HTTP(S) endpoint. SSRF-validated at call start (private / loopback / link-local hosts and non-HTTP schemes are rejected).
headersNoneSent with every POST (e.g. an Authorization bearer). Never logged.
timeout_s30.0Per-consult timeout — higher than the generic webhook-tool default (10 s) because a consult may run deeper reasoning.
tool_name"consult_agent"The tool name the model sees.
description(sensible default)Tune to steer when the agent escalates.
allow_loopbackFalseOpt-in: permit a loopback / private / link-local url (e.g. a local back-office agent on 127.0.0.1 or an RFC1918 host). See Pointing consult at a local agent.

Pointing consult at a local agent

By default the consult URL is SSRF-validated and loopback / private / link-local targets are rejected — so http://localhost:8000/consult will not pass. When your back-office agent (or a thin adapter) runs on the same machine, set allow_loopback=True to relax that check:
agent = phone.agent(
    system_prompt="...",
    consult=ConsultConfig(
        url="http://localhost:8000/consult",   # local agent on loopback
        timeout_s=30.0,
        allow_loopback=True,
    ),
)
What the flag does:
  • Scope. Relaxes the loopback (127.0.0.0/8, ::1, localhost), RFC1918 private (10/8, 172.16/12, 192.168/16), and link-local host checks for the consult URL only. The generic webhook-tool validator path — which can be reached by tool / LLM input — stays strict and is unaffected.
  • Always enforced. Non-HTTP(S) schemes (file:, javascript:, …) are rejected even with the flag on.
  • Why it is safe. The consult URL is SDK-user configuration, not caller-derived input. Cloud-metadata hostnames also become reachable when opted in — only enable the flag for a URL you control.

Behaviour & limits

  • Failure is graceful. A timeout, non-2xx response, or unreachable endpoint does not crash the turn — the agent speaks a short fallback line and carries on.
  • Security. The URL is SSRF-validated; header values are never logged. The URL is trusted SDK configuration (not caller-supplied). To point consult at a local agent, opt in with allow_loopback=True — see Pointing consult at a local agent.
  • Mode support. Injected in Realtime and Pipeline modes. ElevenLabs ConvAI is not supported — its tools live on the ElevenLabs-hosted agent, so a warning is emitted if you set consult with that provider.
See the TypeScript version for the same feature in getpatter for Node.