Lalabase
티켓·문서·근무시간·고객대화를 한 곳에 모아 KI로 검색, 소프트웨어 기업 고객 프로젝트용, 오픈소스로 자체 서버·독일 클라우드에 배포
아직 감지된 업데이트가 없습니다. GitHub 릴리스가 나오면 여기에 보입니다.
개인 계정의 공개 저장소 소유자는 GitHub로 로그인해 운영자를 확인하고 소개를 직접 관리할 수 있습니다. 관리자 승인은 필요하지 않습니다.
로그인한 뒤 확인 파일을 만들어 이 저장소의 기본 브랜치에 30분 안에 커밋해 주세요. 다른 브랜치나 포크의 파일은 인정하지 않습니다. 파일을 올린 뒤 아래에서 확인하면 관리자 승인 없이 관리할 수 있습니다. 자격을 유지하려면 파일을 남겨 두세요.
로그인이 필요하면 로그인 화면으로 이동합니다. 로그인 후 이곳으로 돌아와 원하는 확인 버튼을 다시 눌러 주세요.
프로젝트 폴더에서 /nomorevibe verify를 실행하면 소유권을 확인하고 소개를 직접 관리할 수 있습니다.
1분 만에 확인하기메이커가 쓴 소개는 위의 한 줄이 전부입니다. 더 자세한 내용은 저장소 README에서 읽을 수 있습니다. 저장소 README ↗
README 전체를 불러오는 중입니다.
README 전문 보기 ↗Every phone enquiry goes to a voice agent (Vaani Labs) at any hour. The agent qualifies the caller against Nikhil's rules and books a consultation on the call (Cal.com). After the call, Gemini Flash classifies the transcript. Qualified leads become HubSpot deals, and the designer gets a brief by email (Resend) within two minutes. Nikhil follows it all on a mobile dashboard.
Next.js 16 (App Router, TypeScript) on Vercel · Neon Postgres · HubSpot free CRM · Resend · Cal.com · Gemini.
| Part | State |
|---|---|
| Database schema + seed | ✅ db/0001_init.sql, db/seed.sql (every app query checked against real Postgres) |
| Replay test | ✅ npm run replay -- --stub passes. Real-Gemini run needs the 12 transcripts in tests/fixtures/transcripts/ |
| Classification (Gemini) | ✅ written, not yet run against real transcripts |
| Routing + emails | ✅ written, not yet run against live Neon/Resend |
| Cal.com tools | ✅ live: Consultation event 7422764 (Mon–Sat 10:00–19:00 IST, 12 h notice, 30 min buffer), slots verified 10 Oct 2026 |
| Vaani adapter | ⏳ stub: src/lib/vaani/adapter.ts returns 501 until written against Vaani's API docs |
| HubSpot | ✅ written, not yet run live |
| Dashboard | ✅ |
| Crons | ✅ (see the cron note below) |
Caller ─▶ Vaani agent ──(mid-call)──▶ POST /api/tools/availability ─▶ Cal.com slots for the assigned designer
└─(mid-call)──▶ POST /api/tools/book ─▶ Cal.com booking (or "a designer will call within 2 hours")
call ends ──▶ POST /api/webhooks/vaani
1. verify signature 2. store raw payload 3. 200 OK
4. after(): Gemini classify → validate → confidence gate → route
qualified → designer email (+ack button) → HubSpot contact + deal
existing_client → [URGENT] email to Nikhil + escalation address
needs_review → email Nikhil (+ "pending review" brief to the designer if already booked)
declined/not_a_lead/dropped → log only (dropped with a number → call-back list)
agent said a price → compliance incident + email Nikhil
Crons: ack-check every 15 min (escalate after 2h, retry failed processing) · HubSpot sync hourly · digest 08:45 IST
Only src/lib/vaani/ knows Vaani's payload shapes. Everything else uses NormalizedInteraction / NormalizedToolCall (src/lib/types.ts). The calls table has a channel column, so WhatsApp or a web form can come in later as another adapter with no schema change.
db/0001_init.sql, then db/seed.sql. From a terminal, psql "$DATABASE_URL" -f db/0001_init.sql does the same.areas (Pune localities they prefer), and calcom_event_type_id (step 3).DATABASE_URL. The app talks to Neon over HTTPS with @neondatabase/serverless, which suits Vercel functions: there's no connection pool to manage.DATABASE_URL for you.Only the server holds DATABASE_URL. The browser never talks to the database.
Copy .env.example → .env.local for local dev, and set the same keys in Vercel. EMAIL_TEST_MODE defaults to true: every email goes to EMAIL_TEST_RECIPIENT with a [TEST → real recipient] prefix. Set it to false only when going live.
designers.calcom_event_type_id. Designers without an ID are never offered to callers during a call.CALCOM_API_KEY.CALCOM_FALLBACK_ATTENDEE_EMAIL.Qualified calls become a HubSpot contact plus a deal in the Consultation booked stage, and the dashboard's pipeline panel syncs hourly.
crm.objects.contacts.read/write, crm.objects.deals.read/write and crm.schemas.deals.read/write. Put the token in .env.local and Vercel as HUBSPOT_ACCESS_TOKEN.npm run hubspot:setup. It checks the token, creates a test pipeline "Aangan enquiries (test)" (or, on the free plan's single pipeline, adds a Consultation booked stage to it) and prints HUBSPOT_PIPELINE_ID and HUBSPOT_STAGE_CONSULTATION_BOOKED. Set both in .env.local and Vercel, then redeploy.Deals never get an amount from this system. The dashboard's "won value" only sums amounts a person typed into HubSpot on won deals.
Verify your sending domain, create an API key → RESEND_API_KEY, and set RESEND_FROM.
Pending API docs. Once the adapter is written:
agent/vaani-system-prompt.md into the agent. Apply the platform settings and run the red-team test script in agent/README.md before go-live and after every prompt change.check_availability → POST <APP_URL>/api/tools/availability. Args: location (string), consultation_mode (home | studio).book_consultation → POST <APP_URL>/api/tools/book. Args: slot (ISO start time returned by check_availability), caller_name, phone, location, consultation_mode.POST <APP_URL>/api/webhooks/vaani with VAANI_WEBHOOK_SECRET.APP_URL to the production URL.vercel.json schedules the daily digest at 15 3 * * * (03:15 UTC = 08:45 IST)..github/workflows/crons.yml). Add the repo secrets APP_URL and CRON_SECRET. GitHub can start scheduled runs a few minutes late, which is fine for these jobs. On Vercel Pro you can move both into vercel.json and delete the workflow.Authorization: Bearer $CRON_SECRET.npm run replay -- --stub # no network: gate, routing plan, email rendering, price guard
npm run replay # real Gemini over tests/fixtures/transcripts/T*.txt (needs GEMINI_API_KEY)
npm run replay -- T07 T10 # selected cases
Hard failures: outcome, decline_reason, pricing_requested, price_mentioned_by_agent (must be false), routing (T09 must never create a deal or handoff), and any price figure in a rendered email or deal. Flags are free text, so they are printed side by side but never fail the run.
src/lib/price-guard.ts). Caller-derived text is redacted before rendering. Every email and deal description is scanned again before sending, and a hit blocks the send and logs an incident. A volunteered budget shows as "Mentioned by caller (amount withheld)". The dashboard transcript view hides amounts too.incidents row + immediate email to Nikhil.src/lib/log.ts strips them from logs.(provider, external_id). Processing claims the row atomically, reuses an existing classification, and every side effect has its own dedupe record (handoffs, hubspot_sync, incidents, emails.dedupe_key).needs_review: the designer still gets the brief, marked "pending review", so the slot isn't missed. Nikhil gets the review email. No HubSpot deal is created until Nikhil decides.areas match the caller's location. The pointer moves only when a booking is made, or when a handoff is assigned post-call.