Build a coding agent from scratch in 13 iterative steps — from a bare Gemini API call to a fully functional coding agent deployed on Modal with Telegram integration, persistent memory, and sandboxed execution.
View the presentation for a visual walkthrough of the entire build.
This project is based on the outstanding work by Ivan Leo and Hugo Bowne-Anderson:
- hugobowne/build-your-own-ai-assistant — original repo
- Openclawd From Scratch — Ivan Leo's article series that walks through the concepts in depth
- Original livestream — Hugo & Ivan building it live (~100 min)
- Building Agents That Build Themselves — Hugo Bowne-Anderson's writeup
I discovered this material through Hugo's workshop and was inspired to rebuild it as a structured tutorial. Huge thanks to both Hugo and Ivan for making this knowledge accessible.
The original repo contains the code in two parallel tracks (article directories and a workshop folder). This version reorganizes and extends it:
- Unified 13-step progression — single clean sequence from
01_first_api_callto13_cloud_deploy, each step self-contained and independently runnable - Cloud deployment in the tutorial — Step 13 brings Modal sandbox deployment into the learning path
- Dynamic tool rewriting works in cloud — bidirectional sync between the Modal sandbox and the host agent, so the agent can genuinely extend its own tools even when deployed remotely
- Sandbox persistence connected — the
SaveEnvironmenttool's filesystem images are actually used when restoring sandboxes (three-tier restore: process snapshot → saved filesystem image → fresh base) - Deploy/teardown scripts for every step — each step from 09 onward can be independently started and stopped with a single command
- No secrets in the repo — proper
.env.templateand.gitignore - Presentation included — a visual walkthrough of the entire 13-step build
| Step | Concept |
|---|---|
| 01 | First API call — Gemini + tool declaration |
| 02 | Tool execution — execute and feed result back |
| 03 | Agentic loop — chain multiple tool calls |
| 04 | Tool factory — AgentTool base class + Pydantic |
| 05 | Full toolset — Read, Write, Edit, Bash |
| 06 | Hot reload — self-extending agent |
| 07 | Hooks — event system + Rich output |
| 08 | HTTP server — FastAPI endpoint |
| 09 | Telegram — webhook integration |
| 10 | Sessions — SQLite persistence |
| 11 | Compaction — memory summarization |
| 12 | Guardrails — system prompt + tool budget |
| 13 | Cloud deploy — Modal sandbox + snapshots |
- Python 3.11+
- uv
- Gemini API key
- Telegram Bot Token (steps 09+)
- ngrok (steps 09–12)
- Modal account + CLI (step 13)
- Clone and install dependencies:
git clone https://github.com/labdmitriy/build-your-own-coding-agent.git
cd build-your-own-coding-agent
uv sync- Configure environment variables:
cp .env.template .envEdit .env and fill in:
| Variable | Required for | How to get |
|---|---|---|
GOOGLE_API_KEY |
All steps | Google AI Studio — create a Gemini API key |
TELEGRAM_BOT_TOKEN |
Steps 09+ | BotFather — create a bot and copy the token |
TELEGRAM_CHAT_ID |
Steps 09+ | Send any message to your bot, then visit https://api.telegram.org/bot<TOKEN>/getUpdates to find your chat ID |
- For steps 09–12 (Telegram via ngrok):
Install ngrok, sign up for a free account, and authenticate:
ngrok config add-authtoken <your-token>- For step 13 (Modal cloud deploy):
Install the Modal CLI and authenticate:
uv run modal setupEach step is self-contained:
uv run python steps/01_first_api_call/agent.py
uv run python steps/06_hot_reload/agent.pySteps 09–12 use deploy.sh / teardown.sh to start and stop the Telegram webhook:
cd steps/09_telegram
bash deploy.sh # starts uvicorn + ngrok, registers webhook
bash teardown.sh # stops processes, clears webhookStep 13 uses the same pattern for Modal cloud deployment:
cd steps/13_cloud_deploy
bash deploy.sh # creates Modal secrets, deploys server + worker, registers webhook
bash teardown.sh # clears webhook, stops apps, deletes Modal resources- Building a minimal coding agent — Mario Zechner's Pi agent
- Pi: The Minimal Agent Within OpenClaw — Armin Ronacher's analysis