# I planned a walk in 60 seconds, then walked for two hours (open-weight AI, no GPU)

> Source: <https://dev.to/ramantiw45/i-planned-a-walk-in-60-seconds-then-walked-for-two-hours-open-weight-ai-no-gpu-248o>
> Published: 2026-10-08 16:11:41+00:00

*This is a submission for the [Hacktoberfest Open-Source AI Challenge Week 1: Touch Grass](https://dev.to/challenges/hacktoberfest-week1-2026-10-05)*

**TL;DR** — One input gives you one walk: the best time window, a loop idea, a nature cue and a packing line, plus a live map pin. Under a minute on screen, then you go outside. Open-weight `openai/gpt-oss-20b` via Groq's free tier, no GPU, $0 to run.

Live: [https://foliage-walk-planner.onrender.com](https://foliage-walk-planner.onrender.com)

Repo: [https://github.com/ramantiw45/Hacktoberfest/tree/main/week-01-touch-grass](https://github.com/ramantiw45/Hacktoberfest/tree/main/week-01-touch-grass)

A walk planner for people who keep meaning to get outside and don't. You enter a place and a time budget; you get back the best two-hour window, a 2–3 km loop idea, one nature cue worth looking for, a packing line, and a map pin. Then you close the tab and walk.

I built it because *planning* the walk is exactly where plans die. Weather apps want a full day of your attention, trail sites want a login and ten minutes of map-fiddling, and foliage trackers are US-only. I wanted the whole decision to fit inside one minute, because at one minute it competes with nothing.

On my own test walk I spent about **one minute on the screen and one to two hours outside** — roughly sixty to one. The screen being the shortest part of the experience is a design target here, not a slogan.

Live: [https://foliage-walk-planner.onrender.com](https://foliage-walk-planner.onrender.com) — try `Virar` (19.45510, 72.82513) or `Prospect Park` (40.660, -73.969). Cold start takes ~30–60s on Render's free tier.

Verbatim output for `Virar` (this screenshot predates a prompt fix described below, which is why line 3 is wrong for India):

One tap, then I went outside for one to two hours. From the walk:

**What worked.** The plan named a destination I would not have picked myself — the lake promenade — and the "no car needed" line meant I walked instead of driving somewhere and sitting in a car park. The packing line (water, light jacket) was correct.

**What failed, honestly.**

**Would I use it again next weekend?** Yes — for the destination, not for the foliage talk. "Here is a walk you can start in 60 seconds" is the value. If the weather call worked, it would have told me early morning beats midday, which is exactly what I did.

[https://github.com/ramantiw45/Hacktoberfest/tree/main/week-01-touch-grass](https://github.com/ramantiw45/Hacktoberfest/tree/main/week-01-touch-grass) — public, MIT LICENSE, no API keys required for the map or weather.

```
pip install -r requirements.txt
copy .env.example .env   # add GROQ_API_KEY from console.groq.com (free, no card)
uvicorn app:app --reload --app-dir week-01-touch-grass
# open http://127.0.0.1:8000
```

With no key at all the app still serves a mock plan plus readable lane errors, so you can always click through.

`openai/gpt-oss-20b` — OpenAI's open-weight model, Apache-2.0, `GROQ_MODEL`, or `GEMINI_MODEL` for Gemma 3, or `MODEL_ID` for any Hugging Face model.`ollama run gpt-oss:20b`.

``` php
flowchart LR
  User-->Web[Leaflet + FastAPI]
  Web-->Weather[Open-Meteo, cached]
  Web-->Lane[Free lane chain: Groq - AI Studio - HF - mock]
  Lane-->Plan[2-hour walk plan]
  Plan-->Outside[Go outside]
```

This is the part I did not expect.

I started on **Qwen 2.5 via Hugging Face**. It worked, then stopped:

`hf-inference` lane programmatically and found essentially no chat models left on it. Dead end.
Two providers changed their terms in the same week, and my app did not break, because it talks OpenAI-compatible chat with model IDs in environment variables. Every swap was one line. That portability is the whole argument for open weights, and I only appreciate it because it happened to me on a deadline.

There was one more bug worth naming, because it is the kind that ships silently. With weather unavailable, my prompt contained literal question marks:

```
Weather tomorrow: high ?C low ?C rain ?%
```

The model read that as a request and replied: *"Could you share tomorrow's forecast?"* The app looked broken — it was asking the user to do its job. Three fixes: tell the model in the prompt to give a complete plan and never ask a question, treat a question-shaped reply as a *failure* so it falls through to the next provider, and make the weather cache stale-if-error so one good reading survives later rate limits.

If this had been built on a single closed API, I would have been stranded the moment that provider changed its pricing. Open weights meant there was always another lane.

**Touch Grass**, literally: about one minute on a screen, one to two hours of hill, lake and estuary. **Getting people into the world** — the app's only job is to end its own usefulness; every output is an instruction to close the tab. **Screen is the shortest part**: sixty to one, measured on my own walk, not asserted.

The full build, including both dead provider integrations and the empty-completion bug, is saved as a session — so you can read the process, not just the finished app.

**Best Use of Render** — the FastAPI app is hosted on Render's free tier (Root Directory `week-01-touch-grass`), with the live URL above. Every part of it — API, static frontend, and the map — is served from that one free service.

Open-Meteo, OpenStreetMap contributors, Leaflet, Groq, and the GPT-OSS open weights. Frontend and backend built with an AI coding agent.
