Tasca
A voice agent that answers a Lisbon restaurant's phone and books tables in Portuguese.
- Year
- 2026
- Role
- Solo, end to end
- Stack
- ElevenLabs Agents · Twilio · FastAPI · Postgres · React

The problem
Small restaurants lose bookings when nobody can pick up the phone during service. Tasca is a phone agent for Tasca Tagarela, a fictional Lisbon tasca, that takes reservations in European Portuguese, answers questions about hours and the menu, and hands off to a human when it should.
How it works
- A caller dials a Twilio number. ElevenLabs Agents handles speech-to-text, the LLM and text-to-speech.
- The agent can only act through four webhook tools on the FastAPI backend: check availability, book, find a booking and cancel it.
- Confirmed bookings trigger an SMS, and staff manage tables, sittings and bookings in a React admin dashboard.
Key decisions
Tools that return facts, not wording
Each tool replies with only the facts the model needs next, never phrasing, other customers’ data or table numbers. Business outcomes come back as a status instead of an error, so the agent can recover on the call instead of failing.
Forgiving inputs for a model that can be wrong
Times and ids arrive as strings, so a malformed value comes back as “invalid” or “not found” the agent can talk about, rather than a validation error it can’t.
Race-safe bookings, tested for real
Booking rules are pure functions with the clock passed in. Integration tests run against a real Postgres and force two bookings to collide, so the retry path is exercised, not assumed.
Results
- Handles the full booking loop by phone: check, book, find and cancel
- Speaks European Portuguese and never invents facts outside its tools
- Strict typing, unit and integration tests, and CI on every pull request

Staff can book by hand too, using the same availability rules as the agent
What I’d do next
Richer handoff to staff mid-call, menu questions grounded in a real menu, and call analytics in the dashboard.