Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 8 additions & 1 deletion .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,14 @@ MODAL_TOKEN_ID=
MODAL_TOKEN_SECRET=
MODAL_INFERENCE_URL=

# Model variant for Modal deployment (this branch defaults to MiniCPM)
# Allowed values: minicpm, nemotron, qwen
MODEL_FAMILY=minicpm
# Optional explicit override of model ID (takes precedence over family default)
MODEL_ID=openbmb/MiniCPM3-4B
# Optional: set true for model families that require custom model code
TRUST_REMOTE_CODE=true

# Hugging Face (for dataset backup + Space deployment)
# Token needs Write access (classic) or fine-grained with repo read+write
HF_TOKEN=
Expand All @@ -15,4 +23,3 @@ HF_TRACES_REPO=your-username/aether-garden-traces

# Development: use mock AI when Modal is not configured
USE_MOCK_AI=true
MODEL_ID=Qwen/Qwen2.5-7B-Instruct
18 changes: 16 additions & 2 deletions DEPLOYMENT.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,27 @@
3. Authenticate: `modal token new`
4. Deploy inference:
```bash
modal deploy modal_app.py
MODEL_FAMILY=minicpm MODEL_ID=openbmb/MiniCPM3-4B TRUST_REMOTE_CODE=true modal deploy modal_app.py
```
5. Copy the `inference` endpoint URL (looks like `https://your-name--aether-garden-inference.modal.run`)
6. Set in your `.env`:
```
MODAL_INFERENCE_URL=https://your-endpoint.modal.run
USE_MOCK_AI=false
MODEL_FAMILY=minicpm
MODEL_ID=openbmb/MiniCPM3-4B
TRUST_REMOTE_CODE=true
```

MiniCPM and Nemotron switch:

- MiniCPM track (default on this branch):
```bash
MODEL_FAMILY=minicpm MODEL_ID=openbmb/MiniCPM3-4B TRUST_REMOTE_CODE=true modal deploy modal_app.py
```
- Nemotron hardware prize variant:
```bash
MODEL_FAMILY=nemotron MODEL_ID=nvidia/Llama-3.1-Nemotron-Nano-8B-v1 TRUST_REMOTE_CODE=false modal deploy modal_app.py
```

### 2. Hugging Face Account ($20 credits — mostly unused)
Expand Down Expand Up @@ -59,7 +73,7 @@ python app.py # Verify at localhost:7860

### Step 2: Deploy Modal
```bash
modal deploy modal_app.py
MODEL_FAMILY=minicpm MODEL_ID=openbmb/MiniCPM3-4B TRUST_REMOTE_CODE=true modal deploy modal_app.py
```
- Note the inference URL
- The hourly `run_world_simulation` job starts automatically
Expand Down
90 changes: 68 additions & 22 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,57 +15,74 @@ tags:
- three.js
- persistent-world
- hackathon
- thousand-token-wood
- best-agent
- off-brand
- modal
- codex
- minicpm
- tiny-model
---

<div align="center">
<img src="assets/banner.png" width="100%" alt="Aether Garden" />

# Aether Garden

**The Living Tome — a living AI world where every visitor writes a new page.**
**The Living Tome — a persistent AI world where every visitor writes a new page.**

[![Gradio](https://img.shields.io/badge/Gradio-4.x-F97316?style=flat-square)](https://gradio.app)
[![Hugging Face](https://img.shields.io/badge/Hugging_Face-Spaces-FFD21E?style=flat-square&logo=huggingface&logoColor=black)](https://huggingface.co/spaces)
[![Modal](https://img.shields.io/badge/Modal-A10G-7C3AED?style=flat-square)](https://modal.com)
[![Qwen 2.5](https://img.shields.io/badge/Qwen_2.5-7B_Instruct-06B6D4?style=flat-square)](https://huggingface.co/Qwen/Qwen2.5-7B-Instruct)
[![MiniCPM](https://img.shields.io/badge/MiniCPM-3_4B-06B6D4?style=flat-square)](https://huggingface.co/openbmb/MiniCPM3-4B)
[![Thousand Token Wood](https://img.shields.io/badge/Hackathon-Thousand_Token_Wood-C8A040?style=flat-square)](https://huggingface.co/blog/gradio-llm-hackathon)
</div>

---

## The problem
## Submission Snapshot

- Live Space: [build-small-hackathon/aether-garden](https://huggingface.co/spaces/build-small-hackathon/aether-garden)
- Track focus: Thousand Token Wood
- Core model (this branch): MiniCPM3-4B via Modal
- Agent behavior: autonomous hourly simulation tick with memory updates
- Persistent state: SQLite + HF Dataset backup/restore

---

## Problem

Most AI demos generate a thing and forget it. You type a prompt, get a character sheet, close the tab — and the output dies with the session. There is no world, no history, no consequence. Judges asked for something different: **AI as the product**, not a wrapper around a static response.

Aether Garden is the opposite. When you open it, the world is already days old. Strangers have already built it. A Joke Dragon became Mayor while you were asleep. The Book of Ages remembers. You add one strange thing — *a blind cartographer who maps places that don't exist yet* — and hours later, without you watching, the simulation runs. The cartographer meets someone else's Crystal Tree. History writes itself.

---

## What it does
## What It Does

A visitor opens an ancient leather-bound grimoire. Instead of navigating dashboard tabs, they turn pages through six spreads: The Realm, Explore the Realm, Book of Ages, Souls of the Garden, Bonds and Alliances, and Summoning. Each page is tied to the same persistent world state. Summoning something new triggers a full AI pipeline:

```
Visitor description (5–200 words)
|
Qwen 2.5 7B on Modal (A10G) name, appearance, backstory, goals, fears,
personality, greeting, sacred location
MiniCPM 3-4B on Modal (A10G) name, appearance, backstory, goals, fears,
personality, greeting, sacred location
|
SQLite + WAL entity persisted; arrival logged to Book of Ages
SQLite + WAL entity persisted; arrival logged to Book of Ages
|
SVG world map entity appears as a dot at their location
SVG world map entity appears as a dot at their location
|
Hourly simulation tick 1 world event + 2–4 entity interactions
(Modal scheduled job) relationships form; memories compress; lifecycle updates
Hourly simulation tick 1 world event + 2–4 entity interactions
(Modal scheduled job) relationships form; memories compress; lifecycle updates
|
HF Dataset backup world.db snapshot pushed after every tick
HF Dataset backup world.db snapshot pushed after every tick
```

Nobody scripts the encounters. The model decides what happens between visits. Remove inference and the Realm is just a database of text — the AI is load-bearing by definition.

---

## What you see when you open it
## First-Run Experience

The world is designed to feel alive on first load:

Expand Down Expand Up @@ -93,7 +110,7 @@ python run_tick.py # run 3–7× to build simulation history
python app.py # → http://localhost:7860
```

```
```text
1. Open the Tome cover, then use page turns or the ribbon table of contents.
2. In The Realm spread, inspect the map and live chronicle.
3. In Explore the Realm, choose a place and step into the diorama window.
Expand All @@ -106,7 +123,7 @@ Step 6 is the key test. The simulation runs without user input. History accumula

---

## Build from source
## Build From Source

**Prerequisites:** Python 3.11+, Modal account (for production AI), Hugging Face account (for Space + dataset backup).

Expand All @@ -121,20 +138,20 @@ python app.py
# Production AI via Modal
pip install modal
modal token new
modal deploy modal_app.py
MODEL_FAMILY=minicpm MODEL_ID=openbmb/MiniCPM3-4B TRUST_REMOTE_CODE=true modal deploy modal_app.py
# Copy inference URL → MODAL_INFERENCE_URL in .env, set USE_MOCK_AI=false

# Manual simulation tick (demo prep)
python run_tick.py
```

Full deployment (HF Space secrets, dataset backup, UptimeRobot keepalive): see [DEPLOYMENT.md](DEPLOYMENT.md).
Full deployment details: [DEPLOYMENT.md](DEPLOYMENT.md).

---

## How it handles the hard parts
## Technical Notes

**Structured AI output.** Entity generation, interactions, and world events all require valid JSON. Qwen 2.5 7B is chosen for consistent structured output. Failed parses trigger an automatic retry at lower temperature.
**Structured AI output.** Entity generation, interactions, and world events all require valid JSON. This branch runs MiniCPM 3-4B by default for tiny-model impact and low latency while staying under the 32B cap. Failed parses trigger an automatic retry at lower temperature.

**World coherence at scale.** Each entity carries a compressed `memory_summary` (max 150 words) updated after significant events — not a raw log. Interactions are scoped by location. The 8 sacred locations act as narrative containers so the world does not sprawl into contradiction.

Expand All @@ -148,7 +165,7 @@ Full deployment (HF Space secrets, dataset backup, UptimeRobot keepalive): see [

---

## The autonomous simulation
## Autonomous Simulation

Every hour, Modal runs a 7-step tick:

Expand All @@ -166,6 +183,35 @@ Estimated cost over 10 days: **~$68 of $250 Modal credits**, including demo-day

---

## Submission Compliance

| Requirement | Status | Evidence |
|---|---|---|
| REQ-02: each model under 32B | Met | MiniCPM3-4B for text generation; SDXL-Turbo for portraits |
| REQ-05: Gradio app in HF Space | Met | Space uses Gradio with app entrypoint app.py |
| REQ-06: Zero GPU app limit | Met | Single Space app |
| README tags + write-up | Met | YAML frontmatter tags and complete technical write-up |

Variant switching is environment-driven (no code changes required):

- MiniCPM variant: MODEL_FAMILY=minicpm and MODEL_ID=openbmb/MiniCPM3-4B
- Nemotron variant: MODEL_FAMILY=nemotron and MODEL_ID=nvidia/Llama-3.1-Nemotron-Nano-8B-v1

---

## Prize Mapping

| Prize | Current Position |
|---|---|
| Best MiniCPM Build | Directly targeted in this branch |
| Best Use of Modal | Modal inference + scheduled simulation runtime |
| Best Use of Codex | Codex-attributed commits on variant branch |
| Off Brand | Heavy custom UI + non-default Gradio experience |
| Best Agent | Autonomous multi-step simulation loop |
| Tiny Titan | MiniCPM3-4B model size aligns with criteria |

---

## Documentation

| Document | Contents |
Expand All @@ -182,7 +228,7 @@ Estimated cost over 10 days: **~$68 of $250 Modal credits**, including demo-day
```
.
├── app.py Gradio frontend — map, Book of Ages, entity summoning
├── modal_app.py Qwen 2.5 7B inference + hourly simulation (deploy to Modal)
├── modal_app.py MiniCPM/Nemotron/Qwen inference + hourly simulation (deploy to Modal)
├── seed_world.py Pre-populate 10 entities, history, relationships
├── run_tick.py Manual simulation tick for testing and demo prep
├── world/ SQLite schema, entities, locations, Book of Ages, relationships
Expand All @@ -196,7 +242,7 @@ Estimated cost over 10 days: **~$68 of $250 Modal credits**, including demo-day

---

## Hackathon targets
## Hackathon Targets

| Prize track | Why this qualifies |
|-------------|-------------------|
Expand All @@ -206,7 +252,7 @@ Estimated cost over 10 days: **~$68 of $250 Modal credits**, including demo-day
| **Best Demo** | World already alive for days when judges open it |
| **Modal Award** | Inference + scheduled jobs on Modal A10G |

Badge targets: Off-Brand (built-in), Well-Tuned (fine-tune Qwen 2.5 3B), Sharing is Caring (agent traces), Field Notes (HF blog post).
Badge targets: Off-Brand (built-in), Tiny Titan (MiniCPM 3-4B), Sharing is Caring (agent traces), Field Notes (HF blog post).

---

8 changes: 8 additions & 0 deletions README_HF_SPACE.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,18 @@ sdk_version: 5.50.0
app_file: app.py
pinned: true
license: mit
tags:
- gradio
- minicpm
- agents
- simulation
- modal
---

# Aether Garden

The World That Remembers — a living AI world where every visitor leaves something behind.

This Space variant runs MiniCPM 3-4B by default via Modal for low-latency, under-32B inference.

Open the app, read the Book of Ages, summon something strange, and watch the world remember.
Loading
Loading