chipzen-bot 0.2.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (37) hide show
  1. chipzen_bot-0.2.0/.gitignore +58 -0
  2. chipzen_bot-0.2.0/CHANGELOG.md +97 -0
  3. chipzen_bot-0.2.0/IP-PROTECTION.md +115 -0
  4. chipzen_bot-0.2.0/Makefile +55 -0
  5. chipzen_bot-0.2.0/PKG-INFO +130 -0
  6. chipzen_bot-0.2.0/QUICKSTART.md +75 -0
  7. chipzen_bot-0.2.0/README.md +98 -0
  8. chipzen_bot-0.2.0/RELEASING.md +124 -0
  9. chipzen_bot-0.2.0/pyproject.toml +67 -0
  10. chipzen_bot-0.2.0/src/chipzen/__init__.py +20 -0
  11. chipzen_bot-0.2.0/src/chipzen/__main__.py +55 -0
  12. chipzen_bot-0.2.0/src/chipzen/bot.py +148 -0
  13. chipzen_bot-0.2.0/src/chipzen/client.py +440 -0
  14. chipzen_bot-0.2.0/src/chipzen/conformance.py +357 -0
  15. chipzen_bot-0.2.0/src/chipzen/examples/__init__.py +1 -0
  16. chipzen_bot-0.2.0/src/chipzen/examples/call_bot.py +22 -0
  17. chipzen_bot-0.2.0/src/chipzen/examples/random_bot.py +30 -0
  18. chipzen_bot-0.2.0/src/chipzen/examples/tight_aggressive.py +53 -0
  19. chipzen_bot-0.2.0/src/chipzen/models.py +316 -0
  20. chipzen_bot-0.2.0/src/chipzen/scaffold.py +190 -0
  21. chipzen_bot-0.2.0/src/chipzen/validate.py +711 -0
  22. chipzen_bot-0.2.0/starters/python/.dockerignore +51 -0
  23. chipzen_bot-0.2.0/starters/python/Dockerfile +80 -0
  24. chipzen_bot-0.2.0/starters/python/README.md +55 -0
  25. chipzen_bot-0.2.0/starters/python/bot.py +61 -0
  26. chipzen_bot-0.2.0/starters/python/requirements.txt +1 -0
  27. chipzen_bot-0.2.0/tests/conftest.py +7 -0
  28. chipzen_bot-0.2.0/tests/test_cli.py +128 -0
  29. chipzen_bot-0.2.0/tests/test_client.py +547 -0
  30. chipzen_bot-0.2.0/tests/test_conformance.py +161 -0
  31. chipzen_bot-0.2.0/tests/test_integration.py +122 -0
  32. chipzen_bot-0.2.0/tests/test_models.py +139 -0
  33. chipzen_bot-0.2.0/tests/test_models_property.py +196 -0
  34. chipzen_bot-0.2.0/tests/test_python_starter.py +105 -0
  35. chipzen_bot-0.2.0/tests/test_reference_bot.py +313 -0
  36. chipzen_bot-0.2.0/tests/test_scaffold.py +68 -0
  37. chipzen_bot-0.2.0/tests/test_validate.py +226 -0
@@ -0,0 +1,58 @@
1
+ # Python
2
+ __pycache__/
3
+ *.py[cod]
4
+ *.egg-info/
5
+ .pytest_cache/
6
+ .mypy_cache/
7
+ .ruff_cache/
8
+ .venv/
9
+ venv/
10
+ env/
11
+ dist/
12
+ build/
13
+
14
+ # JavaScript / TypeScript
15
+ node_modules/
16
+ *.log
17
+ .npm
18
+ .pnpm-store/
19
+ coverage/
20
+ .next/
21
+ .nuxt/
22
+ .turbo/
23
+
24
+ # Rust
25
+ target/
26
+ Cargo.lock
27
+
28
+ # IDE
29
+ .vscode/
30
+ .idea/
31
+ *.swp
32
+ *.swo
33
+ .DS_Store
34
+
35
+ # Local env
36
+ .env
37
+ .env.local
38
+ .env.*.local
39
+ .envrc
40
+
41
+ # Credentials and secrets — defense in depth, the platform's threat
42
+ # model assumes uploaded bot images carry no per-user secrets but a
43
+ # leaked dotfile in a contributor's working tree is still bad.
44
+ *.key
45
+ *.pem
46
+ *.cert
47
+ *.crt
48
+ secrets.*
49
+ credentials.*
50
+ .aws/credentials
51
+
52
+ # Build artifacts
53
+ *.tar.gz
54
+ *.zip
55
+ *.whl
56
+
57
+ # CLA signatures storage
58
+ .cla-signatures.json
@@ -0,0 +1,97 @@
1
+ # Changelog
2
+
3
+ All notable changes to the `chipzen-bot` Python SDK will be documented
4
+ in this file.
5
+
6
+ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
7
+ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
8
+
9
+ ## [0.2.0] — Initial public release
10
+
11
+ First release of `chipzen-bot` to PyPI. The package was previously
12
+ developed inside the Chipzen platform repo and is now extracted to
13
+ [chipzen-ai/chipzen-sdk](https://github.com/chipzen-ai/chipzen-sdk)
14
+ as the canonical home.
15
+
16
+ ### Scope
17
+
18
+ The published SDK is intentionally narrow:
19
+
20
+ 1. A **protocol adapter** (`chipzen.Bot` base class plus the WebSocket
21
+ client) so your bot doesn't hand-roll the wire protocol.
22
+ 2. A **`chipzen-sdk validate`** CLI that runs the same pre-upload
23
+ checks the platform performs (size, imports, sandbox-blocked
24
+ modules, `decide()` timeout sniff).
25
+ 3. (Forthcoming, in a follow-up release) An **IP-protected Dockerfile
26
+ recipe** — Cython multi-stage build that ships compiled `.so`
27
+ artifacts only, not your `.py` source.
28
+
29
+ Local match simulation, hand evaluation, opponent pools, and
30
+ bot-vs-bot strength testing are explicitly out of scope; the platform
31
+ runs that evaluation post-upload. See the
32
+ [README](README.md#what-the-sdk-is-for-and-what-it-isnt).
33
+
34
+ ### CLI surface
35
+
36
+ Two commands. Both have detailed `--help` output.
37
+
38
+ - `chipzen-sdk init <name>` — scaffold a new bot project from a
39
+ starter template.
40
+ - `chipzen-sdk validate <path>` — pre-upload go/no-go.
41
+
42
+ ### Public API
43
+
44
+ - **`chipzen.Bot`** — abstract base class (alias for
45
+ `chipzen.bot.ChipzenBot`). Override `decide(state) -> action`.
46
+ Optional lifecycle hooks: `on_match_start`, `on_round_start`,
47
+ `on_hand_start`, `on_phase_change`, `on_turn_result`,
48
+ `on_round_result`, `on_hand_result`, `on_match_end`.
49
+ - **`chipzen.GameState`** — dataclass built from the server's
50
+ `turn_request` payload. Fields documented in the
51
+ [DEV-MANUAL §2.3](https://github.com/chipzen-ai/chipzen-sdk/blob/main/docs/DEV-MANUAL.md#23-gamestate).
52
+ - **`chipzen.Action`** — factory: `Action.fold()`, `Action.check()`,
53
+ `Action.call()`, `Action.raise_to(amount)`, `Action.all_in()`.
54
+ `Action.to_wire()` produces the two-layer `turn_action` params
55
+ schema.
56
+ - **`chipzen.Card`** — `(rank, suit)` frozen dataclass.
57
+ `Card.from_str("Ah")` parses wire format; `str(card)` renders it.
58
+ - **`chipzen.client.run_bot(...)`** — async runner that drives the
59
+ full WebSocket lifecycle (handshake, envelope sequence check,
60
+ ping/pong, `action_rejected` retry, reconnect, clean exit on
61
+ `match_end`).
62
+
63
+ ### Built-in example bots
64
+
65
+ Importable as canonical `Bot` subclass examples (not as competitive
66
+ opponents — there is no local match runner):
67
+
68
+ - `chipzen.examples.call_bot.CallBot` — always calls.
69
+ - `chipzen.examples.random_bot.RandomBot` — picks a uniform random
70
+ valid action.
71
+ - `chipzen.examples.tight_aggressive.TightAggressiveBot` — simplified
72
+ TAG strategy.
73
+
74
+ ### Two-layer wire protocol
75
+
76
+ The client speaks the Chipzen two-layer protocol (Layer 1 Transport +
77
+ Layer 2 Poker) defined in
78
+ [`docs/protocol/TRANSPORT-PROTOCOL.md`](https://github.com/chipzen-ai/chipzen-sdk/blob/main/docs/protocol/TRANSPORT-PROTOCOL.md)
79
+ and
80
+ [`docs/protocol/POKER-GAME-STATE-PROTOCOL.md`](https://github.com/chipzen-ai/chipzen-sdk/blob/main/docs/protocol/POKER-GAME-STATE-PROTOCOL.md).
81
+
82
+ Highlights for clients written in other languages or for anyone
83
+ debugging at the wire level:
84
+
85
+ - The `run_bot` handshake sends `authenticate` first, waits for the
86
+ server `hello`, then sends the client `hello` with
87
+ `supported_versions=["1.0"]`.
88
+ - Heartbeat: client replies to `ping` with `pong`.
89
+ - `action_rejected`: SDK falls back to `check` (or `fold` if check is
90
+ not legal) using the original `request_id`.
91
+ - `reconnected` messages with embedded `pending_request` are
92
+ dispatched as if they were fresh `turn_requests`.
93
+
94
+ ### License
95
+
96
+ Apache-2.0 (changed from MIT in earlier internal builds — aligns with
97
+ the chipzen-sdk repo's root LICENSE).
@@ -0,0 +1,115 @@
1
+ # IP protection — what shipping a Cython-compiled bot does and doesn't do
2
+
3
+ The Python starter at
4
+ [`starters/python/`](starters/python/) ships a multi-stage Dockerfile
5
+ that compiles `bot.py` to a Cython `.so` module in a builder stage,
6
+ then copies only that compiled binary into the runtime image.
7
+
8
+ This is the **alpha-tier IP-protection recipe**. Anything stronger is
9
+ on the future-hardening list (see the bottom of this file).
10
+
11
+ ## What this protects against
12
+
13
+ - **Casual source disclosure.** Anyone who somehow obtains read access
14
+ to your image (e.g., a misconfigured backup, a leaked tarball) can
15
+ no longer `cat bot.py` to see your strategy. The `.py` source is
16
+ discarded in the builder stage and never enters the runtime image.
17
+ - **Direct copy-paste forks.** A compromised image can't be
18
+ re-uploaded as-is by a different account because the published
19
+ contents are obfuscated enough that the next reviewer would ask
20
+ questions. Not a hard guarantee, but a friction layer.
21
+ - **Trivial introspection from inside a running container.** Even if
22
+ an attacker gains code execution inside your bot's container during
23
+ a match, they can't read your strategy directly — they'd be reading
24
+ C-extension memory, not Python source.
25
+
26
+ ## What this does NOT protect against
27
+
28
+ - **Determined reverse engineering.** Cython compiles Python to C and
29
+ then to a `.so`. Decompilation is harder than reading Python source
30
+ but absolutely possible with disassemblers (Ghidra, Hex-Rays). A
31
+ motivated attacker with infinite time can recover your algorithm.
32
+ Treat this as "raises the cost", not "makes it impossible".
33
+ - **The Chipzen platform owner.** The platform stores your uploaded
34
+ image in its own infrastructure. The platform owner can technically
35
+ inspect what you uploaded. This SDK assumes you trust the platform
36
+ with your image; if you don't, this Dockerfile won't help you.
37
+ - **Side-channel leakage from observed gameplay.** Opponents who play
38
+ against your bot at the table will infer aspects of your strategy
39
+ from its actions, regardless of how the source was packaged. Bet
40
+ sizing, timing, action distributions, and showdown information are
41
+ all visible to opponents and the platform.
42
+ - **The `requirements.txt` you ship.** Your dependency list is shipped
43
+ in the runtime image as plain text. If you depend on a unique
44
+ combination of solver / model libraries, the requirements.txt is a
45
+ meaningful tell. Strip it from the runtime image (after `pip install`
46
+ succeeds in the builder stage) if this matters to you.
47
+
48
+ ## Why this is sufficient for alpha
49
+
50
+ The Chipzen platform's posture (see
51
+ [`../../SECURITY.md`](../../SECURITY.md#bot-runtime--what-the-platform-enforces-on-uploaded-bots)
52
+ for the full version):
53
+
54
+ - Uploaded bot images go directly to platform-controlled storage,
55
+ encrypted at rest.
56
+ - No public access to bot images.
57
+ - Bot containers run with strict network egress controls — your
58
+ competitors can't pull your image while a match is running.
59
+
60
+ Combined, the practical threat model for an alpha bot author is
61
+ "casual access via an unexpected leak" rather than "well-resourced
62
+ adversary with disassembler". Cython compilation handles the former.
63
+
64
+ ## How the recipe works (step by step)
65
+
66
+ ```
67
+ Stage 1 (builder):
68
+ - python:3.12-slim @ <pinned digest>
69
+ - pip install cython==3.0.* setuptools
70
+ - COPY bot.py
71
+ - cythonize -i bot.py # produces bot.cpython-312-<arch>-linux-gnu.so
72
+ - rm bot.py # remove the source so stage 2 cannot copy it
73
+
74
+ Stage 2 (runtime):
75
+ - python:3.12-slim @ <same pinned digest>
76
+ - PYTHONUNBUFFERED=1, no .pyc emission, no pip cache
77
+ - pip install -r requirements.txt
78
+ - strip /usr/local/lib/python3.12/**/__pycache__ and **/tests
79
+ - COPY --from=builder /build/*.so /bot/
80
+ - non-root user (uid 10001)
81
+ - ENTRYPOINT ["python", "-c", "from bot import main; main()"]
82
+ ```
83
+
84
+ The `from bot import main` form works because Python's standard
85
+ import system finds `bot.cpython-312-<arch>-linux-gnu.so` and loads
86
+ it as the module named `bot`. The `main()` callable inside the
87
+ compiled module is whatever you defined in your `bot.py` before
88
+ compilation.
89
+
90
+ ## Build-time / runtime Python ABI compatibility
91
+
92
+ Cython output is ABI-specific. The builder and runtime stages must
93
+ use the **same Python version + platform**. This Dockerfile pins
94
+ both stages to identical `python:3.12-slim` digests so the ABI line
95
+ up. If you change one, change both.
96
+
97
+ If you want to ship for multiple Python versions or architectures
98
+ (e.g., arm64 for Apple Silicon devs running locally), use Docker
99
+ Buildx with `--platform=linux/amd64,linux/arm64` and a Dockerfile
100
+ template that parameterizes the digest per platform.
101
+
102
+ ## Future hardening (not in alpha)
103
+
104
+ The implementation plan calls these out as follow-ups, not blockers:
105
+
106
+ - **Nuitka** instead of Cython for stronger optimization + harder
107
+ reverse engineering. Larger binaries, longer build times.
108
+ - **PyArmor** obfuscation as a layer on top of Cython for
109
+ resistance against the easy decompilation paths.
110
+ - **Encrypted-at-rest module loading** — the bot decrypts itself at
111
+ runtime using a per-match key the platform injects at launch. Adds
112
+ startup latency and requires platform-side coordination.
113
+ - **ELF binary stripping** of the Cython output (`strip --strip-all`
114
+ on the `.so`) to remove debug symbols and harden against quick
115
+ symbol-table inspection. Easy to add when the platform supports it.
@@ -0,0 +1,55 @@
1
+ .PHONY: install dev lint format test build clean
2
+
3
+ ## Install the SDK in the current environment
4
+ install:
5
+ pip install .
6
+
7
+ ## Install with development dependencies
8
+ dev:
9
+ pip install -e ".[dev]"
10
+
11
+ ## Run linter (ruff check)
12
+ lint:
13
+ ruff check src/ tests/
14
+
15
+ ## Auto-format code
16
+ format:
17
+ ruff format src/ tests/
18
+
19
+ ## Run the test suite
20
+ test:
21
+ pytest tests/ -v
22
+
23
+ ## Run tests with coverage
24
+ coverage:
25
+ pytest tests/ -v --cov=chipzen --cov-report=term-missing
26
+
27
+ ## Build distribution packages
28
+ build:
29
+ python -m build
30
+
31
+ ## Remove build artifacts
32
+ clean:
33
+ rm -rf dist/ build/ *.egg-info src/*.egg-info
34
+ find . -type d -name __pycache__ -exec rm -rf {} + 2>/dev/null || true
35
+ find . -type f -name "*.pyc" -delete 2>/dev/null || true
36
+
37
+ ## Validate that the scaffolded bot template passes checks
38
+ validate-template:
39
+ @tmpdir=$$(mktemp -d) && \
40
+ chipzen-sdk init test_bot --dir "$$tmpdir" && \
41
+ chipzen-sdk validate "$$tmpdir/test_bot" && \
42
+ rm -rf "$$tmpdir"
43
+
44
+ ## Show help
45
+ help:
46
+ @echo "Available targets:"
47
+ @echo " install Install the SDK"
48
+ @echo " dev Install with dev dependencies"
49
+ @echo " lint Run ruff linter"
50
+ @echo " format Auto-format code"
51
+ @echo " test Run test suite"
52
+ @echo " coverage Run tests with coverage"
53
+ @echo " build Build distribution packages"
54
+ @echo " clean Remove build artifacts"
55
+ @echo " validate-template Validate the scaffolded bot template"
@@ -0,0 +1,130 @@
1
+ Metadata-Version: 2.4
2
+ Name: chipzen-bot
3
+ Version: 0.2.0
4
+ Summary: Build, test, and deploy poker bots for the Chipzen AI competition platform
5
+ Project-URL: Homepage, https://chipzen.ai
6
+ Project-URL: Documentation, https://chipzen.ai/docs/sdk
7
+ Project-URL: Repository, https://github.com/chipzen-ai/chipzen-sdk
8
+ Project-URL: Issues, https://github.com/chipzen-ai/chipzen-sdk/issues
9
+ Project-URL: Changelog, https://github.com/chipzen-ai/chipzen-sdk/blob/main/packages/python/CHANGELOG.md
10
+ Author-email: "Chipzen, Inc." <support@chipzen.ai>
11
+ License-Expression: Apache-2.0
12
+ Keywords: ai,bot,chipzen,competition,poker,sdk
13
+ Classifier: Development Status :: 3 - Alpha
14
+ Classifier: Intended Audience :: Developers
15
+ Classifier: License :: OSI Approved :: Apache Software License
16
+ Classifier: Programming Language :: Python :: 3
17
+ Classifier: Programming Language :: Python :: 3.10
18
+ Classifier: Programming Language :: Python :: 3.11
19
+ Classifier: Programming Language :: Python :: 3.12
20
+ Classifier: Programming Language :: Python :: 3.13
21
+ Classifier: Topic :: Games/Entertainment
22
+ Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
23
+ Classifier: Typing :: Typed
24
+ Requires-Python: >=3.10
25
+ Requires-Dist: websockets>=12.0
26
+ Provides-Extra: dev
27
+ Requires-Dist: hypothesis>=6.100.0; extra == 'dev'
28
+ Requires-Dist: pytest-asyncio>=0.24.0; extra == 'dev'
29
+ Requires-Dist: pytest>=7.0; extra == 'dev'
30
+ Requires-Dist: ruff>=0.5.0; extra == 'dev'
31
+ Description-Content-Type: text/markdown
32
+
33
+ # chipzen-bot
34
+
35
+ > [!WARNING]
36
+ > **Alpha software.** This SDK is in active development; the public
37
+ > API may change between minor versions before 1.0. Pin to a specific
38
+ > version in production. Report issues at
39
+ > [chipzen-ai/chipzen-sdk/issues](https://github.com/chipzen-ai/chipzen-sdk/issues).
40
+
41
+ The Python adapter for the [Chipzen](https://chipzen.ai) AI poker
42
+ competition platform. Wraps the WebSocket protocol so your bot only
43
+ has to implement `decide(state) -> action`, and ships a `validate`
44
+ CLI that confirms your bot will be accepted by the upload pipeline.
45
+
46
+ ## Install
47
+
48
+ ```bash
49
+ pip install chipzen-bot
50
+ ```
51
+
52
+ Python 3.10+ is supported. The runtime dependency is a single package
53
+ (`websockets`); your bot can pull in whatever else it needs (numpy,
54
+ torch, etc.) on top.
55
+
56
+ ## Minimal bot
57
+
58
+ ```python
59
+ from chipzen import Bot, Action, GameState
60
+
61
+ class MyBot(Bot):
62
+ def decide(self, state: GameState) -> Action:
63
+ if "check" in state.valid_actions:
64
+ return Action.check()
65
+ return Action.fold()
66
+
67
+ if __name__ == "__main__":
68
+ MyBot().run()
69
+ ```
70
+
71
+ The SDK handles the Layer-1 transport handshake, Layer-2 game-state
72
+ parsing, ping/pong, request-id echoing, `action_rejected` retries,
73
+ and reconnect. Subclass `Bot`, override `decide()`, return an
74
+ `Action`. That's the entire surface for a working bot.
75
+
76
+ Lifecycle hooks (`on_match_start`, `on_round_start`, `on_phase_change`,
77
+ `on_turn_result`, `on_round_result`, `on_match_end`) are optional —
78
+ override them if you need to maintain per-match or per-hand state
79
+ between turns.
80
+
81
+ ## CLI
82
+
83
+ The `chipzen-sdk` CLI is installed alongside the Python package:
84
+
85
+ | Command | Purpose |
86
+ |---|---|
87
+ | `chipzen-sdk init <name>` | Scaffold a new bot project from a starter template. |
88
+ | `chipzen-sdk validate <path>` | Run the same checks the upload pipeline runs (size, imports, sandbox-blocked modules, decide() timeout sniff). The supported go/no-go before docker packaging. |
89
+
90
+ Run `chipzen-sdk <command> --help` for the full option list per command.
91
+
92
+ ## What the SDK is for (and what it isn't)
93
+
94
+ The SDK does three things and nothing else:
95
+
96
+ 1. **Protocol adapter** — your bot doesn't hand-roll WebSockets.
97
+ 2. **`chipzen-sdk validate`** — pre-upload conformance check.
98
+ 3. **(Forthcoming) IP-protected Dockerfile recipe** — Cython
99
+ multi-stage build that produces an image containing only compiled
100
+ `.so` files, not your `.py` source.
101
+
102
+ It does **not** include a local match simulator, hand evaluator, or
103
+ opponent pool. Bot strength testing happens after upload; the platform
104
+ runs comprehensive bot-vs-bot evaluation as part of the submission
105
+ pipeline. If you want fast local iteration, write your own profiling
106
+ harness that calls your `Bot.decide()` directly with recorded
107
+ `GameState` objects.
108
+
109
+ ## Reference
110
+
111
+ Full developer documentation lives in the [chipzen-sdk
112
+ repo](https://github.com/chipzen-ai/chipzen-sdk):
113
+
114
+ - [DEV-MANUAL](https://github.com/chipzen-ai/chipzen-sdk/blob/main/docs/DEV-MANUAL.md)
115
+ — SDK reference, lifecycle hooks, performance budgets, container
116
+ contract, troubleshooting.
117
+ - [QUICKSTART](https://github.com/chipzen-ai/chipzen-sdk/blob/main/docs/QUICKSTART.md)
118
+ — write a bot, validate it, package it (~10 minutes).
119
+ - [Protocol spec](https://github.com/chipzen-ai/chipzen-sdk/tree/main/docs/protocol)
120
+ — Layer 1 (Transport) + Layer 2 (Poker game state). Authoritative.
121
+ - [Bot runtime security model](https://github.com/chipzen-ai/chipzen-sdk/blob/main/SECURITY.md)
122
+ — what the platform enforces on uploaded bots (sandbox, network
123
+ egress, resource limits).
124
+
125
+ Per-package quickstart: [QUICKSTART.md](QUICKSTART.md).
126
+
127
+ ## License
128
+
129
+ Apache-2.0. See the [LICENSE](https://github.com/chipzen-ai/chipzen-sdk/blob/main/LICENSE)
130
+ file in the repo.
@@ -0,0 +1,75 @@
1
+ # chipzen-bot quickstart
2
+
3
+ The Python-specific path. For the broader story (Docker, upload, debugging on the platform) see the [top-level QUICKSTART](https://github.com/chipzen-ai/chipzen-sdk/blob/main/docs/QUICKSTART.md).
4
+
5
+ ## 1. Install
6
+
7
+ ```bash
8
+ pip install chipzen-bot
9
+ ```
10
+
11
+ Python 3.10+. One runtime dependency (`websockets`).
12
+
13
+ ## 2. Scaffold a bot project
14
+
15
+ ```bash
16
+ chipzen-sdk init my_bot
17
+ cd my_bot
18
+ ```
19
+
20
+ You'll get a small project with `main.py`, `requirements.txt`, and a Dockerfile.
21
+
22
+ ## 3. Implement your strategy
23
+
24
+ Open `main.py`. The default scaffold gives you a `MyBot(Bot)` subclass
25
+ with a no-op `decide()`. Replace it with your strategy:
26
+
27
+ ```python
28
+ from chipzen import Bot, Action, GameState
29
+
30
+ class MyBot(Bot):
31
+ def decide(self, state: GameState) -> Action:
32
+ # Your strategy. The SDK has already handed you a fully-parsed
33
+ # GameState (hole cards, board, pot, valid_actions, etc.) and
34
+ # is waiting on a single Action in return.
35
+ if "check" in state.valid_actions:
36
+ return Action.check()
37
+ return Action.fold()
38
+ ```
39
+
40
+ The full `GameState` and `Action` surfaces are documented in the
41
+ [DEV-MANUAL §2.3 / §2.4](https://github.com/chipzen-ai/chipzen-sdk/blob/main/docs/DEV-MANUAL.md#23-gamestate).
42
+
43
+ ## 4. Validate before packaging
44
+
45
+ ```bash
46
+ chipzen-sdk validate .
47
+ ```
48
+
49
+ Runs the same checks the upload pipeline runs: artifact size, syntax,
50
+ imports against the platform's sandbox-blocked module list, presence
51
+ of a `Bot` subclass with a `decide()` method, a `decide()` timeout
52
+ sniff, and a smoke instantiation. Exits non-zero on any failure.
53
+
54
+ This is the **supported go/no-go** before you build a container image.
55
+ A clean validate means "the upload pipeline will accept this on
56
+ protocol grounds" — not "your bot is good".
57
+
58
+ ## 5. Package and upload
59
+
60
+ The Docker build + upload steps are the same across all SDK languages.
61
+ See the [top-level QUICKSTART](https://github.com/chipzen-ai/chipzen-sdk/blob/main/docs/QUICKSTART.md)
62
+ from step 5 onwards.
63
+
64
+ ## Where to go next
65
+
66
+ - **Lifecycle hooks** (`on_match_start`, `on_round_start`,
67
+ `on_phase_change`, `on_turn_result`, `on_round_result`,
68
+ `on_match_end`) for per-match / per-hand state tracking — see
69
+ [DEV-MANUAL §2.2](https://github.com/chipzen-ai/chipzen-sdk/blob/main/docs/DEV-MANUAL.md#22-bot-lifecycle-hooks).
70
+ - **Performance budgets** (per-tier decision timeouts, queue drain
71
+ pitfalls) — see
72
+ [DEV-MANUAL §6](https://github.com/chipzen-ai/chipzen-sdk/blob/main/docs/DEV-MANUAL.md#6-performance).
73
+ - **Bot runtime security model** (sandbox, network egress, resource
74
+ limits) — see
75
+ [SECURITY.md](https://github.com/chipzen-ai/chipzen-sdk/blob/main/SECURITY.md#bot-runtime--what-the-platform-enforces-on-uploaded-bots).
@@ -0,0 +1,98 @@
1
+ # chipzen-bot
2
+
3
+ > [!WARNING]
4
+ > **Alpha software.** This SDK is in active development; the public
5
+ > API may change between minor versions before 1.0. Pin to a specific
6
+ > version in production. Report issues at
7
+ > [chipzen-ai/chipzen-sdk/issues](https://github.com/chipzen-ai/chipzen-sdk/issues).
8
+
9
+ The Python adapter for the [Chipzen](https://chipzen.ai) AI poker
10
+ competition platform. Wraps the WebSocket protocol so your bot only
11
+ has to implement `decide(state) -> action`, and ships a `validate`
12
+ CLI that confirms your bot will be accepted by the upload pipeline.
13
+
14
+ ## Install
15
+
16
+ ```bash
17
+ pip install chipzen-bot
18
+ ```
19
+
20
+ Python 3.10+ is supported. The runtime dependency is a single package
21
+ (`websockets`); your bot can pull in whatever else it needs (numpy,
22
+ torch, etc.) on top.
23
+
24
+ ## Minimal bot
25
+
26
+ ```python
27
+ from chipzen import Bot, Action, GameState
28
+
29
+ class MyBot(Bot):
30
+ def decide(self, state: GameState) -> Action:
31
+ if "check" in state.valid_actions:
32
+ return Action.check()
33
+ return Action.fold()
34
+
35
+ if __name__ == "__main__":
36
+ MyBot().run()
37
+ ```
38
+
39
+ The SDK handles the Layer-1 transport handshake, Layer-2 game-state
40
+ parsing, ping/pong, request-id echoing, `action_rejected` retries,
41
+ and reconnect. Subclass `Bot`, override `decide()`, return an
42
+ `Action`. That's the entire surface for a working bot.
43
+
44
+ Lifecycle hooks (`on_match_start`, `on_round_start`, `on_phase_change`,
45
+ `on_turn_result`, `on_round_result`, `on_match_end`) are optional —
46
+ override them if you need to maintain per-match or per-hand state
47
+ between turns.
48
+
49
+ ## CLI
50
+
51
+ The `chipzen-sdk` CLI is installed alongside the Python package:
52
+
53
+ | Command | Purpose |
54
+ |---|---|
55
+ | `chipzen-sdk init <name>` | Scaffold a new bot project from a starter template. |
56
+ | `chipzen-sdk validate <path>` | Run the same checks the upload pipeline runs (size, imports, sandbox-blocked modules, decide() timeout sniff). The supported go/no-go before docker packaging. |
57
+
58
+ Run `chipzen-sdk <command> --help` for the full option list per command.
59
+
60
+ ## What the SDK is for (and what it isn't)
61
+
62
+ The SDK does three things and nothing else:
63
+
64
+ 1. **Protocol adapter** — your bot doesn't hand-roll WebSockets.
65
+ 2. **`chipzen-sdk validate`** — pre-upload conformance check.
66
+ 3. **(Forthcoming) IP-protected Dockerfile recipe** — Cython
67
+ multi-stage build that produces an image containing only compiled
68
+ `.so` files, not your `.py` source.
69
+
70
+ It does **not** include a local match simulator, hand evaluator, or
71
+ opponent pool. Bot strength testing happens after upload; the platform
72
+ runs comprehensive bot-vs-bot evaluation as part of the submission
73
+ pipeline. If you want fast local iteration, write your own profiling
74
+ harness that calls your `Bot.decide()` directly with recorded
75
+ `GameState` objects.
76
+
77
+ ## Reference
78
+
79
+ Full developer documentation lives in the [chipzen-sdk
80
+ repo](https://github.com/chipzen-ai/chipzen-sdk):
81
+
82
+ - [DEV-MANUAL](https://github.com/chipzen-ai/chipzen-sdk/blob/main/docs/DEV-MANUAL.md)
83
+ — SDK reference, lifecycle hooks, performance budgets, container
84
+ contract, troubleshooting.
85
+ - [QUICKSTART](https://github.com/chipzen-ai/chipzen-sdk/blob/main/docs/QUICKSTART.md)
86
+ — write a bot, validate it, package it (~10 minutes).
87
+ - [Protocol spec](https://github.com/chipzen-ai/chipzen-sdk/tree/main/docs/protocol)
88
+ — Layer 1 (Transport) + Layer 2 (Poker game state). Authoritative.
89
+ - [Bot runtime security model](https://github.com/chipzen-ai/chipzen-sdk/blob/main/SECURITY.md)
90
+ — what the platform enforces on uploaded bots (sandbox, network
91
+ egress, resource limits).
92
+
93
+ Per-package quickstart: [QUICKSTART.md](QUICKSTART.md).
94
+
95
+ ## License
96
+
97
+ Apache-2.0. See the [LICENSE](https://github.com/chipzen-ai/chipzen-sdk/blob/main/LICENSE)
98
+ file in the repo.