Inspiration

What it does

How we built it

Challenges we ran into

Accomplishments that we're proud of

What we learned

What's next for Jitters picks tonight

Inspiration

At 2 am a coder can still write a database migration, but cannot pick a film. Every streaming app asks the same question at the worst hour: what do you want? Tired people don't want a menu. They want someone who knows their taste to just pick.

Jitters is an anxious little monkey who codes all night, and he knows the feeling. So he picks for you, from your own taste, with his nerves showing.

What it does

Tell Jitters three things you love: a film or show, an artist, a food place or brand. He reads the hour on your clock and how many coffees you had, asks Qloo what fits your taste, and picks tonight's three things:

  • Watch: a film, or an episode if it's past midnight or you're wired (a promise you can keep).
  • Eat: a place in your city (filled in from your time zone), or a brand if you leave the city empty.
  • Listen: an artist.

For each pick he tells you the runner-up he almost chose ("Justice. Air was close. don't tell Air."). Under the picks, "his working" shows every call he made to Qloo, in order, in his voice, with its arguments and how many results came back. If Qloo doesn't know something you love, he says so instead of inventing an answer.

How we built it

The agent (tonight/__init__.py) is a small tool-using loop around the Qloo Taste API:

  1. Plan from the night. The hour and the coffee count set his nerves (0-100) and the plan: movie or TV episode, place or brand.
  2. Search. Each thing you love goes to /search; he keeps the entities Qloo knows.
  3. Insights. For each slot he calls /v2/insights with your entities as signal.interests.entities and the slot's filter.type (urn:entity:movie / urn:entity:tv_show, urn:entity:place with filter.location.query, urn:entity:artist).
  4. Observe and retry. He drops anything you already gave him. An empty answer is retried with fewer signals (the entity of the same type), then the slot is dropped and said so.
  5. Pick. The top fresh result, with the runner-up shown.

The Qloo key never reaches the browser: the page posts to our server, which calls hackathon.api.qloo.com with the key in X-Api-Key. Each Qloo answer is cached per query, so the same ask never costs twice.

The page is plain HTML, CSS and JS with no build: Jitters is inline SVG animated by CSS, and his face follows his mood (calm, groggy, wired). The trace plays back one call at a time, so you watch him think.

Tests first. A small working fake of the Qloo API (tests/fake_qloo.py) backs 18 contract tests of the agent (picks, late-night plan, retries, bad input, a missing or wrong key, Qloo down) and a browser test that drives the page in Chromium at phone and desktop width.

Challenges we ran into

Choosing what an agent should do when the API returns nothing. The easy path is to fill the gap with something plausible. We made him retry once, narrower, and then say plainly that nothing fit, because a tired person trusts a picker that admits it's stuck.

Accomplishments that we're proud of

The trace. Most agents hide their steps. Jitters panics through his out loud, and it turns out that's the fun part: you see your own taste go in, and you see why he landed where he did.

What we learned

Taste is a better input than a mood slider. Three things someone loves say more about tonight than any "what are you in the mood for" form.

What's next for Jitters picks tonight

Tags for the hour (comfort picks after 1 am), the Qloo audiences of your taste to explain each pick, a "no, again" button that re-plans without the rejected pick, and Jitters living in a Telegram bot that sends tonight's three at your usual bedtime.

Built With

Share this project:

Updates

Submission history