About the project
Inspiration
Every subscription ping interrupts you, and most of it isn't yours. Nobody wants a clogged up notification feed either. Turning notifications off costs you the few uploads you actually wanted. GamePal keeps the useful half of notifications — being told when something is truly for you — and deletes the fatigue half: everything else is filtered, held, or dropped with a reason.
What it does
gamepal is a personal media-triage agent built on the Caspian SDK. It polls your video and podcast subscriptions, reads each item's chapter index, and judges every chapter against interests you stated by just talking to it — "I play Zelda and Fire Emblem" is the whole configuration flow.
- Only your minutes arrive: a YouTube card taps straight to the exact second
(
&t=deep link); a podcast card shows "1 of 14 chapters for you" with the timestamp beside it. - While you're busy (schedules, or "starting work now"), nothing pings you. When you're free, you get one private selection — a numbered list you pick from, not a burst of cards.
- What it drops, it drops with a reason, and it reports the count. A poll
that ends
sent 0is a poll that worked. - When the reason is wrong, you teach it in one sentence ("8. Send everything from this guy") and a per-channel rule remembers permanently.
- It even takes the tone you ask for — secretary, friend, or plain — and a bare "thanks" earns a silent 👍 reaction, not another message.
How we built it
One process, one @client.on_message handler on the Caspian SDK (Telegram +
email lanes). Two model roles behind any OpenAI-compatible endpoint: a small
fast model for live conversation (~0.8 s) and a larger judge for background
relevance calls — local llama.cpp models by default, switchable to hosted
APIs with two env vars. RSS/chapter parsing, a held-queue with an offer flow,
per-channel rule storage, and a 76-case measured intent test set. The judge's
verdicts, the drop reasons, and the delivery cards in the demo are all live —
nothing is mocked.
Challenges we ran into
- Silent degradation: with no model reachable, an early version turned into an unfiltered feed reader without a single error. Every outage path is now loud, including a mid-run judge outage tagging deliveries as unjudged.
- Gateway outages: a live 522 killed the bot twice during development; it now rides through with backoff at both the listen loop and startup, proven against a real outage.
- Honest rejection UX: making "nothing arrived" feel like the feature working, not the system failing — drop reasons, skipped-count receipts, and an explain-what-you-skipped flow.
- Claude restricted the model behind the conversation so much that it acted like a simple bot. Human intervene was nessesary to 'free up' the agent for actual conversation.
Accomplishments we're proud of
- The demo is a single continuous live session: real feeds, a real judge, real corrections — including the agent surviving typos and paraphrases we didn't script.
- A stranger can reproduce the judging in 30 seconds:
pipeline.py --dryneeds no credentials. - Zero-delivery honesty as a design principle instead of an apology.
What we learned
Chapter indexes are an underused public good — every long video ships one and almost nobody reads it. A judge model plus a person's own words is enough to turn that metadata into minutes-level delivery. And most "agent UX" problems are really honesty problems: say what you held, what you dropped, and why.
What's next
Named-drop receipts, more feed kinds, and letting the agent open the conversation on schedule boundaries instead of waiting for an inbound message.
Log in or sign up for Devpost to join the conversation.