Spaces:
Sleeping
Sleeping
|
Download README.md from misack/war_gaming: direct link, hf CLI and curl.
- Browser
- Download file 15.1 kB
-
https://huggingface.co/spaces/misack/war_gaming/resolve/main/README.md
- Command line
-
hf download hf://spaces/misack/war_gaming/README.md
-
curl -L -o README.md https://huggingface.co/spaces/misack/war_gaming/resolve/main/README.md
15.1 kB
| title: Wargame Backend | |
| emoji: "\U0001F3AF" | |
| colorFrom: blue | |
| colorTo: indigo | |
| sdk: docker | |
| app_port: 7860 | |
| pinned: false | |
| short_description: AI war-gaming engine API (private trial) | |
| # AI War Gaming | |
| > Strategic war-gaming for company executives. A human CEO plays one seat; 11–13 AI agents (CFO, CMO, rival CEO, regulator, media, board chair, unions…) simulate the rest of the world. Five turns, ~15 minutes of play, and an end-game **debrief** that reveals every agent's hidden agenda, their private per-turn deliberation, and the umpire's structured verdict on every action. | |
| The differentiator isn't the play — it's the reveal. Every scenario has 11–13 *named* characters (Bettina Lange the CFO, Sir Rupert the Chair, Andrew Greenwood the activist MP, Aergis's Li Wei Zhang…), each with a hidden agenda and a hidden irritant pinned into their prompt. If reading the debrief doesn't make a playtester say *"wait, that's what **Sir Rupert** was really thinking?"* or *"that's what **Aergis** was about to do?"*, the prototype failed regardless of anything else. | |
| ## What's in the box | |
| A **headless Python engine** with three surfaces: | |
| - **CLI** — the primary interface (`uv run wargame --help`). | |
| - **Web API** — FastAPI wrapper powering the Vite + React + TS UI in [`frontend/`](frontend/). | |
| - **Debrief exporter** — markdown report, the product's signature output. | |
| ### Features | |
| | Area | What it does | | |
| |---|---| | |
| | **Matrix-game engine** | 5-phase turn loop. Actions must carry 3 anchors (`prior_analogue`, `stated_capability`, `resource_committed`). Control scores plausibility 1-5 against the anchors and emits `effect_major` / `effect_minor` / `no_effect` / `backfires`. | | |
| | **Scenario library** | 12 shipped scenarios — 4 original archetypes (`competitor_disruption`, `crisis_response`, `ma_integration`, `activist_investor`) plus 8 DACH/EU scenarios grounded in recent European events (`signa_contagion`, `russia_exit`, `energy_supply_shock`, `ev_transition`, `hormuz_energy_shock`, `defense_ramp_up`, `orf_reform`, `swiss_bank_contagion`). Each ships a world bible + 11–13 named agents with hidden agendas + hidden irritants + initial state. | | |
| | **Setup wizard** | LLM-driven interactive scenario composer. Asks 1-3 rounds of clarifying questions, synthesises a brief, commits a fully-generated scenario. | | |
| | **Document grounding** | Attach `.pdf` / `.docx` / `.md` / `.txt` documents when scaffolding a scenario — board decks, 10-Ks, competitor filings become grounding material for the generator. | | |
| | **Multi-model** | 5 registered models across 3 providers: Claude Opus 4.6 / 4.7 and Sonnet 4.6 (Anthropic via Azure AI Foundry), GPT-5.4 (Azure OpenAI Responses), Kimi K2.5 (Azure AI Inference). Model is pinned per game via `wargame new --model <id>`. | | |
| | **Scenario Orchestrator** | Agentic-age Monte Carlo equivalent. Before turn 1, spins up K forked branches (default 3) auto-played by proxy CEOs under different strategic vectors. Synthesises a landscape the real CEO studies before committing to their opening move. | | |
| | **Mid-game tools (non-blocking)** | *Peek* — reveal one agent's past deliberation. *Challenge-the-umpire* — dispute a verdict, re-adjudicated async without pausing the game. *Fork/replay* — branch a new game from any past turn to play forward differently. | | |
| | **Prompt caching** | Stable system prompt (world bible + persona + rules) is cached across every agent call via Anthropic's top-level `cache_control`. Verified live with substantial cache-read token ratios. | | |
| ## Quick start | |
| ```bash | |
| # Install | |
| uv sync --extra dev | |
| # Configure Azure AI Foundry endpoint + key | |
| cp .env.example .env | |
| # Edit .env — set AZURE_AI_FOUNDRY_ENDPOINT and AZURE_AI_FOUNDRY_KEY | |
| # Verify install (156 tests, fully offline, ~60s) | |
| uv run pytest -q | |
| # Play | |
| uv run wargame new --scenario activist_investor | |
| uv run wargame briefing | |
| uv run wargame ask cfo "what's the real capital-return room?" | |
| uv run wargame act "Convene the board and commit publicly to a £200M buyback + NED review" \ | |
| --why "Pre-empt Greenwood's EGM window by 10 days; split L&G off from the activist coalition" \ | |
| --anchor "prior_analogue: Sainsbury's 2022 response to Czech-origin activist letter" \ | |
| --anchor "stated_capability: Board can convene by Thursday; CFO has sale-leaseback scenarios in-ready" \ | |
| --anchor "resource_committed: £200M from existing £480M revolver capacity" | |
| uv run wargame advance # ~2-5 min — deliberation → adjudication → world update | |
| uv run wargame debrief --out debrief.md | |
| ``` | |
| More commands: | |
| ```bash | |
| uv run wargame scenarios # list installed scenarios | |
| uv run wargame models # list registered LLM models | |
| uv run wargame setup my_topic --brief "..." --auto-commit # compose a scenario via the wizard | |
| uv run wargame scaffold custom_case --brief "..." --doc board_deck.pdf # one-shot scaffold with docs | |
| uv run wargame orchestrate --branches 3 --turns 1 # pre-play strategic landscape | |
| uv run wargame orchestrate-show # print the synthesis | |
| uv run wargame new --scenario activist_investor --orchestrate # one-command: game + orchestrator | |
| uv run wargame setup my_topic --brief "..." --orchestrate # full walk-up: setup → game → orchestrator | |
| uv run wargame peek cfo # reveal the CFO's most recent deliberation | |
| uv run wargame challenge 2 --actor player --argument "..." # dispute a past verdict, non-blocking | |
| uv run wargame fork --from-turn 2 # branch a new game from turn 2 | |
| uv run wargame games --all # list including sim-branch games | |
| ``` | |
| ## Run the Web API | |
| ```bash | |
| uv run uvicorn wargame.api.app:app --reload --port 8080 | |
| ``` | |
| Then `http://localhost:8080/docs` for Swagger UI, `http://localhost:8080/openapi.json` for the spec. | |
| The API is a thin wrapper — every CLI command has a corresponding endpoint. See [`frontend/endpoints.md`](frontend/endpoints.md) for the full reference. | |
| ## Frontend | |
| A Vite + React + TypeScript UI ships in [`frontend/`](frontend/), built by Claude Design against the API contract below. | |
| ```bash | |
| cd frontend | |
| npm install | |
| npm run dev # http://localhost:5173 — proxies /api/* to the FastAPI backend | |
| ``` | |
| The `frontend/` directory doubles as the API contract for any UI builder (Claude Design or equivalent): | |
| - [`frontend/README.md`](frontend/README.md) — entry point, run instructions, navigation guide. | |
| - [`frontend/openapi.json`](frontend/openapi.json) — full OpenAPI 3.1 spec (~42 KB). | |
| - [`frontend/endpoints.md`](frontend/endpoints.md) — human reference of all endpoints grouped by use case. | |
| - [`frontend/state-machine.md`](frontend/state-machine.md) — the 5-phase turn loop + which endpoints are legal when. | |
| - [`frontend/examples/`](frontend/examples/) — captured JSON responses from the live API. | |
| - [`frontend/flows/`](frontend/flows/) — UX flow narratives (first-time player, setup wizard, orchestrate, peek/challenge/fork). | |
| - [`frontend/design-notes/`](frontend/design-notes/) — matrix-game mechanics, hidden-state reveal, async patterns, visualization ideas. | |
| - [`frontend/src/`](frontend/src/) — the shipped React app (screens: `GamesList`, `NewGame`, `GameView`, `Debrief`). | |
| ## Scenarios | |
| Twelve ship out of the box. All fictional but operator-grade (named entities, named numbers, named regulators). | |
| **Original archetypes:** | |
| | Scenario | The setup | | |
| |---|---| | |
| | `competitor_disruption` | Norhard Thermal AG (German heat-pump maker, €680M) vs Aergis Climate (Chinese entrant 38% below list). Installers defecting, sell-side downgrading, FSR filing on the table. | | |
| | `crisis_response` | Perlman Cardio (US pacemaker maker, $452M) facing a 61-event MAUDE cluster from Cleveland Clinic. FDA inspection in 3 weeks, class action filed, Silverlake's 2027 IPO pressure mounting. | | |
| | `ma_integration` | Wendland Performance Chemicals AG, 9 months post the €742M Mercier Additifs acquisition. Synergy targets slipping (6.4 / 22 €M), incumbent MD building a succession, BaFin watching. | | |
| | `activist_investor` | Haverford Retail plc (£2.1B UK food retailer) vs Greenwood Strategic Partners (6.81% stake demanding £720M sale-leaseback + break-up + board refresh). 14-day board response clock. | | |
| **DACH / EU scenarios grounded in recent European events:** | |
| | Scenario | The setup | | |
| |---|---| | |
| | `signa_contagion` | Königstadt Warenhaus Holding (DACH department-store retail, 73 stores) vs Tremont Credit Partners — post-Signa-style liquidity squeeze. | | |
| | `russia_exit` | Altösterreich Bank AG (pan-European banking, CEE/Russia footprint) navigating exit pressure from regulators and a hostile Russian counterparty. | | |
| | `energy_supply_shock` | Donau Energie AG (Austrian gas trading + generation + distribution) vs Transgazprom OAO — supply-contract crisis. | | |
| | `ev_transition` | Radmann Präzisionstechnik (German Tier-1 automotive supplier) vs BYD Component Systems EU — EV-transition cliff. | | |
| | `hormuz_energy_shock` | Nordstern Energie (AT-HQ integrated oil & gas, Gulf-exposed) vs Pacific Sun Trading — Hormuz-strait disruption. | | |
| | `defense_ramp_up` | Westfalia Rüstungswerke (German ammunition / land systems, MDAX) vs an NBIM / ABP / Ethos divestment coalition coordinated by Urgewald. | | |
| | `orf_reform` | Bundesrundfunk Österreich (Austrian public broadcaster) with a hostile Stiftungsrat chair driving reform under political pressure. | | |
| | `swiss_bank_contagion` | Zürich Privatbank AG (Swiss private banking, CHF 142B AUM) vs Morgan Sterling Private Wealth — lateral-hire raid during contagion. | | |
| Run `uv run wargame scenarios` to list what's installed locally. | |
| ## Architecture (one page) | |
| ``` | |
| wargame/ | |
| cli.py Typer CLI entry point | |
| config.py Env loading + model registry + per-provider client factories (Anthropic / Azure OpenAI / Azure AI Inference) | |
| engine/ | |
| loop.py Public turn orchestrator (new_game / act / advance / etc.) | |
| phases.py Per-phase step functions (briefing / deliberation / ...) | |
| state.py Pydantic state models (WorldState, Game, Verdict, etc.) | |
| persistence.py JSON snapshot per game | |
| agents/ | |
| base.py call_structured() — every LLM call, with prompt caching | |
| control.py Umpire: briefings, adjudication, world updates, re-adjudication | |
| role.py Generic role-agent driven by YAML persona | |
| rival_ceo.py Special: maintains multi-turn RivalPlan; revised on surprise | |
| registry.py Load scenarios/{id}/agents.yaml | |
| prompts_loader.py Markdown templates with {placeholder} slots | |
| orchestrator/ | |
| models.py StrategyVector, SimBranchOutcome, ScenarioMap, … | |
| vectors.py Strategy-vector generator + diversity constraint | |
| anchor_precheck.py Control-side proxy-action gate (anti-inflation) | |
| proxy_player.py Autonomous CEO stand-in per branch | |
| runner.py Branch orchestration (sequential branches, parallel deliberations) | |
| synthesis.py Post-branch strategic-landscape synthesis | |
| persistence.py ScenarioMap storage | |
| scaffold/ Scenario authoring: setup wizard + one-shot scaffold + doc extractors | |
| scenarios/ Data only: world_bible.md + agents.yaml + initial_state.json per scenario | |
| prompts/ Markdown templates (one per LLM call type) | |
| debrief/exporter.py Markdown debrief — the killer output | |
| api/ FastAPI thin wrapper over engine | |
| agents/providers/ Provider adapters — one per wire format, all return Pydantic instances | |
| tests/ Offline test suite (fake LLM via conftest.fake_llm) | |
| frontend/ Vite + React + TS UI + API contract (OpenAPI, flows, examples) | |
| scripts/benchmark_models.py Opt-in cross-model benchmark (real API calls; writes to benchmarks/) | |
| benchmarks/ Markdown reports from benchmark runs | |
| ``` | |
| Design invariants that must survive edits (see [`CLAUDE.md`](CLAUDE.md) for the full list): | |
| 1. **Data-driven agents.** Personas live in `scenarios/{id}/agents.yaml`. Adding an agent is a YAML edit, not a Python edit. | |
| 2. **Structured outputs always.** Every LLM call goes through `call_structured` and targets a Pydantic schema. Free-form JSON parsing is banned. | |
| 3. **The action contract is enforced.** Exactly 3 anchors per action, at the Pydantic layer. Do not loosen. | |
| 4. **Hidden agenda + hidden irritant per agent.** The anti-milquetoast mechanism that makes the debrief substantive. Do not drop. | |
| 5. **World bible is pinned.** Every agent prompt includes the full world bible. Specificity kills AI slop. | |
| 6. **Control does not play.** Control writes briefings, adjudicates, and synthesises world updates. It never submits an `ActionSubmission`. | |
| ## LLM backend | |
| Everything runs through Azure, but across three different API shapes — one wrapper (`call_structured` in `wargame/agents/base.py`) hides the differences: | |
| | Provider | Transport | Models | | |
| |---|---|---| | |
| | **Anthropic via Azure AI Foundry** | native Anthropic SDK, `base_url` pointed at `{foundry}/anthropic` | `claude-opus-4-6`, `claude-opus-4-7`, `claude-sonnet-4-6` | | |
| | **Azure OpenAI Responses** | `AzureOpenAI` SDK | `gpt-5.4` (default) | | |
| | **Azure AI Inference** | OpenAI-compatible chat completions | `Kimi-K2.5` | | |
| Default model is `gpt-5.4` (override via `WARGAME_DEFAULT_MODEL` env or `--model` on `wargame new`). Every game is pinned to a single model at creation time — this is deliberate, so the reveal in the debrief is attributable to one model. Use `scripts/benchmark_models.py` for a cross-model A/B on a fixed turn. Prompt caching uses Anthropic's top-level `cache_control={"type": "ephemeral"}` when the active provider is Anthropic. | |
| ## Testing | |
| ```bash | |
| uv run pytest -q # 156 tests, fully offline, ~60s | |
| ``` | |
| Tests use a `fake_llm` fixture (in `wargame/tests/conftest.py`) that monkey-patches `call_structured` and dispatches canned responses by Pydantic schema class name. Adding a new structured-output schema requires extending the `_dispatch()` map. | |
| ## Security | |
| - `AZURE_AI_FOUNDRY_KEY` lives **only** in `.env` (gitignored). Never hardcoded, never logged. | |
| - API has **no auth** in MVP — localhost-only by design. | |
| - No PII flows through. Scenario docs uploaded for grounding are held in-memory during scaffold and not persisted. | |
| ## Deferred to v1 | |
| - Per-agent model routing (model is currently pinned per-game; every role in a game shares one model). | |
| - Multi-user / team play (single-player is the MVP's deliberate shape). | |
| - Real-data connectors (EDGAR, news wires, analyst feeds). | |
| - Export formats beyond markdown (PDF, board decks, CSV). | |
| - Authentication on the Web API. | |
| - SQLite / real DB (JSON snapshots are fine for MVP). | |
| ## License | |
| TBD — this is an early prototype, not yet licensed for distribution. | |
| ## Acknowledgements | |
| Matrix-game methodology is a well-established wargaming tradition; this project applies it to an agentic-LLM multi-agent simulation. The strategic-orchestrator pattern is novel to this codebase. | |