Spaces:
Sleeping
title: CrisisWorldCortex Environment Server
emoji: 🧠
colorFrom: yellow
colorTo: pink
sdk: docker
pinned: false
app_port: 8000
base_path: /web
tags:
- openenv
- crisis-simulation
- multi-agent
CrisisWorldCortex Environment
CrisisWorldCortex is an OpenEnv benchmark for crisis governance under partial observability. The outer environment, CrisisWorld, is a regional outbreak simulator with delayed telemetry, noisy measurements, scarce resources, legal constraints, hidden cascade events, and typed interventions. The inner agent system, Cortex, treats cognition itself as a budgeted control problem: which expert brain to consult, when to challenge consensus, when to recurse, and when to stop thinking and act.
The core thesis is simple:
Same base model. Same compute. Better governance of thought should produce better control of the world.
Most environments reward only the final action. CrisisWorldCortex also makes the path to that action measurable: action validity, token budget, disagreement health, collapse risk, and the external outbreak outcome can all be tracked separately. That is the novelty: cognition is not hidden inside a prompt; it is an explicit, testable, trainable surface.
flowchart LR
A[Agent or Cortex] -->|typed OuterAction| E[CrisisWorld]
E --> W[Latent outbreak state]
W -->|delayed and noisy| O[Observation]
W -->|dense r_outer| R[Reward]
O --> A
R --> A
Why It Matters
CrisisWorldCortex is built to test a stronger claim than "more agents are better." Naive multi-agent systems often converge too early, repeat the same prior, or let a single judge collapse diverse reasoning into soft consensus. This benchmark asks whether a structured, budgeted council can outperform flat agents under matched model and token constraints.
The environment is therefore designed around three properties:
- High-stakes partial observability: reported cases are delayed and noisy, while hospital load, compliance, resources, and action history form the operational picture.
- Typed, enforceable action space: six MVP actions are legal; V2-only or illegal actions are rejected and penalized without corrupting state.
- Dense reward signal: per-tick reward separates active useful policies from no-op, rejected, and parse-failure behavior, making training and ablation curves meaningful.
flowchart TB
O[CrisisWorld observation] --> L[Per-brain lenses]
L --> E[Epidemiology brain]
L --> G[Governance brain]
L --> Q[Logistics brain]
E --> C[Council]
G --> C
Q --> C
C --> M[Metacognition router]
M -->|challenge or preserve dissent| C
M -->|spend another round| E
M -->|converge| A[One OuterAction]
Quick Start
The simplest way to use the environment is through the
CrisisworldcortexEnv class:
from CrisisWorldCortex import CrisisworldcortexAction, CrisisworldcortexEnv
from CrisisWorldCortex.models import DeployResource, RequestData
env = CrisisworldcortexEnv.from_docker_image("CrisisWorldCortex-env:latest")
try:
result = env.reset(task_name="outbreak_easy", seed=0, max_ticks=12)
obs = result.observation
print(f"Reset: tick={obs.tick}, regions={len(obs.regions)}")
actions = [
RequestData(region="R1", data_type="case_survey"),
DeployResource(region="R1", resource_type="test_kits", quantity=100),
]
for payload in actions:
result = env.step(CrisisworldcortexAction(action=payload))
obs = result.observation
print(f"Action: {payload.kind}")
print(f" tick: {obs.tick}")
print(f" reward: {result.reward:.3f}")
print(f" done: {result.done}")
finally:
env.close()
The CrisisworldcortexEnv.from_docker_image() method handles:
- Starting the Docker container
- Waiting for the server to be ready
- Connecting to the environment
- Container cleanup when you call
close()
Building the Docker Image
Before using the environment from Docker, build the image:
# From project root
docker build -t CrisisWorldCortex-env:latest -f server/Dockerfile .
For the hackathon inference harness, the root Dockerfile is also present:
docker build -t CrisisWorldCortex-runner:latest .
Deploying to Hugging Face Spaces
You can deploy the OpenEnv environment to Hugging Face Spaces using
openenv push:
# From the environment directory, where openenv.yaml is located
openenv push
# Or specify options
openenv push --repo-id my-org/CrisisWorldCortex --private
The openenv push command will:
- Validate that the directory is an OpenEnv environment
- Prepare a Hugging Face Docker Space build
- Upload the Space, assuming Hugging Face auth is configured
After deployment, your Space will be available at:
https://huggingface.co/spaces/<repo-id>
The deployed Space includes:
- Web Interface at
/web- standard OpenEnv UI - Cortex Dashboard at
/cortex- project-specific visual interface - API Documentation at
/docs- OpenAPI/Swagger docs - Health Check at
/health- container health monitoring - WebSocket at
/ws- persistent session endpoint
Environment Details
Tasks
| Task | Regions | What changes |
|---|---|---|
outbreak_easy |
4 | Lower spread, 1-tick telemetry delay, generous resources |
outbreak_medium |
4 | Higher spread, 2-tick delay, scarcer resources, multiple hot regions |
outbreak_hard |
5 | Higher spread, 3-tick delay, chain cascade, legal constraint, hidden superspreader |
Training episodes default to 12 ticks. Evaluation can pass max_ticks=20
when longer-horizon behavior is needed.
Action Space
CrisisworldcortexAction wraps one typed OuterActionPayload.
| Action kind | Purpose |
|---|---|
deploy_resource |
Send test kits, hospital beds, mobile units, or vaccines to a region |
request_data |
Reduce telemetry noise for a region for a few ticks |
restrict_movement |
Apply none/light/moderate/strict movement restrictions |
escalate |
Escalate authority; national escalation unlocks strict restrictions |
reallocate_budget |
Move resources between inventory classes with efficiency loss |
no_op |
Advance the tick without intervention |
public_communication exists only as a V2 forward-compatible schema. In the
MVP it is rejected at runtime and receives a policy penalty.
Observation Space
CrisisworldcortexObservation contains:
regions: delayed reported cases, current hospital load, compliance proxyresources: current inventory for each resource classactive_restrictions: region-level policy constraints currently in forcelegal_constraints: rules that block specific actions until unlockedtickandticks_remainingcognition_budget_remaining: per-tick token budget surfacerecent_action_log: last accepted or rejected actions
Latent SEIR state is never exposed on the wire. The agent must infer the world from delayed/noisy telemetry and operational signals.
Reward
The environment returns a dense per-tick r_outer in [-1.0, 1.0]:
r_outer =
0.15 * infection_control
+ 0.05 * time_remaining
+ 0.10 * hospital_pressure
+ 0.10 * cascade_control
+ 0.55 * policy_validity
+ 0.05 * fairness
Policy validity is deliberately strong because it gives the learner a clean gradient:
- Accepted real intervention:
+1.0 - Accepted
no_op:0.0 - Rejected legal/V2 action:
-0.5 - Parse-failure marker:
-1.0and terminal failure
Regression tests lock the reward signal quality:
- all-
no_opmean reward onoutbreak_easymust stay below0.40 - all-rejected mean reward must stay below
0.40 - active strategic deployment must stay above
0.50 - active-vs-no-op separation must stay at least
0.20
flowchart LR
S[Post-tick WorldState] --> I[Infection]
S --> H[Hospital load]
S --> C[Cascade risk]
S --> P[Action validity]
S --> F[Fairness]
I --> R[r_outer]
H --> R
C --> R
P --> R
F --> R
B[Tokens used] --> T[Training reward]
R --> T
Baselines and Cortex
The repository includes controlled comparisons rather than only a single hero agent:
baselines/flat_agent.py- B1, one LLM call per tick.baselines/flat_agent_matched_compute.py- B2, self-critique and revision under the same 6000-token per-tick envelope.baselines/cortex_fixed_router.py- B3, Cortex with a deterministic router.cortex/- typed subagents, per-brain lenses, council orchestration, anti-hivemind protocol, metacognition, and routing policy interfaces.training/- reward shaping, rollout buffer, eval metrics, and notebook surfaces for GRPO/TRL-style training.
The important comparison is not "Cortex used more thought." B2 exists to match compute. Cortex has to win by allocating thought better: preserving useful dissent, challenging overconfident consensus, and converging only when the action is ready.
Running the Inference Harness
inference.py runs the flat baseline across the three-task ladder and emits
the validator-facing stdout format:
[START] task=<task> env=CrisisWorldCortex model=<model>
[STEP] step=<N> action=<action> reward=<r> done=<true|false> error=<error|null>
[END] success=<true|false> steps=<N> score=<score> rewards=<...>
Required:
HF_TOKEN- One of
LOCAL_IMAGE_NAMEorENV_URL
Optional:
API_BASE_URL- defaults tohttps://router.huggingface.co/v1MODEL_NAME- defaults toQwen/Qwen2.5-72B-Instruct
Example:
$env:HF_TOKEN = "<token>"
$env:LOCAL_IMAGE_NAME = "CrisisWorldCortex-env:latest"
uv run python inference.py
Advanced Usage
Connecting to an Existing Server
If a CrisisWorldCortex server is already running, connect directly:
from CrisisWorldCortex import CrisisworldcortexAction, CrisisworldcortexEnv
from CrisisWorldCortex.models import NoOp
env = CrisisworldcortexEnv(base_url="http://localhost:8000")
result = env.reset(task_name="outbreak_medium", seed=1, max_ticks=12)
result = env.step(CrisisworldcortexAction(action=NoOp()))
When connecting to an existing server, env.close() closes the client
connection but does not stop the server process.
Context Manager
The client supports context manager usage for automatic connection cleanup:
from CrisisWorldCortex import CrisisworldcortexAction, CrisisworldcortexEnv
from CrisisWorldCortex.models import DeployResource
with CrisisworldcortexEnv(base_url="http://localhost:8000") as env:
result = env.reset(task_name="outbreak_easy", seed=0)
result = env.step(
CrisisworldcortexAction(
action=DeployResource(
region="R1",
resource_type="test_kits",
quantity=100,
)
)
)
The client uses WebSocket sessions for:
- Lower latency across many sequential steps
- Persistent environment state per session
- Cleaner episode loops for training and evaluation
Development & Testing
Install dependencies:
uv sync --extra dev
Run the server locally:
uv run server --port 8000
Run tests:
uv run pytest tests/ -v
uv run ruff check .
Useful direct checks:
# OpenEnv validation
uv run openenv validate -v
# Smoke one environment episode through tests
uv run pytest tests/test_smoke_env.py tests/test_reward_signal_quality.py -v
Project Structure
CrisisWorldCortex/
|-- README.md
|-- openenv.yaml
|-- pyproject.toml
|-- Dockerfile
|-- inference.py
|-- client.py
|-- models.py
|-- server/
| |-- app.py
| |-- CrisisWorldCortex_environment.py
| |-- simulator/
| | |-- seir_model.py
| | `-- tasks.py
| `-- graders/
| `-- outer_reward.py
|-- cortex/
| |-- council.py
| |-- routing_policy.py
| |-- metacognition.py
| |-- lenses.py
| |-- subagents/
| `-- brains/
|-- baselines/
| |-- flat_agent.py
| |-- flat_agent_matched_compute.py
| `-- cortex_fixed_router.py
|-- training/
| |-- reward_shaping.py
| |-- rollout_buffer.py
| `-- eval_metrics.py
|-- frontend/
| `-- index.html
`-- tests/