Inspiration
Every small business loses money when they can't answer the phone. Wedding photographers lose $72,000/year because they're shooting weddings when couples call. Plumbers miss 40-60% of emergency calls because they're on a job site. The stats are brutal — 50% of customers book the first business that responds.
We built an AI voice agent that plugs into the WeddingOS vendor platform: upload your business personality (SOUL.md), connect your Google Calendar, and get a phone number. Your AI answers calls 24/7 in YOUR voice, checks YOUR real calendar availability, quotes YOUR packages, and books consultations — all through natural multi-turn phone conversation powered by Gemini on Google Cloud. After the call, the lead appears in your WeddingOS dashboard with a draft follow-up email ready to send.
What it does
Call the phone number. Talk to Emma — she's the AI studio manager for Prism Cinema, a wedding cinematography studio. She knows their packages ($3,800 Signature, $2,500 Essential, $5,500 Cinematic), checks real Google Calendar availability, and books consultations. She sounds natural, handles interruptions, and maintains context across the full conversation.
After the call ends, the transcript and lead data bridge from GCP to the AWS-hosted WeddingOS platform via Workload Identity Federation (zero static credentials). OpenClaw — the AI agent running on AWS — generates a personalized follow-up email draft. The vendor sees the new lead in their dashboard and can approve/edit the draft with one click.
The same platform powers any business. Different SOUL.md = different personality. Different Calendar = different availability. One codebase, infinite businesses. Two vendors are live today: Prism Cinema and Sunset Photography, each with their own phone number and AI personality.
How I built it
Voice Pipeline (GCP): Twilio ConversationRelay handles speech-to-text and text-to-speech. Gemini 2.5 Flash (via Vertex AI) powers the conversational reasoning with tool calls to real Firestore data and Google Calendar. The backend runs on Cloud Run as a FastAPI app connected via WebSocket.
Cross-Cloud Bridge: After each call, the GCP service authenticates to AWS using Workload Identity Federation (OIDC token exchange, zero static credentials) and sends transcript + caller data to an AWS Lambda bridge. The bridge writes to 4 DynamoDB tables (calls, transcripts, threads, messages) and triggers OpenClaw to generate a follow-up email draft.
Personality Architecture (SOUL.md): Each business gets a SOUL.md file (AI personality — packages, voice, FAQs) and Principles.md (behavior rules — pricing boundaries, escalation triggers). Loaded from Cloud Storage at call start. The AI becomes a completely different person for each business. Source of truth is AWS S3, with GCP Cloud Storage as the runtime cache.
WeddingOS Platform (AWS): The main platform handles email (Gmail API with OAuth), onboarding (SOUL.md generation from uploaded docs + URL scraping), a Next.js dashboard, and an OpenClaw AI agent that generates draft replies for both phone leads and email inquiries. Backend is FastAPI + DynamoDB + S3 + Cognito on ECS Fargate.
Harness Engineering: We built this using harness engineering methodology — 594 automated tests on AWS, 131 on GCP (725 total), 24 validation gates on GCP, A+ harness scorecard (30/31 checks) on AWS, and a quality ratchet tracking 12 categories that prevents regressions. Every commit must pass the gate. The ratchet only clicks forward.
Infrastructure: Cloud Run (serverless), Firestore (vendor data + call records), Cloud Storage (SOUL.md personalities), Vertex AI (Gemini), Secret Manager, Terraform IaC — all on Google Cloud. AWS side: ECS Fargate, DynamoDB, S3, Cognito, Lambda, OpenClaw on EC2.
Challenges I ran into
Gemini Live API audio recognition: Our initial implementation used Gemini Live API with Twilio MediaStreams for native speech-to-speech. The greeting worked but multi-turn audio conversations failed — Gemini's VAD couldn't detect speech boundaries in the transcoded telephony audio. After extensive research (including studying Google's official gemini-live-telephony-app sample), we identified three root causes: silence frame suppression, SDK parameter naming, and missing turn signals. We pivoted to ConversationRelay (Twilio handles STT/TTS, Gemini handles reasoning) which works reliably for multi-turn, while keeping the Gemini Live API + ADK implementation as an alternative path.
Cross-cloud authentication debugging: Getting Workload Identity Federation working between GCP Cloud Run and AWS Lambda required debugging a non-obvious audience value. The OIDC audience must be the GCP project number (not "sts.amazonaws.com" as AWS docs suggest for generic providers). This took multiple iterations to get right, but the result is zero stored credentials — the most secure cross-cloud pattern possible.
Transcript accumulation bug: The GCP voice service was sending empty transcripts to the AWS bridge — the post-call handler had hardcoded empty strings instead of passing the accumulated conversation. Our E2E data test (not just connectivity test) caught this: it verified actual data traversal through all 4 DynamoDB tables. The fix was straightforward once the test pinpointed it.
Harness engineering gaps: Our automated validation gates initially only covered the backend. When a subagent built the frontend, it bypassed the gate entirely. This taught us the core principle: validate.sh must be the universal gate for ALL code — backend, frontend, infrastructure. No exceptions.
Accomplishments we're proud of
Live phone number (+61 3 4713 5683) — judges can call and talk to Emma right now Full cross-cloud pipeline working — call Emma, see the lead in the AWS dashboard with a draft follow-up email Multi-turn conversation — proven working with 7+ turns including live tool calls (calendar, packages) SOUL.md architecture — per-business AI personality loaded from a file, not hardcoded 725 tests across both repos — 594 on AWS + 131 on GCP, all tracked by quality ratchet A+ harness scorecard (30/31 checks) — 12-category ratchet enforcing test counts, lint, architecture Zero static credentials — GCP-to-AWS auth via Workload Identity Federation Email HTML rendering — outbound emails render markdown as real bold/bullets, not raw syntax Google ADK agent — Emma defined as an ADK agent with tools for the Gemini Live API path
What I learned
Harness engineering changes everything. We built this with automated gates that caught bugs humans couldn't — Python 3.14 removing the audioop module, Gemini WebSocket keepalive timeouts, empty transcript accumulation, DynamoDB GSI visibility requirements. The quality ratchet (inspired by Notion's eslint-seatbelt) means every commit must maintain or improve 12 quality metrics — test pass count, lint errors, architecture violations, test coverage ratio, and more. Human review shifts from reading code to reviewing outcomes.
The cross-cloud architecture taught us that separation of concerns applies at the infrastructure level too. GCP handles voice (Twilio + Gemini excel at telephony audio). AWS handles the platform (DynamoDB + OpenClaw + email). Each cloud does what it does best. Workload Identity Federation bridges them with zero secrets.
What's next
Cross-cloud integration — already working. Post-call data flows GCP -> AWS Lambda -> DynamoDB -> OpenClaw -> draft email. Verified E2E. Multi-vendor live demo — Prism Cinema and Sunset Photography both have live phone numbers today Google Calendar live integration — real-time availability checking during phone calls (working) Automated onboarding pipeline — paste a website URL, AI scrapes it, generates SOUL.md automatically Call analytics dashboard — sentiment analysis, conversion tracking, missed-call recovery SMS follow-up — post-call text with consultation confirmation and business infoww
Built With
- cloud-build
- cloud-storage
- fastapi
- firestore
- gemini-live-api
- google-adk-(agent-development-kit)
- google-cloud-run
- google-genai
- next.js
- python
- secret-manager
- tailwind-css
- terraform
- twilio-conversationrelay
- typescript
- vertex-ai-(gemini-2.5-flash)
Log in or sign up for Devpost to join the conversation.