
Inspiration
Most "personalised" services ask for your history first, then guess who you are. Wrong guesses cost twice: money spent on the wrong audience, and the feeling of being misread. Our bookmarks already say a lot about what we want to do with our time, from a badminton tutorial to a café we saved a year ago and never visited. We asked the opposite question: what if the understanding happened on your device, and the world only saw a city and a few place categories that you approved?
What it does
Understood, not seen is an agent that reads a bookmarks export inside your own browser tab and turns it into real places for the coming weekend, with two gates between your data and the world.
- Gate one, privacy. It fails closed: adult, account, personal, private-address and identifier links are removed first, together with their neighbours. Only counts are shown, never the removed titles.
- Understand. What is left is mapped to what each activity does for you (social, stress relief, quiet time, outdoors ...): 73 activities in English and Traditional Chinese, with an optional small on-device model for titles that share no keyword. It never puts a label on you; you can pick your own needs.
- Beyond your bookmarks. Neighbouring ideas in four labelled ways: deeper, same feeling, goes with, balance, plus Taiwan holidays and international days.
- Gate two, consent. The exact outgoing payload is shown: a city, Qloo place-tag ids, and only the saved place names you tick. Nothing leaves until you press the button.
- Act with Qloo. Real places in your city, ranked by the taste of a place you saved ("because you saved X"), with an optional "quality first" mode. Every place opens on a map inside the page.
- Look forward. History cannot be replayed, so it ends with an invitation for the next weekend or holiday, a small ritual, a note when you saved something long ago, and one tap to copy an invitation for a friend.
- Evidence. Every Qloo request behind the page is listed (endpoint, parameters, status, time, result count). The API key is never shown.
What makes it Qloo-powered
Without Qloo there is nothing to recommend: on the device the agent only knows activity categories. Every real place comes from Qloo, and so does what makes the list personal: signal.interests.entities with feature.explainability (taste of a saved place, with a reason per place), signal.interests.tags for refined, minimal, artisan ambience, and filter.rating.min, on top of filter.tags and filter.location.query; saved places are resolved with /search.
We asked the same question three ways ("cafés in Taipei for someone who loves Simple Kaffa"). The chat answers were real and good: 8 of 8 places exist, and the API answer and the chat app agreed on 7 of 8 well-known award winners. Qloo's taste graph returned 8 real places too, but 6 of 8 were in neither chat answer, each came with "because you saved Simple Kaffa", and it needed only the names you tick, no account and no chat history.
How we built it
- A browser app in plain JavaScript (no framework): the privacy gate, the activity knowledge base, the consent preview and the results all run in the tab. It installs as a PWA and keeps one language per page.
- A thin Node proxy with no dependencies, hosted on Zeabur: input validation, a per-visitor rate limit, a monthly budget guard, a 24-hour memory cache, the API key kept server-side, and a request trace for the Evidence panel.
- Coverage was measured, not assumed: for the first 66 activities across 11 cities, Qloo returned places in 674 of 726 city-activity cells (93%).
- 60 automated tests (gate rules, routing, both demo samples, server protections, language audit, a locked design), plus gitleaks, semgrep and npm audit before every push.
Challenges we ran into
- Privacy rules that were too strict. On a real export, harmless bookmarks were removed (a news site's "LINE", a word for gunpowder). We narrowed the rules against real data and kept a test for every case.
- A small generative model copied its template. We replaced it with sentence embeddings and measured it on held-out titles (18 of 20 correct; optimistic, because the vocabulary was tuned by us).
- One language per page. Qloo stores one name per place, so mixed names are split and a small hand-written table fills in official names, with the rest left as Qloo stores them.
- Hosting surprises. On the hosted site, a click before the data had loaded did nothing, browsers mixed old and new versions, and a reload right after the first visit could stall. We fixed each one (buttons that wait for the data, no-cache for page and code, a release id check, a late and small service worker, a 10-second reload safety net) and re-tested on the live site.
What we learned
Understanding does not require collecting. A city, a few public category ids and the visitor's own choices are enough to ask a taste graph a good question. Chat models already know the famous places; the value of Qloo is reaching beyond the obvious with a reason you can see, without handing over your history.
Honest limits
Places, not event sessions; opening hours are not checked. Taiwan holiday dates come from public reports of the government calendar. Phone browsers cannot export bookmarks. No user study yet. The privacy gate is rules, not a guarantee.
What's next
A local relation map from your own folders to suggest neighbouring activities, a small user study, and the same on-device payload for other services.
Built With
- css3
- gemini
- html5
- javascript
- node.js
- pwa
- qloo
- transformer.js
- zeabur

Log in or sign up for Devpost to join the conversation.