|
| 1 | +# CLAUDE.md |
| 2 | + |
| 3 | +This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. |
| 4 | + |
| 5 | +## Project Overview |
| 6 | + |
| 7 | +Balatrollm is an LLM-powered bot that plays Balatro (a roguelike poker deck-building game) using the BalatroBot client. The bot uses LiteLLM proxy to communicate with various LLM providers and makes strategic decisions based on game state analysis. |
| 8 | + |
| 9 | +## Development Commands |
| 10 | + |
| 11 | +### Environment Setup |
| 12 | + |
| 13 | +```bash |
| 14 | +# Install dependencies (including dev dependencies) |
| 15 | +uv sync --all-extras --group dev |
| 16 | + |
| 17 | +# Create environment configuration |
| 18 | +cp .envrc.example .envrc |
| 19 | +source .envrc |
| 20 | +``` |
| 21 | + |
| 22 | +### LiteLLM Proxy |
| 23 | + |
| 24 | +```bash |
| 25 | +# Start the LiteLLM proxy server (required before running the bot) |
| 26 | +litellm --config config/litellm.yaml |
| 27 | +``` |
| 28 | + |
| 29 | +### Running the Application |
| 30 | + |
| 31 | +```bash |
| 32 | +# Run with default settings |
| 33 | +balatrollm |
| 34 | + |
| 35 | +# Run with specific model |
| 36 | +balatrollm --model groq-qwen3-32b |
| 37 | + |
| 38 | +# List available models from proxy |
| 39 | +balatrollm --list-models |
| 40 | + |
| 41 | +# Enable verbose logging |
| 42 | +balatrollm --verbose |
| 43 | +``` |
| 44 | + |
| 45 | +### Development Quality Commands |
| 46 | +```bash |
| 47 | +# Run all quality checks |
| 48 | +make all |
| 49 | + |
| 50 | +# Individual quality checks |
| 51 | +make lint # Run ruff linter (check only) |
| 52 | +make lint-fix # Run ruff linter with auto-fixes |
| 53 | +make format # Run ruff formatter |
| 54 | +make typecheck # Run basedpyright type checker |
| 55 | + |
| 56 | +# Development workflow |
| 57 | +make dev # Quick development check (format + lint + typecheck) |
| 58 | + |
| 59 | +# Cleanup |
| 60 | +make clean # Remove build artifacts and caches |
| 61 | +``` |
| 62 | + |
| 63 | +### Testing |
| 64 | + |
| 65 | +```bash |
| 66 | +# Run tests (using pytest) |
| 67 | +pytest |
| 68 | + |
| 69 | +# Run specific test file |
| 70 | +pytest tests/test_example.py |
| 71 | +``` |
| 72 | + |
| 73 | +## Architecture |
| 74 | + |
| 75 | +### Core Components |
| 76 | + |
| 77 | +**LLMBot (`src/balatrollm/llm.py`)** |
| 78 | +- Main bot implementation that orchestrates game play |
| 79 | +- Manages LiteLLM client connection and model validation |
| 80 | +- Handles game state analysis and decision making through LLM |
| 81 | +- Executes actions via BalatroClient integration |
| 82 | +- Uses Jinja2 templates for prompt generation |
| 83 | + |
| 84 | +**CLI Entry Point (`src/balatrollm/__init__.py`)** |
| 85 | +- Command-line interface with argument parsing |
| 86 | +- Environment variable support for configuration |
| 87 | +- Proxy connection validation and error handling |
| 88 | +- Async game execution wrapper |
| 89 | + |
| 90 | +**Template System (`src/balatrollm/templates/`)** |
| 91 | +- `system.md.jinja`: Comprehensive Balatro strategy guide and rules |
| 92 | +- `game_state.md.jinja`: Dynamic game state representation for LLM analysis |
| 93 | +- Templates use Jinja2 with custom filters (e.g., `from_json`) |
| 94 | + |
| 95 | +**Tools Configuration (`src/balatrollm/tools.json`)** |
| 96 | +- OpenAI function calling definitions for different game states |
| 97 | +- Maps game states (BLIND_SELECT, SELECTING_HAND, SHOP) to available actions |
| 98 | +- Defines function schemas for LLM tool use |
| 99 | + |
| 100 | +### Key Dependencies |
| 101 | + |
| 102 | +- **balatrobot**: Core Balatro game client (from git repository) |
| 103 | +- **litellm**: LLM proxy server for multiple providers |
| 104 | +- **openai**: OpenAI client for LLM communication |
| 105 | +- **jinja2**: Template engine for prompt generation |
| 106 | +- **httpx**: HTTP client for proxy health checks |
| 107 | + |
| 108 | +### Game Integration Flow |
| 109 | + |
| 110 | +1. **Initialization**: Validate LiteLLM proxy connection and model availability |
| 111 | +2. **Game Loop**: |
| 112 | + - Get current game state from BalatroClient |
| 113 | + - Render game state using Jinja2 templates |
| 114 | + - Send context to LLM with state-specific tools |
| 115 | + - Parse LLM tool call response |
| 116 | + - Execute action through BalatroClient |
| 117 | +3. **State Handling**: Different logic for BLIND_SELECT, SELECTING_HAND, SHOP, ROUND_EVAL states |
| 118 | + |
| 119 | +### LiteLLM Configuration |
| 120 | + |
| 121 | +The `config/litellm.yaml` defines available models: |
| 122 | +- **Cerebras**: High-performance cloud inference (gpt-oss-120b, gpt-oss-20b) |
| 123 | +- **Groq**: Fast inference with Qwen models |
| 124 | +- **Local**: LM Studio integration for development |
| 125 | + |
| 126 | +Environment variables required: |
| 127 | +- `CEREBRAS_API_KEY`: For Cerebras models |
| 128 | +- `GROQ_API_KEY`: For Groq models |
| 129 | + |
| 130 | +## Development Guidelines |
| 131 | + |
| 132 | +### Code Quality |
| 133 | +- Uses Ruff for linting and formatting with import sorting |
| 134 | +- Uses basedpyright for type checking in basic mode |
| 135 | +- Follows conventional commits specification |
| 136 | +- Automated release process with Release Please |
| 137 | + |
| 138 | +### Project Structure |
| 139 | +``` |
| 140 | +src/balatrollm/ |
| 141 | +├── __init__.py # CLI entry point and argument parsing |
| 142 | +├── llm.py # Core LLMBot implementation |
| 143 | +├── tools.json # OpenAI function definitions by game state |
| 144 | +└── templates/ |
| 145 | + ├── system.md.jinja # Comprehensive game strategy guide |
| 146 | + └── game_state.md.jinja # Dynamic game state representation |
| 147 | +``` |
| 148 | + |
| 149 | +### Template System Usage |
| 150 | +- Templates handle complex game state rendering for LLM context |
| 151 | +- System template contains extensive Balatro strategy documentation |
| 152 | +- Game state template dynamically formats current game information |
| 153 | +- Custom Jinja2 filter `from_json` for JSON parsing in templates |
| 154 | + |
| 155 | +### Error Handling Patterns |
| 156 | +- Proxy connection validation before game start |
| 157 | +- Model availability checking with fallback suggestions |
| 158 | +- Graceful keyboard interrupt handling |
| 159 | +- Comprehensive logging with different verbosity levels |
| 160 | + |
| 161 | +## Dependency Documentation |
| 162 | + |
| 163 | +When working with code that uses these dependencies, search their documentation using Context7 MCP server (`--c7` flag) with these library IDs: |
| 164 | + |
| 165 | +**Core Dependencies:** |
| 166 | +- **balatrobot**: `/s1m0n38/balatrobot` |
| 167 | +- **jinja2**: `/pallets/jinja` |
| 168 | +- **openai**: `/openai/openai-python` |
| 169 | +- **litellm**: `/berriai/litellm` |
| 170 | +- **httpx**: `/encode/httpx` |
| 171 | + |
| 172 | +**Dev Dependencies:** |
| 173 | +- **basedpyright**: `/detachhead/basedpyright` |
| 174 | +- **pytest**: `/pytest-dev/pytest` |
| 175 | +- **pytest-asyncio**: `/pytest-dev/pytest-asyncio` |
| 176 | +- **ruff**: `/astral-sh/ruff` |
| 177 | +- **uv**: `/astral-sh/uv` |
| 178 | + |
| 179 | +**Usage:** When implementing features or fixing issues related to any of these libraries, use the Context7 MCP server to get up-to-date documentation and code examples. |
| 180 | + |
| 181 | +## Important Notes |
| 182 | + |
| 183 | +- The bot currently has LLM decision-making enabled only for SELECTING_HAND state |
| 184 | +- BLIND_SELECT and SHOP states use hardcoded actions (TODOs indicate future LLM integration) |
| 185 | +- Game state management relies on BalatroClient state machine |
| 186 | +- LiteLLM proxy must be running before starting the bot |
| 187 | +- Response history is maintained for context in subsequent LLM calls |
0 commit comments