My journey building an autonomous meeting-intelligence agent for the Qwen Cloud Global AI Hackathon (Track 4: Autopilot Agent)
The problem I wanted to solve
If you've ever run a small team, church group, or SME, you know the pattern: a meeting happens, someone half-takes notes, and three days later nobody remembers who was supposed to follow up with the supplier, or what the actual decision was on the budget line. Meeting notes get written, then they die in a Notes app or a WhatsApp thread.
I wanted to build something that didn't just transcribe a meeting, but actually understood it — pulled out the decisions, the action items, who owns what, and then closed the loop by drafting the follow-up emails itself. That's the idea behind Minutely.
When I saw Qwen Cloud's hackathon had a Track 4: Autopilot Agent category — built for agents that automate real business workflows end-to-end, with human-in-the-loop checkpoints — it was a clean fit for what I was already building.
The stack
Minutely runs on:
Next.js (App Router) + TypeScript for the frontend and API routes
Tailwind + shadcn/ui for the interface
Supabase (Postgres) for persistence
Clerk for authentication
Qwen Cloud (qwen-plus and qwen-turbo, with qwen-max reserved for a future paid tier) as the reasoning layer
The core of the system is a multi-agent orchestration pipeline — six distinct agent steps that take a raw meeting transcript and progressively turn it into structured output: summary, decisions, action items, owners, and drafted follow-ups. Rather than one giant prompt trying to do everything, each agent has a narrow job, which made the output far more reliable and easier to debug.
To keep all of that manageable, I centralized every model call into a single lib/ai-config.ts file — model selection, token limits, and prompt templates live in one place instead of being scattered across API routes. When Qwen Cloud's available models or pricing tiers shift, I only need to touch one file.
*The hard part: persistence and a stale closure bug
*
Two bugs ate most of my build time, and they're the kind of thing that don't show up in a demo video but matter enormously for production-readiness.
Row-Level Security vs. Clerk JWTs. Supabase's RLS expects Supabase-issued auth tokens, but I'm using Clerk for auth. That mismatch meant writes were silently failing under RLS policies that couldn't validate a Clerk-issued JWT. The fix was a full persistence rewrite using an admin Supabase client (service role) for server-side writes, while keeping RLS intact for anything touched directly from the client. It's not the prettiest solution, but it's the correct boundary: trust the server, not the browser.
A stale closure in AnalysisChat. Users could chat with Minutely about a specific meeting's analysis, but edits to that analysis weren't reflected in the chat's responses. The cause: the send() function was capturing a stale analysis prop from the render it was created in, not the latest one. Classic React closure trap. The fix was making sure send() always read from a ref or the latest prop on each call rather than capturing it once.
Neither of these are flashy, but they're the difference between a demo that works once on stage and an agent that's actually trustworthy across sessions — which is exactly what Track 4 judging criteria are looking for.
Designing for human-in-the-loop
Track 4 explicitly asks for agents that handle ambiguous input and include human checkpoints at critical decision points — not just full autopilot. A few of Minutely's design choices reflect that directly:
The follow-up email step is editable, not auto-sent. The agent drafts the recipient, subject, and body, but a human reviews and can change the recipient before anything goes out. Meeting agents that fire off emails with zero review are a liability, not a feature.
Upload handling is intentionally scoped to .txt and .md transcripts after I discovered FileReader.readAsText silently corrupts binary formats like .docx — better to be explicit about what's supported than to fail unpredictably on bad input.
I'm currently working through a pdfjs-dist worker initialization issue in the upload zone, since PDF transcripts are a natural next input type — a good example of the kind of "ambiguous input handling" this track rewards, even mid-build.
What's left
Before the July 9 submission deadline, my checklist is:
Finalize Alibaba Cloud deployment (ECS) as proof the backend runs in production, not just on localhost
Architecture diagram showing how Qwen Cloud, Supabase, and the Next.js frontend connect
A clean 3-minute demo video
Polishing the submission write-up
Why this track, why now
A lot of "AI agent" demos are impressive in a sandbox and fall apart the moment real, messy human input shows up — bad transcripts, ambiguous action items, edge cases in formatting. Building Minutely has mostly been an exercise in handling that messiness gracefully rather than chasing a flashier demo. That's the bet I'm making for Track 4: production-readiness over toy demos, exactly as the brief asks for.
If you're building on Qwen Cloud too, I'd love to hear what you're running into — the orchestration and persistence problems in particular feel like they come up for almost everyone building multi-agent systems on top of a Postgres backend.
Minutely is built in the open. Follow the repo here: github.com/howelldevs
Top comments (0)