How it works

Inspiration

Most "personalised" services ask for your history first, then guess who you are. 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

Who it is for: anyone with a bookmark export from a desktop browser; the moment is a free weekend and a folder of saved cafés, courts and museums with no plan.

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. It also runs in a phone browser (installable as a PWA): the bookmarks file is read and filtered in the page on the device, and only the clean payload (a city, place categories and the saved names you tick) leaves it. The bookmarks file itself has to be exported on a computer first.

  1. Gate one, privacy. Rules run first: adult, account, personal, private-address and identifier links are removed, and adult and account links also take their neighbours on the same site. Counts are shown, never the removed titles.
  2. 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, plus a small on-device model for titles that share no keyword. It never puts a label on you; you can pick your own needs.
  3. Beyond your bookmarks. Neighbouring ideas in four labelled ways: deeper, same feeling, goes with, balance, plus Taiwan holidays and international days.
  4. Gate two, consent. The exact outgoing payload is shown: a city, Qloo place-tag ids, and the saved place names you tick. Nothing leaves until you press the button. After that the request goes from your browser to our own server (on Coolify, behind Cloudflare), which adds the API key and calls Qloo; the browser never talks to Qloo directly.
  5. 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 has a Map link; Google Maps loads only when you press it. If a lookup fails, the page says it failed instead of showing "no places".
  6. 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.
  7. Evidence. Each Qloo lookup behind the page is listed (endpoint, parameters, status, time, result count). The API key is never shown.

Why it is an agent

It pursues one goal, turning your taste into real places, in a loop: perceive (read the bookmarks in your tab), two gates (privacy rules, then your consent), act (call Qloo /search and /v2/insights as tools) and adapt (when quality-first finds nothing it relaxes the bar and says so; when a city has no pickleball courts or massage places it tries badminton and tennis courts or spas). The decisions are rules plus a small on-device model, not a chat model, and you stay in the loop at the consent gate. Agentic here means a perceive, gate, act and adapt loop that calls Qloo as its tools; a chat model is deliberately kept out of the loop because the input is private. Keeping it out also means no extra model cost per recommendation: a run spends only Qloo calls (7 in the live test below), with no token bill and no third party reading your bookmarks. After the one consent click the agent runs on its own: it maps each idea to Qloo tags, resolves a saved place with /search before ranking with /v2/insights, relaxes quality-first when nothing passes, and swaps in a fallback venue type when a city has none, up to 18 Qloo calls with no further input.

What makes it Qloo-powered

A separate opt-in heatmap, off by default, draws where the taste of your saved places clusters in the city (filter.type=urn:heatmap); it sends the same ticked place names and nothing more.

On the device the agent maps bookmarks to activity categories, and Qloo turns those into real places (/search to resolve a saved place, /v2/insights for the list, plus the taste heatmap); the app focuses on place bookmarks rather than music, film and fashion entities. 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 places. Qloo's taste graph returned 8 real places too, and 6 of 8 were in neither chat answer, each came with "because you saved Simple Kaffa", and it needed just the names you tick, no account and no chat history. With a saved place as the signal, the taste-ranked café list shared only 0 to 1 of 8 places with the plain category list, and each ranked place states which saved place it was ranked by. This is one prompt, one city and one run on 2026-10-11, and "exist" means found by a Qloo place search: it shows what Qloo adds in one case, not that it is better on average. The chat answers and the counts are in evidence/llm_baseline_20261011_summary.json; Qloo's own response is not stored, per the API terms.

We stay with place entities on purpose: every extra Qloo domain (music, film, brands) would mean sending more of your private bookmarks off the device, so here depth means the taste of a saved place used as the signal, not more domains.

How to test

Open the live site (no sign-in, no key), press "Use sample bookmarks", tick up to 12 ideas, choose a city, optionally tick Simple Kaffa as a saved place, read "Everything that leaves your device", press "Find places", then open "Evidence". Demo data only. Places by Qloo. MIT licensed.

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. Only if you press "Start on-device matching" does the page download its code from cdn.jsdelivr.net and the model from huggingface.co (nothing from your bookmarks is sent), and Google Maps loads only when you press a place's Map link. It installs as a PWA and keeps one language per page.
  • A thin Node proxy with no dependencies, hosted on Coolify: input validation, a per-visitor rate limit, a call budget guard (8,000 calls per server run), a 24-hour memory cache, the API key kept server-side, and a request trace for the Evidence panel. The server does not write requests to disk or log them; Cloudflare terminates HTTPS, so it handles the request contents (a city, category ids and any ticked place names) in transit as well as your IP address, and Coolify, which hosts the server, sees connection metadata.
  • Coverage was measured, not assumed: for 66 activities (the first 22, then 44 added later) across 11 cities, Qloo returned places in 674 of 726 city-activity cells (93%, tags only; with a saved-place signal some ideas return nothing from Qloo; the page then shows the ordinary list and says so).
  • 73 automated tests, passing on a fresh clone (gate rules, routing, both demo samples, server protections, language audit, a locked design); a pre-push hook runs gitleaks and the full test suite, and npm run security adds semgrep and npm audit.

Outside the web app, Google AI was used three ways: 15 of the knowledge-base entries came from Gemini chat answers pasted into the project notes; the Gemini API answered the café question in the comparison above; Veo made the mood clips in the video and Gemini text-to-speech voiced it; the music is "A Tale's Background" by Liborio Conti (no-copyright-music.com). Inside the web app an in-browser embedding model matches bookmark titles to activities; every place recommendation comes from Qloo.

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 with our tuned vocabulary, with 1 wrong activity, 1 miss and 1 false positive; the titles were written by the same author as the vocabulary, so treat this as optimistic).
  • 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: sample bookmarks read 35 links, removed 6 and kept 29, and a Taipei run with the sample's default ideas and a saved coffee shop made 7 Qloo requests (all HTTP 200) and returned 17 places, with the Evidence panel and the map.

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.

Scope

Recommendations cover places rather than event sessions, and opening hours are not checked. The bookmarks export comes from a desktop browser, because phone browsers cannot export bookmarks. Taiwan holiday dates come from public reports of the government calendar. No user study has been done yet; whether taste-ranked results are better for a person is not measured.

What's next

A small user study, a local relation map from your own folders to suggest neighbouring activities, and the same on-device payload for other services.

Built With

Share this project:

Updates

Submission history