DEV Community

Cover image for I built an AI that sends me on autumn walks. Then I got sick.
Mialy333 🎧ྀི
Mialy333 🎧ྀི

Posted on

I built an AI that sends me on autumn walks. Then I got sick.

Hacktoberfest Open-Source AI Challenge Week 1: Touch Grass Submission 🌿

This is a submission for the Hacktoberfest Open-Source AI Challenge Week 1: Touch Grass

Telegram message from the Autumn Walks bot, in English: weather advice with the driest hour of the afternoon, five trees with their street and autumn colour, total distance, walking time and a Google Maps link

Every morning, a small bot on my laptop picks five trees in Paris that are changing colour, checks the weather, and sends me a walk on Telegram. Reading it takes about 20 seconds. The walk takes about an hour. That ratio is the whole idea.

What I Built

Autumn is my favourite season. I'm fascinated by the colours, and there's a particular atmosphere to it, something warm. I love walking through the streets of Paris with a bit of music in my ears, just feeling those vibes. It's also the season of soups and comfort food, and of going out for a hot chocolate in a coffee shop with fogged-up windows, with the people you love.

So this week, I built something to make sure I don't spend this autumn behind a screen.

Autumn Walks is a Telegram bot that sends me one walk every morning at 8:30:

  • a line of weather advice (umbrella or not, the driest hour of the afternoon)
  • 3 to 5 trees that turn red, orange or gold in October, with their street and their autumn colour
  • the total distance, an honest walking time, and a Google Maps link for the loop

It never sends the same streets two days in a row. It works in French and English. It is for one person: me.

The trees come from Paris open data. The city publishes every tree it manages: 220,174 of them. I kept 2,065: the species with strong autumn colour (ginkgo, liquidambar, Persian ironwood, maple, oak) in five central arrondissements, and only trees you can actually walk up to: streets, public gardens, cemeteries. No school yards. (An early version sent me to a tree inside a nursery.)

Demo

Here's what reached my phone on Thursday morning, in French, with nobody touching the laptop:

Telegram message from the Autumn Walks bot, in French: weather advice, five trees with their street and autumn colour, total distance 3.9 km, walking time 65 minutes, and a Google Maps link

In English:

  1. Oak, 73 rue de Provence, copper brown
  2. Persian ironwood, rue Milton, red to orange
  3. Liquidambar, 3 rue de la Jussienne, red to purple
  4. Liquidambar, Jardin Nelson Mandela, red to purple
  5. Maple, 8 rue de la Banque, red or orange

Total distance: 3.9 km, walking time: 65 minutes.

The part I didn't plan

On Thursday I got sick. Properly sick. I didn't take a single one of these walks.

It frustrated me a lot, because when someone gives me a challenge, I love seeing it through to the end. But my health comes first.

On Friday, the bot went silent. The log had no entry at all. My Mac had been shut down overnight, and macOS launchd catches up on a job missed during sleep, but not one missed while the machine is off. The bot built to get me outside was stuck inside with me.

So this post is about a tool I built and tested, that ran on its own, and that I haven't used yet. The first walk is waiting for me when I'm back on my feet.

Code

GitHub logo Mialy333 / autumn-walks

Plan short autumn walks past colourful Paris trees with a local LLM agent (Strands + Gemma 4 E2B on Ollama)

autumn-walks

Ask "Where should I go for a walk this fall?" and get a short message, ready to send, inviting you on an autumn walk in Paris past trees with strong autumn colour (ginkgo, sweetgum, Persian ironwood, maple, oak). It runs on a small local model.

Morning walk message in French on Telegram: weather advice, five trees with their October colours, distance, walking time and a Google Maps link   The same kind of walk message in English on Telegram, with a different route through five trees

Design principle: the LLM writes, the code does the geography.

How it works

flowchart LR
    Q["Question<br/>or daily 8:30 job"] --> A["Strands agent<br/>Gemma 4 E2B via Ollama"]
    A --> W["get_weather<br/>Open-Meteo"]
    A --> F["find_autumn_trees<br/>SQLite: Paris trees"]
    A --> B["build_walk<br/>Python: stops, distances, Maps link"]
    H[("Walk history<br/>SQLite")] -- "skip recent streets" --> B
    W --> A
    F --> A
    B --> A
    A --> M["Message<br/>checked before sending"]
    M --> T["Telegram"]
    M -- "record walk" --> H
Loading

A Strands Agents agent running Gemma 4 E2B on Ollama uses three tools:

  • get_weather: this afternoon's temperature, rain probability and wind from Open-Meteo (no API key), plus whether to take…

How I Built It

Stack, all open and all local except two HTTP calls:

  • Model: Gemma 4 E2B, running locally with Ollama
  • Agent framework: Strands Agents (Python)
  • Data: Paris open data "Les arbres" (ODbL), filtered once into SQLite
  • Weather: Open-Meteo (free, no API key)
  • Delivery: a Telegram bot, triggered by a launchd job every morning

Step 1: check that a small model can call tools at all

Before writing anything else, I ran a spike: Gemma 4 E2B, one fake weather tool, one question, three runs. It called the tool correctly 3 times out of 3, in 3 to 7 seconds. That was the main risk of the week, and it took an evening to clear.

Step 2: the design principle that made it work

My first agent let Gemma do everything: search the trees, pick the stops, compute the distances. It failed in instructive ways:

  • Without a system prompt, it called no tools at all, in 3 runs out of 3, and said it couldn't plan routes.
  • When it picked the stops itself, it chose far-apart rare trees and produced 4.8 to 5.5 km loops for a 40-minute walk, retrying up to 4 times.
  • It invented places. One walk included the Jardin du Luxembourg, which is not in any of the arrondissements I loaded.
  • It got numbers wrong: it called a 1.2 km loop "about 3 km" and mislabelled distances.

So I split the work:

The LLM writes. The code does the geography.

Python now searches the trees, picks the best set of 3 to 5 stops that fits the distance limit (most species first, then the shortest loop), computes every distance and the walking time (straight-line distance × 1.3 for real streets), and builds the Maps link. Tree names and autumn colours come from a fixed dictionary. Gemma reads all of that and writes a short, friendly message in French or English. It never invents a tree, a colour or a number.

Before a message is sent, the code checks it: the walk was actually built, the exact link is present, the start point is right, the wind is mentioned, no street repeats from the last two walks, under 150 words. If a check fails, the agent is told why and tries again, at most twice. Every retry reason is logged.

Current results: 11 checks out of 11 on every test run, 15 to 21 seconds per walk on a laptop.

Step 3: memory

The first daily version sent the same walk every day: same start, same trees. A small SQLite history fixed it. The agent now skips the streets of the last two walks. (Skipping only the trees wasn't enough: it produced the same route with the tree next door.) The history stays on my machine and never goes to GitHub.

Why Does Open Innovation Matter?

  • It costs nothing to run. Inference is local. The only network calls are the weather and the Telegram message.
  • My location and habits stay mine. A hosted model would receive my starting point and my walking history every single day. Here they never leave the laptop. To be precise: the Telegram message itself goes through Telegram's servers, and the weather call sends the coordinates of the Opéra, a public landmark I chose on purpose rather than my home.
  • The data is open too. The trees are Paris open data under ODbL. Any city that publishes its trees could get the same bot by swapping one file.
  • I could see and change everything. When the agent misbehaved, I didn't have to guess what a black-box API was doing. I moved the geography out of the model and into code I can test. Swapping the model is one line of config.

What Broke

  • The bot went silent on the day I got sick (see above): a shut-down Mac doesn't run missed launchd jobs.
  • My agent session uploads were blocked. Saving the coding sessions to DEV with DevRelay hit a Cloudflare 403 whenever the transcript contained code. I published lighter versions without code; the code is in the repo.
  • My Gmail address was in my first commit, both as the commit author and in pyproject.toml. Caught before the first push, fixed with a squash and GitHub's noreply address.
  • The Maps link was cut in half in Telegram, because of the | separators between waypoints. Encoding them as %7C fixed it.
  • Open-Meteo returned 503 "overloaded" while I was building, so the weather tool now retries, and tells the agent honestly when the weather is unavailable.

What's Next

  • Take the walks. All of them.
  • Let friends subscribe, each with their own language and starting point.
  • Make the colour depend on the date: "starting to turn" in early October, "golden" later on.

Want your own?

There's no public bot to message: it runs on one laptop for one person. But the repo is built to be adapted: your start point, your language, your send time. If your city publishes its trees as open data, tell me in the comments. I'd love to know where this could go next.

My Agent Session

The whole build was done with a coding agent in my terminal. Here's the session where the bot got its memory and its Telegram voice:

Autumn walks: walk memory and a Telegram morning message
You

Keep the 4 km limit. Step 4a: give the agent a memory. Save each walk (date, start, trees, loop length) and leave out the trees of the last 2 walks, then plan 3 walks in a row and show they differ. Step 4b: Telegram. I created a bot and put its token in an environment file; never print that file, make sure it is ignored by git, find my chat id and save it there. Add a command that plans a walk and sends it to my chat, schedule it every morning at 8:30 without turning it on yourself, and send one real message now.

Agent

Leaving out tree ids changes nothing a walker would notice. The next walk now skips the streets and parks of the last 2 walks instead.

The walk history lives in its own small database that is not committed, so the tree data stays shareable and the history stays private. A walk is only recorded after it is actually sent, and tests use a throwaway history.

The daily job was prepared but not turned on, from a template so the repository holds no personal paths. Everything was paused until the chat id was available.

You

I sent the bot two new messages. Try again, and if nothing comes back, check whether an earlier call acknowledged my messages. Then send the real walk, commit and push.

Agent
You

Turn on the morning job.

Agent

Loaded: it runs every day at 8:30, or on wake if the Mac was asleep. The first walk goes out tomorrow and will avoid today's streets.

You

Add a language option for a single run and an option to send without recording the walk, then send me one walk in English without recording it, for a screenshot.

Agent

Takeaways: memory has to be about what the user experiences, which here means streets rather than tree ids. Secrets stay safe by never printing them, checking the ignore list before anything else, and scanning every commit against the real values. And a check before sending turns a small model's occasional slip into a logged retry instead of a wrong message on someone's phone.

Prize Categories

  • Best Use of Gemma: Gemma 4 E2B runs locally and is the agent at the core of the project.

Top comments (0)