Spaces:
Running
A newer version of the Gradio SDK is available: 6.20.0
title: DAYDREAM
emoji: ๐
colorFrom: indigo
colorTo: purple
sdk: gradio
sdk_version: 6.16.0
app_file: app/app.py
pinned: true
license: mit
short_description: 'Small models, big dreams: a dream game with your tiger'
tags:
- track:thousand-token-wood
- sponsor:openbmb-minicpm
- sponsor:modal
- badge:best-agent
- badge:off-brand
- badge:best-demo
๐ DAYDREAM โ Press Your Luck, Keep Your Tiger
A bedtime dream you play โ a real, goal-driven story, dreamed in real time by a fleet of small models, none bigger than fits on one GPU. Each world gives you a quest; you pursue it by taking gambits (safe / bold / reckless) through surreal scenes with your stuffed tiger Hobbes, who grows brave because of the bets you take together. Code rolls the dice; the little models supply the soul. Reach the goal to wake with the prize โ or run out of lucidity and dissolve.
The thesis โ small models, big dreams. You don't own one giant brain; you command a fleet of scrappy small minds. In a dream, a small model's fuzziness isn't a bug โ it's the aesthetic. The constraint is the art. Every model โค32B, by design.
๐ Submission tags
- Track: An Adventure in Thousand Token Wood (whimsical) โ there's even a
Thousand Token Woodworld inside. - Sponsor prizes: OpenBMB / Best MiniCPM (MiniCPM5-1B is our Keeper) ยท Modal / Best Use (4 services + a cost-guardian).
- Bonus badges: Best Agent (a coordinated multi-agent fleet) ยท Off Brand (custom dream-deck UI + live generated visuals) ยท Best Demo.
โจ What makes it different
- A real story, not a chat. Every world is a quest with a visible goal; the Dreamweaver weaves one coherent tale that moves toward it each turn (forward on success, setback on failure) and resolves in a genuine climax โ reach the prize, or the dream collapses.
- A fleet, not a chatbot. Five small models โ ๐ Dreamweaver, ๐ Nightmare, ๐ฏ Hobbes, ๐บ Keeper, ๐จ Painter โ each with one job, coordinated per turn. Every model โค32B.
- Code owns the dice, models own the words. Pass/fail and every reward is computed by a seeded, model-free resolver. The models never decide outcomes โ so it's a fair game, not a story that flatters you. This is the heart of the design.
- Hobbes grows brave because of you. A COURAGE meter rises when you survive bets made with him; his voice shifts cowering โ steady โ "I've got you." The "aww" is earned.
- The dream paints itself โ fast. A FLUX image renders each beat on-GPU in ~0.5s; a pre-generated hero greets you the instant you arrive, then live per-beat images shift the scene. Choices and state run async, so a warm turn is ~5s with narration streaming in under a second.
- Engineered for real Modal deployment. Multi-backend (vLLM MoE + llama.cpp + FLUX) plus a cloud cost-guardian we built after a runaway-GPU lesson โ scale-to-zero, hard container caps, a lease-based dead-man's-switch, and robustness so a cold/failed backend degrades gracefully instead of hanging a turn.
- Deterministic & shareable. Same dream seed replays the same dice and the same images โ "beat my run, seed
abc123." Download your full run as a keepsake.
๐ง Architecture
DAYDREAM is a fleet of small models refereed by code: a deterministic Python core owns the truth and the dice, while a handful of sub-32B models โ each on its own Modal GPU โ supply only words and pixels. Three views:
1 ยท System โ three layers, one rule
The rule: outcomes flow down from code; only language flows up from models.
flowchart TB
P([๐ค Player])
subgraph CODE["โ๏ธ Orchestration โ Python ยท owns the truth"]
direction LR
ENGINE["DreamEngine<br/><i>turn loop</i>"]
RESOLVER{{"๐ฒ Resolver<br/><i>seeded dice + rewards</i>"}}
STATE[("๐บ๏ธ WorldState<br/><i>externalized memory</i>")]
end
subgraph FLEET["๐ค The Fleet โ Modal serverless GPUs ยท every model โค 32B"]
direction LR
SPEC["๐ Dreamweaver ยท ๐ Nightmare ยท ๐ฏ Hobbes<br/><b>Qwen3-30B-A3B</b> MoE on vLLM<br/><i>30B total ยท only 3B active/token</i>"]
ROUTER["๐บ Keeper<br/><b>MiniCPM-1B</b> ยท llama.cpp"]
VISION["๐จ Painter<br/><b>FLUX.1-schnell</b>"]
end
P -- "gambit (safe/bold/reckless)" --> ENGINE
ENGINE --> RESOLVER -- "verdict" --> ENGINE
ENGINE <-. "context slice โ patch" .-> STATE
ENGINE == "narrate ยท react" ==> SPEC
ENGINE -. "async" .-> ROUTER
ENGINE -. "async" .-> VISION
SPEC == "prose + 3 choices" ==> P
VISION -. "image" .-> P
ROUTER -. "state patch" .-> STATE
classDef code fill:#1b1640,stroke:#7c5cff,color:#fff;
classDef fleet fill:#241a4d,stroke:#9d7bff,color:#fff;
classDef dice fill:#2a1022,stroke:#ff5c7c,color:#fff;
classDef player fill:#0b0a1c,stroke:#cdbcff,color:#fff;
class ENGINE,STATE code; class SPEC,ROUTER,VISION fleet; class RESOLVER dice; class P player;
2 ยท One turn โ critical path vs. async (why it feels instant)
sequenceDiagram
autonumber
actor P as ๐ค Player
participant C as โ๏ธ Resolver
participant D as ๐ Dreamweaver
participant H as ๐ฏ Hobbes
participant K as ๐บ Keeper
participant F as ๐จ FLUX
P->>C: pick gambit
C->>C: roll seeded dice โ verdict
Note over C: the outcome is FIXED before any model speaks โ the game is fair
C->>D: narrate this verdict
D-->>P: streams prose ยท first words in ~0.4s
par off the critical path (async)
C-)K: patch world-state (background)
C-)F: paint the beat (~0.5s on GPU)
end
D->>H: finished scene
H-->>P: reaction + 3 fresh gambits ยท ~5s
F--)P: dream image fades in
Note over P,F: you wait only for narration + choices (~5s) โ<br/>state and image never block the turn
3 ยท The fairness spine โ code owns the dice
flowchart LR
G["gambit + seed + turn"] --> R{{"๐ฒ resolve()<br/>pure ยท deterministic"}}
R --> V["verdict<br/>success / partial / fail<br/>+ reward magnitudes"]
V --> A["apply()<br/>move LUCIDITY ยท PROGRESS<br/>ยท COURAGE ยท MENACE"]
V --> N["๐ model narrates<br/><i>the words, not the outcome</i>"]
A --> S[("WorldState")]
classDef c fill:#2a1022,stroke:#ff5c7c,color:#fff;
classDef m fill:#241a4d,stroke:#9d7bff,color:#fff;
class R,V,A c; class N m;
Same (seed, turn) โ same dice โ "beat my run, seed abc123" is honest. A model can never decide whether you succeed.
๐ฎ How it plays
- Pick a world (Candy Desert, Sunken City, Rain Street, Red Planet, Thousand Token Wood) and a seed. A hero image and your quest greet you instantly.
- Pursue the quest: take a gambit โ ๐ข safe / ๐ก bold / ๐ด reckless (each shows its odds + reward) โ or type your own action. Hobbes' three options are concrete, scene-specific steps toward the goal.
- The Dreamweaver narrates the outcome the dice already decided, moving the story toward the goal; the Nightmare presses when menace climbs; Hobbes reacts in his current mood and offers the next steps; the Keeper updates world-state; the Painter repaints the scene.
- Climb PROGRESS to 100 to wake with the prize, or run out of LUCIDITY and dissolve โ both end in a climactic beat. Watch COURAGE turn Hobbes brave along the way. Win or lose, the run freezes into a shareable Dream Journal you can download.
๐ค The fleet
*Full design + diagrams: docs/ARCHITECTURE.md.*
| Agent | Role | Backend (โค32B each) | Job |
|---|---|---|---|
| ๐ Dreamweaver | specialist | Modal vLLM ยท Qwen3-30B-A3B (MoE, 3B active) | narrate the pre-decided outcome |
| ๐ Nightmare | specialist | Modal vLLM ยท Qwen3-30B-A3B (MoE, 3B active) | press the dread when menace is high |
| ๐ฏ Hobbes | specialist | Modal vLLM ยท Qwen3-30B-A3B (MoE, 3B active) | companion; voice keyed to COURAGE; offer gambits |
| ๐บ Keeper | router | Modal llama.cpp ยท MiniCPM5-1B | structured world-state (location, items, memory) |
| ๐จ dream image | vision | Modal ยท FLUX.1-schnell | paint each beat, in parallel under the narration |
Backends are OpenAI-compatible โ swap models or run "off the grid" via one env var, no code change.
๐ง Why it stays coherent on small models
The world-state lives in code, outside the models (agents/world.py). Each turn the engine
feeds each agent a compact slice of truth, so a 1B router can keep a consistent world that a
single small context never could. The resolver (agents/resolver.py) owns all game math,
seeded by (seed, turn) โ fair, replayable, and impossible for a model to fudge.
โ๏ธ Best Use of Modal โ and a cost story
DAYDREAM runs four Modal services (vLLM, llama.cpp, FLUX, and a guardian). After a keep-warm GPU once cold-looped and burned real money, we made cost control structural:
- Scale-to-zero +
max_containers=1on every GPU app โ $0 idle, no fan-out. - A cloud guardian: a cheap cron that warm-pings endpoints only while a time-boxed lease is active โ so warmth is a pull, not a pin. Forget to tear down? The lease expires and everything scales to zero on its own, independent of your laptop.
- A
makecontrol surface:make status(apps + lease + live spend tracker),make stop(panic),make demo-up/down.
All endpoint URLs derive from one MODAL_WORKSPACE slug, so moving workspaces is a one-line change.
๐ Run it
Offline (no backend, fully playable):
python -m venv .venv && source .venv/bin/activate
pip install -r requirements.txt
DAYDREAM_MOCK=1 python app/app.py
Against Modal inference: set MODAL_WORKSPACE + keys in .env (see .env.example), then make deploy && python app/app.py.
๐ Layout
| Path | What |
|---|---|
agents/dream.py |
the fleet engine (Dreamweaver ยท Nightmare ยท Hobbes ยท Keeper) |
agents/resolver.py |
seeded, model-free dice + reward math (code owns the game) |
agents/world.py |
environments + externalized WorldState |
agents/vision.py |
per-beat dream-image prompts + FLUX client |
agents/base.py |
tiny streaming/JSON Agent + DAYDREAM_MOCK offline mode |
app/app.py |
Gradio dream-deck UI |
modal_app/*.py |
Modal vLLM ยท llama.cpp ยท FLUX ยท guardian |
Small models, big dreams. ๐