CrisisWorldCortex / README.md
Angshuman28's picture
Upload folder using huggingface_hub
f6ae66b verified
|
Raw
History Blame Contribute Delete
12.2 kB
---
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.
```mermaid
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.
```mermaid
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:
```python
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:
```bash
# From project root
docker build -t CrisisWorldCortex-env:latest -f server/Dockerfile .
```
For the hackathon inference harness, the root `Dockerfile` is also present:
```bash
docker build -t CrisisWorldCortex-runner:latest .
```
## Deploying to Hugging Face Spaces
You can deploy the OpenEnv environment to Hugging Face Spaces using
`openenv push`:
```bash
# 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:
1. Validate that the directory is an OpenEnv environment
2. Prepare a Hugging Face Docker Space build
3. Upload the Space, assuming Hugging Face auth is configured
After deployment, your Space will be available at:
```text
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 proxy
- `resources`: current inventory for each resource class
- `active_restrictions`: region-level policy constraints currently in force
- `legal_constraints`: rules that block specific actions until unlocked
- `tick` and `ticks_remaining`
- `cognition_budget_remaining`: per-tick token budget surface
- `recent_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]`:
```text
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.0` and terminal failure
Regression tests lock the reward signal quality:
- all-`no_op` mean reward on `outbreak_easy` must stay below `0.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`
```mermaid
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:
```text
[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_NAME` or `ENV_URL`
Optional:
- `API_BASE_URL` - defaults to `https://router.huggingface.co/v1`
- `MODEL_NAME` - defaults to `Qwen/Qwen2.5-72B-Instruct`
Example:
```powershell
$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:
```python
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:
```python
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:
```bash
uv sync --extra dev
```
Run the server locally:
```bash
uv run server --port 8000
```
Run tests:
```bash
uv run pytest tests/ -v
uv run ruff check .
```
Useful direct checks:
```bash
# 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
```text
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/
```