townlet / README.md
Budlee's picture
Update README.md
f6f6cd1 verified
|
Raw
History Blame Contribute Delete
6.09 kB

A newer version of the Gradio SDK is available: 6.20.0

Upgrade
metadata
title: Townlet
emoji: 🏘️
colorFrom: red
colorTo: indigo
sdk: gradio
sdk_version: 6.17.3
python_version: '3.12'
app_file: app.py
startup_duration_timeout: 1h
preload_from_hub:
  - HuggingFaceTB/SmolLM2-360M-Instruct-GGUF
  - nvidia/NVIDIA-Nemotron-3-Nano-4B-GGUF
  - Qwen/Qwen2.5-Coder-3B-Instruct-GGUF
  - openbmb/MiniCPM3-4B-GGUF
  - bartowski/Llama-3.2-3B-Instruct-GGUF
models:
  - HuggingFaceTB/SmolLM2-360M-Instruct-GGUF
  - nvidia/NVIDIA-Nemotron-3-Nano-4B-GGUF
  - Qwen/Qwen2.5-Coder-3B-Instruct-GGUF
  - openbmb/MiniCPM3-4B-GGUF
  - bartowski/Llama-3.2-3B-Instruct-GGUF
tags:
  - thousand-token-wood
  - nemotron
  - llama-cpp
  - smolagents
  - agent-simulation
  - track:wood
  - sponsor:nvidia
  - achievement:offgrid
  - achievement:offbrand
  - achievement:llama
  - achievement:fieldnotes
  - award:tiny-titan
  - award:best-agent
short_description: Agents share a Python interpreter, mine, message, dream.

Townlet

Build Small Hackathon entry (Thousand Token Wood track).

Demo, blog & social

Townlet is a multi-agent simulation. LLM-driven characters live on a tile-grid map. They walk to a cave to mine electricity, to a well to draw water, and to a shared shell to spend resources running Python statements in a single long-lived interpreter. They post on a public message board. They sleep, they dream, they evolve. The shared interpreter is the world's only mutable substrate β€” characters can read or rewrite each other's state, and crash the operating system if they so choose. Every character knows this. Mutual awareness of the brick-risk is the source of dramatic tension.

The game element is customisation: click a character to edit their personality (system prompt), swap which small model drives them, or spawn new ones from a pre-baked archetype pool. The simulation is otherwise self-driving.

Model stack

Every character runs on NVIDIA Nemotron 3 Nano 4B (nvidia/NVIDIA-Nemotron-3-Nano-4B-GGUF) by default. One model across the whole town means each @spaces.GPU fork pays a single cold-load and every subsequent character decision reuses the same weights in VRAM β€” a real quota saving on Zero-GPU.

Click any character in the side panel to swap them to a different model mid-simulation; the roster bundled at build time covers:

  • NVIDIA Nemotron 3 Nano 4B β€” default
  • Qwen2.5 Coder 3B β€” for code-heavy goals
  • OpenBMB MiniCPM3 4B
  • Meta Llama 3.2 3B
  • SmolLM2 360M β€” terse, cheap, useful for testing the model-swap UI

All run on Zero-GPU via llama-cpp-python, which gives us the πŸ¦™ Llama Champion badge regardless of which roster model is selected (the badge requirement is "model runs through llama.cpp runtime", not a specific model family).

Agent loops use smolagents CodeAgent, emitting Python tool calls the scheduler queues onto the world.

The map is rendered by the frontend canvas β€” no image model in the loop.

Local development

The project runs in mock mode locally β€” no model weights downloaded, no CUDA needed. Mocks return canned tool-call sequences whose style varies by model_id (deliberate / terse / verbose / chaotic), so the model-swap UI is exercisable without GPUs.

python -m venv .venv
source .venv/bin/activate
pip install -r requirements-dev.txt
python app.py

Or hit β–Ά on the "Run Small Stage (mocks)" config in VS Code.

The mode is selected automatically:

  • SPACE_ID env var present (set by HF Spaces) β†’ real models
  • Otherwise β†’ mocks
  • Set FORCE_REAL_MODELS=1 to override locally (requires Spaces deps).

Deploy to Hugging Face Spaces

git remote add hf https://huggingface.co/spaces/<org>/<space-name>
git push hf main

Then in the Space Settings β†’ Hardware, pick Zero-GPU. The preload_from_hub block above pre-downloads every roster model at build time so the first user click hits a warm cache.

Project layout

app.py                  # gr.Server entrypoint
backend/                # inference layer (mock + real, env-selected)
  factory.py            # get_llm(model_id) β€” per-id cached
  mock.py, real.py      # MockLLMBackend / RealLLMBackend
  interfaces.py         # LLMBackend Protocol
game/                   # the simulation
  models.py             # model roster (id β†’ repo + gguf + style)
  character.py          # Character dataclass
  world.py              # tile grid, BFS pathing, message board
  actions.py            # smolagents.Tool subclasses + per-tick drivers
  interpreter.py        # the long-lived shared Python subprocess
  scheduler.py          # tick loop + per-character CodeAgent invocations
  perception.py         # builds the prompt the CodeAgent receives
  the_dot.py            # the shared system-prompt prefix (substrate truth)
  archetypes.py         # ~15 hand-written personality templates
  dreams.py             # the sleep β†’ insight + delta + trait nudge cycle
  sentiment.py          # board-mood classifier for the UI tint
  smol_adapter.py       # smolagents.Model wrapper around LLMBackend
frontend/index.html     # vanilla HTML/JS top-down view served by app.py
requirements.txt        # Spaces deps
requirements-dev.txt    # local mock-only deps
docs/hackathon.md       # hackathon rules summary
CONTEXT.md              # canonical glossary