@holdem-api/holdem-sdk 0.1.0 → 0.1.1
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.
- package/README.md +82 -2
- package/package.json +2 -3
package/README.md
CHANGED
|
@@ -2,6 +2,69 @@
|
|
|
2
2
|
|
|
3
3
|
Server-side JavaScript/TypeScript client for Node.js 20+. Zero runtime dependencies, ESM and TypeScript declarations. All requests use `POST /api/actions`.
|
|
4
4
|
|
|
5
|
+
## Install
|
|
6
|
+
|
|
7
|
+
In your **backend/server project** (for Blitzfold, use `blitzfold-server`):
|
|
8
|
+
|
|
9
|
+
```sh
|
|
10
|
+
npm install @holdem-api/holdem-sdk
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
No repository clone, local archive, or SDK build step is required. Node.js 20+ is required. The package is ESM-only. JavaScript `.mjs` files can import it directly. CommonJS applications can use native `await import('@holdem-api/holdem-sdk')` inside an async function; TypeScript compiling to CommonJS must preserve that native import rather than rewriting it to require().
|
|
14
|
+
|
|
15
|
+
Verify installation without an API key or network request:
|
|
16
|
+
|
|
17
|
+
```sh
|
|
18
|
+
node --input-type=module -e "import { HoldemClient, RangeStore } from '@holdem-api/holdem-sdk'; console.log('SDK ready:', typeof HoldemClient, typeof RangeStore)"
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
Expected output: `SDK ready: function function`.
|
|
22
|
+
|
|
23
|
+
## Configure your API access
|
|
24
|
+
|
|
25
|
+
Obtain a Holdem API key and the origin of the API deployment you are authorized to use. Installing this package does not create an API account, provision a server, or include credentials. Configure these variables on your backend:
|
|
26
|
+
|
|
27
|
+
```dotenv
|
|
28
|
+
HOLDEM_API_KEY=your_api_key
|
|
29
|
+
HOLDEM_API_URL=https://your-api-host.example
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
Replace the example host with your actual deployment origin, without `/api`. Keep `.env` out of version control. Node 20.6+ can load it using `node --env-file=.env your-script.mjs`; on earlier Node 20 versions set environment variables in your shell or use your application's environment loader. Never put the key in browser code.
|
|
33
|
+
|
|
34
|
+
## First live request
|
|
35
|
+
|
|
36
|
+
Save this as `holdem-smoke.mjs` in the project where you installed the SDK:
|
|
37
|
+
|
|
38
|
+
```js
|
|
39
|
+
import { readFile } from 'node:fs/promises'
|
|
40
|
+
import { HoldemClient } from '@holdem-api/holdem-sdk'
|
|
41
|
+
|
|
42
|
+
const { HOLDEM_API_KEY: apiKey, HOLDEM_API_URL: baseUrl } = process.env
|
|
43
|
+
if (!apiKey || !baseUrl || !process.argv[2]) {
|
|
44
|
+
throw new Error('Set HOLDEM_API_KEY and HOLDEM_API_URL; supply a request JSON file')
|
|
45
|
+
}
|
|
46
|
+
const client = new HoldemClient({ apiKey, baseUrl })
|
|
47
|
+
const request = JSON.parse(await readFile(process.argv[2], 'utf8'))
|
|
48
|
+
const result = await client.actions(request)
|
|
49
|
+
console.log({
|
|
50
|
+
chosenAction: result.chosenAction,
|
|
51
|
+
probabilities: result.output,
|
|
52
|
+
equity: result.equity,
|
|
53
|
+
expectedValues: result.expectedValues,
|
|
54
|
+
rangeCount: Object.keys(result.range).length,
|
|
55
|
+
})
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
Export a real pre-decision game state using the policy encoding below into `actions-request.json`, with top-level `{ "hand": "AsAh", "policy": { "schemaVersion": "holdem-public-board-joint-v1", "context": [...], "history": [...], "legalMask": [0,1,1] } }`. The ellipses describe encoder output; replace them with actual arrays. Do not use made-up features or an empty context. Then run:
|
|
59
|
+
|
|
60
|
+
```sh
|
|
61
|
+
node --env-file=.env holdem-smoke.mjs actions-request.json
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
This makes one live request and may consume API quota. It does not execute an action in your game. If this fails, 401/403 indicates an access/authentication issue; 400 indicates invalid input; 502/503 can indicate unavailable equity/model services. Inspect the SDK error status and your API configuration.
|
|
65
|
+
|
|
66
|
+
## Integrate decisions and track ranges
|
|
67
|
+
|
|
5
68
|
```ts
|
|
6
69
|
import { HoldemClient, RangeStore } from '@holdem-api/holdem-sdk'
|
|
7
70
|
import type { PublicPolicy } from '@holdem-api/holdem-sdk'
|
|
@@ -51,7 +114,7 @@ Supply the exact public encoder output as `policy`: schemaVersion `holdem-public
|
|
|
51
114
|
|
|
52
115
|
`HoldemValidationError` rejects local invalid input before sending. `HoldemApiError` includes status and body. `HoldemResponseError` rejects malformed successful responses. `HoldemTransportError` wraps network, timeout and cancellation failures. Methods accept `{signal}` as the second argument. Default timeout is 60 seconds and covers body reading. No automatic retries. Keys use `x-api-key`; keep credentials on your backend.
|
|
53
116
|
|
|
54
|
-
##
|
|
117
|
+
## SDK maintainers: build and publish
|
|
55
118
|
|
|
56
119
|
```sh
|
|
57
120
|
npm ci
|
|
@@ -69,4 +132,21 @@ The package is configured for public publication as `@holdem-api/holdem-sdk` und
|
|
|
69
132
|
|
|
70
133
|
Do not put credentials in source or the package. Before publishing another release, bump the version with `npm version patch` (requires a clean git checkout) or edit the version and update the lockfile.
|
|
71
134
|
|
|
72
|
-
|
|
135
|
+
## Public policy encoding reference
|
|
136
|
+
|
|
137
|
+
The SDK accepts encoded public features; it does not reconstruct betting state. Use consistent seat IDs 0�8 throughout a hand. Cards are indexed by `rankIndex * 4 + suitIndex`, ranks `23456789TJQKA`, suits `cdhs`. Street indexes are preflop=0, flop=1, turn=2, river=3. A one-hot block has exactly one 1; an empty board slot is all zeros. Board slots retain deal order. All amounts below are BB unless a count is specified; scale amounts/counts using `log1p(max(0,x))/log1p(400)`.
|
|
138
|
+
|
|
139
|
+
| Context indexes | Encoding |
|
|
140
|
+
| --- | --- |
|
|
141
|
+
| 0�259 | Five ordered 52-value board one-hot slots |
|
|
142
|
+
| 260�268 | Actor seat one-hot |
|
|
143
|
+
| 269�272 | Street one-hot |
|
|
144
|
+
| 273�278 | Scaled pot, facing amount, call payment, min raise-to, max raise-to, number of seats |
|
|
145
|
+
| 279�314 | Nine seat records: present flag, scaled remaining stack, scaled current-street contribution, active flag; absent seats have four zeros |
|
|
146
|
+
| 315 | Remaining active opponent count divided by 9 |
|
|
147
|
+
|
|
148
|
+
Each history event has 32 values: actor seat one-hot (9), street one-hot (4), action one-hot (6, ordered posts/folds/checks/calls/bets/raises), four scaled values (payment added, raise-to or 0, live post or 0, dead post or 0), and nine scaled refund amounts indexed by seat. Sum multiple refunds to the same seat after the event before scaling. History must contain all actual preceding events in order, across streets, excluding the current decision. Send no artificial padding; empty history is supported. Maximum history length is 512. LegalMask is `[fold, passive, aggressive]` derived from actual engine legality, with only 0/1 values and at least one allowed action. Do not include opponents' private cards or future events. Encode call payment, contributions, and raise limits from actual engine state; do not infer them from incomplete logs.
|
|
149
|
+
|
|
150
|
+
## Blitzfold migration checklist
|
|
151
|
+
|
|
152
|
+
Install in the server. Replace the `/api/equity_actions` request with `client.actions(payload)` using the existing public encoder. Preserve the full response, including `range`; remove any code deleting it. Use `chosenAction` directly instead of sampling the action category a second time. Sample only the conditional size after aggression and enforce engine legality. Commit the actor range only after that same category executes successfully; reject stale hand/turn responses and clear completed hands. Select optional player styles locally and send them with the request, so decisions need only `/api/actions`. Keep error/cooldown handling and the game's timeout budget. Verify both the development runner and the compiled server can load this ESM package.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@holdem-api/holdem-sdk",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.1",
|
|
4
4
|
"description": "Typed server-side client for Holdem API",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -21,8 +21,7 @@
|
|
|
21
21
|
"scripts": {
|
|
22
22
|
"build": "tsc -p tsconfig.json",
|
|
23
23
|
"typecheck": "tsc -p tsconfig.json --noEmit",
|
|
24
|
-
"test": "npm run build && node --test test/client.test.mjs"
|
|
25
|
-
"prepack": "npm run build"
|
|
24
|
+
"test": "npm run build && node --test test/client.test.mjs"
|
|
26
25
|
},
|
|
27
26
|
"devDependencies": {
|
|
28
27
|
"typescript": "5.7.3"
|