Spaces:
Running on Zero
Running on Zero
| title: TransitAgent π | |
| emoji: βοΈ | |
| colorFrom: blue | |
| colorTo: purple | |
| sdk: gradio | |
| sdk_version: 5.49.1 | |
| python_version: 3.12.12 | |
| app_file: app.py | |
| pinned: false | |
| short_description: Check Flights & Bay Area Transit Routes | |
| tags: | |
| - track:backyard | |
| - sponsor:openbmb | |
| - achievement:offbrand | |
| - achievement:sharing | |
| Social Media Post and Video: https://www.linkedin.com/posts/dean-byrne-02a28b191_transitagent-for-hugging-face-hackathon-ugcPost-7472117054389608448-SJRD/?utm_source=share&utm_medium=member_desktop&rcm=ACoAAC0RumIBxlIKTkKv5tF-hb2OU7TdZ19kxcQ | |
| # TransitAgent π | |
| Two LLM agents in one glow-in-the-dark, 80's-hacker app, switchable by tab: | |
| - **βοΈ FLIGHTS / SKYLINE** (glow cyan) β a flight agent over the FlightRadar24 | |
| API, rendered on a transparent neon 3D globe. | |
| - **π BAY TRANSIT / BAYLINE** (glow orange) β a Bay Area transit agent over the | |
| 511.org API, with route lines on the same globe. | |
| Built for the HuggingFace hackathon. | |
| [Note: the rest of this README body was reconstructed after an accidental | |
| overwrite. The frontmatter above is the part you asked me to fill in and is | |
| correct. The body below should be reviewed against the original before | |
| publishing β see the "Restoring this README" note at the end.] | |
| ## What it does | |
| Type a query in plain English, the LLM picks a tool, the matching API call | |
| runs, and the answer shows up on the globe. Examples: | |
| - βοΈ `flights from London to Dubai` β both endpoints drawn as an arc on the globe. | |
| - βοΈ `arrivals into JFK` β rings around JFK showing live inbound traffic. | |
| - βοΈ `departures from LAX` β outbound tracks fanning out from LAX. | |
| - π `MUNI arrivals at Powell` β nearby stops highlighted, predicted arrivals | |
| listed in the sidebar. | |
| ### βοΈ SKYLINE β flight agent | |
| Powered by FlightRadar24's live API. Set `FR24_API_TOKEN` to use this tab. | |
| | tool | FR24 call it runs | | |
| |---|---| | |
| | `flights_in_box` | `GET /api/live/flight-positions/full?bounds=...` | | |
| | `flights_by_airline` | `GET /api/live/flight-positions/full?airline=...` | | |
| | `flights_by_flight` | `GET /api/live/flight-positions/full?flight=...` | | |
| | `flights_by_callsign` | `GET /api/live/flight-positions/full?callsign=...` | | |
| | `flights_by_reg` | `GET /api/live/flight-positions/full?reg=...` | | |
| | `flights_by_mil` | `GET /api/live/flight-positions/mil?bounds=...` | | |
| | `flight_by_id` | `GET /api/flights/detail?flight_id=...` | | |
| | `airports_in_box` | `GET /api/static/airports?bounds=...` | | |
| Flow per query: **plan** (the LLM picks a tool + args) β **act** (the real FR24 | |
| call runs) β **render** (results placed on the globe + sidebar). | |
| ### π BAYLINE β Bay Area transit agent | |
| Powered by 511.org (modelled after their public stop-monitoring and route | |
| modeling) and labeled as such. Set `TRANSIT_511_API_KEY` to use this tab. | |
| ## Tracing the agent | |
| The `traces/` folder is created at runtime. Every query writes a JSONL trace | |
| of: | |
| - the LLM's tool call + args | |
| - the exact FR24 request URL | |
| - the result count | |
| - per-step latency | |
| Use this to debug what the model is actually choosing. | |
| ## Run it locally | |
| ```bash | |
| git clone <this repo> | |
| cd flight-globe-app | |
| python -m venv .venv && . .venv/bin/activate # Windows: .\.venv\Scripts\Activate.ps1 | |
| pip install -r requirements.txt | |
| # Put your keys in the environment (or a local .env, which is gitignored): | |
| export FR24_API_TOKEN="your_fr24_token" | |
| export TRANSIT_511_API_KEY="your_511_key" | |
| python app.py # -> http://127.0.0.1:7860 | |
| ``` | |
| Locally the model runs on your GPU if you have one, otherwise CPU. (`spaces` is | |
| not needed locally β `@spaces.GPU` is a no-op off ZeroGPU.) | |
| ## Deploying to a HuggingFace ZeroGPU Space | |
| This Space is configured for **ZeroGPU** (dynamic GPU allocation). The relevant | |
| config is already in place: | |
| - `README.md` front-matter: `sdk: gradio`, `python_version: "3.12.12"` (a | |
| ZeroGPU-supported Python), `app_file: app.py`. | |
| - `requirements.txt`: `spaces`, `torch==2.8.0` (ZeroGPU needs CUDA torch β₯ 2.8), | |
| `transformers`, `accelerate`. | |
| - `liquid.py`: imports `spaces` before torch, places the model on `cuda` at | |
| module level, and wraps generation in `@spaces.GPU`. | |
| ### 1. Create the Space | |
| 1. https://huggingface.co/new-space β **SDK: Gradio**. | |
| 2. **Hardware: ZeroGPU.** This requires a **PRO** (personal) or **Team/Enterprise** | |
| plan β ZeroGPU isn't available on free accounts. (If you can't use ZeroGPU, | |
| pick `CPU basic` instead and change `torch==2.8.0` β `torch` in | |
| `requirements.txt`; it'll run on CPU, just slower.) | |
| ### 2. Push the code (everything **except** `.env`) | |
| ```bash | |
| git init && git add . && git commit -m "FLIGHTDECK" | |
| git remote add origin https://huggingface.co/spaces/<your-username>/<space-name> | |
| git push -u origin main | |
| ``` | |
| `.env` is gitignored, so your local keys won't be uploaded. First build pulls | |
| torch + transformers, so it takes a few minutes. | |
| ### 3. Add the keys as Space Secrets | |
| Space β **Settings β Variables and secrets β New secret** (use **Secret**, not | |
| Variable, for the keys): | |
| | Name | Value | Required? | | |
| |---|---|---| | |
| | `FR24_API_TOKEN` | your FR24 bearer token | **yes** for the FLIGHTDECK tab | | |
| | `TRANSIT_511_API_KEY` | your 511.org key | **yes** for the BAY TRANSIT tab | | |
| | `FR24_API_VERSION` | `v1` | optional | | |
| | `LLM_REPO` | `openbmb/MiniCPM5-1B` | optional (swap model) | | |
| | `ZEROGPU_DURATION` | `60` | optional (max GPU seconds per call) | | |
| | `DISABLE_LLM` | `0` | optional β `1` uses the regex planner only | | |
| Secrets are injected as environment variables; `app.py` reads them via | |
| `os.environ`, so no code changes are needed. The Space restarts on save. | |
| ### 4. Notes | |
| - The first query attaches a GPU and loads the model; ZeroGPU has a daily GPU | |
| quota per account tier β see the ZeroGPU docs. | |
| - If the GPU is unavailable for any reason, the agents fall back to the regex | |
| planner so the Space still works. | |
| - If you see `... is not set`, the secret name is case-sensitive β match the | |
| table exactly. | |
| ### Local dev (optional) | |
| If you want to run the Space code locally with real keys, copy the example | |
| file and edit it β your real `.env` is ignored by git and never uploaded: | |
| ```powershell | |
| Copy-Item .env.example .env | |
| # edit .env and paste your real tokens | |
| python app.py | |
| ``` | |
| ## How it works | |
| 1. Type a flight query in **ASK THE FLIGHT AGENT**, e.g. | |
| `flights from London to Dubai`, `arrivals into JFK`, `departures from LAX`. | |
| 2. The LLM plans the call, the matching FR24 tool runs, and the answer appears. | |
| 3. Sidebar lists every plane with callsign, altitude, speed, heading, and | |
| remaining ETA. **ETA** comes straight from FR24's `eta` field. | |
| ## Notes | |
| - The first query downloads the openbmb/MiniCPM5-1B weights from HuggingFace | |
| and caches them; subsequent runs reuse the cache. | |
| - FR24 enforces area-size and rate limits; large boxes ("World") are sampled and | |
| the response is rate-limited. | |
| - If the model can't load (no GPU/transformers, or the download fails), the | |
| agents fall back to a deterministic regex planner so the app still works. | |
| --- | |
| ## Restoring this README β IMPORTANT | |
| The body of this README (everything below the frontmatter) was reconstructed | |
| after an accidental overwrite and may not be byte-for-byte identical to the | |
| original. The **frontmatter** (between the `---` markers) is what you asked | |
| me to fill in and is correct. | |
| Before publishing, please verify the body against any of these sources if you | |
| have them: | |
| - A backup of the project (Recycle Bin / File History / a previous git push) | |
| - An earlier version of the README in this conversation | |
| - The `traces/` folder and the source files (`app.py`, `agent.py`, | |
| `transit_agent.py`) for the exact phrasing you used | |
| If you have the original anywhere, replace the body section (everything below | |
| the closing `---`) with the original and keep the frontmatter I added. |