Inspiration
Campus events look simple from the outside — a poster, a room, a registration link. Behind the scenes, a student organizer at our college (Govt. Model Engineering College) spends 3-5 hours on repetitive ops for every single event:
Find a room → check capacity → write a permission letter to the Principal → create a Google Form → link a Sheet → draft an announcement → send it → manually monitor registrations → send reminders.
We watched clubs like FOSS MEC, MACS, IEEE do this every week in WhatsApp groups and shared sheets. The work is fragmented across Gmail, Forms, Sheets and a paper room ledger — and it's the same every time. An LLM that just tells you what to do doesn't help. We wanted an agent that does the work and only interrupts you when a real decision is needed.
That is the core of the Everyday Agents track: run quietly in the background, surface only for human judgment.
What it does
CampusOps is an AI Event Operations Agent. You describe your event in one sentence, and it executes the entire operational workflow:
"FOSS MEC wants to conduct a GIT workshop for 80 students next Saturday 2pm-4pm with speaker John Doe"
From that single prompt, CampusOps:
- Extracts structured data —
org,title,date,capacity,time,speaker,purpose— resolving "next Saturday" againstTODAY = YYYY-MM-DD. - Finds a room via
check_room_availability— filtering a live Google Sheet (Bookingsledger withRoom | Date | Start | End) by capacity and time-slot overlap. Ifsource=mock_fallback, it transparently discloses: "This is a mock registrar sheet standing in for a real room-booking API." - Locks the slot with
book_room_slotto prevent double-booking. - Generates permission letters — a Principal letter + optional On-foot publicity letter using institution-aware templates (
Govt. Model Engineering College, Thrikkakararesolved perOrgSettings), including chairperson and staff-in-charge. - Shows drafts for human-edit — the club edits or says "make more formal" before anything is sent.
- Emails the Principal with PDFs only after club confirmation, then waits in
PENDING_APPROVAL. - On approval: creates a live Google Form with custom fields (
text,paragraph,multiple_choice,checkbox,file_upload), links a response Google Sheet, and sends the announcement via Gmail/Brevo to configured recipients. - Monitors — syncs
Forms -> Sheetsand updatesregistrant_count. Proactive reasoning:
$$ \text{if } \frac{R_{\text{current}}}{R_{\text{expected}}} < 0.4 \land T_{\text{until_event}} < 2\text{ days} \Rightarrow \text{propose reminder draft for approval} $$
- Maintains state across days via a persistent
Eventlifecycle:DRAFT \rightarrow ROOM\_IDENTIFIED \rightarrow PENDING\_APPROVAL \rightarrow LIVE \rightarrow CLOSEDstored locally in SQLite (designed to be persisted with AgentCore Memory).
Core principle: Action over explanation. Human control over authorization.
How I built it
Stack: Strands Agents SDK 1.53.0 + Gemini 3.5 Flash Lite (via google-genai) + FastAPI + Google APIs (Forms, Sheets, Gmail, Drive) + SQLite + Brevo for announcements. Currently running locally — deployment is planned, not yet live.
Agent Layer (backend/app/agent.py):
A single flat Strands agent — deliberate for MVP reliability — with a system prompt defining role, responsibilities, and safety boundaries. Tools exposed:
check_room_availability(date, capacity, start_time, end_time)
book_room_slot(room, date, start_time, end_time, event_id)
generate_permission_letter / generate_onfoot_letter
create_registration_form(title, date, description, fields_json)
send_announcement(title, date, room, registration_link)
get_registration_count(sheet_id, form_id)
upsert_event(...) # persistent state
- Deterministic fast-path (backend/app/main.py): If date + start_time + end_time are provided, we bypass Gemini entirely — check room, book slot, generate letters, and save_event() in under 500ms. This saves ~90% of LLM calls and keeps local resource usage low (no singleton agent, per-request GC).
- Human-in-the-loop: Agent prepares drafts, but POST /events/{id}/send-permission-email and POST /events/{id}/approve (admin-only) are explicit state transitions.
- State Model (backend/app/models.py): Pydantic Event + OrgSettings (per-club institution_name, faculty_email, chairperson, allowed_types) + SQLite with a reset routine that prunes room_bookings WHERE date < TODAY from both DB and Sheet.
Integrations: Google Sheets as mock room DB (Rooms/Bookings), Forms API with drive.file + forms.body + spreadsheets scopes, per-org token_{org}.json OAuth flow (GET /auth/google/url -> /callback), and MOCK_MODE=true for local development without credentials.
Architecture Intent: Local FastAPI backend with background tasks (polling + daily reset) as asyncio loops. The system is designed for Amazon Bedrock AgentCore Runtime + Memory — Runtime to host the agent and Memory to persist event workflows — which we plan to adopt on deployment.
## Challenges
1. Reliability > Cleverness. Gemini would occasionally hallucinate rooms or assume approval. We enforced strict tool schemas, validation (field_validator for YYYY-MM-DD and 3:30 PM), a global _agent_invocation_lock to prevent concurrent tool races, and a rule: never claim mocked data is real — disclose source.
2. Google OAuth & Sheets. forms.body and drive.file scopes require re-consent and per-club tokens. We built a browser OAuth flow + central-drive fallback (CENTRAL_DRIVE=true) and a local mock_fallback ledger so local testing and demos never break if the API is unavailable. The room inventory vs. bookings split (static RoomInventory + append-only Bookings ledger) eliminated time-slot conflicts.
3. Time is harder than date. "Next Saturday 3:30 PM - 4:30 PM" needs timezone-correct overlap detection, not just date filtering. We added HH:MM normalization and ledger overlap checks — otherwise two clubs could book SDPK at the same hour.
4. Resource constraints. Gemini timeouts (GEMINI_TIMEOUT_MS=45000), local memory limits, and Sheets API latency forced us to implement a deterministic path, AgentBusyError (409), lite model (gemini-3.5-flash-lite), and polling instead of webhooks.
5. Honest architecture. We had to explicitly separate real (Forms, Sheets, Gmail) from mocked (room DB) and future (multi-agent) in both code and documentation, with disclosure strings, to avoid misleading users.
## Accomplishments that Im proud of
- End-to-end local loop: One prompt -> real Google Form + Sheet + email with PDF — not a simulation — working fully in local environment.
- 1-Chat Heart: Collecting date, time, speaker, purpose, staff, fields upfront in a single UI heart, so letters are correct the first time and no follow-up "what time?" loops are needed.
- Zero-config sandbox: TEST_CLUB demo account works without Google Drive; any real club can connect their own Drive in one click.
- Safety by design: Draft-then-approve, never auto-sending to the Principal; RBAC (admin vs club), JWT + bcrypt, rate limiting (slowapi $100/\text{min}$).
- Resilient workflow: Mock fallback, validation, and background polling make the operational workflow reliable even when external APIs are flaky.
## What I learned
Building an agent taught us that prompting is 20%, tool design is 80%. A good tool has a narrow, validated contract and idempotent side effects — the LLM's job is just to choose and sequence them.
We learned to design for statefulness: events live for days (Day 1: create -> Day 5: reminder -> Day 7: summary), so persistent EventStatus matters more than chat history.
We learned the value of determinism as a feature: for constrained, known inputs (date + time), a code path beats an LLM call in latency, cost, and predictability — modeled as:
$$ Cost_{total} = N_{LLM} \cdot C_{token} + N_{tool} \cdot C_{API} \quad \text{minimize } N_{LLM} $$
And most importantly: useful autonomy = work independently, interrupt sparingly. The best agent is invisible until a human decision is truly required.
## What's next for CampusOps
Short-term: Deploy to Amazon Bedrock AgentCore (Runtime + Memory), add live demo hosting, Slack/Discord announcement channels, and Google Calendar integration.
Medium-term: Multi-agent Strands architecture (Event Agent -> Communication Agent -> Logistics Agent via agent-as-tool), generate_summary() with ReportLab PDFs + attendance analytics, proactive monitoring with $F_1$-tuned reminder thresholds, and real room-booking API integration with the college.
Long-term vision: From fragmented admin work to a single conversation — CampusOps becomes the operating system for campus life, where any student org can turn intent into operation, faculty retain approval authority, and the agent handles the busywork that currently drains hours every week.
CampusOps doesn't tell you how to run an event. It runs it for you
Log in or sign up for Devpost to join the conversation.