Spaces:
Sleeping
Sleeping
Commit History
-
chore: switch ENDPOINT to dedicated pod (zopt7f90d1ydgy)β
The shared pod (qry6crb96ko8ep) was being saturated by ~2-5 req/sec of external traffic, leading to ~50% HTTP 500 rate even with cache_prompt:false. Build update from b9038 β b9049 didn't fix this; the failure mode is GPU saturation across 4 shared slots, not a slot-bookkeeping bug. New pod zopt7f90d1ydgy is dedicated to mini-world: - LLAMA_ARG_N_PARALLEL=1 (single slot, no multi-tenant slot pollution) - Same image (ghcr.io/ggml-org/llama.cpp:server-cuda) - Same model (unsloth/Qwen3.6-27B-GGUF / Qwen3.6-27B-UD-Q4_K_XL.gguf) - Same RTX 3090, ctx_size 8192 - Costs $0.46/hr β same as old pod Verified: 20/20 successful chat completions on the fresh pod (vs 10/20 on the shared pod immediately after restart). Updated default ENDPOINT in: - server.ts (Space inference loop) - eval.ts (long-horizon eval harness) - eval-scenarios.ts (controlled-scenario eval) - README.md (doc reference) Old pod can be deleted once Space rebuild confirms the new endpoint works.a0a680b -
feat: enable thinking for the summarizer (only)β
Live observation: agent gets stuck in directional loops (e.g. 5 consecutive move:up's all failing with "Cannot move into obstacle"). The error feedback reaches the model on the very next turn but doesn't break the lock. After compaction, the bland bullet summary preserves the loop but doesn't surface it as a problem the agent should correct, so the model resumes the same direction. Hypothesis: a smarter summarizer that actually reasons about what happened can flag the failure pattern explicitly ("direction up is blocked, try another") in the summary the agent reads next turn. Changes: - callSummarizer: chat_template_kwargs.enable_thinking β true. Bumped max_tokens 400 β 2048 to leave room for the thinking chain plus the bullet output. Thinking adds ~5-10s to compaction calls but those happen ~once per ~30 turns, so the per-turn loop stays fast (cache off, ~6-8s/turn). - SUMMARY_SYS: explicitly call out repeated-failure detection as a required signal in the summary β gives tβ¦b5023c0 -
fix: retry connect() forever instead of crashing the Space when pod is restarting
870fbcf -
fix: disable cache_prompt by default β slot poisoning is unfixable on this buildβ
Empirical pattern observed across many runs: ~5-12 turns succeed with cache_prompt:true, then every subsequent request 500s with "Context size has been exceeded", and the retry-without-cache also fails because the upstream slot itself is saturated. Container rebuild fixes it briefly, then the cycle repeats. The clean fix is to stop opting into the broken default. cache_prompt:false on every request gives stable ~6-8s/turn forever, vs ~1.4s/turn with cache that catastrophically fails after a few turns. USE_CACHE env var lets us opt back in once the upstream build (b9038-2ca1161bd) is updated to a version without the regression, without another code change.ac90842 -
chore: boot Space paused during experiment phaseβ
Add START_PAUSED env var support in server.ts. When START_PAUSED=1, agent loop comes up idle and waits for /api/resume. Set it in the Dockerfile so the deployed Space stops hammering the shared runpod endpoint while we run controlled experiments locally. Resume via the browser when the Space should run again. Local dev unaffected (env unset β unpaused as before). Also: - engine.js: SinglePlayerGame now accepts a {seed} option using a mulberry32 PRNG so eval runs are reproducible across variants. - agent-brain.js: buildPickFirstPrompt and analyzeViewport now take an optional radius (default 4 = 9Γ9). Allows variant sweeps. - eval.ts (new): headless agent benchmark. Takes --variant --seed --turns and emits one JSON metrics object per run. Variants in VARIANTS map (baseline, viewport_5, viewport_13, temp_0/high, thinking_on, cache_on). Captures: diamonds/N, realActionRate, illegalMoveRate, pickPrecision, directionEntropy, medianLatency, cacheHitRate, full per-turn token sβ¦327ab12 -
fix: no-op the turn on inference failure instead of random walkβ
Prior behavior: when callModel failed (HTTP error after retries) or returned no usable tool_call, randomFallbackAction() picked a uniform- random direction and the agent moved. This meant the agent's body wandered randomly while the brain had no memory of those moves β fallbacks were invisible to memory because tool_call_id was null. The action histogram looked balanced because of these random-walk turns, masking the model's actual decision distribution. New behavior: on fallback, do nothing. - Snapshot memory.messages.length at the top of each iteration; if no usable action comes back, popLast() until we're back to that depth. Cleans up both an orphan user message (HTTP error path) and an empty assistant turn (no-tool_calls path). - Don't move the agent, don't push to actionLog, don't emit tool_execution_start/end. Just log fallback_action + turn_end and loop. - The agent stays in place. Next iteration rebuilds the same prompt fresh β the runpod LB may pick a healthier slβ¦700271c -
fix: cache contention + 9Γ9 viewport + tighter compactionβ
Three changes from a parallel-agent debugging round investigating why the live agent was hitting 0 diamonds in 34 turns. server.ts callModel: - Old retry only fired when the original request had cache_prompt:true, so once cooldown started, every subsequent 500 fell straight through to fallback. New retry fires on any "Context size has been exceeded" 500 regardless of cache state. - Up to 3 retries with 200ms gap so the upstream LB has a chance to route to a different (non-poisoned) slot. Slot contention is real on this build (b9038-2ca1161bd) β even bare "hi" 500s ~80% of the time when slots are saturated. - Critical: explicitly set `cache_prompt: false` on disabled / retry paths instead of deleting the key. Omitting it falls back to the server's broken default behavior, so deletion was a no-op. - Same explicit cache_prompt on the summarizer. agent-brain.js: - buildPickFirstPrompt viewport: 5Γ5 β 9Γ9 (radius 4). The 5Γ5 worked in unit tests but in the live game the β¦8c2dc59 -
feat: pause/resume the agent loop without hitting the modelβ
POST /api/pause sets a flag that the loop checks at the top of each iteration; while paused, the loop idles in 500ms ticks and emits no inference calls. POST /api/resume clears the flag and the next iteration runs normally. - server.ts: paused flag, /api/pause + /api/resume handlers, agent_paused / agent_resumed trace events, paused exposed in /api/state debug block. - index.html: status dot renders gray (bg-gray-400, no pulse) when state is "paused" β distinguishable from green (running), yellow (thinking), red (error/fallback). Verified end-to-end: curl -X POST /api/pause β paused:true, status:paused 6s later β turn count unchanged (zero LLM calls) curl -X POST /api/resume β paused:false 12s later β turns advanced 2 β 425db49f -
feat: pi-mono compliant NDJSON traces, debug API, illegal-move rule, red dotsβ
Several related changes that came up while debugging a "constant fallback" state on the live deploy. Game rules: - engine.js: moving onto a tile with a pickable object now throws "Cannot move onto <emoji> β use pick <dir> instead". Forces the model to choose the right tool; the error string self-corrects via the tool result fed back next turn. - agent-brain.js: drop the LEGAL_ACTIONS line and the diamond-adjacent warning from buildPickFirstPrompt β the engine error + tool/system prompt descriptions now carry the constraint. Update tool descriptions and system prompt to match (move fails on diamonds, pick is the way). - index.html: failed actions now render with a red dot in the action history (was always green/blue regardless of outcome). Server-side robustness: - server.ts: cache_prompt:true broke on the upstream llama.cpp build (b9038-2ca1161bd) once a slot accumulated >n_ctx of stale cache. callModel now retries without cache_prompt on "Context size has been exβ¦c8de5f5 -
feat: move agent loop server-side, multi-viewer SSE livestreamβ
Previously each browser tab ran its own SinglePlayerGame, AgentMemory, and inference loop β two tabs meant two independent worlds with two independent agents. Now the agent runs once on a Bun server that owns the world state and broadcasts every turn to all connected viewers via Server-Sent Events. Multiple tabs see the same agent acting on the same world in lockstep. Files: - server.ts (new): Bun HTTP server. Lifts connect/callModel/callSummarizer/ agent loop verbatim from the previous client-side script. After each turn builds a JSON state snapshot {viewport, inventory, stats, actions, status, thinking, summary, debug} and broadcasts to a Set of SSE controllers. New connections get an immediate snapshot so they don't wait a full turn. All round-1+round-2 mechanics carry over: structured tool_calls, cache_prompt:true, enable_thinking:false, pair-aware trim, popLast on inference failure, n_ctx-derived budgets, LLM-summarization compaction. - index.html: stripped from a 3β¦f7df30f
-
chore: aggressive cleanup β keep only the browser harnessβ
The repo started as a research project with a multi-agent REST API, ONNX-based eval scripts, a CLI agent client, and several test suites. The shipped browser harness now hits a remote llama.cpp endpoint directly and has no need for any of that infrastructure. Drop it. Removed: - server.ts, gameState.ts, aiService.ts (legacy multi-agent REST API) - middleware/, types.ts, agent-client.ts, replay.html - API.md, openapi.yaml (REST API docs) - __tests__/ entire directory: 10 ai-eval scripts (~1500 LOC) + their result JSONs, plus the e2e/integration/unit test suites for the multi-agent server - Dockerfile, package.json, bun.lockb (no runtime deps anymore) Slimmed: - engine.js: 481 β 175 LOC. Drops the prompt-building helpers (SYS_PROMPT, FEW_SHOT, buildUserPrompt, buildMessages, MCQ_*, getAdjacencyFromViewport, parseAction, isValidAction), the pixel-buffer renderers (renderMapToRGBA, renderAnnotatedMapToRGBA, EMOJI_COLOURS), and unexports the world-gen internals. Public surfaceβ¦49df1c0 -
chore: squash pre-2026-05-06 historyβ
Initial mini-world snapshot at c0da002 β collapses 25 commits of research and feature work into a single root: - single-player game engine (Perlin world gen, viewport rendering, image rendering for vision evals) - in-browser ONNX agent with pick_first strategy and 5 alternative prompting strategies for evals - multi-agent REST API server with auth, rate limiting, and SSE - 10 eval scripts comparing prompt strategies, tool calling, vision, and context compaction at 0.8B/2B/4B - agent-client.ts CLI for autonomous play against the API - replay viewer for recorded eval sessions The squashed history is preserved in reflog locally; for the public record this is the starting point that the remote-only harness + compaction work builds on.e208045