Spaces:
Runtime error
Runtime error
Commit ·
fd38971
1
Parent(s): 261988e
docs: spec for food resources + scripted memory policies + LLM-spectate fix
Browse files
docs/superpowers/specs/2026-06-02-food-resources-and-memory-policies-design.md
ADDED
|
@@ -0,0 +1,103 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Food resources, prompt fixes, scripted memory policies, LLM-spectate fix — design
|
| 2 |
+
|
| 3 |
+
Date: 2026-06-02
|
| 4 |
+
Status: approved (extends 2026-06-02-memory-replay-and-pack-evade-walls)
|
| 5 |
+
|
| 6 |
+
## Scope (this batch)
|
| 7 |
+
|
| 8 |
+
A. **Food/resource system** for `pack_evade` — observational only (rendered + named
|
| 9 |
+
in the prompt; collecting does nothing, survival stays the only scored objective).
|
| 10 |
+
B. **Prompt fixes** — `rules_text`/`memory_brief` no longer say "no walls"; add a
|
| 11 |
+
food (먹이) description. Keep self (3×3) + caught=eaten. No "bear" framing.
|
| 12 |
+
C. **Memory length** — generation runs 100 turns (was 8).
|
| 13 |
+
D. **Web UI** — hide the memory text block (the replay is enough). The model still
|
| 14 |
+
receives `render_memory_block` text (an LLM can only read text).
|
| 15 |
+
E. **LLM-spectate bug** — install provider SDKs; return a clear 400 (not a 500) when
|
| 16 |
+
a provider cannot be built (missing SDK or key).
|
| 17 |
+
F. **Three scripted 100-turn memory policies** — survival-dynamic, survival-refuge,
|
| 18 |
+
food-rush — selectable as handover memory in the web UI.
|
| 19 |
+
|
| 20 |
+
## A. Food system
|
| 21 |
+
|
| 22 |
+
- New palette `FOOD_IDX = 14` (#4FCC30 green); legend `"F"`.
|
| 23 |
+
- `self._food_cells: list[tuple[int,int]]` built in `build_level` (seeded, deterministic):
|
| 24 |
+
- **mandatory** one near focal spawn (free cell within radius 3–10 of focal center),
|
| 25 |
+
- **mandatory** one "behind" the predator (beyond predator center along the
|
| 26 |
+
focal→predator direction, nearest free cell),
|
| 27 |
+
- plus difficulty-scaled extras (EASY 1 / MED 2 / HARD 3) on random free cells.
|
| 28 |
+
- free = on-grid, not a wall, not a spawn footprint, not another food cell.
|
| 29 |
+
- Food sprites are 1×1, `BlockingMode.NOT_BLOCKED` (movement/scoring unaffected); added
|
| 30 |
+
to the Level so they appear in `current_grid()`/live renders. Focal/predator draw on top.
|
| 31 |
+
- `render_frame` prose appends `Food (1x1 edible cells): (x,y); …` (one near you, one
|
| 32 |
+
behind the predator).
|
| 33 |
+
- `legend()` adds `FOOD_IDX: "F"`.
|
| 34 |
+
- `Scenario.food_cells() -> list[tuple[int,int]]` (base `[]`; pack_evade returns
|
| 35 |
+
`self._food_cells`). Stored on the checkpoint (`food_cells`) like `wall_rects`.
|
| 36 |
+
- `memory_frames` paints food (under predator/focal, over walls/bg) from
|
| 37 |
+
`checkpoint.food_cells` for prose scenarios; grid scenarios get food from ASCII
|
| 38 |
+
inversion (legend has `F`).
|
| 39 |
+
|
| 40 |
+
## B. Prompt fixes (pack_evade)
|
| 41 |
+
|
| 42 |
+
`rules_text` / `memory_brief`: replace "open field (no walls)" with a wall-aware
|
| 43 |
+
description ("a field laced with impassable wall blocks; your 3×3 body cannot overlap
|
| 44 |
+
them"), and add the food line ("Food cells (1×1) are scattered — one near you and one
|
| 45 |
+
behind the predator — they are edible context"). Keep "You are A, a 3×3 block" and
|
| 46 |
+
"you are eaten if the predator's block overlaps yours".
|
| 47 |
+
|
| 48 |
+
## C. Memory length → 100
|
| 49 |
+
|
| 50 |
+
`memory_turns=100` in: pack_evade `default_memory`, web `_resolve_web_memory` default,
|
| 51 |
+
and the new policy-generation path. (Offline persona/policy generation is fast; the
|
| 52 |
+
episode still stops early on terminal.)
|
| 53 |
+
|
| 54 |
+
## D. Web UI: drop the memory text block
|
| 55 |
+
|
| 56 |
+
Hide `#memoryBlock` (`<pre>`) — keep the step-through replay only. `render_memory_block`
|
| 57 |
+
remains in the model's observation pipeline (unchanged); only the human-facing panel
|
| 58 |
+
text is removed.
|
| 59 |
+
|
| 60 |
+
## E. LLM-spectate fix
|
| 61 |
+
|
| 62 |
+
- Install the `providers` extra (`uv pip install -e ".[providers]"`): httpx, openai,
|
| 63 |
+
anthropic, google-genai. (Done in the environment; pyproject already declares them.)
|
| 64 |
+
- Broaden provider-construction error handling: in `_create_spectate` and the
|
| 65 |
+
generate/latest branch of `_resolve_web_memory`, catch `Exception` (not only
|
| 66 |
+
`ValueError`) and return a 400 with the message, so a missing SDK/key surfaces as a
|
| 67 |
+
clear client error instead of a 500.
|
| 68 |
+
|
| 69 |
+
## F. Scripted memory policies
|
| 70 |
+
|
| 71 |
+
New module `proteus/runtime/memory_policies.py` — each `policy(scenario, game) -> str`:
|
| 72 |
+
- **`survival_dynamic`**: `scenario.optimal_action(game)` (greedy max-distance from the
|
| 73 |
+
predator, wall-legal). Keeps moving and evading.
|
| 74 |
+
- **`survival_refuge`**: step (focal-wall-aware BFS) toward the nearest *refuge* cell —
|
| 75 |
+
a cell where the 3×3 focal fits but the 5×5 predator cannot reach the 1-ring around it
|
| 76 |
+
— then `stay` once inside. Refuge set is computed once per episode (walls static),
|
| 77 |
+
cached on the scenario.
|
| 78 |
+
- **`food_rush`**: step (focal BFS, predator ignored) toward the nearest
|
| 79 |
+
`scenario.food_cells()`; `stay` when no food remains/reachable.
|
| 80 |
+
|
| 81 |
+
`generate_memory` gains a `policy: Callable | None` path (parallel to agent/persona):
|
| 82 |
+
when set, `action = policy(scenario, game)`, `reasoning=""`, `model_name="policy:<name>"`.
|
| 83 |
+
|
| 84 |
+
Web `_resolve_web_memory` adds `policy:<name>` mode → `generate_memory(..., policy=...,
|
| 85 |
+
memory_turns=100)`. UI memory dropdown gains `policy:survival_dynamic`,
|
| 86 |
+
`policy:survival_refuge`, `policy:food_rush`.
|
| 87 |
+
|
| 88 |
+
## Testing
|
| 89 |
+
- Food generation: deterministic per seed; mandatory near-focal + behind-predator cells
|
| 90 |
+
present, all free; extras count by difficulty; food never on walls/spawns.
|
| 91 |
+
- Food in observation + checkpoint + memory_frames (green index painted at recorded
|
| 92 |
+
cells for prose; legend `F` round-trips for grid).
|
| 93 |
+
- Prompt: no "no walls"; mentions walls + food; keeps self + eaten.
|
| 94 |
+
- memory length: generated checkpoints have up to 100 turns.
|
| 95 |
+
- Policies: survival_refuge ends in a stay-stable refuge; food_rush reduces distance to
|
| 96 |
+
nearest food over turns; survival_dynamic increases predator distance vs a passive baseline.
|
| 97 |
+
- Web: `policy:*` modes attach a memory; bad provider → 400 (not 500); `frames` present;
|
| 98 |
+
served HTML no longer shows the text block but keeps the replay controls.
|
| 99 |
+
- Full suite green; merge to master.
|
| 100 |
+
|
| 101 |
+
## Out of scope
|
| 102 |
+
- Food scoring/collection, respawning, or win-condition changes (observational only).
|
| 103 |
+
- Predator awareness of food. Bear/persona narrative framing.
|