Inspiration

I'm bad at one specific thing: remembering who agreed to do what after a meeting. Someone says "I'll send you the numbers Friday" and by Wednesday I've completely lost track of whether it happened. I tried writing it down manually and gave up after a week, so for this hackathon I used that exact annoyance as my problem instead of picking something hypothetical.

The twist I wanted was specific too. I didn't just want something that logs tasks, plenty of apps already do that. I wanted something that would actually go bother people (well, bother me about people) without me opening an app every morning to check a list.

What it does

You send a voice note, or just text, to a Telegram bot right after a meeting. One agent transcribes it and pulls out the action items: who owns each one, what it is, when it's due. No forms, nothing to open.

Then once a day, on its own, a second agent looks at everything that's still open and decides what actually needs my attention today. If Diego's been sitting on a contract for three weeks with no movement, it escalates. If Carla just got reminded yesterday, it leaves her alone. Instead of five separate pings I get one message that reads like something a person would actually send me, and sometimes it notices patterns too, like Diego and Renata both being behind at the same time.

There's a small dashboard too, in case I want to see everything at once, but the point is I mostly don't have to.

How we built it

Two Cloud Functions, one Firestore database, one Telegram bot.

Extraction Agent: triggered by Telegram's webhook, transcribes audio and turns it into structured tasks using Gemini 3.5 Flash through Google ADK, then writes to Firestore.

Follow-up Agent: triggered daily by Cloud Scheduler, pulls every pending task, hands the whole list to Gemini in one call, and gets back a decision per task plus one digest message.

Dashboard: a small React app that reads Firestore directly, no backend of its own, locked down with Firestore Security Rules instead of a login.

Both agents run on Vertex AI with no API key, just Application Default Credentials, which mattered more than I expected.

Challenges we ran into

The biggest challenge wasn't technical. It was a design mistake I didn't catch until I actually watched the agent run in production. My first version of the Follow-up Agent classified tasks one at a time: for each one, ask Gemini remind, escalate, or skip. It worked, but the reminder messages it wrote were addressed to whoever owned the task, things like "Hola Carla, todavĂ­a tienes pendiente..." The problem is the bot only ever talks to me. Carla has never used it and never will. Those messages were sent successfully and completely useless, because they were meant for someone who'd never read them.

Fixing that meant rethinking the whole approach. Instead of judging tasks one by one, I feed the agent the entire portfolio in a single call and have it write one message addressed to me, summarizing what needs attention. That change also unlocked something I hadn't planned on: the agent started noticing things like two overdue tasks both belonging to the same person, which a one-task-at-a-time loop could never catch.

The second challenge was more subtle. reminder_count >= 2 looks like a clean escalation rule until you realize two tasks can have the same count and mean completely different things: one nudged twice over three weeks is genuinely stuck, one nudged twice in the last two days is still fresh. So I gave the agent an actual tool, get_task_events, that lets it pull the real timestamps for a task and decide for itself if the pattern looks stale, instead of me hardcoding a threshold that would eventually be wrong for someone.

Then there was the usual pile of infrastructure problems. gemini-3.5-flash is only served from Vertex AI's global location, not the regional one the rest of my infra used, which took a while to figure out. Setting up Firebase without a working firebase login (no interactive browser in my dev environment) meant calling the Firebase Management API directly with a gcloud access token instead. And a stale Application Default Credentials quota project on my machine caused a PERMISSION_DENIED that had nothing to do with the IAM roles I kept double checking.

Accomplishments that we're proud of

Getting the Follow-up Agent to run completely unattended in production and make different calls on tasks that looked almost identical. Not a scripted demo, an actual scheduled run that escalated one task while quietly skipping an unrelated one that was still 15 days out, and separately treated two tasks with the exact same reminder count differently after pulling their real history. That's the part that makes it feel like an agent instead of a script with a cron job attached.

I'm also proud that none of the agent's reasoning is hidden. The dashboard shows the exact message it sent for every reminder and escalation, timestamped, so it's not just me saying it's smart, you can actually see what it said and when.

What we learned

The main thing I learned is that an agent reasoning over a whole list is a genuinely different product than the same agent classifying one item at a time, even though the model call underneath looks almost identical. The part where it notices patterns across tasks wasn't something I prompted for directly, it just showed up once I stopped forcing it to look at one task alone.

I also got a better sense of when to give an agent a tool versus when to just hardcode logic myself. get_task_events only makes sense because the agent decides for itself, per task, whether it's even worth checking, it never bothers calling it for tasks with zero reminders. Before this project I probably would have just written that logic myself instead of letting the model decide when it needs more information.

What's next for ReunIA

Right now this whole thing is built around one person, me. The obvious next step is letting more than one person register with their own Telegram chat, so it stops being a one-person hack and turns into something a small team could actually run together.

Share this project:

Updates

Submission history