Inspiration
It started with a quote from a sales rep: "we lose some clients because we don't know what to ask." And another: "once you exhaust your network you're actually pretty stuck outside of word of mouth referrals and paid marketing."
Small B2B services firms run out of warm leads, then buy lists against a persona somebody guessed in a workshop.
What it does
The answer to "who should we target" was already sitting in their sales calls, which nobody reviews and nobody writes into the CRM. So the idea became a loop: the call makes the CRM true, the CRM shows who actually converts, and that decides who the team finds next. Your next customer should change when your last deal does.
How we built it
Four people, four lanes, one API seam. FastAPI owns transcription, extraction, scoring, the ideal customer profile and drafts; Next.js renders it; Supabase with pgvector stores it. ElevenLabs is the ears: text-to-dialogue voiced our thirteen labelled fixture calls, Scribe batch feeds the record, Scribe realtime fed the live coach.
We chose models by a rule written before the bake-off ran: the cheapest model within one call of the best on every check. Mistral Medium 3.1 won extraction at a third of a cent per call and DeepSeek V3.2 won the scorecard judge. Every quote a model returns is checked verbatim against the transcript, repaired or dropped.
Challenges we ran into
On Saturday evening we found that two of the AI steps on main were faked: extraction copied the fixture's expected labels and the follow-up was a string template. The rubric says no faked or hardcoded steps, so both were rebuilt that night through one provider-agnostic structured-output helper with the grounding pass behind it. On Llama 4 Maverick that pass repaired ten quotes in thirteen calls, which is when we understood it was load-bearing. Also the lead generation API we wanted to experiment with required a paid plan, so we had to use an alternative method.
The live coach was the feature we were proudest of and the one we cut. It shared the extraction model, and on Mistral its analysis came back as truncated JSON on both runs of the spot check. We pulled it from the demo rather than ship something that hides questions it should not.
The biggest problem was us. Two of us landed rebrands and UI rewrites on top of each other on Sunday evening, a scorecard wiring branch was superseded by a parallel store nobody knew about, and code got overwritten. We fixed it with documentation: claim a row in BOARD.md and push it before touching a file, work only inside your listed folders, keep a dated change log in the architecture doc, and put what only a human can unblock in STATUS.md.
What we learned
Claim before code, one lane each. Four people and their agents merged 91 pull requests in 48 hours, and the days that went well were the days the board and the change log were current. The product is a loop that keeps a CRM honest; the team only worked once we kept our own docs honest too.
Built With
- caddy
- deepseek
- electron
- elevenlabs
- fastapi
- github-actions
- mistral
- next.js
- openai
- openrouter
- pgvector
- postgresql
- python
- railway
- react
- supabase
- typescript

Log in or sign up for Devpost to join the conversation.