WanderLust / README.md
coreprinciple's picture
Remove stale DEPLOY.md runbook + its dead README link
6b41d01
|
Raw
History Blame Contribute Delete
9.16 kB
---
title: WanderLust
emoji: πŸ—ΊοΈ
colorFrom: blue
colorTo: green
sdk: gradio
sdk_version: 6.18.0
python_version: '3.12'
app_file: app.py
pinned: true
license: apache-2.0
short_description: A-to-B routes through places you'll love
tags:
- track:backyard
- sponsor:openbmb
- achievement:offgrid
- achievement:offbrand
- achievement:sharing
- achievement:fieldnotes
- badge-off-the-grid
- badge-off-brand
- badge-tiny-titan
- badge-field-notes
- openbmb
---
# WanderLust
### Spend your extra time on discovery.
**Track 1 β€” Backyard AI** Β· **Live Space:** https://huggingface.co/spaces/build-small-hackathon/WanderLust
Most navigation apps answer one question: *what's the fastest way there?* **WanderLust
asks a better one: what if those few extra minutes were a gift?** You tell it where you're
going and the kind of moment you're after β€” "a slow Sunday-morning kind of walk,"
"bookshops and quiet streets," "a lively cafΓ© crawl" β€” and it threads you from A to B
**past the places you'll actually love**, then tells you, in your own words, why each
one is on your path. Same destination. A walk you'll remember instead of one you'll forget.
> One-liner: **WanderLust turns any walk or ride from A to B into a personal discovery β€”
> routing you through places that match your taste, not just the fastest path.** **Nine
> cities across four continents** β€” Paris, London, Barcelona, Berlin, New York, San
> Francisco, Tokyo, Mumbai, Shanghai β€” all routed **fully offline** (no cloud APIs at request time).
---
## Why we built it (Backyard AI)
This started as our own itch. We're cyclists, and pedaling around new cities we kept
hitting the same frustration: the map only ever knows the *fastest* line between two
points, but the whole joy of exploring your "backyard" β€” the city around you β€” is the
bookshop, the quiet square, the viewpoint you'd never have found on the direct route.
We wanted a tool that plans the *interesting* way from A to B, tuned to the mood we're in
that day. WanderLust is that tool: a personal, local-first exploration companion for the
ground right under your wheels.
## πŸ”— Links (judges start here)
- **πŸ—ΊοΈ Live Space:** https://huggingface.co/spaces/build-small-hackathon/WanderLust
- **πŸ’» Source code (GitHub):** https://github.com/tristanleduc/wanderlust
- **🎬 Demo video:** https://www.youtube.com/watch?v=55Ofnt6Hhv4
- **πŸ“£ Social post:** [LinkedIn](https://www.linkedin.com/posts/ishrat-jahan-ananya_build-small-hackathon-build-small-hackathon-activity-7472015876708548609-Ss8T) Β· [X/Twitter](https://x.com/coreprinciple_/status/2066248778416267553)
- **πŸ“ Field notes (HF blog):** https://huggingface.co/blog/coreprinciple/wanderlust
- **πŸ§‘β€πŸ€β€πŸ§‘ Team:**
- **Ishrat Jahan Ananya** β€” [Hugging Face](https://huggingface.co/coreprinciple) Β· [GitHub](https://github.com/coreprinciple6) Β· [Website](https://coreprinciple.vercel.app/)
- **Tristan Leduc** β€” [Hugging Face](https://huggingface.co/JohnDoe6) Β· [GitHub](https://github.com/tristanleduc) Β· [LinkedIn](https://www.linkedin.com/in/tristan-leduc-56491b188/)
---
## Why the AI is load-bearing
WanderLust **cannot work without the model.** The hard problem isn't routing β€” it's the
gap between how people describe what they want and what a router can optimize. A user
types a fuzzy, open-ended vibe ("somewhere that feels like a slow Sunday morning"), and
**MiniCPM5-1B converts it into concrete, scored routing weights** across 17 place
categories plus quiet/green/lively modifiers. No lookup table, keyword list, or rule
engine can map unbounded human mood onto a route β€” the model *is* the bridge. It then
writes the itinerary that explains why each chosen stop matches what you asked for,
grounded so it can only name real places on your route.
(When no GPU is allocated, the app degrades gracefully to an embedding + keyword
interpreter and a deterministic template β€” it never breaks β€” but the model is what makes
the experience feel like it read your mind.)
## The tech, one sentence each
- **Model β€” `openbmb/MiniCPM5-1B`:** a 1B-parameter model does two jobs β€” vibe β†’ routing
weights (JSON), and route β†’ first-person itinerary narration.
- **ZeroGPU:** the model runs **inside the Space** on HF ZeroGPU via `@spaces.GPU`,
weights pulled from the Hub β€” no external inference API, nothing leaves the Space.
- **OpenStreetMap + OSMnx:** walking/biking graphs and POIs for nine cities, pre-built and
pulled from an open Hub dataset, then **pre-warmed at boot** so every city is instant β€”
and routes with **no cloud API calls at request time** β€” fully offline.
- **Routing β€” classical, exact:** a `networkx` + SciPy multi-source Dijkstra travel-time
matrix, solved by a custom **orienteering** (prize-collecting TSP) heuristic with
submodular diversity β€” so you get a park + a viewpoint + a bookshop, not five cafΓ©s.
- **Frontend β€” Gradio `gr.Server`:** a hand-built HTML/CSS/JS app-shell on Gradio's
FastAPI backend, called from the browser via `@gradio/client` β€” **no default Gradio UI**.
## What it does
- **Plain vs. discovery route** drawn on one map, with the exact time the detour buys you.
- **Vibe β†’ route:** free-text mood reshapes which places the route seeks out.
- **Walk or bike**, across nine cities, with a city picker (cores pulled on demand).
- **Detour budget:** one slider trades extra time for discovery; the route never exceeds
`(1 + budget) Γ—` the direct time. Budget 0 = the plain fastest route.
- **Adventurousness:** low β†’ well-documented places; high β†’ injects hidden gems.
- **Grounded narration:** an itinerary naming only real waypoints, behind a hard
zero-hallucination gate.
- **Alternative routes:** up to three genuinely distinct options.
- **Persistent taste profile:** standing preferences + saved places, per device, blended
with each trip's mood. No accounts.
## Achievements & badges we're claiming
**Achievements** (`achievement:*` tags):
| Achievement | How WanderLust earns it |
|---|---|
| **Off the Grid** (`offgrid`) | With `DISCOVERROUTE_OFFLINE=1`, **zero cloud APIs at request time** β€” every city is pre-baked + pre-warmed at boot, geocoding is local, and the 1B model runs in-Space on ZeroGPU. |
| **Off-Brand** (`offbrand`) | A hand-built `gr.Server` HTML/CSS/JS app-shell β€” **zero default Gradio components**: custom map, custom controls, custom live-map loader. |
| **Sharing is Caring** (`sharing`) | Two reusable artifacts shared publicly on the Hub: the city-cores dataset [`build-small-hackathon/discoverroute-cities`](https://huggingface.co/datasets/build-small-hackathon/discoverroute-cities) and the inference-trace dataset `build-small-hackathon/discoverroute-traces`. |
| **Field Notes** (`fieldnotes`) | The end-to-end build story β€” decisions, dead ends, fixes β€” in [`FIELD_NOTES.md`](FIELD_NOTES.md) and published as an **[HF blog post](https://huggingface.co/blog/coreprinciple/wanderlust)**. |
**Bonus badges** (prize categories) we're going for:
| Badge | Basis |
|---|---|
| **Off Brand** ($1,500) | The hand-built `gr.Server` custom UI (same evidence as the achievement). |
| **Tiny Titan** ($1,500) | **MiniCPM5-1B β€” 1B parameters** (well under the 4B cap), in-Space on ZeroGPU. |
| **Best Agent** ($1,000) | Four-stage planning pipeline: vibe β†’ routing weights β†’ POI scoring β†’ orienteering solve β†’ grounded narration. |
> **Sponsor prize:** built on OpenBMB's **MiniCPM5-1B**, so eligible for **Best MiniCPM Build** (OpenBMB).
## Run it locally
```bash
uv venv --python 3.11
uv pip install -e ".[ml,dev]" # routing + vibe interpretation/narration + tests
# one-time offline data prep for Paris (downloads OSM, builds the graph + POIs)
python -m discoverroute.data.build_graph
python -m discoverroute.data.build_pois
python app.py # serves the gr.Server app-shell on :7860
```
The other eight cities are pulled on demand from the Hub dataset (and pre-warmed at boot).
Run the test suite with `pytest` (config in `pyproject.toml`, tests in `tests/`).
See [`FIELD_NOTES.md`](FIELD_NOTES.md) for the build story.
## Architecture
**Offline (built once per city, cached):** OSM extract β†’ walk/bike routing graph β†’
POIs with feature priors + confidence. Paris ships full-city; the other eight (London,
Barcelona, Berlin, New York, San Francisco, Tokyo, Mumbai, Shanghai) are baked as walkable
cores via `python -m discoverroute.data.build_city` and hosted as an open Hub dataset, then
pulled + pre-warmed at boot.
**Runtime (per request):** pick the city β†’ interpret vibe β†’ score corridor POIs β†’ solve
the detour (orienteering) β†’ trace a real polyline β†’ narrate + overlay on the map.
The model is load-bearing only in **interpretation and narration**; routing is pure
classical algorithms. Geocoding is local-first β€” named places resolve against the cached
POI index with no network call. With `DISCOVERROUTE_OFFLINE=1` (the deployed config) there
are **zero cloud API calls at request time** β€” routing is limited to the pre-baked cities.
Map data Β© OpenStreetMap contributors (ODbL).