{"_id":"@drvillo/moltpoker-agents","_rev":"7-1c166d292e289e207fb1f8bbceb16b52","name":"@drvillo/moltpoker-agents","dist-tags":{"latest":"0.2.6"},"versions":{"0.2.0":{"name":"@drvillo/moltpoker-agents","version":"0.2.0","_id":"@drvillo/moltpoker-agents@0.2.0","maintainers":[{"name":"drvillo","email":"f.vivoli@gmail.com"}],"bin":{"molt-agent":"dist/cli.js"},"dist":{"shasum":"ed972d9591109f8cb104309945e4e6d1624bbd99","tarball":"https://registry.npmjs.org/@drvillo/moltpoker-agents/-/moltpoker-agents-0.2.0.tgz","fileCount":120,"integrity":"sha512-3bG/araRAqdllFdMXxaFpQ3quJPFLqQFlLeJ4y+taE2klusniX4JmvsUz5d2Q4M2IhukvhXJ2UP0K27Ah2zZsg==","signatures":[{"sig":"MEUCIHBIW9NAVZL1cWmXKnDRaQ13k7lnhULMzVYuwPrWDklXAiEApnX9qBuIAq2rkhNL1jRpiO+K8gauDX8kYRX9U4Ciwnc=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":432510},"main":"./dist/index.js","type":"module","_from":"file:drvillo-moltpoker-agents-0.2.0.tgz","types":"./dist/index.d.ts","exports":{".":{"types":"./src/index.ts","import":"./dist/index.js","development":"./src/index.ts"}},"scripts":{"test":"vitest run","agent":"node dist/cli.js","build":"tsc","clean":"rm -rf dist","dev:agent":"tsx src/cli.ts","typecheck":"tsc --noEmit","test:watch":"vitest"},"_npmUser":{"name":"drvillo","email":"f.vivoli@gmail.com"},"_resolved":"/private/var/folders/0z/4k6_4lnn4yvct1vk5m96c4fc0000gp/T/c3fe54dc7491f2dc51ce71a7d170b329/drvillo-moltpoker-agents-0.2.0.tgz","_integrity":"sha512-3bG/araRAqdllFdMXxaFpQ3quJPFLqQFlLeJ4y+taE2klusniX4JmvsUz5d2Q4M2IhukvhXJ2UP0K27Ah2zZsg==","_npmVersion":"11.6.2","description":"Reference poker agents for MoltPoker","directories":{},"_nodeVersion":"25.2.1","dependencies":{"ai":"^6.0.73","zod":"^3.25.76","dotenv":"^16.6.1","commander":"^11.1.0","gray-matter":"^4.0.3","@ai-sdk/openai":"^3.0.25","@ai-sdk/anthropic":"^3.0.37","@drvillo/moltpoker-sdk":"0.2.0","unique-names-generator":"^4.7.1","@drvillo/moltpoker-poker":"0.2.0","@drvillo/moltpoker-shared":"0.2.0","@jmespath-community/jmespath":"^1.3.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"tsx":"^4.21.0","typescript":"^5.3.3"},"_npmOperationalInternal":{"tmp":"tmp/moltpoker-agents_0.2.0_1771849429497_0.5613983020629245","host":"s3://npm-registry-packages-npm-production"}},"0.2.1":{"name":"@drvillo/moltpoker-agents","version":"0.2.1","_id":"@drvillo/moltpoker-agents@0.2.1","maintainers":[{"name":"drvillo","email":"f.vivoli@gmail.com"}],"bin":{"molt-agent":"dist/cli.js"},"dist":{"shasum":"e5852ac1f14f4c644a5b8c0669bcd0aa72768c11","tarball":"https://registry.npmjs.org/@drvillo/moltpoker-agents/-/moltpoker-agents-0.2.1.tgz","fileCount":120,"integrity":"sha512-1fZ7dwe3OT7AWqR0QNuWs4SOaCKqea11OvG/cWSf1St+pPAa/mFFCZlkEjEv5dAq7MEoAVgKm4WFGdKUuoPmaQ==","signatures":[{"sig":"MEYCIQDF/Z3Ofcpg9rdjjZTG4vdwDYkRJQxrXj/NYHfUtevrCQIhAM/swN5IXDoApHQH47u37/j+hKxVZKBfjVrzu+fdWfMO","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":432512},"main":"./dist/index.js","type":"module","_from":"file:drvillo-moltpoker-agents-0.2.1.tgz","types":"./dist/index.d.ts","exports":{".":{"types":"./src/index.ts","import":"./dist/index.js","development":"./src/index.ts"}},"scripts":{"test":"vitest run","agent":"node dist/cli.js","build":"tsc","clean":"rm -rf dist","dev:agent":"tsx src/cli.ts","typecheck":"tsc --noEmit","test:watch":"vitest"},"_npmUser":{"name":"drvillo","email":"f.vivoli@gmail.com"},"_resolved":"/private/var/folders/0z/4k6_4lnn4yvct1vk5m96c4fc0000gp/T/7da80e3574b2f0855bdfed99a74baeb8/drvillo-moltpoker-agents-0.2.1.tgz","_integrity":"sha512-1fZ7dwe3OT7AWqR0QNuWs4SOaCKqea11OvG/cWSf1St+pPAa/mFFCZlkEjEv5dAq7MEoAVgKm4WFGdKUuoPmaQ==","_npmVersion":"11.6.2","description":"Reference poker agents for MoltPoker","directories":{},"_nodeVersion":"25.2.1","dependencies":{"ai":"^6.0.73","zod":"^3.25.76","dotenv":"^16.6.1","commander":"^11.1.0","gray-matter":"^4.0.3","@ai-sdk/openai":"^3.0.25","@ai-sdk/anthropic":"^3.0.37","@drvillo/moltpoker-sdk":"0.2.1","unique-names-generator":"^4.7.1","@drvillo/moltpoker-poker":"^0.2.0","@drvillo/moltpoker-shared":"^0.2.0","@jmespath-community/jmespath":"^1.3.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"tsx":"^4.21.0","typescript":"^5.3.3"},"_npmOperationalInternal":{"tmp":"tmp/moltpoker-agents_0.2.1_1771921254712_0.13670274265738658","host":"s3://npm-registry-packages-npm-production"}},"0.2.2":{"name":"@drvillo/moltpoker-agents","version":"0.2.2","_id":"@drvillo/moltpoker-agents@0.2.2","maintainers":[{"name":"drvillo","email":"f.vivoli@gmail.com"}],"bin":{"molt-agent":"dist/cli.js"},"dist":{"shasum":"d1bba68caffa685d1683c366641d3ac38f1f14bf","tarball":"https://registry.npmjs.org/@drvillo/moltpoker-agents/-/moltpoker-agents-0.2.2.tgz","fileCount":120,"integrity":"sha512-RH8sk92i1HSBQ7+eRN2rShI62QUIvUwpW146PjPw7IgIU78ujQkYWWZn/D6xWlWVl1bHFmgYo01mP13Bt3Qfjw==","signatures":[{"sig":"MEUCIQCdPPZ949DZqTziWbz05jVBa4yivz2Ux0hw1mw0/ltTogIgG3HG6zwokF8S+LqNJfOJcCCXxIUy4P1lur7/WPMxiug=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":432512},"main":"./dist/index.js","type":"module","_from":"file:drvillo-moltpoker-agents-0.2.2.tgz","types":"./dist/index.d.ts","exports":{".":{"types":"./src/index.ts","import":"./dist/index.js","development":"./src/index.ts"}},"scripts":{"test":"vitest run","agent":"node dist/cli.js","build":"tsc","clean":"rm -rf dist","dev:agent":"tsx src/cli.ts","typecheck":"tsc --noEmit","test:watch":"vitest"},"_npmUser":{"name":"drvillo","email":"f.vivoli@gmail.com"},"_resolved":"/private/var/folders/0z/4k6_4lnn4yvct1vk5m96c4fc0000gp/T/c38a4277187fe7fa5aecf400e07290eb/drvillo-moltpoker-agents-0.2.2.tgz","_integrity":"sha512-RH8sk92i1HSBQ7+eRN2rShI62QUIvUwpW146PjPw7IgIU78ujQkYWWZn/D6xWlWVl1bHFmgYo01mP13Bt3Qfjw==","_npmVersion":"11.6.2","description":"Reference poker agents for MoltPoker","directories":{},"_nodeVersion":"25.2.1","dependencies":{"ai":"^6.0.73","zod":"^3.25.76","dotenv":"^16.6.1","commander":"^11.1.0","gray-matter":"^4.0.3","@ai-sdk/openai":"^3.0.25","@ai-sdk/anthropic":"^3.0.37","@drvillo/moltpoker-sdk":"0.2.2","unique-names-generator":"^4.7.1","@drvillo/moltpoker-poker":"^0.2.0","@drvillo/moltpoker-shared":"^0.2.0","@jmespath-community/jmespath":"^1.3.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"tsx":"^4.21.0","typescript":"^5.3.3"},"_npmOperationalInternal":{"tmp":"tmp/moltpoker-agents_0.2.2_1771932083128_0.09446431242018671","host":"s3://npm-registry-packages-npm-production"}},"0.2.3":{"name":"@drvillo/moltpoker-agents","version":"0.2.3","_id":"@drvillo/moltpoker-agents@0.2.3","maintainers":[{"name":"drvillo","email":"f.vivoli@gmail.com"}],"bin":{"molt-agent":"dist/cli.js"},"dist":{"shasum":"ade676060dbb44f6cf494a50e496e8112abbb6d3","tarball":"https://registry.npmjs.org/@drvillo/moltpoker-agents/-/moltpoker-agents-0.2.3.tgz","fileCount":120,"integrity":"sha512-DWUwfDDjyXVEre8BhMsSXx+ckcu9BJsgRmMxSqYvijJzWSZ0dRcJCt8myXbLzhqruFw2kLHgIuJbZnsnWQipoA==","signatures":[{"sig":"MEYCIQDcL8UmeqHYgqZnBDU0HCRA+ieZ657wd0t9Qy0+hYVKzAIhAPIFrsVnbwrCopDyDgc/0OzmDJr250wpGVm4R7BUx5WQ","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":432512},"main":"./dist/index.js","type":"module","_from":"file:drvillo-moltpoker-agents-0.2.3.tgz","types":"./dist/index.d.ts","exports":{".":{"types":"./src/index.ts","import":"./dist/index.js","development":"./src/index.ts"}},"scripts":{"test":"vitest run","agent":"node dist/cli.js","build":"tsc","clean":"rm -rf dist","dev:agent":"tsx src/cli.ts","typecheck":"tsc --noEmit","test:watch":"vitest"},"_npmUser":{"name":"drvillo","email":"f.vivoli@gmail.com"},"_resolved":"/private/var/folders/0z/4k6_4lnn4yvct1vk5m96c4fc0000gp/T/1ef41c3320b7fa725c72b0997c045b6d/drvillo-moltpoker-agents-0.2.3.tgz","_integrity":"sha512-DWUwfDDjyXVEre8BhMsSXx+ckcu9BJsgRmMxSqYvijJzWSZ0dRcJCt8myXbLzhqruFw2kLHgIuJbZnsnWQipoA==","_npmVersion":"11.6.2","description":"Reference poker agents for MoltPoker","directories":{},"_nodeVersion":"25.2.1","dependencies":{"ai":"^6.0.73","zod":"^3.25.76","dotenv":"^16.6.1","commander":"^11.1.0","gray-matter":"^4.0.3","@ai-sdk/openai":"^3.0.25","@ai-sdk/anthropic":"^3.0.37","@drvillo/moltpoker-sdk":"0.2.3","unique-names-generator":"^4.7.1","@drvillo/moltpoker-poker":"^0.2.0","@drvillo/moltpoker-shared":"^0.2.0","@jmespath-community/jmespath":"^1.3.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"tsx":"^4.21.0","typescript":"^5.3.3"},"_npmOperationalInternal":{"tmp":"tmp/moltpoker-agents_0.2.3_1771932286245_0.2744328549299424","host":"s3://npm-registry-packages-npm-production"}},"0.2.4":{"name":"@drvillo/moltpoker-agents","version":"0.2.4","_id":"@drvillo/moltpoker-agents@0.2.4","maintainers":[{"name":"drvillo","email":"f.vivoli@gmail.com"}],"bin":{"molt-agent":"dist/cli.js"},"dist":{"shasum":"59c3b72528c911a1ef0e454f8dcac8f285c8f0e4","tarball":"https://registry.npmjs.org/@drvillo/moltpoker-agents/-/moltpoker-agents-0.2.4.tgz","fileCount":120,"integrity":"sha512-YAWfxwFdchLhxlWyjYg+7tsK6NUH+0ZxOXnIBYQIBcUMpGvlodiAG6YDyHs+U+toS1PucAiTKRRvjnO/tSAGlA==","signatures":[{"sig":"MEYCIQCCIubGyZTG/AUoEV1dNdu3vbppgQ36RewCcYEs1inYQwIhAKQeNVBWZfiUyFXzdj5IOphWsfFCvsmynoRcto6qJqmf","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":432515},"main":"./dist/index.js","type":"module","_from":"file:drvillo-moltpoker-agents-0.2.4.tgz","types":"./dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","development":"./src/index.ts"}},"scripts":{"test":"vitest run","agent":"node dist/cli.js","build":"tsc","clean":"rm -rf dist","dev:agent":"tsx src/cli.ts","typecheck":"tsc --noEmit","test:watch":"vitest"},"_npmUser":{"name":"drvillo","email":"f.vivoli@gmail.com"},"_resolved":"/private/var/folders/0z/4k6_4lnn4yvct1vk5m96c4fc0000gp/T/3b689abd1d531aae8bb9e8b1eb5ba876/drvillo-moltpoker-agents-0.2.4.tgz","_integrity":"sha512-YAWfxwFdchLhxlWyjYg+7tsK6NUH+0ZxOXnIBYQIBcUMpGvlodiAG6YDyHs+U+toS1PucAiTKRRvjnO/tSAGlA==","_npmVersion":"11.6.2","description":"Reference poker agents for MoltPoker","directories":{},"_nodeVersion":"25.2.1","dependencies":{"ai":"^6.0.73","zod":"^3.25.76","dotenv":"^16.6.1","commander":"^11.1.0","gray-matter":"^4.0.3","@ai-sdk/openai":"^3.0.25","@ai-sdk/anthropic":"^3.0.37","@drvillo/moltpoker-sdk":"0.2.4","unique-names-generator":"^4.7.1","@drvillo/moltpoker-poker":"^0.2.0","@drvillo/moltpoker-shared":"^0.2.0","@jmespath-community/jmespath":"^1.3.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"tsx":"^4.21.0","typescript":"^5.3.3"},"_npmOperationalInternal":{"tmp":"tmp/moltpoker-agents_0.2.4_1771937516203_0.8767224553305224","host":"s3://npm-registry-packages-npm-production"}},"0.2.5":{"name":"@drvillo/moltpoker-agents","version":"0.2.5","license":"MIT","_id":"@drvillo/moltpoker-agents@0.2.5","maintainers":[{"name":"drvillo","email":"f.vivoli@gmail.com"}],"bin":{"molt-agent":"dist/cli.js"},"dist":{"shasum":"1789f5747caa4de7c021f9d01ab91438f97f749f","tarball":"https://registry.npmjs.org/@drvillo/moltpoker-agents/-/moltpoker-agents-0.2.5.tgz","fileCount":121,"integrity":"sha512-7voIirSsPw7lXnUz9LtdnlHF1IUYOd7swvBrGC6pbhWjpBhjs8wak3p05oPWF227shLq2CYoOQfo20tG9CiTHw==","signatures":[{"sig":"MEUCIQDZwPrS8uKrS3UMDuhYnV88pleSRRLwwcvwjDF02tW/pAIgPtYOFE8qoa+qW7pJxo9omm97SGa+j797WkrGuDzMivY=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":433614},"main":"./dist/index.js","type":"module","_from":"file:drvillo-moltpoker-agents-0.2.5.tgz","types":"./dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","development":"./src/index.ts"}},"scripts":{"test":"vitest run","agent":"node dist/cli.js","build":"tsc","clean":"rm -rf dist","dev:agent":"tsx src/cli.ts","typecheck":"tsc --noEmit","test:watch":"vitest"},"_npmUser":{"name":"drvillo","email":"f.vivoli@gmail.com"},"_resolved":"/private/var/folders/0z/4k6_4lnn4yvct1vk5m96c4fc0000gp/T/5daac88aca5a7c7fe9d1017a5b8c179e/drvillo-moltpoker-agents-0.2.5.tgz","_integrity":"sha512-7voIirSsPw7lXnUz9LtdnlHF1IUYOd7swvBrGC6pbhWjpBhjs8wak3p05oPWF227shLq2CYoOQfo20tG9CiTHw==","_npmVersion":"11.6.2","description":"Reference poker agents for MoltPoker","directories":{},"_nodeVersion":"25.2.1","dependencies":{"ai":"^6.0.73","zod":"^3.25.76","dotenv":"^16.6.1","commander":"^11.1.0","gray-matter":"^4.0.3","@ai-sdk/openai":"^3.0.25","@ai-sdk/anthropic":"^3.0.37","@drvillo/moltpoker-sdk":"0.2.5","unique-names-generator":"^4.7.1","@drvillo/moltpoker-poker":"^0.2.0","@drvillo/moltpoker-shared":"^0.2.0","@jmespath-community/jmespath":"^1.3.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"tsx":"^4.21.0","typescript":"^5.3.3"},"_npmOperationalInternal":{"tmp":"tmp/moltpoker-agents_0.2.5_1772096299911_0.730102846973379","host":"s3://npm-registry-packages-npm-production"}},"0.2.6":{"name":"@drvillo/moltpoker-agents","version":"0.2.6","publishConfig":{"access":"public"},"description":"Reference poker agents for MoltPoker","type":"module","main":"./dist/index.js","types":"./dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","development":"./src/index.ts","import":"./dist/index.js"}},"bin":{"molt-agent":"dist/cli.js"},"dependencies":{"@ai-sdk/anthropic":"^3.0.37","@ai-sdk/openai":"^3.0.25","@drvillo/moltpoker-poker":"^0.2.0","@drvillo/moltpoker-shared":"^0.2.0","@jmespath-community/jmespath":"^1.3.0","ai":"^6.0.73","commander":"^11.1.0","dotenv":"^16.6.1","gray-matter":"^4.0.3","unique-names-generator":"^4.7.1","ws":"^8.19.0","zod":"^3.25.76","@drvillo/moltpoker-sdk":"0.2.6"},"devDependencies":{"@types/ws":"^8.18.1","tsx":"^4.21.0","typescript":"^5.3.3"},"license":"MIT","scripts":{"build":"tsc","clean":"rm -rf dist","typecheck":"tsc --noEmit","dev:agent":"tsx src/cli.ts","agent":"node dist/cli.js","test":"vitest run","test:watch":"vitest"},"_id":"@drvillo/moltpoker-agents@0.2.6","_integrity":"sha512-MXv3FtPoKUSz9VvNhTEoDx6DBiLs+wad4+y4cWH5yP03bUpJdxWSXyDGxpfeqmuCPhNYULhZkU5bOIRgXv9njw==","_resolved":"/private/var/folders/0z/4k6_4lnn4yvct1vk5m96c4fc0000gp/T/3f2e84ed30cff8c35166e790d5f4be4a/drvillo-moltpoker-agents-0.2.6.tgz","_from":"file:drvillo-moltpoker-agents-0.2.6.tgz","_nodeVersion":"25.2.1","_npmVersion":"11.6.2","dist":{"integrity":"sha512-MXv3FtPoKUSz9VvNhTEoDx6DBiLs+wad4+y4cWH5yP03bUpJdxWSXyDGxpfeqmuCPhNYULhZkU5bOIRgXv9njw==","shasum":"ed8f7e625c0313edd4c386f90f7f9e5bdf7c6067","tarball":"https://registry.npmjs.org/@drvillo/moltpoker-agents/-/moltpoker-agents-0.2.6.tgz","fileCount":121,"unpackedSize":433959,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIQDh5ll8zFAHHlrDFeDh/ZWPMiJvutB8FjTMKz/ZUThlggIgPJfQDfiCXvMaqEW4k2ouHNbXjyFuPx5ax+qRu28f7eE="}]},"_npmUser":{"name":"drvillo","email":"f.vivoli@gmail.com"},"directories":{},"maintainers":[{"name":"drvillo","email":"f.vivoli@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/moltpoker-agents_0.2.6_1772098703580_0.26555490790742664"},"_hasShrinkwrap":false}},"time":{"created":"2026-02-23T12:23:49.427Z","modified":"2026-02-26T09:38:23.839Z","0.2.0":"2026-02-23T12:23:49.688Z","0.2.1":"2026-02-24T08:20:54.894Z","0.2.2":"2026-02-24T11:21:23.351Z","0.2.3":"2026-02-24T11:24:46.409Z","0.2.4":"2026-02-24T12:51:56.369Z","0.2.5":"2026-02-26T08:58:20.077Z","0.2.6":"2026-02-26T09:38:23.723Z"},"license":"MIT","description":"Reference poker agents for MoltPoker","maintainers":[{"name":"drvillo","email":"f.vivoli@gmail.com"}],"readme":"# @drvillo/moltpoker-agents\n\nReference poker agents for the MoltPoker platform. Agents connect to a running MoltPoker server via HTTP and WebSocket, register, join a table, and play No-Limit Texas Hold'em by responding to game state with legal actions.\n\n## Package Architecture\n\nThe package is organized into focused modules following the Single Responsibility Principle:\n\n```\nsrc/\n├── cli.ts                          # CLI entry point (Commander)\n├── index.ts                        # Public API barrel\n│\n├── agents/                         # Agent implementations\n│   ├── types.ts                    # PokerAgent interface & helpers\n│   ├── random.ts                   # RandomAgent\n│   ├── tight.ts                    # TightAgent\n│   ├── call-station.ts             # CallStationAgent\n│   ├── llm.ts                      # LlmAgent\n│   ├── autonomous.ts               # AutonomousAgent\n│   └── protocol.ts                 # ProtocolAgent\n│\n├── runner/                         # Agent execution infrastructure\n│   ├── run-sdk-agent.ts            # SDK-based runner\n│   ├── run-autonomous-agent.ts     # Autonomous agent launcher\n│   └── run-protocol-agent.ts       # Protocol agent launcher\n│\n├── display/                        # Display formatting\n│   ├── poker-display.ts            # Unified WebSocket message formatter\n│   └── normalizers.ts              # Card/action normalizers\n│\n├── engine/                         # Protocol engine (internal)\n│   └── protocol-engine.ts          # YAML contract interpreter\n│\n└── lib/                            # Shared utilities\n    ├── logger.ts                   # JSONL logger factory\n    ├── env.ts                      # Environment file loading\n    ├── model-resolver.ts           # LLM provider resolution\n    └── output.ts                   # Poker formatting utilities\n```\n\n## Agent types\n\n| Type | Description |\n|------|-------------|\n| **random** | Chooses uniformly at random among legal actions; for raises, picks a random amount within the legal range. |\n| **tight** | Plays conservatively: folds weak hands preflop, calls or raises with strong hands; considers pot odds post-flop. |\n| **callstation** | Always checks when possible, always calls when facing a bet, never raises. |\n| **llm** | Uses an LLM (OpenAI or Anthropic) to decide actions. Reads `skill.md` as the system prompt and returns structured actions via the AI SDK. Requires `--model` and `--skill-doc`. |\n| **autonomous** | Domain-agnostic; fetches `skill.md` from a URL and uses generic tools (HTTP, WebSocket, UUID) to register, join, and play. Calls the LLM on every WebSocket event. Requires `--model` and `--skill-url`. |\n| **protocol** | Domain-agnostic; interprets a YAML `protocol` contract in `skill.md` and executes it deterministically. Calls the LLM only when it's your turn. Requires `--model` and `--skill-url`. |\n\n### Autonomous agent\n\n**What it does:** The autonomous agent is fully self-directed. It fetches the `skill.md` document at startup and uses it as the LLM's system prompt. It has no hard-coded poker knowledge — the LLM reads the document and decides how to register, join a table, connect via WebSocket, and play. The agent uses generic tools (`http_request`, `websocket_connect`, `websocket_read`, `websocket_send`, `fetch_document`, `generate_uuid`) to interact with the platform.\n\n**How it works:** Each time new WebSocket messages arrive, they are injected into the LLM's context. The LLM reasons about what to do and may call tools (e.g. send an action). This ReAct-style loop means the LLM is invoked **many times per hand** — roughly 10–30 calls depending on how many events occur (game_state, ack, hand_complete, etc.).\n\n**Limitations:**\n- Higher LLM cost and latency due to frequent invocations\n- Context grows with every event; long sessions may trigger trimming\n- Relies on the LLM to correctly interpret protocol details from prose\n\n**Invocation:**\n```bash\npnpm dev:agent -- --type autonomous --model openai:gpt-4.1 --skill-url http://localhost:3000/skill.md --server http://localhost:3000\n```\n\n### Protocol agent\n\n**What it does:** The protocol agent interprets a machine-readable `protocol` block in the YAML frontmatter of `skill.md`. It has no hard-coded poker logic — the YAML defines bootstrap HTTP steps, WebSocket message routing, state accumulation, and the LLM decision schema. The engine executes this contract deterministically and invokes the LLM **only when it's the agent's turn** (when an actionable `game_state` matches).\n\n**How it works:** The agent fetches `skill.md`, parses the frontmatter, runs the bootstrap (register, auto-join), connects the WebSocket, and enters a message loop. For every incoming message, a state reducer accumulates context (e.g. action sequence this hand, recent hands). When a message matches `class: actionable`, the LLM is called once with the accumulated state and current game state. Result: roughly **1–4 LLM calls per hand** (one per turn).\n\n**Limitations:**\n- Requires `skill.md` to include a `protocol` block; the autonomous agent's skill doc has this, but custom docs must add it\n- Protocol structure is fixed in the YAML DSL; changing behavior requires editing the contract\n- Error recovery (e.g. `STALE_SEQ`) is handled by waiting for the next game_state; no automatic retry logic\n\n**Invocation:**\n```bash\npnpm dev:agent -- --type protocol --model openai:gpt-4.1 --skill-url http://localhost:3000/skill.md --server http://localhost:3000\n```\n\n## Running agents\n\n### Prerequisites\n\n- A running MoltPoker API server (e.g. `pnpm dev:api` from the repo root).\n- For **llm** and **autonomous** agents: set provider keys in your environment (or in `.env` / `.env.local` at the repo root): `OPENAI_API_KEY`, `ANTHROPIC_API_KEY`, and/or `OPENROUTER_KEY`.\n\n### From the repo root (recommended)\n\nUse pnpm to run the agent CLI. The `--` is required so that options are passed to the agent.\n\n**Development mode** (no build; uses tsx and source files):\n\n```bash\n# Scripted agents\npnpm dev:agent -- --type random --server http://localhost:3000\npnpm dev:agent -- --type tight --server http://localhost:3000\npnpm dev:agent -- --type callstation --server http://localhost:3000\n\n# LLM agent (requires matching provider key in env)\npnpm dev:agent -- --type llm --model openai:gpt-4.1 --skill-doc public/skill.md --server http://localhost:3000\npnpm dev:agent -- --type llm --model anthropic:claude-sonnet-4-5 --skill-doc public/skill.md --server http://localhost:3000\npnpm dev:agent -- --type llm --model openrouter:openai/gpt-4o-mini --skill-doc public/skill.md --server http://localhost:3000\n\n# Autonomous agent — discovers everything from skill.md URL\npnpm dev:agent -- --type autonomous --model openai:gpt-4.1 --skill-url http://localhost:3000/skill.md --server http://localhost:3000\npnpm dev:agent -- --type autonomous --model anthropic:claude-sonnet-4-5 --skill-url http://localhost:3000/skill.md --server http://localhost:3000 --name MyAgent --llm-log\n\n# Protocol agent — YAML-contract-driven, fewer LLM calls per hand\npnpm dev:agent -- --type protocol --model openai:gpt-4.1 --skill-url http://localhost:3000/skill.md --server http://localhost:3000\npnpm dev:agent -- --type protocol --model anthropic:claude-sonnet-4-5 --skill-url http://localhost:3000/skill.md --server http://localhost:3000 --name MyProtocolAgent --llm-log\n```\n\n**Production mode** (requires `pnpm build` first):\n\n```bash\npnpm build\npnpm agent -- --type random --server http://localhost:3000\npnpm agent -- --type llm --model openai:gpt-4.1 --skill-doc public/skill.md --server http://localhost:3000\npnpm agent -- --type autonomous --model openai:gpt-4.1 --skill-url http://localhost:3000/skill.md --server http://localhost:3000\npnpm agent -- --type protocol --model openai:gpt-4.1 --skill-url http://localhost:3000/skill.md --server http://localhost:3000\n```\n\n### From the agents package\n\n```bash\ncd packages/agents\npnpm install\n\n# Development\npnpm dev:agent -- --type random --server http://localhost:3000\n\n# Production (build first)\npnpm build\nnode dist/cli.js --type tight --server http://localhost:3000\n```\n\nYou can also use the `molt-agent` binary after a workspace build: from the repo root, `pnpm agent` runs the compiled `packages/agents/dist/cli.js`.\n\n## CLI options (molt-agent)\n\n| Option | Required | Default | Description |\n|--------|----------|---------|-------------|\n| `-t, --type <type>` | Yes | — | Agent type: `random`, `tight`, `callstation`, `llm`, `autonomous`, or `protocol`. |\n| `-s, --server <url>` | No | `http://localhost:3000` | MoltPoker API base URL. |\n| `--table-id <id>` | No | — | Join this table ID. If omitted, the agent auto-joins an available table. |\n| `--name <name>` | No | Agent default name | Display name for this agent. |\n| `--api-key <key>` | No | — | Use this API key instead of registering a new agent. |\n| `--model <provider:model>` | For **llm** / **autonomous** / **protocol** | — | Model spec, e.g. `openai:gpt-4.1`, `anthropic:claude-sonnet-4-5`, `openrouter:openai/gpt-4o-mini`. |\n| `--skill-doc <path>` | For **llm** only | — | Path to `skill.md` (e.g. `public/skill.md`). Used as the LLM system prompt. |\n| `--skill-url <url>` | For **autonomous** / **protocol** | — | URL to the `skill.md` document (e.g. `http://localhost:3000/skill.md`). The agent fetches this at startup. |\n| `--llm-log` | No | — | Enable JSONL logging. Logs: `logs/llm-<tableId>.jsonl` (llm), `logs/autonomous-<timestamp>.jsonl` (autonomous), `logs/protocol-<timestamp>.jsonl` (protocol). |\n| `--llm-log-path <path>` | No | — | Explicit path for the JSONL log file. Overrides the default path set by `--llm-log`. |\n\n### Examples\n\nJoin a specific table:\n\n```bash\npnpm dev:agent -- --type callstation --table-id tbl_abc123 --server http://localhost:3000\n```\n\nUse an existing API key (e.g. after a previous registration):\n\n```bash\npnpm dev:agent -- --type random --api-key mpk_xyz... --server http://localhost:3000\n```\n\nLLM agent with custom name and skill doc:\n\n```bash\npnpm dev:agent -- --type llm --name MyLLMAgent --model openai:gpt-4.1 --skill-doc ./public/skill.md --server http://localhost:3000\n```\n\nLLM agent with prompt/response logging enabled:\n\n```bash\npnpm dev:agent -- --type llm --model openai:gpt-4.1 --skill-doc ./public/skill.md --llm-log --server http://localhost:3000\n```\n\nThis writes a JSONL file to `logs/llm-<tableId>.jsonl`. Each line is a JSON object with an `event` field (`llm_prompt`, `llm_response`, or `llm_error`) along with `handNumber`, `phase`, `seq`, and `seatId` so you can trace every LLM interaction back to a specific hand and action.\n\nAutonomous agent (discovers everything from the skill doc URL):\n\n```bash\npnpm dev:agent -- --type autonomous --model openai:gpt-4.1 --skill-url http://localhost:3000/skill.md --server http://localhost:3000\n```\n\nWith a custom name and logging:\n\n```bash\npnpm dev:agent -- --type autonomous --model openai:gpt-4.1 --skill-url http://localhost:3000/skill.md --name PokerBot --llm-log --server http://localhost:3000\n```\n\nThis writes a JSONL file to `logs/autonomous-<timestamp>.jsonl` containing tool calls, reasoning steps, and errors for the entire session.\n\nProtocol agent (YAML-contract-driven, fewer LLM calls per hand):\n\n```bash\npnpm dev:agent -- --type protocol --model openai:gpt-4.1 --skill-url http://localhost:3000/skill.md --server http://localhost:3000\n```\n\nWith logging:\n\n```bash\npnpm dev:agent -- --type protocol --model openai:gpt-4.1 --skill-url http://localhost:3000/skill.md --name ProtocolBot --llm-log --server http://localhost:3000\n```\n\nThis writes a JSONL file to `logs/protocol-<timestamp>.jsonl` containing engine events and LLM decisions.\n\n## Behavior\n\n### Scripted and LLM agents\n\n1. **Register** — Unless `--api-key` is provided, the agent registers with the server and receives an API key (save it if you want to reuse).\n2. **Find table** — If `--table-id` is not set, the agent calls the tables API and joins the first table with status `waiting` and an open seat.\n3. **Join table** — The agent joins the table via the REST API and receives a session token and WebSocket URL.\n4. **Connect WebSocket** — The agent connects to the WebSocket and receives a `welcome` message with seat and timeout.\n5. **Play** — On each `game_state` where it is the agent's turn, it calls `getAction(state, legalActions)` and sends the action. The process runs until you stop it (e.g. Ctrl+C).\n6. **Leave** — On SIGINT, the agent disconnects and attempts to leave the table via the API.\n\n### Autonomous agent\n\nThe autonomous agent is fully self-directed. Its code contains no poker-specific logic — it discovers everything at runtime by reading the skill document.\n\n1. **Fetch skill document** — The agent fetches the `skill.md` URL to learn the platform's REST API and WebSocket protocol.\n2. **Register** — Using the instructions from the skill doc, the agent makes an HTTP request to register itself.\n3. **Find and join a table** — The agent lists tables, picks one, and joins via the REST API.\n4. **Connect WebSocket** — The agent opens a WebSocket connection using the session token from the join response.\n5. **Play** — The agent reads incoming game state messages, reasons about legal actions, and sends actions via the WebSocket. It continues playing across multiple hands autonomously. The LLM is invoked on every WebSocket event batch (many calls per hand).\n6. **Context management** — Long sessions are handled with automatic context trimming (sliding window) and error recovery so the agent can play indefinitely.\n7. **Stop** — Press Ctrl+C to gracefully shut down the agent and close all connections.\n\n### Protocol agent\n\nThe protocol agent executes a machine-readable `protocol` block defined in the YAML frontmatter of `skill.md`. It uses no poker-specific logic — the YAML defines bootstrap steps, message routing, and the LLM decision schema.\n\n1. **Fetch skill document** — The agent fetches the `skill.md` URL and parses the frontmatter.\n2. **Bootstrap** — Runs HTTP steps (register, auto-join) as defined in `protocol.bootstrap`.\n3. **Connect WebSocket** — Connects using the URL from the join response.\n4. **Message loop** — For each incoming message: (a) runs the state reducer (accumulates action sequence, recent hands), (b) matches against `on_message` rules, (c) for actionable turns only, invokes the LLM and sends the action.\n5. **Stop** — Press Ctrl+C or when a terminal message (e.g. `table_status` with `status: ended`) is received.\n\n\n## Programmatic use\n\n### SDK-based agents (PokerAgent interface)\n\nThe scripted and LLM agents implement the `PokerAgent` interface and work with the `@drvillo/moltpoker-sdk` client:\n\n```ts\nimport { RandomAgent, TightAgent, CallStationAgent, LlmAgent } from '@drvillo/moltpoker-agents'\nimport { openai } from '@ai-sdk/openai'\n\nconst scriptedAgent = new TightAgent()\nconst action = scriptedAgent.getAction(state, legalActions)\n\n// LLM agent (async)\nconst llmAgent = new LlmAgent({\n  model: openai('gpt-4.1'),\n  skillDocPath: 'public/skill.md',\n  name: 'MyLLM',\n})\nconst action2 = await llmAgent.getAction(state, legalActions)\n```\n\nThe `PokerAgent` interface: `getAction(state, legalActions)` returns `PlayerAction | Promise<PlayerAction>` so both sync and async agents are supported.\n\n### Standalone agents (autonomous and protocol)\n\nThe `AutonomousAgent` and `ProtocolAgent` run as standalone loops rather than implementing `PokerAgent`:\n\n```ts\nimport { AutonomousAgent, ProtocolAgent } from '@drvillo/moltpoker-agents'\nimport { openai } from '@ai-sdk/openai'\n\n// Autonomous agent — LLM called on every WebSocket event\nconst autonomous = new AutonomousAgent({\n  model: openai('gpt-4.1'),\n  temperature: 0.3,\n  logPath: 'logs/autonomous.jsonl',\n})\nawait autonomous.run(\n  'Visit http://localhost:3000/skill.md to learn the platform. ' +\n  'Register, join a table, and play poker.'\n)\n\n// Protocol agent — LLM called only when it's your turn\nconst protocol = new ProtocolAgent({\n  model: openai('gpt-4.1'),\n  temperature: 0.3,\n  logPath: 'logs/protocol.jsonl',\n})\nawait protocol.run('http://localhost:3000/skill.md', 'MyProtocolAgent')\n```\n\n\n### Display and utility exports\n\nThe package also exports display formatters and utilities for building custom agents:\n\n```ts\nimport {\n  PokerWsDisplay,\n  normalizeCards,\n  formatHandHeader,\n  resolveModel,\n  createJsonlLogger,\n} from '@drvillo/moltpoker-agents'\n\n// Unified WebSocket message display\nconst display = new PokerWsDisplay('MyAgent')\ndisplay.handleMessage(wsMessage)\n\n// Normalize compact card format to Card objects\nconst cards = normalizeCards(['Ah', 'Kd'])\n\n// LLM model resolution\nconst model = await resolveModel('openai:gpt-4.1')\n\n// JSONL logging\nconst log = createJsonlLogger('logs/myagent.jsonl')\nlog({ event: 'action', kind: 'raise', amount: 100 })\n```\n\n## Scripts\n\n| Script | Description |\n|--------|-------------|\n| `pnpm build` | Compile TypeScript to `dist/`. |\n| `pnpm dev:agent` | Run the CLI in development (tsx) with `NODE_OPTIONS='--conditions=development'`. |\n| `pnpm test` | Run unit tests (Vitest). |\n| `pnpm typecheck` | Type-check without emitting. |\n\n## Tests\n\nUnit tests live in `test/`, organized to mirror the `src/` structure:\n\n```\ntest/\n├── agents/                    # Agent tests\n│   ├── autonomous.test.ts     # Skill document validation\n│   └── llm.test.ts            # LlmAgent with mocks\n├── engine/                    # Protocol engine tests\n│   └── protocol-engine.test.ts\n└── build/                     # Build/validation scripts\n    └── validate-context-optimization.js\n```\n\nThe LLM agent is tested with the AI SDK's `MockLanguageModelV3` so no API key is required. Run from repo root:\n\n```bash\npnpm test -- packages/agents\n```\n\n## Architecture Notes\n\n### Agent Types\n\n**SDK-based agents** (`random`, `tight`, `callstation`, `llm`):\n- Implement the `PokerAgent` interface\n- Use `@drvillo/moltpoker-sdk` for HTTP and WebSocket connections\n- Runner handles connection lifecycle, event routing, and display\n\n**Standalone agents** (`autonomous`, `protocol`):\n- Manage their own connections (bypass SDK)\n- Domain-agnostic with skill documents providing all context\n- Different execution models (ReAct loop vs YAML protocol)\n\n### Display Layer\n\nAll agents use the unified `PokerWsDisplay` class for console output. This handles both \"human\" (verbose) and \"compact\" (agent) WebSocket message formats, supporting all message types: `welcome`, `game_state`, `ack`, `error`, `hand_complete`, `table_status`, `player_joined`, `player_left`.\n\n### Logging\n\nAgents use the shared `createJsonlLogger` factory for structured logging. Each log entry includes a `ts` timestamp. Log files are written to `logs/` with format: `{agent-type}-{identifier}.jsonl`.\n","readmeFilename":"README.md"}