Skip to main content

Python compat PyPi GHA Status Documentation Status


econagents

econagents is a Python library for running economic experiments with LLM agents as participants. You describe the game — roles, prompts, and game state — and econagents connects one agent per player to your experiment server, keeps each agent's view of the game up to date, queries an LLM for decisions each phase, and logs everything for analysis.

What you can do with it

  • Run classic economic games with LLM players: Prisoner's Dilemma, Dictator, Public Goods, and a continuous double auction shipped as runnable examples with local servers included.
  • Agent runtime: Run one explicit Agent per simulated player.
  • Define experiments in YAML: Declare roles, per-phase prompts (Jinja templates), agent assignments, and game state in a single config file, then launch with run_experiment_from_yaml — no framework code required for standard setups.
  • Ports and Adapters: Swap protocol codecs, transports, prompt renderers, response parsers, and state projectors.
  • Flexible agent customization: Customize behavior with Jinja templates, response schemas, personas, or custom Python phase handlers; give agents different strategies and personas to study heterogeneous populations.
  • Event-driven state management: Project server events into typed public, private, and meta state.
  • Hosted and local models: Use OpenAI, OpenRouter, or run local models via Ollama; configurable per role so different players can run on different models.
  • Connect to your own experiment server: Agents talk to game servers over WebSockets. The default protocol targets IBEX-style envelopes, and codecs, transports, and parsers are swappable for other servers.
  • Turn-based and continuous action support: Handle one-shot phase decisions and repeated actions within continuous market phases (as in the double auction example).
  • Trace and analyze runs: Per-agent logs are written for every game, with optional LangSmith or Langfuse tracing of all LLM calls.

Installation

# Install from PyPI
pip install econagents

# Or install directly from GitHub
pip install git+https://github.com/IBEX-TUDelft/econagents.git

The runnable examples are not part of the PyPI package. To run them, clone the repository and install it with the examples extra as shown in the Quickstart.

On Debian/Ubuntu the system Python ships without venv and pip; run sudo apt install python3-venv python3-pip first.

Quickstart

The fastest way to see it in action is the repeated Prisoner's Dilemma, which runs entirely on your machine:

git clone https://github.com/IBEX-TUDelft/econagents.git
cd econagents
python -m venv .venv && source .venv/bin/activate
pip install -e ".[examples]"
echo 'OPENAI_API_KEY=<your-key>' > .env

Then, from the repository root, start the game server and, in a second terminal, the experiment:

# Terminal 1: run the game server
python -m examples.prisoner.server.server

# Terminal 2: run the experiment
python -m examples.prisoner.run_game

If you use uv, uv sync replaces the venv and pip steps and uv run python ... replaces python ....

Two LLM agents play five rounds against each other; per-agent logs land in examples/prisoner/logs/.

To run the same experiment through OpenRouter, put OPENROUTER_API_KEY in .env and use the YAML-driven variant, which routes both agents through ChatOpenRouter:

python -m examples.prisoner.run_game_from_yaml prisoner_openrouter.yaml

Most of the experiment lives in a YAML file. Here's a condensed look at examples/prisoner/prisoner.yaml:

roles:
  - role_id: 1
    name: "cooperator"
    llm_type: "ChatOpenAI"
    llm_params:
      model_name: "gpt-5.4-mini"
    prompts:
      - system: |
          {% include "_partials/game_description.jinja2" %}
          You will generally cooperate with the other prisoner.
      - user: |
          {% include "_partials/game_history.jinja2" %}
          {% include "_partials/game_instructions.jinja2" %}
  - role_id: 2
    name: "defector"
    # ...

agents:
  - id: 1
    role_id: 1
  - id: 2
    role_id: 2

state:
  public_information:
    - name: "history"
      type: "list"
      default_factory: "list"

Prompts are Jinja templates rendered against the live game state, so agents always see the current round, their payoffs, and the history you choose to expose. Running it is one call:

from econagents.adapters.config import run_experiment_from_yaml

await run_experiment_from_yaml("prisoner.yaml", login_payloads, game_id=game_id)

When YAML isn't flexible enough — custom phase logic, bespoke state handling — you can drop down to Python and compose the same building blocks directly (see examples/prisoner/run_game.py).

Example experiments

Example What it shows
prisoner Iterated Prisoner's Dilemma, 2 agents, 5 rounds, local server included
prisoner_personas Same game, but each agent plays a distinct persona
dictator Modified Dictator game with 2 agents, local server included
public_goods Public goods game with 4 players, local server included
continuous_double_auction LLM-backed traders in a continuous market phase

More examples are in the econagents cookbook.

How it works

Each simulated player is an Agent that connects to the game server over a transport (WebSockets by default), decodes server events through a protocol codec, and projects them into typed public, private, and meta state. When a phase requires a decision, the agent's role renders prompts from that state, queries its LLM, parses the response into an action, and sends it back to the server. A GameRunner supervises all agents, logging, timeouts, and cleanup. Every piece — codec, transport, prompt renderer, response parser, state projector — sits behind a port interface, so you can swap implementations to fit your server or workflow.

To route a YAML role through OpenRouter, set OPENROUTER_API_KEY and use an OpenRouter model slug:

roles:
  - role_id: 1
    name: "player"
    llm_type: "ChatOpenRouter"
    llm_params:
      model_name: "anthropic/claude-sonnet-4"

ChatOpenRouter supports structured outputs, tool calling, normalized reasoning controls, provider routing options, and optional app attribution. examples/prisoner/prisoner_openrouter.yaml is a complete, runnable example.

Relative logs_dir and prompts_dir values in the runner section of a YAML config are resolved against the directory containing the YAML file.

Documentation

For detailed guides and API reference, visit the documentation.

Release files for econagents 0.2.12

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for econagents 0.2.12
File Size Uploaded
econagents-0.2.12.tar.gz 88.2 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for econagents 0.2.12
File Interpreter ABI Platform
econagents-0.2.12-py3-none-any.whl Python 3 none any Details

Total release size: 158.3 kB

Release files / econagents-0.2.12.tar.gz

Download URL econagents-0.2.12.tar.gz
Size 88.2 kB
Tags Source
SHA-256 checksum
How to use checksums
c03a407d36e5a173ae17871d9a729bdd930cc92489ccd697d14b61f1d1a8cc3d
BLAKE2b-256 checksum
How to use checksums
ee20387e24d4967d3f87b97ef6170a234a5d2715ef1bc4405681cbfbc6450293
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.12.15 {"installer":{"name":"uv","version":"0.12.15","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release files / econagents-0.2.12-py3-none-any.whl

Download URL econagents-0.2.12-py3-none-any.whl
Size 70.1 kB
Tags Python 3
SHA-256 checksum
How to use checksums
645ba69c2e95a4e8a2e247b952c3f885e00ff8141b704a6bf74c33f2de23bc54
BLAKE2b-256 checksum
How to use checksums
ac55898350960c6364dee237ef54af21aa12e0cb7028923399ad891443dc2337
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.12.15 {"installer":{"name":"uv","version":"0.12.15","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release history Release notifications | RSS feed

This release

0.2.12 This release

2 release files

0.2.11

2 release files

0.2.10

2 release files

0.2.9

2 release files

0.2.8

2 release files

0.2.7

2 release files

0.2.6

2 release files

0.2.4

2 release files

0.2.3

2 release files

0.2.2

2 release files

0.2.1

2 release files

0.1.2

2 release files

0.1.1

2 release files

0.0.11

2 release files

0.0.10

2 release files

0.0.9

2 release files

0.0.8

2 release files

0.0.7

2 release files

0.0.5

2 release files

0.0.3

2 release files

0.0.2

2 release files

0.0.1

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page