What it does

You type three to five things a person loves (a book, a band, a shop, a place) and a budget. Tasteloom asks Qloo what else that person is likely to love, turns those suggestions into real products with real prices (and, for places, experience links), and puts a plain reason on every idea: "Because they love Nujabes". You pick up to six items inside the budget and pay in the PayPal sandbox as a guest, no account needed. A receipt shows the order. No real money moves, and Tasteloom does not store the favourites you type.

An AI agent does the legwork. It chooses which Qloo and shop lookups to make, and the server checks every step, so the model cannot invent an id, a price or a charge.

How it uses Qloo

Qloo is the only part of the app that decides what fits a person's taste. The model never makes up taste.

  1. Search: GET /search turns each favourite into a Qloo entity. The optional type hint (book, artist, brand, place...) is sent as types=urn:entity:<type>, so "Kafka on the Shore" is found as a book.
  2. Insights with explainability: for each gift category (brand, book, artist, place, destination) the app calls GET /v2/insights with all the favourites' entity ids as signal.interests.entities, filter.type for the category and feature.explainability=true. Qloo returns entities the person is likely to like and, for each one, which of the favourites drove it.
  3. Ranking: the explainability scores order the candidates, strongest link first. The ideas of one run are kept apart: at most two of one type, and not all led by the same favourite. Something the person typed never comes back as an idea.
  4. "Because they love X": the explanation Qloo gives is the line on each idea card. The model writes the sentence, but if it does not name the favourite Qloo links most strongly, the server replaces it with a template built from that link. So the reason on the screen always comes back to something Qloo said.
  5. From taste to things to buy: a brand, a book or an artist becomes a product search at Channel3 (real products, prices, shops; for an artist, records and music). A place or destination becomes experience links found with Tavily; those are links, never buyable cards.

One live run makes about 9 Qloo calls with four favourites (4 searches and 5 insight calls, one per gift category). Qloo answers are used inside the request and not stored or cached in production. The app was checked against the live API (npm run contract:qloo, 5 requests, 9 checks), and the three places where the real answers differed from the documented shapes were fixed in the parser.

How we built it (AI disclosure)

Tasteloom was built by AI agents (Claude Code), working in separate stages (build, review, test, fix) from a written brief, with a person setting the goals and owning the accounts the app uses. It also uses an AI model at run time: Qwen3-30B-A3B on Cloudflare Workers AI, through a Worker binding (no API key).

The code is TypeScript on a Cloudflare Worker (Hono) with a static page in plain HTML, CSS and ES modules. The agent has tools for the lookups (qloo_search, qloo_insights, find_products) and for checkout (create_order, get_order, capture_order). The model drives them in a loop of up to 6 turns. The server then fills in any step the model skipped by calling the same tools in a fixed order, and if the model is unavailable it uses template choices and reasons. So a model problem never breaks the page, and the page says when the model did not take part.

Safety rules sit on the server: prices come only from the product cards the server saved for the session; a total above the budget is refused before PayPal is called; an order is captured once, only after PayPal shows it approved; the PayPal host is a constant, so it cannot leave the sandbox.

Tests: 160 unit tests (money rules, adapters on synthetic documented-shape fixtures, malformed model output, spend counters, colour contrast), and an end-to-end run in a real browser that does a live search, a PayPal sandbox guest payment to COMPLETED and a tour of every screen and error state at several screen sizes.

Challenges we ran into

  • The real Qloo answers differed from the documented shapes in three places (hits list their kind in types, insight entities name the kind in subtype, search answers carry no success flag). We ran the live contract check, fixed the parser and kept the in-repo stand-in (used for tests and offline work) in step with the real structure, without storing any real Qloo answer.
  • Qloo suggestions often have nothing in a shop catalog. The agent moves on to other suggestions, is capped at 8 product searches per run, and turns places into experience links so a run is rarely empty.
  • A free model has to hold a tool loop. Of the seven Workers AI models we tried, Qwen3-30B-A3B (with its no-think switch) was the cheapest and quickest that completed the tool loop; two others sent invalid tool arguments. Workers AI also rejects an empty tool-call turn sent as null, and Qwen3 "thinking" made a run take 48 s and 141 neurons, against 12 s and 57 neurons with its no-think switch (fake Qloo and catalog, real model).
  • Staying free. A Durable Object keeps exact daily counters per visitor and for everyone (Qloo calls, model calls, model neurons, Channel3, Tavily, orders, returns), and refuses a call before it is made when its cap is reached. Shop search, web search and the model pause on their own and the run goes on: with shop search paused the ideas still come from Qloo, each with its reason, but without buy buttons; with web search paused the price checks and place links are skipped; without the model the steps are fixed. A run that Qloo's allowance cannot finish is refused before it starts, so it spends nothing. The page says what happened in plain words and offers a saved example that always works.
  • PayPal's hosted sandbox page changes layout between loads; the end-to-end test handles both layouts and never creates a PayPal account.

Accomplishments that we are proud of

  • The reason on each card traces back to a favourite that Qloo linked to the suggestion, and the server enforces it.
  • It is a finished flow (taste, ideas, pick, pay, receipt) with every state designed: loading, empty, errors, limits, cancelled and failed payments.
  • It runs inside free plans and says so when a daily limit is reached.

What we learned

Explainability is the useful part of Qloo for a shopping flow: the score says how strongly a suggestion is tied to which favourite, which is what makes a reason honest and lets the list be ranked without asking the model.

What's next for Tasteloom (plans, not built)

  • Use more of Qloo's insight signals (for example location for local experiences).
  • A catalog with wider coverage, so more of Qloo's suggestions become something buyable.
  • Gifts for a group and a shared budget.

Try it (testing instructions)

No account or sign-in, and it is free. The demo stays up until at least Nov 17, 2026 (judging ends Nov 5).

  1. Open https://tasteloom.kylne700.workers.dev
  2. Quick look without waiting: press Try an example. It replays a saved run (its taste matches and reasons are stand-ins and the page says so; its products and prices were live on the day it was recorded).
  3. Live run: add three or four favourites. Good ones: Kafka on the Shore (book), Nujabes (artist), Muji, Kyoto (destination). Pick a budget (for example $120) and press Find gift ideas. The ideas appear one by one while the page shows each Qloo, shop and model step; live runs with four favourites took 14 to 24 s on the deployed site. Every idea says "Because they love ..." and names the favourite Qloo links most strongly. Place suggestions come as experience links.
  4. Pick one or two product cards (Add to gift; a bar shows how many are picked and the total against the budget) and press Review and pay.
  5. On the checkout screen press the Pay ... with PayPal button. PayPal's own sandbox page opens. Choose Pay with Debit or Credit Card and enter the test card shown on our page (with copy buttons): 4005 5192 0000 0004, expiry 12/30, security code 123. Name, email, phone and address can be made up. If the page has a "Save info & create your PayPal account" switch, turn it off and press Pay Now; if it has two buttons, press Pay now as guest (not "Create Account & Pay Now"). No real money moves.
  6. You return to a receipt: order id, status COMPLETED, items, and a "PayPal sandbox, no real money" row.

If a daily limit has been reached, the page says which one; try again after 00:00 UTC. When shop search is paused the ideas still come from Qloo, with their reasons, but without buy buttons; press Try an example to go through the picking and paying steps. When Qloo's allowance is used up the page offers the saved example instead. The caps are per visitor and for everyone (see the README, "Limits"): Qloo calls 60 and 600 a day, model calls 80 and 600, Channel3 searches 24 and 25, Tavily searches 20 and 25 (small on purpose: their free credits last a month), sandbox orders 8 and 100.

What is sent where: what you type goes to Qloo and to the model on Cloudflare Workers AI; searches built from it go to Channel3 and Tavily; PayPal gets only the order, in its sandbox. Tasteloom does not store the favourites you type. The server keeps only the saved product cards and the budget for pricing (2 hours; the saved example is not stored), sandbox orders (7 days), cached shop and web search answers (12 hours) and daily counters keyed by a hash of the day and your IP; the browser keeps your inputs in this tab only. Qloo answers are not cached in production.

Built With

Share this project:

Updates

Submission history