OpenPoker
A Python poker engine (with a terminal UI) for building LLM poker apps, servers, and custom interfaces. Play against LLMs from OpenAI, Anthropic, and Openrouter.
Terminal UI
Play Texas Hold'em No-Limit against agents directly in your terminal:
- Agent memory allows agents to store insights and observations at the end of each hand, learning opponent playing styles and carrying knowledge from one hand to another within a game session
- Player personalities can be configured to create distinct playing styles and behaviors for each agent
- Model selection supports OpenAI, Anthropic, and OpenRouter models, letting you mix different LLM providers at the same table
- Agent rationales are produced for every decision and can be viewed in debug mode, showing the reasoning behind each action
- Tool-based decisions use function calling to structure agent actions, with game state presented through context assembly that includes hand strength, pot odds, opponent behaviors, and historical insights
- Monte Carlo simulation using Treys provides agents with win probability statistics to inform their decision-making and increase gameplay difficulty
- Pot odds and EV calculations are automatically computed and available to agents for more strategic play
- Type-safe implementation with full type hints and Pydantic models throughout
Quick Install
pip install openpoker
Run the Terminal UI
openpoker
Or with debug mode:
openpoker --debug
The terminal will prompt for API keys if needed, or you can create a .env file:
OPENAI_API_KEY=your_openai_key
ANTHROPIC_API_KEY=your_anthropic_key
OPENROUTER_API_KEY=your_openrouter_key
Development Install
git clone https://github.com/philippe-page/openpoker.git
cd openpoker
python3 -m venv venv
source venv/bin/activate # On Windows: venv\Scripts\activate
pip install -e ".[dev]"
OpenPoker Engine
OpenPoker's terminal UI runs on a standalone engine designed as a library for building LLM-powered poker applications. The engine is built on PokerKit for game state and rule enforcement, and uses Treys for fast Monte Carlo simulations. The event-driven architecture makes it suitable for building servers, web applications with SSE or WebSocket transports, custom clients, or integrating poker gameplay into larger systems.
The engine handles game state, rule enforcement, agent decision orchestration, and emits granular events for every game action. Build React frontends, multiplayer servers, training environments, or any poker application on top of the same engine that powers the terminal UI.
Engine quickstart
from openpoker import (
AIProvider, ActionType, EngineOptions, GameConfig,
PlayerConfig, PlayerType, PokerAction, PokerEngine,
)
engine = PokerEngine(
options=EngineOptions(enable_memory=True, enable_monte_carlo=True)
)
game_id = engine.create_game(
game_name=table_name,
config=GameConfig(small_blind=small_blind, big_blind=big_blind, starting_stack=buy_in),
players=[
PlayerConfig(id=user_id, name=display_name, player_type=PlayerType.HUMAN),
PlayerConfig(id=agent_id, name=agent_name, player_type=PlayerType.AI, provider=provider, model=model),
],
)
snapshot = engine.start_hand(game_id)
while snapshot.hand_active:
if snapshot.current_actor_id == user_id:
available = engine.get_available_actions(game_id, user_id)
action = get_action_from_client(available)
snapshot = await engine.submit_action(game_id, user_id, action)
else:
snapshot = await engine.step(game_id)
Events and app integration
Subscribe once, then push events to whatever transport your app uses (SSE, websocket, queue, logs).
def on_event(event):
data = event.model_dump(mode="json")
print(event.event_type.value, data["sequence"])
unsubscribe = engine.subscribe(on_event)
Event types:
game_created- New game initialized with playershand_started- New hand dealt, blinds postedaction_required- Player needs to act, includes available actionsaction_applied- Player action processed (fold, check, call, bet, raise)street_changed- Flop, turn, or river dealtshowdown- Hand complete, winners determinedplayer_eliminated- Player out of chipsgame_over- Single player remainsai_decision- AI agent decision with rationale and metadataengine_error- Error occurred during game processing
Snapshots
Use snapshots as read-model state for clients:
snapshot = engine.get_snapshot(game_id, viewer_id=user_id)
Tutor/admin view can reveal all hole cards:
snapshot = engine.get_snapshot(game_id, reveal_all_hole_cards=True)
Agent payloads
Agent decisions return normalized metadata including:
providerandmodelrationale- tool call name and arguments
- token usage details (input/output/total, provider-specific fields when available)
Examples
See examples/:
examples/server_like_loop.pyexamples/api_style_session.pyexamples/sse_event_stream.py
Documentation
Testing
Run the full test suite:
python -m unittest discover -s tests -p "test_*.py" -v
Current coverage so far includes 200+ tests covering:
- Poker game logic and rules
- Engine orchestration
- Event system
- Monte Carlo simulation
- Pot odds calculations
- Snapshot visibility
- TUI rendering
- Elimination logic
- LLM token usage tracking and validation
Contributing
See CONTRIBUTING.md for development setup and guidelines.
License
MIT - See LICENSE for details.
Changelog
See CHANGELOG.md for version history.
Metadata
Release files for openpoker 0.0.3
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| openpoker-0.0.3.tar.gz | 34.3 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| openpoker-0.0.3-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 71.6 kB
Release files / openpoker-0.0.3.tar.gz
| Download URL | openpoker-0.0.3.tar.gz |
|---|---|
| Size | 34.3 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
3d8d67ad89f9651d1a9f815dc48ea367ccb395d46125b4219747791204ed1ce2
|
|
BLAKE2b-256 checksum How to use checksums |
a76a2e0f81cdd2c7b49543dbb86c270db73ca4edd65495c74180b73cff2b16dc
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.13.11
|
Release files / openpoker-0.0.3-py3-none-any.whl
| Download URL | openpoker-0.0.3-py3-none-any.whl |
|---|---|
| Size | 37.2 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
a49908a685e83cc4414d336fdb77624b5a99aeb198098fc8351379a53ca4d8a0
|
|
BLAKE2b-256 checksum How to use checksums |
f6a2d64706fbe206557be5e9dce834e07a0e37932c5596e27676f215d6ef74e1
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.13.11
|