Inspiration

Vietnamese VAT invoices land in Gmail as photos. Someone retypes them into a sheet. If the totals do not add up, that row must not be written. We wanted that chore to finish without a chat turn — and without letting the model touch Sheets or Gmail.

What it does

A dedicated inbox receives a VAT invoice. Pub/Sub wakes Cloud Run (Google ADK). Gemini 3.5 returns a Plan JSON and a confidence score only (tools=[]). Python gates check schema, math (subtotal + VAT = total, ±1 VND), confidence, and duplicates. Pass → one Google Sheets Posted row. Fail → a Gmail draft (never send). Same MST + invoice number → skipped_duplicate, no second row.

How we built it

Gmail users.watch → Pub/Sub → Cloud Run in asia-southeast1. Firestore holds Run state. Gemini extracts; the harness in harness/ is the only writer. Auth is Cloud Run ADC — no OAuth client secrets. Judges clone the repo and run pytest with no GCP.

Challenges we ran into

Org policy blocked API keys and OAuth client secrets, so Gmail and Sheets had to use the runtime service account. The model must not skip math. Cloud Run IAM made the Operator UI see 403/CORS even when ingest was up. Sheets only posts after SHEETS_SPREADSHEET_ID is set and shared with that SA.

Accomplishments that we're proud of

The write path is code, not prompt. A wrong total cannot append. Duplicates cannot double-post. The agent never sends mail. The Taskmaster trigger is Gmail, not chat.

What we learned

Eligibility is Gemini 3.5 + ADK + Cloud Run/Pub/Sub/Firestore — not a chatbot with Workspace function calling. “Autonomous” here means finishing the chore when gates pass, and refusing to write when they fail.

What's next for Olympus VAT Agent

Film the 4-minute pass / math-fail / duplicate demo. Optional: Vietnamese MST checksum, human reply on a review draft to promote to Posted. Business cards stay out of v1.

Built With

  • autonomus
  • cloudrun
  • excusion
  • gemini
  • harness
  • json
  • reasoning
Share this project:

Updates

Submission history