Spaces:
Sleeping
Sleeping
Commit History
-
Trial-mode UX: live progress visibility + cosmetic fixes + tighter caps
Three classes of issue surfaced during the trial playthrough: (1) The 3-minute /advance felt completely silent in the UI even though the LiveProgress component was mounted. Root cause: EventSource has no way to attach an X-Trial-Password header, so the password gate rejected every SSE connection silently. Backend now also accepts the password as a ?token= query param on the /games/{id}/stream endpoint, and the frontend streamUrl appends it from localStorage. Live deliberation cards, the phase rail, and the cost meter now render during advance. (2) Cosmetic SPA bugs that shipped wrong turn counts: - GameView.tsx:96 had `(turns?.length && 5) || 5` which always returned 5 regardless of the game's actual world.max_turns. Read straight from state.world.max_turns now. - Debrief.tsx:31 hardcoded `turn:5, max:5` for the shell header. Now pulls from /games/{id}/state. - i18n strings in en.ts / de.ts hardcoded "Five turns" and "Turn 1 of 5" in newGame.scenario.footnote, newGame.ready.e…b9537b4
-
Add HF Spaces deployment scaffold + trial password gate
Dockerfile (Python 3.12 + uv, listens on 7860, persists to /data) and .dockerignore let us push the FastAPI engine to a Hugging Face Docker Space. README.md gets the YAML frontmatter HF needs to detect the Space type. Two env-driven gates so a public Space stays trial-only: - WARGAME_ALLOWED_ORIGINS CORS allow-list (defaults to *) - WARGAME_TRIAL_PASSWORD shared password; clients send X-Trial-Password. /healthz and CORS preflights are exempt so HF healthchecks and browser preflights still work. Frontend caches the password in localStorage and re-prompts on a 401. Both gates default to permissive so local dev DX is unchanged. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>17a40e4 -
Round 6: German localization (en + de)
Backend (backend-i18n teammate): - Game.language: Literal["en","de"] = "en"; default keeps old snapshots loadable. - language_directive(lang) appended to every call_structured user message; system prefix stays byte-identical so the prompt cache stays warm. - use_game_language() context manager + ContextVar; loop.py + orchestrator pin language across all entry points; ThreadPoolExecutor in run_deliberations now propagates context (fixes a latent issue for per-game model selection too). - CLI: wargame new --language en|de; wargame state shows the language. - API: NewGameRequest.language + StateResponse.language. - _delta_summary, _metrics_table, _recent_events placeholders localized via _t(en, de) helper. - 13 new tests including a system-prompt-byte-identical-across-languages invariant that protects the cache. Frontend (frontend-i18n teammate): - New frontend/src/i18n/ module — ~95-line shim with useI18n() hook, setLanguage, getLanguage, {name} interpolation, English fall…bd956f0 -
Round 5b: frontend wiring — live progress, pause/resume, role overrides, doc upload, constraint manager
Two parallel streams merged cleanly via separate banners in api.ts: LIVE UX (live-ux teammate): - LiveProgress.tsx — SSE-driven step rail (Deliberation → Critic → Pre-mortem → Adjudication → Evaluator → World update → Next briefing), live deliberation feed, verdict cards coloured by outcome, rAF-debounced cost meter, paused banner, error toast, 2s reconnect-after-double-fail. - GameView replaces the fake-ticker terminal with <LiveProgress> while advance is in flight or status==paused. Pause button mid-advance, Resume button when paused. Handles /advance status="paused" the same as the SSE paused event. - api.ts: pauseGame, resumeGame, streamUrl, PhaseEvent union. - frontend/scripts/sse-smoke.mjs + README — stdlib-fetch SSE smoke client. FORMS (forms teammate): - NewGame.tsx — collapsible "Per-role model routing" panel iterating models.roles with fallback list. Role overrides flow through createGame. - SetupCase.tsx — drag-and-drop "Grounding documents" zone (10 docs cap…ecf16e0 -
Action Coach (conversational action input) + orchestrator post-action guard (#6)
schipsy +1: Claude Opus 4.7 (1M context)Unverified signature* Add post-action guard to orchestrator route + UI gate The orchestrator clones a pristine Turn 1 to fork branches; clone_pristine raises ValueError if the source has already played. The route silently passed the request through, the worker swallowed the exception, and the UI showed three failed branches with no usable signal. Now the route rejects with 409 when game.world.turn > 1, the first turn has a player_action, or phase != BRIEFING. The frontend hides the launch button under the same conditions and shows a one-line helper pointing the user at fork. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * Add Action Coach: conversational action input that drafts 3-anchor ActionSubmissions Adds a small LLM-driven coach that turns CEO prose into the engine's exact action contract (intent + justification + 3 anchors of valid kind). Mirrors the setup_agent shape: one structured-output call per turn, JSON session storage under games_dir/action_coach_sessions/, capped…2ead142
-
Merge Board Console UI + setup agent + orchestrator into main (#5)
schipsy +1: Claude Opus 4.7Unverified signature* Wire real agent picker into recon (was hardcoded to missing 'analyst') Before: GameView called api.recon(id, 'analyst', …), which 409ed on every shipped scenario because none of them defines an agent with that id. Now: GameView chains GET /scenarios/{id}/agents off the existing listGames call, renders a dropdown of real agent labels (e.g. "Bettina Lange, CFO"), and passes the selected id to recon. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * Drop Claude Design handoff artifacts now that the UI is built Removes design-notes/, examples/, flows/, openapi.json, endpoints.md, and state-machine.md from frontend/. These were the spec handed to Claude Design to build the UI. Now that frontend/src exists and works against the API, the handoff docs are vestigial — the API is the contract and pyproject/FastAPI generate a live spec at /docs. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * Replace frontend with Claude Design Board Console handoff Port t…fa0970b
-
Multi-model support: per-game model picker + live benchmark (#3)
schipsyUnverified signatureProvider abstraction behind call_structured so each game runs on any of five registered LLMs (Claude Opus 4.6/4.7, Claude Sonnet 4.6, GPT-5.4 via Azure OpenAI Responses, Kimi-K2.5 via Azure AI Inference). Chosen model is pinned on the Game and echoed in CLI, API, UI, and debrief header. Live-benchmarked every model against a fixed one-turn competitor_disruption run; two reports in benchmarks/. Default switched to gpt-5.4 — 45% faster than Opus 4.6 at par quality, the only model that meaningfully exercises server-side prompt caching (~63K re-used tokens per run). Added 429 exponential backoff (10s/30s/60s/120s) to the AI Inference provider after Kimi repeatedly hit its 8-concurrent capacity cap. Two rounds of review feedback addressed in-place. Key fixes: Anthropic cache_control moved from top-level kwarg (silently ignored) to the system content block — the benchmark's cache_read=0 across every Claude model was the smoking gun. Orchestrator now wraps run_orchestration in use_game_mode…b76b644
-
Add Vite + React + TS frontend built by Claude Design
Drops a working UI scaffold into frontend/ wired against the FastAPI backend. Four screens (GamesList, NewGame, GameView, Debrief) hit the contract documented in frontend/openapi.json and frontend/endpoints.md. Vite proxies /api/* to VITE_API_BASE (default http://localhost:8080). Note: CLAUDE.md sec. 1 previously stated no frontend code lives in this repo. That rule needs a follow-up decision — keep the frontend here (update CLAUDE.md) or split into a sibling repo. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>cf8cdd9