Inspiration
I kept noticing the same pattern in my own phone. I'd find something worth coming back to, an article, a tool, a video, and save it somewhere. A bookmark, a screenshot, a note to self. Weeks later I'd scroll past it and have no idea why I saved it or whether it still mattered. The problem was never saving. It was that saving and remembering are two different jobs, and every tool I used only did the first one. I wanted something that took the second job seriously.
What it does
Revia is an agent that takes responsibility for what you save. Share a link to it, from your phone's or laptop's share menu or by pasting it directly, and a Strands agent reads the resource, decides where it belongs based on who you are and what you've already saved, writes a short honest description, and remembers it. Everything gets sorted into categories automatically, no manual filing. When something new connects to something I already saved, Revia tells me, with a stated reason, not a generic reminder. Tapping into any saved item shows exactly why the agent placed it there. It runs local-first, no account required, and installs as a real app on the home screen.
How I built it
The frontend is Next.js with TypeScript and Tailwind CSS, running as an installable PWA with a real Web Share Target so links can be shared to it directly from other apps, not just pasted in. Saved data lives in IndexedDB on the device, there's no server-side database in the current build.
The agent itself runs inside a Next.js API route using the Strands Agents SDK. It has two tools: one that fetches a shared resource, using YouTube's oEmbed endpoint for videos and an Open Graph meta tag scrape for everything else, and one that returns the categories that already exist so the agent reuses one instead of creating duplicates. The agent's final answer is structured output validated against a Zod schema, title, description, type, category, tags, and its own reasoning, which the client then writes to storage. There's deliberately no separate save tool, since the server never holds the user's data, making the agent responsible for a save it can't actually perform would have been agentic in appearance only.
For the model layer, I used Strands' OpenAIModel integration pointed at an OpenAI-compatible endpoint, which let me keep the exact same agent code while changing which provider actually answers the calls.
I built the entire thing from an Android phone, using GitHub Codespaces as the development environment, no laptop involved.
Challenges I ran into
The biggest one wasn't technical, it was infrastructure access. AWS account verification never completed on my end, a payment card type issue outside my control, which meant Amazon Bedrock was never reachable for this build. Rather than block on that, I kept the Strands agent architecture exactly as designed and swapped the model provider underneath it, first attempting a direct integration that hit a real dependency version conflict between two open-source packages, then landing on routing through an OpenAI-compatible endpoint instead. The agent code itself never changed through any of that, which taught me more about why Strands separates the model from the agent loop than reading the docs alone did.
I also hit a genuine, well-documented mobile browser limitation: calling the Notification constructor directly, which I'd initially used for real device notifications, throws silently on nearly all mobile browsers. The fix was routing notifications through the service worker instead, which is the only reliable way to do it on Android.
Accomplishments that I'm proud of
I'm proud that the agent is a real multi-step tool-use loop and not one prompt formatted to look like structured data. I'm proud of the "why here" feature, since I think transparency is the difference between a categorization tool and something a person can actually trust. And I'm proud that when real infrastructure went wrong more than once, the response was always to adapt the implementation, never to quietly cut the feature.
What I learned
The clearest lesson was that model-agnostic architecture isn't a nice-to-have, it's what let this project survive losing access to its original intended provider without losing a single day of agent development. I also learned to verify SDK behavior against actual installed package source and official docs rather than assumption, more than one bug in this build came from a confidently wrong guess about an API shape. And building local-first forced an honest conversation with myself about which "agent tools" were real capabilities and which would have just been for show.
What's next for Revia
Account creation and cross-device sync are the most requested missing piece, and the architecture already separates local and future cloud storage behind the same interface to make that addition clean. Beyond that, I want to move connection detection from a check that only runs at save time to something that actually revisits older saves on its own, true natural-language search instead of keyword matching, and once AWS account verification clears, a real Bedrock and AgentCore deployment path alongside the current one.
Built With
- groq
- indexeddb
- nextjs
- node.js
- openai-sdk
- pwa
- react
- strands-agents-sdk
- tailwindcss
- typescript
- vercel
- zod
Log in or sign up for Devpost to join the conversation.