|
1 | | -# CLAUDE.md |
| 1 | +# AGENTS.md |
2 | 2 |
|
3 | | -This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. |
| 3 | +Instructions for AI agents and automation tools using the Extropy CLI. |
4 | 4 |
|
5 | | -## What Extropy Is |
| 5 | +## Agent Mode |
6 | 6 |
|
7 | | -Extropy is a Python framework + CLI for agent-based population simulation. |
| 7 | +Set agent mode for structured JSON output and non-interactive operation: |
8 | 8 |
|
9 | | -It: |
10 | | -- builds synthetic populations from statistically grounded attribute distributions, |
11 | | -- adds scenario-relevant psychographic/context attributes, |
12 | | -- connects sampled agents in a social network, |
13 | | -- simulates multi-timestep opinion/behavior updates with two-pass LLM reasoning, |
14 | | -- outputs segmented distributional results. |
| 9 | +```bash |
| 10 | +extropy config set cli.mode agent |
| 11 | +``` |
| 12 | + |
| 13 | +Or use the `--json` flag per-command: |
| 14 | + |
| 15 | +```bash |
| 16 | +extropy results --json |
| 17 | +extropy query summary --json |
| 18 | +``` |
| 19 | + |
| 20 | +**Agent mode behavior:** |
| 21 | +- All output is JSON (parseable, no ANSI formatting) |
| 22 | +- Exit codes indicate success/failure (0 = success, non-zero = error) |
| 23 | +- No interactive prompts — commands fail fast if missing required input |
| 24 | +- Clarification requests return exit code 2 with structured error |
15 | 25 |
|
16 | | -## Core CLI Pipeline |
| 26 | +## CLI Pipeline |
17 | 27 |
|
18 | 28 | ```bash |
19 | 29 | extropy spec → extropy scenario → extropy persona → extropy sample → extropy network → extropy simulate → extropy results |
20 | 30 | ``` |
21 | 31 |
|
22 | | -Commands: |
23 | | -- `spec` — Create base population spec with attribute definitions |
24 | | -- `scenario` — Create scenario spec (absorbs old `extend` — adds scenario attributes + event config) |
25 | | -- `persona` — Generate persona rendering config for the scenario |
26 | | -- `sample` — Sample agents from merged population + scenario attributes |
27 | | -- `network` — Generate social network from sampled agents |
28 | | -- `simulate` — Run simulation |
29 | | -- `results` — View simulation results |
| 32 | +| Command | Purpose | |
| 33 | +|---------|---------| |
| 34 | +| `spec` | Create population spec from description | |
| 35 | +| `scenario` | Create scenario with events and outcomes | |
| 36 | +| `persona` | Generate persona rendering config | |
| 37 | +| `sample` | Sample agents from merged spec | |
| 38 | +| `network` | Generate social network | |
| 39 | +| `simulate` | Run simulation | |
| 40 | +| `results` | View results (summary, timeline, segment, agent) | |
| 41 | +| `query` | Export raw data (agents, edges, states, SQL) | |
| 42 | +| `chat` | Chat with simulated agents | |
| 43 | +| `estimate` | Predict simulation cost | |
| 44 | +| `validate` | Validate spec files | |
| 45 | +| `config` | View/set configuration | |
30 | 46 |
|
31 | | -Utility commands: `extropy validate`, `extropy config`, `extropy estimate`. |
| 47 | +## Non-Interactive Usage |
32 | 48 |
|
33 | | -CLI entry point: `extropy` (from `pyproject.toml`), Python `>=3.11`. |
| 49 | +### Pre-supplying answers |
34 | 50 |
|
35 | | -## Local Dev Commands |
| 51 | +For `spec` command, use `--answers` to skip clarification prompts: |
36 | 52 |
|
37 | 53 | ```bash |
38 | | -pip install -e ".[dev]" |
39 | | - |
40 | | -# tests |
41 | | -pytest # all tests |
42 | | -pytest tests/test_sampler.py # single file |
43 | | -pytest -k "test_sampling" # pattern match |
44 | | -pytest --tb=short -q # CI style (quick output) |
45 | | - |
46 | | -# lint / format |
47 | | -ruff check . |
48 | | -ruff format . |
49 | | - |
50 | | -# config |
51 | | -extropy config show |
52 | | -extropy config set pipeline.provider claude |
53 | | -extropy config set simulation.provider openai |
| 54 | +extropy spec "500 German surgeons" -o surgeons --answers '{"location": "Bavaria"}' |
54 | 55 | ``` |
55 | 56 |
|
56 | | -## High-Level Architecture |
| 57 | +Or use `--use-defaults` to accept default values: |
57 | 58 |
|
58 | | -Three phases map to top-level packages: |
| 59 | +```bash |
| 60 | +extropy spec "500 German surgeons" -o surgeons --use-defaults |
| 61 | +``` |
59 | 62 |
|
60 | | -1. Population creation (`extropy/population/`) |
61 | | -- Sufficiency check (`spec_builder/sufficiency.py`) |
62 | | -- Attribute selection (`spec_builder/selector.py`) |
63 | | -- Hydration (`spec_builder/hydrator.py`, `hydrators/`) |
64 | | -- Dependency binding (`spec_builder/binder.py`) |
65 | | -- Sampling (`sampler/core.py`) |
66 | | -- Network generation (`network/`) |
| 63 | +### Skip confirmations |
67 | 64 |
|
68 | | -2. Scenario compilation (`extropy/scenario/`) |
69 | | -- Compiler (`compiler.py`) orchestrates parse -> exposure -> interaction -> outcomes -> assembly |
70 | | -- Event types in code: `announcement`, `news`, `rumor`, `policy_change`, `product_launch`, `emergency`, `observation` |
71 | | -- Outcomes: `categorical`, `boolean`, `float`, `open_ended` |
| 65 | +Use `-y` / `--yes` to skip confirmation prompts: |
72 | 66 |
|
73 | | -3. Simulation (`extropy/simulation/`) |
74 | | -- Engine (`engine.py`) loops over timestep phases |
75 | | -- Seed + network exposure propagation |
76 | | -- Two-pass reasoning (role-play then classification) |
77 | | -- Memory traces (sliding window) |
78 | | -- Conviction-aware sharing + flip resistance |
79 | | -- Checkpoint/resume via `simulation_metadata` |
| 67 | +```bash |
| 68 | +extropy scenario "AI adoption" -o ai-adoption -y |
| 69 | +extropy persona -s ai-adoption -y |
| 70 | +``` |
80 | 71 |
|
81 | | -## LLM Integration |
| 72 | +## Exit Codes |
82 | 73 |
|
83 | | -All LLM calls go through `extropy/core/llm.py`. |
| 74 | +| Code | Meaning | |
| 75 | +|------|---------| |
| 76 | +| 0 | Success | |
| 77 | +| 1 | General error / validation failure | |
| 78 | +| 2 | Clarification needed (agent mode) / file not found | |
| 79 | +| 3 | Sampling error | |
84 | 80 |
|
85 | | -Two-zone routing: |
86 | | -- Pipeline zone (phases 1-2): `simple_call`, `reasoning_call`, `agentic_research` |
87 | | -- Simulation zone (phase 3): `simple_call_async` |
| 81 | +## Querying Data |
88 | 82 |
|
89 | | -Providers are created via `extropy/core/providers/`: |
90 | | -- `openai` |
91 | | -- `claude` |
92 | | -- `azure_openai` |
| 83 | +Export raw data for downstream processing: |
93 | 84 |
|
94 | | -Use provider factories (`get_pipeline_provider`, `get_simulation_provider`) rather than provider-specific calls in feature code. |
| 85 | +```bash |
| 86 | +# Agents as JSONL |
| 87 | +extropy query agents --to agents.jsonl |
95 | 88 |
|
96 | | -## Configuration |
| 89 | +# Network edges |
| 90 | +extropy query edges --to edges.jsonl |
97 | 91 |
|
98 | | -Config lives in `extropy/config.py` and `~/.config/extropy/config.json`. |
| 92 | +# Simulation states |
| 93 | +extropy query states --to states.jsonl |
99 | 94 |
|
100 | | -Resolution order (highest first): |
101 | | -1. Programmatic config (`configure(...)` / constructed `ExtropyConfig`) |
102 | | -2. Environment variables |
103 | | -3. Config file |
104 | | -4. Pydantic model defaults |
| 95 | +# Arbitrary SQL (read-only) |
| 96 | +extropy query sql "SELECT * FROM agent_states WHERE aware = 1" --format json |
| 97 | +``` |
105 | 98 |
|
106 | | -Defaults in code: |
107 | | -- `pipeline.provider = "openai"` |
108 | | -- `simulation.provider = "openai"` |
| 99 | +## Chat API |
109 | 100 |
|
110 | | -API keys are env-only: |
111 | | -- `OPENAI_API_KEY` |
112 | | -- `ANTHROPIC_API_KEY` |
113 | | -- `AZURE_OPENAI_API_KEY` |
| 101 | +Non-interactive chat for automation: |
114 | 102 |
|
115 | | -Azure extras: |
116 | | -- `AZURE_OPENAI_ENDPOINT` |
117 | | -- `AZURE_OPENAI_API_VERSION` (defaults to `2025-03-01-preview`) |
118 | | -- `AZURE_OPENAI_DEPLOYMENT` |
| 103 | +```bash |
| 104 | +extropy chat ask \ |
| 105 | + --study-db study.db \ |
| 106 | + --agent-id agent_042 \ |
| 107 | + --prompt "What changed your mind?" \ |
| 108 | + --json |
| 109 | +``` |
119 | 110 |
|
120 | | -## Data Models |
| 111 | +List available agents: |
121 | 112 |
|
122 | | -Primary Pydantic models are under `extropy/core/models/`: |
123 | | -- `population.py`: `PopulationSpec`, attribute/distribution/sampling models |
124 | | -- `scenario.py`: `ScenarioSpec`, event/exposure/interaction/outcomes/simulation config |
125 | | -- `simulation.py`: `AgentState`, `ReasoningContext`, `ReasoningResponse`, conviction maps, timestep summaries |
126 | | -- `network.py`, `results.py`, `validation.py`, `sampling.py` |
| 113 | +```bash |
| 114 | +extropy chat list --study-db study.db --json |
| 115 | +``` |
127 | 116 |
|
128 | | -YAML I/O helpers exist on core spec/config models (`to_yaml` / `from_yaml`). |
| 117 | +**Note:** The interactive REPL (`extropy chat`) requires a TTY and is not suitable for automation. Use `extropy chat ask` instead. |
129 | 118 |
|
130 | | -## Validation |
| 119 | +## Configuration Keys |
131 | 120 |
|
132 | | -Population validation (`extropy/population/validator/`): |
133 | | -- Structural: hard errors |
134 | | -- Semantic: warnings |
| 121 | +```bash |
| 122 | +extropy config set cli.mode agent # Enable agent mode globally |
| 123 | +extropy config set models.strong openai/gpt-4o |
| 124 | +extropy config set models.fast openai/gpt-4o-mini |
| 125 | +extropy config set simulation.strong anthropic/claude-sonnet-4.5 |
| 126 | +extropy config set simulation.fast anthropic/claude-haiku-3.5 |
| 127 | +extropy config set show_cost true # Show cost after commands |
| 128 | +``` |
135 | 129 |
|
136 | | -Scenario validation: `extropy/scenario/validator.py`. |
| 130 | +## Environment Variables |
137 | 131 |
|
138 | | -## Conventions |
| 132 | +Required API keys (set at least one): |
139 | 133 |
|
140 | | -- Use `_id` from agent JSON as primary ID (fallback to index string). |
141 | | -- Network edges are traversed bidirectionally during simulation. |
142 | | -- Keep LLM reasoning pass semantic; classification pass handles structured outcome extraction. |
143 | | -- Prefer data-driven network behavior through `NetworkConfig` over hardcoded social rules. |
144 | | -- Use Pydantic `BaseModel` for all config/model classes — no dataclasses. |
145 | | -- Canonical state lives in SQLite (`study.db`); use `StateManager` for simulation state access. |
| 134 | +```bash |
| 135 | +export OPENAI_API_KEY=sk-... |
| 136 | +export ANTHROPIC_API_KEY=sk-ant-... |
| 137 | +export OPENROUTER_API_KEY=sk-or-... |
| 138 | +export DEEPSEEK_API_KEY=sk-... |
| 139 | +``` |
146 | 140 |
|
147 | | -## Testing & CI |
| 141 | +## Global Flags |
148 | 142 |
|
149 | | -Tests are in `tests/` and run with `pytest`. Common fixtures are in `tests/conftest.py`: |
150 | | -- `minimal_population_spec`, `complex_population_spec` — ready-to-use PopulationSpec objects |
151 | | -- `ten_agents`, `sample_agents` — agent dicts for propagation/integration tests |
152 | | -- `linear_network`, `star_network` — network topologies for testing propagation |
| 143 | +All commands accept: |
153 | 144 |
|
154 | | -CI (`.github/workflows/test.yml`) runs: |
155 | | -- lint: `ruff check`, `ruff format --check` |
156 | | -- tests on Python 3.11/3.12/3.13 (via `uv`) |
| 145 | +| Flag | Purpose | |
| 146 | +|------|---------| |
| 147 | +| `--json` | JSON output (overrides cli.mode) | |
| 148 | +| `--cost` | Show cost summary after command | |
| 149 | +| `--study PATH` | Explicit study folder path | |
157 | 150 |
|
158 | | -## File Formats |
| 151 | +## Study Folder Structure |
159 | 152 |
|
160 | | -- YAML: population/spec/network/persona/scenario configs |
161 | | -- JSON: sampled agents, network, result artifacts |
162 | | -- SQLite: simulation state/checkpoints |
163 | | -- JSONL: timeline events |
| 153 | +``` |
| 154 | +my-study/ |
| 155 | +├── study.db # Canonical SQLite store |
| 156 | +├── population.v1.yaml # Base population spec |
| 157 | +├── scenario/ |
| 158 | +│ └── my-scenario/ |
| 159 | +│ ├── scenario.v1.yaml # Scenario spec |
| 160 | +│ └── persona.v1.yaml # Persona config |
| 161 | +└── results/ |
| 162 | + └── my-scenario/ # Simulation outputs |
| 163 | +``` |
| 164 | + |
| 165 | +## Typical Automation Flow |
| 166 | + |
| 167 | +```bash |
| 168 | +# Setup |
| 169 | +cd my-study |
| 170 | +extropy config set cli.mode agent |
| 171 | + |
| 172 | +# Build pipeline |
| 173 | +extropy spec "Austin TX commuters" -o . --use-defaults |
| 174 | +extropy scenario "Congestion tax response" -o congestion-tax -y |
| 175 | +extropy persona -s congestion-tax -y |
| 176 | +extropy sample -s congestion-tax -n 500 --seed 42 |
| 177 | +extropy network -s congestion-tax --seed 42 |
| 178 | + |
| 179 | +# Estimate before running |
| 180 | +extropy estimate -s congestion-tax --json |
| 181 | + |
| 182 | +# Run simulation |
| 183 | +extropy simulate -s congestion-tax --seed 42 |
| 184 | + |
| 185 | +# Extract results |
| 186 | +extropy results --json |
| 187 | +extropy query agents --to agents.jsonl |
| 188 | +extropy query states --to states.jsonl |
| 189 | +``` |
0 commit comments