AI Decision Copilot for Veterinary Clinics β built for UMHackathon 2026 (Final Round).
Latin: medical council / advice. The AI that thinks before the consult, acts after it.
Consilium gives solo vet clinics an AI copilot that briefs the doctor before every consult, captures and structures clinical notes during it, and autonomously follows up with owners after β escalating only the cases that genuinely need the doctor's eyes.
π Repository: https://github.com/Shawnchee/DA-Homies π Live demo: https://consilium-tau.vercel.app
All five required submission artifacts are checked into this repository for easy access. Every PDF document carries the Z AI and YTL AI Labs logos on the cover page as required by the submission guidelines.
| # | Deliverable | File | Description |
|---|---|---|---|
| 1 | πΎ Code Repository | https://github.com/Shawnchee/DA-Homies | Full source β Next.js 16 + Claude (Haiku 4.5 / Sonnet 4.6) + Supabase + grammY Telegram bot. Live build at https://consilium-tau.vercel.app. |
| 2 | π§ͺ Refined QA Testing Document | UMHakcathon2026 Refined Testing Analysis Documentation (Final Round) DaHomies.pdf |
Updated test strategy, expanded test matrix, coverage, defect tracking and regression plan for the final round. |
| 3 | π Deployment Plan | Deployment Plan.pdf |
Architecture, environments, CI/CD (Vercel + GitHub Actions AI-eval + Supabase migrations + clinic-brain-sync cron), secret management, step-by-step deploy, monitoring, rollback, risks. |
| 4 | π Business Proposal | UMHackathon2026 Business Proposal (DAHOMIES).pdf |
Market sizing, pricing tiers, go-to-market motion, unit economics, and financial model for the developed product. |
| 5 | π€ Final Round Pitch Deck | Consilium Pitch Deck FINAL LATEST.pdf |
Final-round presentation slides covering problem, solution, decision layer, demo highlights, traction, and ask. |
π Full submission Drive folder: https://drive.google.com/drive/u/0/folders/160O04WT0iuOfyCdfYf1EiLhesZAOUw5k
| Deliverable | File |
|---|---|
| π PRD (Product Requirements) | PRD.pdf |
| ποΈ SAD (System Architecture) | SAD.pdf |
| π§ͺ QATD (initial QA document) | QATD.pdf β superseded by Refined QATD above |
βΆοΈ Watch the pitch + product demo: https://drive.google.com/file/d/1XFIBHLVO8OItMsTh8jcMqsAVfZDE3XTE/view?usp=drive_link
The video walks through the problem, the three-stage decision layer (pre-consult brief β consult capture β post-discharge triage), and a live end-to-end demo of the Telegram-based owner follow-up triggering an escalation card on the doctor dashboard.
The owner-facing follow-up channel is live on Telegram as @consilium_vet_bot. A real grammY bot talks to the Claude triage agent (Sonnet 4.6) and writes decisions back to Supabase, which the dashboard picks up over Realtime.
- Copy
.env.local.exampleβ.env.localand fill in:ANTHROPIC_API_KEY(from console.anthropic.com β required to leave mock mode)DEEPGRAM_API_KEY(from console.deepgram.com β $200 free credit on signup, required for voice consult capture)TAVILY_API_KEY(from app.tavily.com β 1k free searches/mo, required for the LLM's web-search tool)TELEGRAM_BOT_TOKEN(from @BotFather)NEXT_PUBLIC_SUPABASE_URL,NEXT_PUBLIC_SUPABASE_ANON_KEY,SUPABASE_SERVICE_ROLE_KEY
npm install- Apply migrations + seed (via Supabase MCP or psql):
supabase/migrations/*.sqlthensupabase/seed.sql.0004_tavily_cache.sqlis optional β without it Tavily still works, just uncached.0005_storage_buckets.sqlis recommended for production β without it photos work but use inline base64 instead of public Storage URLs (no audit trail, no dashboard thumbnails).
In one terminal, start Next:
npm run dev # http://localhost:3000In a second terminal, start the polling bot:
npx tsx scripts/start-bot.tsYou should see [bot] authenticated as @consilium_vet_bot ....
-
Open Telegram β message
@consilium_vet_botwith/start. It replies with your chat id. -
Seed a follow-up row linked to that chat id (optionally for a specific patient, e.g.
Milo):npx tsx scripts/send-test-followup.ts <CHAT_ID> [PATIENT_NAME]
The bot sends the 24h opener in Telegram and creates a
followupsrow in Supabase.
Reply in Telegram. Examples of what each branch looks like:
- Clear β "She ate breakfast and is bouncing around like normal." β bot confirms, decision
clear. - Monitor β "Eating a little, still a bit slow but better than yesterday." β bot acknowledges, decision
monitor. - Escalate β "She's bleeding from the incision and won't stand." β bot flags urgent, decision
escalate, and the/dashboardpage surfaces an escalation card within 1β2 seconds via Supabase Realtime. - Tool call (ambiguous) β "Not sure, seems off." β on turn 1 the agent calls a tool (e.g.
request_photo,request_temperature,request_appetite_timeline) and asks a clarifying question. Your next reply commits to a terminal decision. - Owner photo β send a photo (with or without caption) β the bot downloads it, persists to the
owner-photosSupabase Storage bucket, and Claude vision factors it into the differential alongside the conversation history. The terminal log shows the public URL.
Watch the terminal running start-bot.ts β you'll see colour-coded boxes for owner inbound, agent reasoning, tool call or decision, and the outbound reply. Open http://localhost:3000/dashboard in parallel to see the escalation card appear live.
| Layer | Tool | Notes |
|---|---|---|
| App framework | Next.js 16 (App Router) + React 19 | Frontend + API routes in one repo, deploys as one unit |
| Styling | Tailwind CSS v4 | Utility-first styling |
| Motion / 3D | motion, three.js (r184) | Dog mascot cursor tracking + page transitions |
| Reasoning + vision | Anthropic Claude β Haiku 4.5 (brief), Sonnet 4.6 (consult, triage) | Multimodal: wound photos / lab images / X-rays pass alongside text. Per-feature model overrides via env. |
| LLM tool-use | tavily_search (server-executed) + 5 user-facing clarifying tools (request_photo, request_temperature, request_appetite_timeline, request_medication_compliance, schedule_doctor_callback) + emit_* structured-output tools |
See lib/tools/registry.ts. Tavily results are 7-day cached in tavily_cache. |
| Speech-to-text | Deepgram nova-3 | Voice consult dictation via POST /api/transcribe. Auto language detection (Bahasa / English / Mandarin code-switching). |
| Web-search | Tavily | Drug-recall + fresh clinical guidance lookups. Optional β when key is absent, Claude proceeds without web context. |
| Telegram bot | grammY (TypeScript) | Polling in dev (scripts/start-bot.ts), webhook route (app/api/telegram/webhook) ready for prod |
| Database | Supabase (PostgreSQL) | Patients / visits / followups / corrections + tavily_cache |
| Realtime | Supabase Realtime | Dashboard live updates the moment a triage decision is written |
| File storage | Supabase Storage | consult-photos + owner-photos public buckets β inline base64 fallback when buckets are missing |
| Agent framework | LangGraph (Python sidecar) | Deferred to finals. Today's TS tool-use loop in lib/llm.ts handles all flows. |
| Deployment | Vercel | One-command deploy, free tier |
| Demo data | Synthetic JSON seed | 150 patients, 10 diagnoses, 3 recovery patterns |
ββββββββββββββββββββββββββ ββββββββββββββββββββββββββββββββββββββ
β Pet Owner (Telegram) ββββββββΊβ Telegram Bot (grammY) β
ββββββββββββββββββββββββββ β β’ polling (dev) β
β β’ webhook (prod) β
ββββββββββββββββ¬ββββββββββββββββββββββ
β shared handler
βΌ
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Next.js 16 (App Router) β single repo β
β β
β App pages (React 19 + Tailwind v4 + three.js): β
β β’ /dashboard /consult /follow-ups /analytics /passport β
β β
β API routes: β
β POST /api/brief β Claude Haiku 4.5 (emit_brief) β
β POST /api/consult β Claude Sonnet 4.6 (emit_consult + β
β tavily_search, multimodal) β
β POST /api/triage β Claude Sonnet 4.6 (tool-use loop: β
β clarifying Γ 1 OR emit_decision) β
β POST /api/transcribe β Deepgram nova-3 β
β POST /api/upload β Supabase Storage β
β POST /api/corrections β feedback loop (few-shot) β
β POST /api/telegram/webhook β
β β
β lib/llm.ts ββ tool-use loop, vision, per-feature model routing β
β lib/tools/ ββ tavily + clarifying + emit tool registry β
β lib/prompts.ts ββ system prompts with guardrails β
ββββββββββββββββββββββββ¬βββββββββββββββββββββββββββββββββββββββββββββββ
β
ββββββββββββββββΌββββββββββββββββββββββββββββββββββ
βΌ βΌ βΌ
ββββββββββββββββ βββββββββββββββ ββββββββββββββββββββββββββββββββββββ
β Anthropic β β Deepgram β β Supabase β
β Claude API β β nova-3 STT β β β’ Postgres (patients/visits/ β
β (Haiku 4.5 β β β β followups/corrections/ β
β + Sonnet β β β β tavily_cache) β
β 4.6) β β β β β’ Realtime (dashboard updates) β
ββββββββββββββββ βββββββββββββββ β β’ Storage (consult-/owner- β
β photos buckets, public) β
βββββββββββββββ ββββββββββββββββββββββββββββββββββββ
β Tavily β
β Search β
β API β (tool-called by Claude during consult / triage when
βββββββββββββββ drug-recall or fresh-guidance check is needed)
BEFORE DURING AFTER
ββββββ ββββββ βββββ
ββββββββββββββββββββ
[F1] Pre-consult brief [F2] Consult capture β [F3] Telegram β
Haiku 4.5 Sonnet 4.6 β follow-up β
emit_brief emit_consult β Sonnet 4.6 β
β + tavily_search β tool loop β
βΌ + vision (photos) β β
5-line patient β β clear / monitor β
briefing card βΌ β / escalate β
SOAP + Rx + billing ββββββββββ¬ββββββββββ
+ todos β
βΌ
[F4] Doctor dashboard
Realtime escalation
β
βΌ
[F5] Doctor approves /
edits β feeds
back as few-shot
β
βΌ
[F6] Pet passport
auto-updated
For the full architecture (sequence diagrams, deployment topology, security model), see SAD.pdf.
npm install
cp .env.local.example .env.local # fill in keys as you get them
npm run dev # http://localhost:3000The app boots in mock mode when ANTHROPIC_API_KEY is missing β every page renders from lib/data.ts / lib/glm-fixtures.ts and no network calls are made. Add keys later to enable the live integrations phase by phase (see TODO.md).
All keys are documented in .env.local.example. The groups that flip the app out of mock mode:
ANTHROPIC_API_KEYβ required. Reasoning + vision (Claude Haiku 4.5 / Sonnet 4.6).DEEPGRAM_API_KEYβ required for voice capture in F2 (/api/transcribe).TAVILY_API_KEYβ optional. When present, the LLM gets atavily_searchtool for drug-recall and fresh-guidance lookups. When absent, the model proceeds without web context.NEXT_PUBLIC_SUPABASE_URL+NEXT_PUBLIC_SUPABASE_ANON_KEY+SUPABASE_SERVICE_ROLE_KEYβ Supabase project settings.TELEGRAM_BOT_TOKENβ @BotFather (needed for the bot scripts above).
Per-feature model overrides (defaults baked in code): ANTHROPIC_MODEL_BRIEF, ANTHROPIC_MODEL_CONSULT, ANTHROPIC_MODEL_TRIAGE.
Clinic identity is env-driven (no hardcoded clinic name): NEXT_PUBLIC_CLINIC_* (client) + CLINIC_* (server) β see lib/env.ts and lib/clinic.ts.
app/
(app)/ # authed shell: dashboard, consult, follow-ups, analytics, passport
api/ # server routes (brief, consult, triage, transcribe, upload, followups, telegram/webhook, ...)
layout.tsx, page.tsx # marketing landing
components/
app-shell/ # store, header, page header, escalation modal, toast, skeletons
react-bits/ # animation primitives
dogs.tsx # three.js hero/companion
landing-page.tsx
lib/
data.ts # mock data (display-only overlays once Supabase is live)
types.ts # domain types
tokens.ts # design tokens
env.ts # typed env reader + mock-mode helpers
clinic.ts # client-side clinic identity (NEXT_PUBLIC_CLINIC_*)
llm.ts # Anthropic Claude wrapper β tool-use loop + vision (per-feature model routing)
glm.ts # back-compat re-export of llm.ts
glm-fixtures.ts # triage/brief/consult fixtures (mock mode)
prompts.ts # Claude prompt templates with tool + vision guardrails
storage.ts # Supabase Storage upload helper (consult-photos / owner-photos) with base64 fallback
tools/
tavily.ts # web-search tool def + executor + 7-day cache
registry.ts # per-feature tool registry (server / user / emit handling modes)
telegram.ts # grammY bot singleton + send helper + photo download
telegram-handler.ts # shared inbound handler (polling + webhook) β text + photo
supabase.ts # browser + server clients
scripts/
start-bot.ts # polling process (dev)
send-test-followup.ts # seed a chat-linked followup + send 24h opener
test-glm.ts # Claude smoke (brief, consult, triage)
test-tavily.ts # Tavily live-search smoke
test-realtime.ts # realtime smoke
test-tool-calling.ts # 2-turn triage smoke
supabase/ # migrations + seed
agent/ # LangGraph triage graph (Python sidecar β deferred to finals)
npm run dev # dev server
npm run build # production build (type-checks + compiles)
npm run start # serve production build
npm run lint # eslint
npx tsx scripts/start-bot.ts # polling Telegram bot
npx tsx scripts/send-test-followup.ts <CHAT> [PET] # seed + opener
npx tsx scripts/test-glm.ts # Claude (or fixture) smoke for brief/consult/triage
npx tsx scripts/test-tavily.ts # Tavily live-search smoke
npx tsx scripts/test-realtime.ts # Supabase Realtime smoke
npx tsx scripts/test-tool-calling.ts # multi-turn triage smokeBuilt by DA-Homies for UMHackathon 2026.
Hackathon submission β all rights reserved by the team.