An AI dining concierge. Say "dinner with the boys tonight", and a voice agent resolves who's in your group, reconciles what they all like, speaks back the top 3 restaurants and why, books the table, then splits the receipt from a photo.
Built in 24 hours at Hook 'Em Hacks (UT Austin) by a team of 4. Won Most Startup Ready and Best Use of Supabase.
React Native (Expo) · Next.js 16 · Supabase (pgvector · Realtime · Edge Functions) · AWS Bedrock + Lambda · ElevenLabs
crave_demo.mp4
Not rendering? Watch the 2:47 demo on YouTube.
Prerequisites: Node 20+, npm, a Supabase project, and AWS credentials with Bedrock model access.
git clone https://github.com/tanushchauhan/crave && cd crave
cp .env.example .env # fill in SUPABASE_URL + SUPABASE_ANON_KEY at minimumEnv lives in the repo root, not per-app. Both
crave-b2bandcrave-appread../.env*. See docs/client-env.md. Without it the dashboard returns HTTP 500.
Restaurant dashboard at localhost:3000
cd crave-b2b && npm install && npm run devMobile app on the iOS Simulator (web is not a supported target: the voice agent depends on native WebRTC, see crave-app/README.md)
cd crave-app && npm install && npx expo run:ios -d "iPhone 16"Both apps sit behind auth and read live data, so they need a provisioned backend to show anything:
| Step | Where |
|---|---|
| Apply the 33 SQL migrations + deploy 6 Edge Functions | docs/supabase.md · ./scripts/supabase-deploy.sh |
| Deploy the 4 Lambdas, API Gateway, S3 triggers | docs/aws.md · infra/aws/scripts/deploy-aws-from-env.sh |
| Seed demo restaurants, users, and embeddings | cd tools/supabase-seed && npm install && npm run seed |
| Wire the Maple voice agent (ElevenLabs Custom LLM) | maple-voice-agent/ · docs/aws.md |
CRAVE figures out where your group should eat, by actually understanding who's in the group, what they each like, and what the vibe is tonight.
There are two sides to the product:
- Consumer mobile app (React Native + Expo): voice-first group dining assistant. Speak naturally, get personalized recommendations, book in-app, split the bill, and give instant feedback, all in one flow.
- Restaurant B2B dashboard (Next.js): AI chatbot for analytics, real-time bookings feed, menu management, KPI tracking, and a one-prompt AI ad campaign generator.
| Layer | Technology |
|---|---|
| Mobile app | React Native 0.81 + Expo 54 |
| B2B dashboard | Next.js 16 + Tailwind CSS 4 + shadcn/ui |
| Voice assistant | ElevenLabs Conversational AI (Custom LLM, "Maple") |
| LLM reasoning | Amazon Bedrock: Claude Sonnet 4 (Converse API) |
| Receipt / doc OCR | Amazon Bedrock: Claude Sonnet 4 (multimodal vision) |
| Text embeddings | Amazon Bedrock: Titan Text Embeddings v1 (1536-d) |
| Image generation | Amazon Bedrock: Nova Canvas / Stability SD3.5 |
| Ad compositing | Satori, Resvg, then Sharp (server-side PNG rendering) |
| Database | Supabase Postgres + pgvector (HNSW indexes) |
| Auth | Supabase Auth: phone OTP (consumer) + email/password (B2B) |
| Realtime | Supabase Realtime (bookings · orders · menu_items · item_feedback) |
| Edge compute | Supabase Edge Functions (Deno), 6 functions |
| Server compute | AWS Lambda (Node.js 20 ES modules) + API Gateway |
| Item matching | pg_trgm trigram + pgvector cosine (3-stage pipeline) |
- Voice in, voice out: ElevenLabs and Bedrock Claude, connected through an OpenAI-compatible shim proxy
- Text to vector search: a query becomes a 1536-d embedding, then pgvector HNSW cosine ranks restaurants
- Image to structure: a receipt photo passes through Bedrock vision into structured JSON, then item matching
- Text to composited image: a prompt drives Bedrock image generation, an SVG overlay, and a final composited PNG ad
Full-duplex voice powered by ElevenLabs Conversational AI with a custom LLM backend (Bedrock Claude Sonnet 4 via an OpenAI-compatible proxy). Maple handles the entire dining journey: onboarding, recommendations, menu clarification, order placement, and booking confirmation, all through natural speech.
The headline moment: say "dinner with the boys" and Maple resolves your group, fans out to the recommendation engine, and speaks back ranked picks with reasons.
Each user carries a 1536-d preference embedding (Amazon Bedrock Titan Text). The resolve-group Edge function aggregates the group's embeddings into a weighted centroid, filters on hard dietary constraints, and biases the result by context tag ("date night" vs "with the boys" vs "family dinner"). pgvector HNSW cosine search ranks candidate restaurants against the group vector.
Multimodal natural-language Q&A over restaurant analytics. Accepts text, images, and PDFs. Ask "How did my margherita pizza do last week?" and Bedrock Claude Sonnet 4 answers with data pulled from the restaurant's analytics tables. Streaming responses. Embedded directly in the dashboard sidebar.
One prompt produces 3 distinct ad designs, each with:
- A hero image generated by Bedrock (Nova Canvas or Stability SD3.5)
- An SVG overlay (Satori, then Resvg) with caption and hashtags composited by Sharp
- Up to 3 image variants per design
All rendered server-side in the ad-generate Lambda and returned as PNGs.
At CRAVE partner restaurants, Maple runs as an overlay on the visual menu. Tell it what you want, it confirms, the place-order Edge function creates the order, and the item appears live on the restaurant's B2B dashboard via Supabase Realtime.
Snap the receipt and items are parsed, matched, and split in seconds. Each swipe updates your preference embedding.
- Receipt photo uploads through a presigned S3 PUT, which fires a Lambda S3 trigger
- Bedrock Claude vision parses receipt to structured JSON (merchant, line items, totals)
- 3-stage item matching: exact text match, then trigram similarity (pg_trgm), then embedding cosine similarity
- Drag-and-drop assignment UI for putting items onto group member avatars
- Subtotal, pro-rata tax, and a tip slider produce Venmo and CashApp deep links sent per member
- Swipe feedback cards ("was this a hit?") insert a row into
item_feedback - Supabase trigger recomputes the user's preference embedding with a weighted blend (likes: +0.15, dislikes: −0.10, L2-normalised)
crave/
├── crave-app/ # Consumer mobile app (Expo / React Native)
├── crave-b2b/ # Restaurant dashboard (Next.js 16)
├── infra/aws/
│ └── lambdas/
│ ├── bedrock-proxy/ # Bedrock + OpenAI shims for ElevenLabs
│ ├── receipt-ocr/ # S3-triggered OCR + item matching
│ ├── b2b-chat/ # Multimodal B2B chat endpoint
│ └── ad-generate/ # Ad design pipeline
├── supabase/
│ ├── migrations/ # 33 ordered SQL migrations
│ └── functions/ # Deno Edge Functions
│ ├── place-order/
│ ├── confirm-booking/
│ ├── recommend/
│ ├── resolve-group/
│ ├── generate-ad/
│ └── match-receipt-items/
├── maple-voice-agent/ # Maple system prompt
├── scripts/ # Deploy helpers
├── tools/supabase-seed/ # Demo data seeder
└── docs/ # Architecture notes
The 2:47 video runs the full loop on real devices:
- User opens the app, says "Dinner with the boys tonight"
- Maple speaks back the top 3 picks with reasons, from Supabase
resolve-group+recommendrunning live - User books at a CRAVE partner restaurant and the B2B dashboard pings live on the adjacent laptop (Realtime)
- Post-meal: snap a receipt, OCR parses it, drag items to avatars, set the tip, hit Send, and a Venmo deep link fires on a second phone
- Swipe feedback cards appear, and Supabase shows
user.pref_embeddingnumerically shift - Switch to B2B and ask "How did my margherita pizza do last week?", and Ask Crave! streams a response inline
- Ask for "an Instagram ad for our Wagyu burger" and Ad Campaign Studio returns 3 composited PNGs
Every swipe of feedback moves the user's preference vector, so the next recommendation is better than the last.
MIT © 2026 Tanush Chauhan



