Build it in your project
Paste this line into your agent (Claude Code, Codex, Cursor, OpenCode, Cline). It sets up your key, then builds the pipeline in your project:The code
One file per language. Both readRUNCRATE_API_KEY from the environment; nothing secret is in the code.
What the proof run cost
The Python file on a 6.4-second recorded question (“where is my order A one zero four two?”). Times are from the start of the script. Measured on 2026-10-23 againstapi.runcrate.ai; costs are what the account was billed, read from each response’s X-LLM-Cost header or usage.cost.
The first Python run, with a cold start, had its first audio at 5.5 s; the TypeScript file had its first audio at 6.4 s for $0.0129. Every run looked the order up before answering.
Scale it
- This is turn-based, a few seconds a turn. For sub-second replies, run an open speech model and LLM on one GPU instance next to your telephony and keep the same tool loop.
- The model is the latency dial: one-shot first-token times on the day were Claude Haiku 5.5 0.65 s, Llama 4 Scout 0.79 s, gpt-oss-20b 0.88 s, gpt-oss-120b 1.41 s (free tier), DeepSeek V4.1 Flash 1017 2.18 s. Set
VOICE_LLMto switch. - Calls in parallel: each call is independent; the account’s rate limit (600 requests a minute on the proof key) is the ceiling, not the code.
Gotchas found in the proof run
- Without the tool, several models answered “what are your opening hours?” with invented hours. The system prompt makes the lookup mandatory, and the agent says nothing about an order before the tool answers.
- Kokoro’s response is chunked but not generated incrementally: the first 4 KB of a sentence arrived after about 2.2 s as PCM and 3.4 s as MP3. Split into sentences and send them in parallel; one long request is slower.
- Whisper heard “A 1042” for “A one zero four two”. Normalise ids in the tool (upper case, no spaces) rather than trusting the transcript.