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:
- 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.
- Search. Each thing you love goes to
/search; he keeps the entities Qloo knows. - Insights. For each slot he calls
/v2/insightswith your entities assignal.interests.entitiesand the slot'sfilter.type(urn:entity:movie/urn:entity:tv_show,urn:entity:placewithfilter.location.query,urn:entity:artist). - 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.
- 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
- javascript
- python
- qloo
- svg
Log in or sign up for Devpost to join the conversation.