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.
- chipzen_bot-0.2.0/.gitignore +58 -0
- chipzen_bot-0.2.0/CHANGELOG.md +97 -0
- chipzen_bot-0.2.0/IP-PROTECTION.md +115 -0
- chipzen_bot-0.2.0/Makefile +55 -0
- chipzen_bot-0.2.0/PKG-INFO +130 -0
- chipzen_bot-0.2.0/QUICKSTART.md +75 -0
- chipzen_bot-0.2.0/README.md +98 -0
- chipzen_bot-0.2.0/RELEASING.md +124 -0
- chipzen_bot-0.2.0/pyproject.toml +67 -0
- chipzen_bot-0.2.0/src/chipzen/__init__.py +20 -0
- chipzen_bot-0.2.0/src/chipzen/__main__.py +55 -0
- chipzen_bot-0.2.0/src/chipzen/bot.py +148 -0
- chipzen_bot-0.2.0/src/chipzen/client.py +440 -0
- chipzen_bot-0.2.0/src/chipzen/conformance.py +357 -0
- chipzen_bot-0.2.0/src/chipzen/examples/__init__.py +1 -0
- chipzen_bot-0.2.0/src/chipzen/examples/call_bot.py +22 -0
- chipzen_bot-0.2.0/src/chipzen/examples/random_bot.py +30 -0
- chipzen_bot-0.2.0/src/chipzen/examples/tight_aggressive.py +53 -0
- chipzen_bot-0.2.0/src/chipzen/models.py +316 -0
- chipzen_bot-0.2.0/src/chipzen/scaffold.py +190 -0
- chipzen_bot-0.2.0/src/chipzen/validate.py +711 -0
- chipzen_bot-0.2.0/starters/python/.dockerignore +51 -0
- chipzen_bot-0.2.0/starters/python/Dockerfile +80 -0
- chipzen_bot-0.2.0/starters/python/README.md +55 -0
- chipzen_bot-0.2.0/starters/python/bot.py +61 -0
- chipzen_bot-0.2.0/starters/python/requirements.txt +1 -0
- chipzen_bot-0.2.0/tests/conftest.py +7 -0
- chipzen_bot-0.2.0/tests/test_cli.py +128 -0
- chipzen_bot-0.2.0/tests/test_client.py +547 -0
- chipzen_bot-0.2.0/tests/test_conformance.py +161 -0
- chipzen_bot-0.2.0/tests/test_integration.py +122 -0
- chipzen_bot-0.2.0/tests/test_models.py +139 -0
- chipzen_bot-0.2.0/tests/test_models_property.py +196 -0
- chipzen_bot-0.2.0/tests/test_python_starter.py +105 -0
- chipzen_bot-0.2.0/tests/test_reference_bot.py +313 -0
- chipzen_bot-0.2.0/tests/test_scaffold.py +68 -0
- 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.
|