Lalabase
Tickets, Doku, Zeiterfassung und Kundengespräche an einem Ort, durchsuchbar per KI. Für Softwarefirmen mit Kundenprojekten. Open Source: auf deinem eigenen Server oder in unserer Cloud in Deutschland.
Translation pending
Post-call pipeline and dashboard for Aangan Studio
BusinessTypeScript · PLpgSQLGitHub @lopamudrabareja12-webOnlineOwner unconfirmed
Have you tried it? One tap is enough. No sign-in needed.
No updates detected yet. GitHub releases will appear here.
Owners of public repositories under a personal GitHub account can sign in to verify ownership and manage the introduction themselves. No administrator approval is needed.
Sign in, generate a verification file, and commit it to this repository’s default branch within 30 minutes. Files on other branches or forks do not count. Then check the file below to manage the project without administrator approval. Keep the file to retain your access.
If needed, you will go to sign-in. After signing in, return here and press your chosen verification button again.
Run /nomorevibe verify in your project folder to verify ownership and manage the introduction yourself.
Verify in one minuteAsk about other verification options
Loading the full README. The saved excerpt is shown below.
An AI voice agent on Vaani answers every incoming call to Aangan Studio, day or night. This repo is
everything that happens after the call: a webhook receives the finished call, a pipeline extracts and
qualifies the enquiry, designers are emailed and claim leads, and Nikhil gets a dashboard of what the
system costs and what it generates.
Scope is incoming phone calls only. WhatsApp and the web form are not built.
Decisions already made live in CLAUDE.md. Source material is in source/.Read the full README ↗An AI voice agent on Vaani answers every incoming call to Aangan Studio, day or night. This repo is everything that happens after the call: a webhook receives the finished call, a pipeline extracts and qualifies the enquiry, designers are emailed and claim leads, and Nikhil gets a dashboard of what the system costs and what it generates.
Scope is incoming phone calls only. WhatsApp and the web form are not built.
Decisions already made live in CLAUDE.md. Source material is in source/.
source/pricing.md is
reference only and is never imported by app code or copied into the voice-agent pack.is_historical = true), never mixed into live metrics..env.local. .env.example lists names only.Next.js (App Router, TypeScript) on Vercel · Supabase Postgres · Gemini Flash · Resend · GitHub. INR formatting, Asia/Kolkata time, working hours 10:00 to 19:00 IST.
npm install
cp .env.example .env.local # then fill in values; never commit this file
npm run dev
Migrations are in supabase/migrations/, placeholder seed data in supabase/seed.sql.
Run them in order in the Supabase SQL editor (or with the Supabase CLI: supabase db push).
All tables have row level security on with no policies, so only the server (service-role key) can touch data.
npm test # unit tests; migration tests run the SQL in an in-process Postgres (PGlite)
npm run typecheck
npm run lint
npm run build
crm.objects.contacts.read/write, crm.objects.deals.read/write, crm.objects.owners.read,
crm.schemas.deals.read/write, crm.schemas.contacts.read. A missing scope returns a 403 whose message names it.
The service key is used exactly like the old private-app token (sent as a Bearer token); verified on a free account..env.local as HUBSPOT_ACCESS_TOKEN (and the numeric hub id as HUBSPOT_PORTAL_ID). Never paste it
anywhere else, and rotate it immediately if it is ever shown in a chat or screenshot.npm run hubspot:setup # dry run, read-only
npm run hubspot:setup -- --apply --adopt-default # free plan: reuse the EMPTY default pipeline
The setup is idempotent, never deletes anything, and refuses to rewrite a pipeline that already has deals.
POST /api/webhooks/vaani verifies the signature, then for each call: stores it (idempotent on the call id), removes
caller identifiers, asks Gemini to fill a structured record, applies Nikhil's rubric in plain code
(src/lib/pipeline/rubric.ts, unit-tested), and queues the HubSpot write (contact, deal, note, tasks) in an outbox with
retries so a HubSpot outage never loses a call.
Outcomes: qualified, qualified with flags, declined (with reason code, kept for review), deferred (with revisit date), escalation (existing-client complaint or lost follow-up), incomplete (missed or dropped call).
Assumptions to replace: Vaani's real payload and signature format have not been seen. The adapter
(src/lib/vaani/adapter.ts) and signature check (src/lib/vaani/signature.ts) are written against an invented sample in
fixtures/vaani/FAKE-sample-call.json.
Privacy limit: phone numbers, emails and the caller's own name are removed before Gemini. Other people's names (a referrer, a designer) are kept, because the referral source is a field we need.
Runs the 20 historical phone enquiries through the real pipeline with no phone and a mock HubSpot, and compares each with the intended outcome. Calls are split into 10 prompt examples and 10 held-out calls.
npm run replay # offline, hand-labelled extractions: tests the rules and wiring
npm run replay -- --extractor=gemini # BILLED: runs the real model (needs GEMINI_API_KEY and GEMINI_MODEL in .env.local)
The offline run does not measure Gemini's accuracy (the labels were written by hand from the same transcripts).
Only --extractor=gemini does. A page for the Replay Lab arrives with the console in Phase 4.
voice-agent/; follow voice-agent/SETUP.md)POST /api/cron/tick (secret required) runs every minute from a Supabase pg_cron job named aangan-tick: re-runs stuck calls,
pushes queued writes to HubSpot, sends due emails, auto-assigns. To stop it: select cron.unschedule('aangan-tick');npm run designers:sync -- --apply links real HubSpot users as designers. npm run phase3:smoke and npm run email:test are live tests.Sign in at /login with DASHBOARD_PASSWORD (set it in .env.local and in Vercel; with no password set, nobody gets in). The public page / stays
the historical-replay dashboard; the console shows live calls only and is private because it holds caller details.
/calls/<id>, which redirects to the signed-in transcript page. Access is checked three times: a proxy before anything renders, the layout, and every data read and action.voice-agent/ has everything to paste into Vaani: prompt.md (the system prompt, with five examples adapted from the
prompt-example half of the historical calls), greeting.md, five knowledge files, and SETUP.md (step by step, with eight test calls).
tests/voice-agent.test.ts guards it: no figure from the internal pricing guide, no currency symbols, the exact approved pricing reply,
the AI-and-recording greeting, one question at a time, every must-have field, the 15-minute complaint rule, and that no held-out call is used as an example.
Four calls show the whole system. There is no inbound phone number yet, so every call starts from Vaani > Agents > aangan-test > Start Test > Audio, which rings the tester's own phone. Wait about two minutes after each call, then look in three places: the dashboard (the Vercel link), HubSpot > Deals (pipeline "Aangan Enquiries"), and the designer's inbox.
Before you start: the designer must be on duty (designers.on_duty), and the every-minute aangan-tick job must be running.
Calls made outside 10:00-19:00 IST are held and their email is sent at 10:00 IST, which is the after-hours rule working, not a fault.
Say: "I want interior design for my 3BHK in Baner, about 1,150 sq ft, whole home. I'm the owner and I'd like it done by March."
Give normal details (for example Wakad, 900 sq ft), then ask "How much will it cost?" twice.
price_asked. The transcript contains no figure.Say: "I'm in Nashik" (anywhere outside Pune and PCMC).
Say: "My designer hasn't replied in five days."
npm run replay runs the 20 labelled historical calls (10 used as prompt examples, 10 held out) through the pipeline and prints the match rate.
These are historical, human-handled enquiries, so they are kept out of the live metrics and out of HubSpot.
npm run replay -- --extractor=gemini measures Gemini's real accuracy (last run: 20/20, 10/10 on the held-out half).
The Phase 4 console (declined-review queue, sync health, designer on-duty toggle) is not built. Gemini is on the free tier and Resend uses its test sender, so use test data only until both are upgraded.