A voice-first AI assistant that rides along with a field sales rep: it preps them before a meeting, answers quietly during it, and captures everything the moment it ends โ so nothing slips between the customer and the paperwork.
What it does
Schraube is the assistant for Schraube GmbH, a fictional German B2B distributor of fasteners and tools. A talking on-screen character is the whole interface. The rep speaks; the assistant listens, answers in one or two sentences, and takes real actions โ drafting a quote, logging a promise, booking a follow-up โ visibly, so the rep always sees what it did.
It behaves differently before, during, after a meeting, and on follow-up. In a meeting it stays terse and only answers what's asked; afterward it becomes proactive and captures everything.
Stock, lead times, and account facts are read from context data, not invented. It refuses to quote a firm price or state a spec it can't verify, and routes those to a human.
Every tool call lands in a visible activity feed. The rep (and the demo audience) watch the note get logged and the quote get drafted in real time.
Who it's for
A field sales rep who lives in his car, visits 6โ8 customers a day, and dreads the evening pile of typing up quotes and follow-ups. Low tech comfort: confident on the phone and WhatsApp, wary of multi-step apps and of "AI" doing something behind his back.
The project cleanly separates content from platform, so non-engineers own what the assistant knows:
How it works
Knowledge lives in markdown files in the repo. At the start of a session those files are injected into the agent as dynamic variables, then ElevenLabs runs the whole voice loop and calls back into the app when it wants to act.
.mdFour files are the source of truth for what the assistant knows. Injected at connect time (and frozen for the session):
| File | Becomes |
|---|---|
company.md | {{company_context}} |
persona.md | {{user_persona}} |
avatar.md | {{avatar_behavior}} |
sales-process.md | {{stage_directive}} โ only the current stage's section |
Two extra data layers โ
accounts.md (mock CRM) and products.md (mock ERP catalogue) โ
give the assistant real facts to cite instead of inventing them.
| Tool | Does |
|---|---|
lookup_product | Stock, material, lead time โ never a firm price |
prepare_quote | Starts a draft quote, never a firm figure |
log_note | Records what was said or promised |
create_followup_task | A to-do with a due date |
schedule_meeting | Books a follow-up |
set_sales_stage | Moves between the four stages |
The agent's prompt and tools live in the repo. npm run provision pushes them to ElevenLabs (idempotent, matched by name). The dashboard is an output, not an input โ so the config can't silently drift from what's in git.
Public: the browser connects with just the agent id (fine for a fictional demo).
Private: a Vercel function api/token.ts mints a short-lived WebRTC
token, so the API key never leaves the server. It is never prefixed with
VITE_, which would bundle it into the browser.
Where it stands
products.md is editable context; lookup_product still reads the
hardcoded catalogue until it's wired up