For friend groups who plan a night out together. TasteTable picks the restaurant where the person with the lowest score is still happy. Qloo scores every restaurant against each person. The LLM only reads the brief and writes the explanations.

Where the submission answers each judging criterion:

  • Technological Implementation: How we built it, Challenges, and the agent code in lib/agent.ts.
  • Design: the live demo and the architecture figure in the gallery. The agent trace shows every Qloo call.
  • Potential Impact: Inspiration and What it does.
  • Quality of the Idea: What we learned. Qloo gives a score for each person. That score lets the app protect the person with the lowest score.

Inspiration

Group plans usually go to whoever cares most. Someone suggests a restaurant. Two people shrug. One person then spends the night at a restaurant they did not want. We wanted a planner that treats the taste of every person as a vote. The planner also shows each person why the pick fits them.

What it does

Each person lists a few movies, artists, shows, or books they love. TasteTable matches those favorites to Qloo entities. It gets restaurants in the chosen city from the combined taste of the group. Then it scores every restaurant against each person. It picks the restaurant where the person with the lowest score is still happy. It finds a bar, music venue, dessert shop, or cinema near dinner. It also suggests a film for the whole table to talk about. Every pick comes with a match score for each person. One sentence tells each person which favorites drove that score.

The pooled ranking and the fair ranking can disagree. In that case, the app shows the pooled pick next to the fair pick. For a meal plan, TasteTable leaves out cat cafes, coffee shops, fast food, and chains. This filter uses Qloo tags and entity data. For the "Film-club friends" preset in Brooklyn, TasteTable picks Joe's Pizza. At Joe's Pizza, nobody at the table drops below 78%. In both presets, the pooled ranking and the fair ranking put the same restaurant first.

How we built it

The architecture figure in the gallery shows the full flow, from the brief to the sentence for each person.

  • The Qloo Insights API is the decision engine. /search resolves each favorite. The search covers movies, artists, TV shows, books, games, and podcasts.
  • /v2/insights gives the shared ambience tags of the group. It gives restaurant candidates for the city with filter.tags=urn:tag:category:place:restaurant and filter.location.query. It scores the same candidate list again for each person with filter.results.entities and feature.explainability. It finds next stops within 2.5 km of dinner, then 6 km, with filter.location=POINT(lon lat). It also gives the film pick.
  • A meal filter removes cafes, fast food, and chains. It uses filter.exclude.tags, primary_genre, and loyalty_program. If fewer than 6 restaurants remain, the agent asks Qloo for more results.
  • Ranking: fairness = 0.6 × lowest affinity + 0.4 × mean affinity. This formula is a least-misery blend.
  • Gemini 3.1 Flash Lite reads the free-text brief. It sets a price ceiling and the kind of next stop. It also writes the explanation for each person from a JSON evidence object. It never ranks anything. If the first Gemini model fails, the Worker tries a second model. Without Gemini, rules and templates take over.
  • The UI is a Next.js static export. A Cloudflare Worker serves the UI and the API. One plan uses 19 to 28 Qloo calls in our tests. The results page lists every call in an agent trace.

Challenges we ran into

One pooled Insights request favors the majority. We score the same candidate list again for each person. This step multiplies the number of calls. The app limits the group to five people and sixteen favorites. That limit keeps one plan under the Workers limit of 50 subrequests. The hackathon key allows 10 requests per second. The client sends at most 8 requests per second. At larger scale, the Workers limit of 50 subrequests is the first limit. A group of more than five people needs a paid Workers plan or a job queue.

The live API also showed us a few things that the docs do not explain. filter.location rejects an entity ID. The agent searches for the next stop around the dinner coordinates as a WKT point. Search without a type filter matched "Chef" to a restaurant and "The Bear" to an album. We limited search to taste domains.

Accomplishments that we're proud of

The explanation for each person points to their own favorites and score. Each person can check why the app chose a restaurant. The agent trace shows the Qloo requests behind the plan.

What we learned

An LLM cannot fake cross-domain affinity. A model can guess that a Daft Punk fan likes a neon ramen bar. It cannot give that guess a number that holds for five people at once. With live data, scores for well-known favorites are close together. For the top three restaurants in our presets, every personal score is between 77.9% and 89.4%. The fairness rule often works as a tie-breaker.

What's next

  • Let each person veto a cuisine or neighborhood. Then run the plan again with filter.exclude.tags.
  • Share a plan link. Friends then add their own favorites from their phones.
  • Add Resy availability filters (filter.external.resy.party_size.min). The pick then has a table for the whole group.

Try it out

Built With

Share this project:

Updates

Submission history