All case studies

AI Automation case study

Fiona

Built for a client. A desktop voice agent that answers and places real phone calls, transcribes them, captures leads, and prices every call from billed usage.

Fiona interface
The Problem

What was actually broken

A client needed to make and receive a high volume of routine phone calls without hiring for it. Qualifying enquiries, chasing a list, answering the same handful of questions.

The usual approach is a menu tree, and everyone has hung up on one. The alternative is a speech-to-speech model that holds an actual conversation, and by the time we built this that had stopped being research. The engineering problem was not intelligence, it was plumbing: a phone call and a realtime model speak different protocols, different audio formats and different sample rates, and neither of them waits.

The commercial problem underneath it was cost. Voice models bill per token, telephony bills per minute, and both are easy to guess at and easy to be wrong about. A tool that tells you a call cost roughly forty cents is not something a business can plan against.

Our Approach

The decision that shaped everything else

A call is a bridge between two sockets

Twilio streams the caller's audio over a websocket. The realtime model expects a websocket of its own. Fiona sits in the middle holding both open, transcoding between telephony G.711 and what the model wants, in each direction, while the conversation is happening. Latency is the whole product here: a delay that would be invisible in a chat interface is a person deciding you are not listening.

Price from what was billed, never from an estimate

Costs come from the exact token counts the realtime API reports and the exact duration Twilio reports, not from a rate multiplied by a guess. Every call carries a real figure, and those roll up per agent and per month broken down by where the money actually went. A team can budget against that.

Capture the lead twice, because the agent will miss things

Agents record structured fields mid-call through tools and confirm them out loud with the caller, which is the only way to be sure a phone number was heard correctly. Then after the call a text model re-reads the entire transcript and catches what the live agent did not. Both paths write into one leads view. Relying on either alone loses records.

Give the campaign the rules a human dialler already follows

Outbound work runs from a spreadsheet: one call at a time, paced rather than blasted, retried on no answer, held inside permitted calling hours in the contact's own time zone, and skipping anyone on the do-not-call list. Those constraints are not features bolted on afterwards, they are what makes the thing legal and tolerable to be on the receiving end of.

The Build

What we shipped, and what fought back

Python, FastAPI and a native window

FastAPI on uvicorn handles both the interface API and Twilio's webhooks, running in a background thread. The shell is pywebview over the operating system's own web runtime rather than a bundled browser, so the download is a desktop application rather than a hundred megabytes of Chromium.

Writing a codec because the standard library dropped one

Telephony audio is G.711 u-law. Python removed the audioop module in 3.13, which is where that codec used to live, so the conversion is implemented over numpy instead. An unglamorous piece of work, and the call does not connect without it.

Memory that makes the second call different from the first

Contacts accumulate across calls. Prior summaries and captured fields are folded into the agent's instructions before it dials, so somebody who has spoken to Fiona before is not asked the same questions again. Webhook signatures are validated, and the time zone database ships with the app because Windows does not provide one.

The Result

The numbers it holds

Fiona handles inbound and outbound calling from one desktop application, with per-call transcripts, summaries, captured leads and costs taken from billed usage rather than estimated.

What we carry out of it is that the hard parts of an AI product are usually not the model. The model was the part that already worked. The work was in the audio path, the billing arithmetic, the calling rules and the second pass that catches what the first missed. That ratio holds on most AI builds we take on, and it is why we scope them around the plumbing rather than the prompt.

Built with
PythonFastAPIOpenAI Realtime APITwilioWebSocketspywebviewNumPy

Fiona is the deep end of what we build with language models: real-time audio, real money, real phone numbers. That work sits under our AI automation service, where the scope, timeline and starting price are published before you talk to anyone.

Next case study

SEO Dashboard

Tell us what’s slowing you down.

Fixed scope, quoted before kickoff, four to eight weeks to production. You talk to the engineer who writes your code.

Start a project