๐Ÿ”ฉ Hackathon demo ยท fictional company

Schraube โ€” the sales rep's voice in the car

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.

Voice-first ยท visible avatar UI ElevenLabs Agents (STT โ†’ LLM โ†’ TTS) Vite ยท React 19 ยท TypeScript ยท Tailwind v4 Deployed on Vercel

What it does

An assistant that shows up at the right moment, by voice

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.

Stage-aware

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.

Grounded, never guessing

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.

Proof-of-action feed

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

Thomas, 54 โ€” strong on product, allergic to software

The primary user

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.

  • Wants: to keep promises, spend more time selling, less on paperwork.
  • Needs: voice-first, phone-first, one or two taps, plain German, no jargon.
  • Trust is earned by: saving time day one, always explaining why, and never acting without a clear yes.

Also built for the team behind it

The project cleanly separates content from platform, so non-engineers own what the assistant knows:

  • Content people edit plain-prose markdown โ€” the company, the persona, the sales playbook, the account and product data.
  • Platform people own the app, the voice connection, and the tools.
  • Changing the assistant's knowledge is a git commit, not a dashboard click.
The goal is a live demo that cannot break on stage, not a production system. That single goal explains the design: actions are mocked, the look is deliberately simple, and all knowledge lives in editable files.

How it works

Markdown in, voice out

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.

Context .md
company ยท persona ยท avatar ยท sales-process
โ†’
buildPrompt
md + current stage โ†’ dynamic variables
โ†’
ElevenLabs Agent
STT โ†’ LLM โ†’ TTS, turn-taking
โ†’
Client tools
6 actions fire in the browser
โ†’
Activity feed
visible proof it acted

Context โ†’ dynamic variables

Four files are the source of truth for what the assistant knows. Injected at connect time (and frozen for the session):

FileBecomes
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.

The six tools

ToolDoes
lookup_productStock, material, lead time โ€” never a firm price
prepare_quoteStarts a draft quote, never a firm figure
log_noteRecords what was said or promised
create_followup_taskA to-do with a due date
schedule_meetingBooks a follow-up
set_sales_stageMoves between the four stages

The four sales stages

01pre_meetingSurface the right signals from the car: renewals, open quotes, competitor moves, one promise still owed.
02in_meetingAnswer the exact question in a sentence. Look up specs on demand. Otherwise stay silent.
03post_meetingCapture everything before memory fades: notes, promises, follow-up tasks, a draft quote.
04follow_upDays later: one clear recommendation โ€” renew, revive a stale quote, re-engage a quiet account โ€” then do it.

Provisioned from code, not clicked

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.

Two ways to connect โ€” key stays secret

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.

Actions are mocked into the activity feed on purpose: on stage it demos identically and cannot fail because of someone else's API. Swap the handler bodies for real CRM/ERP calls when there's a backend.

Where it stands

Built and demoable

Working now

  • Text + voice loop, stage-aware context pipeline
  • Talking avatar state machine (idle / listening / thinking / speaking)
  • All six client tools wired to the activity feed
  • Agent provisioned from code; real company, persona, account & product context
  • Text mode on by default โ€” fastest way to iterate the pipeline, no mic needed

Known constraints

  • Needs an ElevenLabs key with ConvAI scopes for full provisioning & private tokens
  • products.md is editable context; lookup_product still reads the hardcoded catalogue until it's wired up
  • Design is intentionally crude โ€” the avatar is a swappable SVG
  • Actions are mocked, not connected to a real CRM/ERP