@aifight/aifight 0.1.0-alpha.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 +160 -0
- package/dist/bin.mjs +291 -0
- package/dist/index.mjs +107 -0
- package/dist/schemas/README.md +57 -0
- package/dist/schemas/common/README.md +40 -0
- package/dist/schemas/common/action.schema.json +19 -0
- package/dist/schemas/common/error.schema.json +23 -0
- package/dist/schemas/common/event.schema.json +33 -0
- package/dist/schemas/common/game_result.schema.json +31 -0
- package/dist/schemas/common/player_identity.schema.json +29 -0
- package/dist/schemas/common/player_info.schema.json +27 -0
- package/dist/schemas/common/rules.schema.json +34 -0
- package/dist/schemas/games/README.md +43 -0
- package/dist/schemas/games/coup/README.md +104 -0
- package/dist/schemas/games/coup/action.schema.json +198 -0
- package/dist/schemas/games/coup/event.schema.json +249 -0
- package/dist/schemas/games/coup/rules.schema.json +46 -0
- package/dist/schemas/games/coup/state.schema.json +123 -0
- package/dist/schemas/games/liars_dice/README.md +59 -0
- package/dist/schemas/games/liars_dice/action.schema.json +45 -0
- package/dist/schemas/games/liars_dice/event.schema.json +120 -0
- package/dist/schemas/games/liars_dice/rules.schema.json +36 -0
- package/dist/schemas/games/liars_dice/state.schema.json +72 -0
- package/dist/schemas/games/texas_holdem/README.md +58 -0
- package/dist/schemas/games/texas_holdem/action.schema.json +88 -0
- package/dist/schemas/games/texas_holdem/config.schema.json +30 -0
- package/dist/schemas/games/texas_holdem/event.schema.json +135 -0
- package/dist/schemas/games/texas_holdem/rules.schema.json +39 -0
- package/dist/schemas/games/texas_holdem/state.schema.json +98 -0
- package/dist/schemas/messages/README.md +98 -0
- package/dist/schemas/messages/client_action.schema.json +20 -0
- package/dist/schemas/messages/client_join_queue.schema.json +39 -0
- package/dist/schemas/messages/client_leave_queue.schema.json +18 -0
- package/dist/schemas/messages/client_match_confirm.schema.json +25 -0
- package/dist/schemas/messages/client_runtime_status.schema.json +46 -0
- package/dist/schemas/messages/server_action_request.schema.json +71 -0
- package/dist/schemas/messages/server_error.schema.json +16 -0
- package/dist/schemas/messages/server_event.schema.json +30 -0
- package/dist/schemas/messages/server_game_over.schema.json +49 -0
- package/dist/schemas/messages/server_game_start.schema.json +99 -0
- package/dist/schemas/messages/server_game_state.schema.json +33 -0
- package/dist/schemas/messages/server_match_cancelled.schema.json +51 -0
- package/dist/schemas/messages/server_match_confirm_request.schema.json +37 -0
- package/dist/schemas/messages/server_queue_joined.schema.json +26 -0
- package/dist/schemas/messages/server_queue_left.schema.json +24 -0
- package/dist/schemas/messages/server_readiness_check.schema.json +42 -0
- package/dist/schemas/messages/server_welcome.schema.json +49 -0
- package/dist/schemas/rest/README.md +85 -0
- package/dist/schemas/rest/agent_status_response.schema.json +34 -0
- package/dist/schemas/rest/claim_request.schema.json +20 -0
- package/dist/schemas/rest/claim_response.schema.json +24 -0
- package/dist/schemas/rest/error_response.schema.json +15 -0
- package/dist/schemas/rest/register_request.schema.json +35 -0
- package/dist/schemas/rest/register_response.schema.json +54 -0
- package/dist/types/account/credentials.d.ts +29 -0
- package/dist/types/account/errors.d.ts +61 -0
- package/dist/types/account/registration.d.ts +26 -0
- package/dist/types/agents/agent.d.ts +82 -0
- package/dist/types/agents/state-machine.d.ts +96 -0
- package/dist/types/bridge/config.d.ts +35 -0
- package/dist/types/bridge/hermes-provider.d.ts +9 -0
- package/dist/types/bridge/openclaw-provider.d.ts +9 -0
- package/dist/types/bridge/pairing.d.ts +18 -0
- package/dist/types/bridge/provider.d.ts +18 -0
- package/dist/types/bridge/runner.d.ts +30 -0
- package/dist/types/bridge/service.d.ts +55 -0
- package/dist/types/bridge/update-check.d.ts +23 -0
- package/dist/types/cli/agent-resolver.d.ts +25 -0
- package/dist/types/cli/argv.d.ts +13 -0
- package/dist/types/cli/commands/agent-list.d.ts +2 -0
- package/dist/types/cli/commands/agent-status.d.ts +2 -0
- package/dist/types/cli/commands/bridge-accept.d.ts +2 -0
- package/dist/types/cli/commands/bridge-challenge.d.ts +2 -0
- package/dist/types/cli/commands/bridge-connect.d.ts +2 -0
- package/dist/types/cli/commands/bridge-register.d.ts +2 -0
- package/dist/types/cli/commands/bridge-run.d.ts +7 -0
- package/dist/types/cli/commands/bridge-service.d.ts +3 -0
- package/dist/types/cli/commands/bridge-set.d.ts +2 -0
- package/dist/types/cli/commands/bridge-start.d.ts +2 -0
- package/dist/types/cli/commands/bridge-status.d.ts +2 -0
- package/dist/types/cli/commands/bridge-uninstall.d.ts +4 -0
- package/dist/types/cli/commands/config-init.d.ts +2 -0
- package/dist/types/cli/commands/config-probe.d.ts +2 -0
- package/dist/types/cli/commands/config-validate.d.ts +2 -0
- package/dist/types/cli/commands/daily-off.d.ts +2 -0
- package/dist/types/cli/commands/daily-on.d.ts +2 -0
- package/dist/types/cli/commands/daily-set.d.ts +2 -0
- package/dist/types/cli/commands/daily-show.d.ts +2 -0
- package/dist/types/cli/commands/doctor.d.ts +2 -0
- package/dist/types/cli/commands/init.d.ts +2 -0
- package/dist/types/cli/commands/join.d.ts +2 -0
- package/dist/types/cli/commands/leave.d.ts +2 -0
- package/dist/types/cli/commands/mcp.d.ts +2 -0
- package/dist/types/cli/commands/runtime-management.d.ts +16 -0
- package/dist/types/cli/commands/runtime-setup-state.d.ts +21 -0
- package/dist/types/cli/commands/runtime-setup.d.ts +23 -0
- package/dist/types/cli/commands/serve.d.ts +2 -0
- package/dist/types/cli/commands/service/launchd.d.ts +71 -0
- package/dist/types/cli/commands/service/platform.d.ts +69 -0
- package/dist/types/cli/commands/service/systemd.d.ts +55 -0
- package/dist/types/cli/commands/service/types.d.ts +64 -0
- package/dist/types/cli/commands/service-install.d.ts +29 -0
- package/dist/types/cli/commands/setup.d.ts +2 -0
- package/dist/types/cli/commands/shutdown.d.ts +2 -0
- package/dist/types/cli/commands/stubs.d.ts +24 -0
- package/dist/types/cli/commands/version.d.ts +2 -0
- package/dist/types/cli/control-client.d.ts +59 -0
- package/dist/types/cli/format.d.ts +52 -0
- package/dist/types/cli/main.d.ts +18 -0
- package/dist/types/cli/runtime-files.d.ts +11 -0
- package/dist/types/cli/shared.d.ts +74 -0
- package/dist/types/controlapi/profile-routes.d.ts +49 -0
- package/dist/types/controlapi/server.d.ts +3 -0
- package/dist/types/controlapi/types.d.ts +136 -0
- package/dist/types/daemon/agent-decision-adapter.d.ts +40 -0
- package/dist/types/daemon/lifecycle.d.ts +85 -0
- package/dist/types/daemon/router.d.ts +97 -0
- package/dist/types/daemon/runtime-files-write.d.ts +76 -0
- package/dist/types/decision/direct-model/anthropic.d.ts +12 -0
- package/dist/types/decision/direct-model/errors.d.ts +59 -0
- package/dist/types/decision/direct-model/openai.d.ts +12 -0
- package/dist/types/decision/direct-model/types.d.ts +20 -0
- package/dist/types/decision/parser-types.d.ts +31 -0
- package/dist/types/decision/prompt-builder.d.ts +10 -0
- package/dist/types/decision/provider.d.ts +50 -0
- package/dist/types/decision/types.d.ts +87 -0
- package/dist/types/games/_shared/player-info.d.ts +14 -0
- package/dist/types/games/coup/action-parser.d.ts +3 -0
- package/dist/types/games/coup/fallback.d.ts +8 -0
- package/dist/types/games/coup/state-formatter.d.ts +14 -0
- package/dist/types/games/liars_dice/action-parser.d.ts +3 -0
- package/dist/types/games/liars_dice/fallback.d.ts +8 -0
- package/dist/types/games/liars_dice/state-formatter.d.ts +14 -0
- package/dist/types/games/texas_holdem/action-parser.d.ts +3 -0
- package/dist/types/games/texas_holdem/fallback.d.ts +8 -0
- package/dist/types/games/texas_holdem/state-formatter.d.ts +14 -0
- package/dist/types/identity/identity-manager.d.ts +59 -0
- package/dist/types/index.d.ts +30 -0
- package/dist/types/llm/adapter-registry.d.ts +27 -0
- package/dist/types/llm/adapters/anthropic-messages.d.ts +2 -0
- package/dist/types/llm/adapters/deepseek-chat-completions.d.ts +2 -0
- package/dist/types/llm/adapters/openai-chat-compat.d.ts +2 -0
- package/dist/types/llm/adapters/openai-chat-completions.d.ts +2 -0
- package/dist/types/llm/adapters/openai-responses.d.ts +2 -0
- package/dist/types/llm/adapters/types.d.ts +128 -0
- package/dist/types/llm/capabilities/validate-capabilities.d.ts +68 -0
- package/dist/types/mcp/control-client.d.ts +54 -0
- package/dist/types/mcp/profile-tools.d.ts +10 -0
- package/dist/types/mcp/server.d.ts +10 -0
- package/dist/types/mcp/tools.d.ts +31 -0
- package/dist/types/mcp/types.d.ts +27 -0
- package/dist/types/profile/config-schema.d.ts +199 -0
- package/dist/types/profile/identity-schema.d.ts +75 -0
- package/dist/types/profile/index.d.ts +7 -0
- package/dist/types/profile/migrate.d.ts +16 -0
- package/dist/types/profile/profile-loader.d.ts +64 -0
- package/dist/types/profile/secret-ref.d.ts +82 -0
- package/dist/types/profile/soul.d.ts +46 -0
- package/dist/types/profile/strategy-schema.d.ts +70 -0
- package/dist/types/protocol/schemas.d.ts +11 -0
- package/dist/types/protocol/types.d.ts +1333 -0
- package/dist/types/reflection/proposal-store.d.ts +50 -0
- package/dist/types/reflection/reflection-engine.d.ts +81 -0
- package/dist/types/scheduler/daily.d.ts +47 -0
- package/dist/types/scheduler/types.d.ts +42 -0
- package/dist/types/session/match-session-manager.d.ts +113 -0
- package/dist/types/session/session-context-builder.d.ts +68 -0
- package/dist/types/store/errors.d.ts +23 -0
- package/dist/types/store/paths.d.ts +3 -0
- package/dist/types/store/schema.generated.d.ts +1 -0
- package/dist/types/store/sqlite.d.ts +36 -0
- package/dist/types/wsclient/client.d.ts +220 -0
- package/dist/types/wsclient/errors.d.ts +106 -0
- package/dist/types/wsclient/frame-handler.d.ts +20 -0
- package/dist/types/wsclient/reconnect.d.ts +84 -0
- package/package.json +53 -0
|
@@ -0,0 +1,1333 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A player's action in a game. The `type` is game-specific (see protocol/schema/games/<game>/action.schema.json for the canonical oneOf enum per game). `data` holds per-type parameters (e.g. raise amount for Texas Hold'em, target for Coup). Mirrors engine.Action in internal/engine/types.go.
|
|
3
|
+
*
|
|
4
|
+
* **Game narrowing:** This common envelope is intentionally permissive — client_action.schema.json / action_request.data.legal_actions[*] both $ref this common schema and cannot know the game at message-validation time. Runtime validators (P0-09) perform per-game narrowing by selecting the appropriate games/<game>/action.schema.json based on active match context. Per-game oneOf schemas:
|
|
5
|
+
* - games/texas_holdem/action.schema.json (5 types: fold, check, call, raise, allin)
|
|
6
|
+
* - games/liars_dice/action.schema.json (2 types: bid, challenge)
|
|
7
|
+
* - games/coup/action.schema.json (12 types: income, foreign_aid, coup, tax, assassinate, steal, exchange, challenge, pass, block, lose_card, return_cards)
|
|
8
|
+
*
|
|
9
|
+
* Note: `challenge` and `pass` appear in both liars_dice and coup; they cannot be disambiguated by `type` alone, which is why this common schema does NOT attempt an anyOf across games.
|
|
10
|
+
*/
|
|
11
|
+
export interface Action {
|
|
12
|
+
/**
|
|
13
|
+
* Game-specific action name. Legal values depend on game; see games/<game>/action.schema.json for the per-game oneOf discriminated union.
|
|
14
|
+
*/
|
|
15
|
+
type: string;
|
|
16
|
+
/**
|
|
17
|
+
* Action parameters (amount, target, etc.). Game-specific shape; see games/<game>/action.schema.json variants.
|
|
18
|
+
*/
|
|
19
|
+
data?: {};
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Error details referenced by server_error.data. Current server implementation (internal/hub/hub.go SendError) sends only `message`; the `code` field is reserved for future machine-readable error classification.
|
|
23
|
+
*/
|
|
24
|
+
export interface ErrorPayload {
|
|
25
|
+
/**
|
|
26
|
+
* Human-readable error message. Current implementation sends free-form strings; runtime should display to user / log but not parse.
|
|
27
|
+
*/
|
|
28
|
+
message: string;
|
|
29
|
+
/**
|
|
30
|
+
* Reserved for future structured error codes. Not currently populated by server.
|
|
31
|
+
*/
|
|
32
|
+
code?: string;
|
|
33
|
+
/**
|
|
34
|
+
* Reserved for future context. Not currently populated.
|
|
35
|
+
*/
|
|
36
|
+
details?: {};
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* A game event that occurred during a match. Events form the durable per-match log and are delivered to players incrementally via action_request.new_events. Mirrors engine.Event in internal/engine/types.go. The event `type` is game-specific; see games/<game>/event.schema.json for the per-game enum + `data` narrowing.
|
|
40
|
+
*
|
|
41
|
+
* **Game narrowing:** This common envelope is intentionally permissive — action_request.data.new_events[*] / server_event.data.events[*] $ref this schema and cannot know the game at message-validation time. Runtime validators (P0-09) narrow `data` based on active match context. Per-game oneOf schemas:
|
|
42
|
+
* - games/texas_holdem/event.schema.json (7 types: new_hand, player_action, community_cards, cards_dealt, hand_result, match_result, player_disconnected)
|
|
43
|
+
* - games/liars_dice/event.schema.json (6 types: bid, challenge, player_eliminated, round_start, game_over, player_disconnected)
|
|
44
|
+
* - games/coup/event.schema.json (17 types: action, challenge_pass, challenge, challenge_result, block_pass, block, block_challenge_pass, block_accepted, challenge_block, challenge_block_result, influence_lost, player_eliminated, exchange_draw, exchange_complete, action_resolved, game_over, player_disconnected)
|
|
45
|
+
*/
|
|
46
|
+
export interface Event {
|
|
47
|
+
/**
|
|
48
|
+
* Event type name; game-specific enumeration. See games/<game>/event.schema.json.
|
|
49
|
+
*/
|
|
50
|
+
type: string;
|
|
51
|
+
/**
|
|
52
|
+
* PlayerID (p0, p1, ...) this event is attributed to. Omitted for global events (e.g. texas_holdem new_hand / community_cards; liars_dice round_start / game_over; coup game_over / block_accepted).
|
|
53
|
+
*/
|
|
54
|
+
player?: string;
|
|
55
|
+
/**
|
|
56
|
+
* Event-specific payload. Game-specific shape; see games/<game>/event.schema.json variants.
|
|
57
|
+
*/
|
|
58
|
+
data?: {};
|
|
59
|
+
/**
|
|
60
|
+
* Monotonic sequence number within a match. Runtime uses this to deduplicate / detect gaps. Required for engine-emitted events (bundled in action_request.new_events / event_history). **Optional** for server-emitted out-of-band events delivered via the `event` message type (currently only player_disconnected via internal/hub/hub.go:notifyPlayerEvent — see spec 02-message-flow.md §3).
|
|
61
|
+
*/
|
|
62
|
+
seq?: number;
|
|
63
|
+
/**
|
|
64
|
+
* RFC3339 timestamp when the event was appended to the match log. Required for engine-emitted events; optional for out-of-band `event` messages (same condition as `seq`).
|
|
65
|
+
*/
|
|
66
|
+
ts?: string;
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Final outcome of a match, carried in game_over.data.result. Mirrors engine.GameResult in internal/engine/types.go. `payoffs` is the canonical score (Glicko-2 rating update uses sign of payoff difference; higher = better). `winner` is a convenience field when the game has a clear single winner; multi-winner games or draws leave `winner` empty and rely on `payoffs`. `is_draw` is game-specific semantic — not always equivalent to `winner == ""`.
|
|
70
|
+
*/
|
|
71
|
+
export interface GameResult {
|
|
72
|
+
/**
|
|
73
|
+
* Map of PlayerID -> payoff (float). Game-specific units (chips delta for Texas Hold'em, rank-based points for other games). Rating updates consume the sign of differences.
|
|
74
|
+
*/
|
|
75
|
+
payoffs: {
|
|
76
|
+
[k: string]: number;
|
|
77
|
+
};
|
|
78
|
+
/**
|
|
79
|
+
* PlayerID of the single winner, if applicable. Empty for draws / multi-winner games.
|
|
80
|
+
*/
|
|
81
|
+
winner?: string;
|
|
82
|
+
/**
|
|
83
|
+
* True if the match is explicitly a draw by game rules.
|
|
84
|
+
*/
|
|
85
|
+
is_draw: boolean;
|
|
86
|
+
/**
|
|
87
|
+
* Per-player game-specific details (final hand, tricks won, etc.). Optional; game-specific structure per inner value.
|
|
88
|
+
*/
|
|
89
|
+
details?: {
|
|
90
|
+
[k: string]: {};
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Revealed player identity (agent name, agent id) disclosed at game_over. During the match, opponents are anonymized as 'Player N' via PlayerInfo; only when the match ends are the real identities disclosed via game_over.data.players. Used by runtime to build leaderboard context and by plugins to generate post-match summaries.
|
|
95
|
+
*/
|
|
96
|
+
export interface PlayerIdentity {
|
|
97
|
+
/**
|
|
98
|
+
* PlayerID within this match (p0, p1, ...).
|
|
99
|
+
*/
|
|
100
|
+
player_id: string;
|
|
101
|
+
/**
|
|
102
|
+
* Seat/position index within the match (0 = first player).
|
|
103
|
+
*/
|
|
104
|
+
position: number;
|
|
105
|
+
/**
|
|
106
|
+
* Global agent UUID (from agents table).
|
|
107
|
+
*/
|
|
108
|
+
agent_id: string;
|
|
109
|
+
/**
|
|
110
|
+
* Registered agent name.
|
|
111
|
+
*/
|
|
112
|
+
agent_name: string;
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Public information about a player, as seen by other players during a match. Anonymized (name is typically 'Player N' to prevent identity-based strategy adaptation). `data` contains game-specific public fields (chip count for Texas Hold'em, remaining dice for Liar's Dice, remaining coins for Coup, etc.). Mirrors engine.PlayerInfo in internal/engine/types.go.
|
|
116
|
+
*/
|
|
117
|
+
export interface PlayerInfo {
|
|
118
|
+
/**
|
|
119
|
+
* PlayerID (p0, p1, ...) within this match.
|
|
120
|
+
*/
|
|
121
|
+
id: string;
|
|
122
|
+
/**
|
|
123
|
+
* Display name. During active matches this is anonymized ('Player 1', 'Player 2', ...). At game_over, real agent names are revealed via game_over.data.players.
|
|
124
|
+
*/
|
|
125
|
+
name?: string;
|
|
126
|
+
/**
|
|
127
|
+
* Player status (active, folded, all_in, eliminated, etc.); game-specific values.
|
|
128
|
+
*/
|
|
129
|
+
status: string;
|
|
130
|
+
/**
|
|
131
|
+
* Game-specific public data (chips, remaining dice count, visible cards, etc.).
|
|
132
|
+
*/
|
|
133
|
+
data?: {};
|
|
134
|
+
}
|
|
135
|
+
/**
|
|
136
|
+
* Game rules sent to the agent in game_start.data.rules. Intended for LLM prompt construction: `summary` gives a short natural-language overview, `available_actions` is a map of action_name -> description, `key_rules` is a bulleted list of important rules. Mirrors engine.Rules in internal/engine/types.go.
|
|
137
|
+
*/
|
|
138
|
+
export interface Rules {
|
|
139
|
+
/**
|
|
140
|
+
* Game display name.
|
|
141
|
+
*/
|
|
142
|
+
name: string;
|
|
143
|
+
/**
|
|
144
|
+
* Short natural-language summary of the game (1-3 sentences).
|
|
145
|
+
*/
|
|
146
|
+
summary: string;
|
|
147
|
+
/**
|
|
148
|
+
* Ordered list of game phases if applicable (e.g. preflop, flop, turn, river for Texas Hold'em).
|
|
149
|
+
*/
|
|
150
|
+
phases?: string[];
|
|
151
|
+
/**
|
|
152
|
+
* Map of action name -> short description. Used to inform the LLM what actions exist.
|
|
153
|
+
*/
|
|
154
|
+
available_actions: {
|
|
155
|
+
[k: string]: string;
|
|
156
|
+
};
|
|
157
|
+
/**
|
|
158
|
+
* Bulleted list of important rules worth highlighting in the agent prompt.
|
|
159
|
+
*/
|
|
160
|
+
key_rules: string[];
|
|
161
|
+
}
|
|
162
|
+
/**
|
|
163
|
+
* Action payload for Coup, sent as client_action.data when game == 'coup'. Twelve discriminated variants by `type`. Legality depends on the current phase and the actor's role (actor vs. challenger vs. target vs. influence-loser vs. exchange-returner). server_action_request.data.legal_actions is the authoritative list. Mirrors games/coup/coup.go GetLegalActions() L385 + ValidateAction() L613.
|
|
164
|
+
*/
|
|
165
|
+
export type CoupAction = {
|
|
166
|
+
type: "income";
|
|
167
|
+
data?: {};
|
|
168
|
+
} | {
|
|
169
|
+
type: "foreign_aid";
|
|
170
|
+
data?: {};
|
|
171
|
+
} | {
|
|
172
|
+
type: "coup";
|
|
173
|
+
data: {
|
|
174
|
+
/**
|
|
175
|
+
* Player ID of the target. Must be an alive player other than yourself.
|
|
176
|
+
*/
|
|
177
|
+
target: string;
|
|
178
|
+
};
|
|
179
|
+
} | {
|
|
180
|
+
type: "tax";
|
|
181
|
+
data?: {};
|
|
182
|
+
} | {
|
|
183
|
+
type: "assassinate";
|
|
184
|
+
data: {
|
|
185
|
+
target: string;
|
|
186
|
+
};
|
|
187
|
+
} | {
|
|
188
|
+
type: "steal";
|
|
189
|
+
data: {
|
|
190
|
+
target: string;
|
|
191
|
+
};
|
|
192
|
+
} | {
|
|
193
|
+
type: "exchange";
|
|
194
|
+
data?: {};
|
|
195
|
+
} | {
|
|
196
|
+
type: "challenge";
|
|
197
|
+
data?: {};
|
|
198
|
+
} | {
|
|
199
|
+
type: "pass";
|
|
200
|
+
data?: {};
|
|
201
|
+
} | {
|
|
202
|
+
type: "block";
|
|
203
|
+
data: {
|
|
204
|
+
/**
|
|
205
|
+
* Role claimed for the block. Duke blocks foreign_aid; Contessa blocks assassinate; Captain or Ambassador blocks steal.
|
|
206
|
+
*/
|
|
207
|
+
role: "Duke" | "Contessa" | "Captain" | "Ambassador";
|
|
208
|
+
};
|
|
209
|
+
} | {
|
|
210
|
+
type: "lose_card";
|
|
211
|
+
data: {
|
|
212
|
+
/**
|
|
213
|
+
* Zero-based index into your full `cards` array (hidden + already-revealed). Must point to a currently face-down card. Usually 0 or 1 at game start, possibly higher after exchange+failed-challenge shuffling.
|
|
214
|
+
*/
|
|
215
|
+
card_index: number;
|
|
216
|
+
};
|
|
217
|
+
} | {
|
|
218
|
+
type: "return_cards";
|
|
219
|
+
data: {
|
|
220
|
+
/**
|
|
221
|
+
* Indices into all_exchange_options (your hidden_cards ++ exchange_cards) identifying which cards go back to the deck. Must return exactly (total - original_hidden_count) cards.
|
|
222
|
+
*/
|
|
223
|
+
return_indices: number[];
|
|
224
|
+
/**
|
|
225
|
+
* Echo of the role names at return_indices. Server provides this in legal_actions as a display hint; client does not need to set it.
|
|
226
|
+
*/
|
|
227
|
+
cards?: string[];
|
|
228
|
+
/**
|
|
229
|
+
* Echo of all_exchange_options. Server provides as a display hint.
|
|
230
|
+
*/
|
|
231
|
+
all_cards?: string[];
|
|
232
|
+
[k: string]: any;
|
|
233
|
+
};
|
|
234
|
+
};
|
|
235
|
+
/**
|
|
236
|
+
* Coup-specific event payload, describing the `data` field of common/event.schema.json when the event occurred in a Coup match. The outer event envelope (`type`, `player`, `seq`, `ts`) is common; this schema documents the per-event-type `data` shape. Discriminator is the outer `type` field. Mirrors games/coup/coup.go emission sites.
|
|
237
|
+
*/
|
|
238
|
+
export type CoupEvent = {
|
|
239
|
+
action: "income" | "foreign_aid" | "coup" | "tax" | "assassinate" | "steal" | "exchange";
|
|
240
|
+
/**
|
|
241
|
+
* Target player ID for coup/assassinate/steal.
|
|
242
|
+
*/
|
|
243
|
+
target?: string;
|
|
244
|
+
/**
|
|
245
|
+
* Role claimed for tax/assassinate/steal/exchange. Absent for income/foreign_aid/coup.
|
|
246
|
+
*/
|
|
247
|
+
claimed_role?: "Duke" | "Assassin" | "Captain" | "Ambassador";
|
|
248
|
+
} | {
|
|
249
|
+
player: string;
|
|
250
|
+
} | {
|
|
251
|
+
challenger: string;
|
|
252
|
+
actor: string;
|
|
253
|
+
claimed_role: "Duke" | "Assassin" | "Captain" | "Ambassador";
|
|
254
|
+
} | {
|
|
255
|
+
result: "fail" | "success";
|
|
256
|
+
/**
|
|
257
|
+
* Role name of the card briefly exposed during a failed-challenge reshuffle. Present only when result == 'fail'.
|
|
258
|
+
*/
|
|
259
|
+
revealed_card?: "Duke" | "Assassin" | "Captain" | "Ambassador" | "Contessa";
|
|
260
|
+
actor: string;
|
|
261
|
+
challenger: string;
|
|
262
|
+
[k: string]: any;
|
|
263
|
+
} | {
|
|
264
|
+
blocker: string;
|
|
265
|
+
claimed_role: "Duke" | "Contessa" | "Captain" | "Ambassador";
|
|
266
|
+
/**
|
|
267
|
+
* The pending action being blocked.
|
|
268
|
+
*/
|
|
269
|
+
action: "foreign_aid" | "assassinate" | "steal";
|
|
270
|
+
} | {
|
|
271
|
+
blocker: string;
|
|
272
|
+
} | {
|
|
273
|
+
challenger: string;
|
|
274
|
+
blocker: string;
|
|
275
|
+
claimed_role: "Duke" | "Contessa" | "Captain" | "Ambassador";
|
|
276
|
+
} | {
|
|
277
|
+
result: "fail" | "success";
|
|
278
|
+
/**
|
|
279
|
+
* Role exposed during reshuffle on result=='fail'.
|
|
280
|
+
*/
|
|
281
|
+
revealed_card?: "Duke" | "Contessa" | "Captain" | "Ambassador";
|
|
282
|
+
blocker: string;
|
|
283
|
+
challenger: string;
|
|
284
|
+
[k: string]: any;
|
|
285
|
+
} | {
|
|
286
|
+
player: string;
|
|
287
|
+
card: "Duke" | "Assassin" | "Captain" | "Ambassador" | "Contessa";
|
|
288
|
+
card_index: number;
|
|
289
|
+
} | {
|
|
290
|
+
action: "exchange";
|
|
291
|
+
drawn_count: number;
|
|
292
|
+
} | {
|
|
293
|
+
player: string;
|
|
294
|
+
returned_count: number;
|
|
295
|
+
} | {
|
|
296
|
+
action: "foreign_aid" | "tax" | "assassinate" | "steal";
|
|
297
|
+
/**
|
|
298
|
+
* Actor's coin count after the action. Present for foreign_aid/tax/steal.
|
|
299
|
+
*/
|
|
300
|
+
coins_now?: number;
|
|
301
|
+
/**
|
|
302
|
+
* Target player ID. Present for assassinate/steal.
|
|
303
|
+
*/
|
|
304
|
+
target?: string;
|
|
305
|
+
/**
|
|
306
|
+
* Coins actually stolen (capped at target's pre-steal balance). Present for steal.
|
|
307
|
+
*/
|
|
308
|
+
stolen?: number;
|
|
309
|
+
[k: string]: any;
|
|
310
|
+
} | {
|
|
311
|
+
/**
|
|
312
|
+
* Player ID of the winner. Empty string if zero alive players remained.
|
|
313
|
+
*/
|
|
314
|
+
winner: string;
|
|
315
|
+
};
|
|
316
|
+
/**
|
|
317
|
+
* Rules payload for Coup, delivered in server_game_start.data.rules when game == 'coup'. Mirrors games/coup/coup.go Game.Rules(). Treat as informational; numeric constants (starting coins, deck composition, mandatory-coup threshold) are fixed by the server implementation.
|
|
318
|
+
*/
|
|
319
|
+
export interface CoupRules {
|
|
320
|
+
name: "Coup";
|
|
321
|
+
/**
|
|
322
|
+
* Free-form summary paragraph; treat as informational.
|
|
323
|
+
*/
|
|
324
|
+
summary: string;
|
|
325
|
+
/**
|
|
326
|
+
* Human-readable phase descriptions (action, challenge_action, block, challenge_block, lose_influence, exchange_return).
|
|
327
|
+
*/
|
|
328
|
+
phases?: string[];
|
|
329
|
+
available_actions: {
|
|
330
|
+
income: string;
|
|
331
|
+
foreign_aid: string;
|
|
332
|
+
coup: string;
|
|
333
|
+
tax: string;
|
|
334
|
+
assassinate: string;
|
|
335
|
+
steal: string;
|
|
336
|
+
exchange: string;
|
|
337
|
+
challenge: string;
|
|
338
|
+
pass: string;
|
|
339
|
+
block: string;
|
|
340
|
+
lose_card: string;
|
|
341
|
+
return_cards: string;
|
|
342
|
+
};
|
|
343
|
+
key_rules: string[];
|
|
344
|
+
}
|
|
345
|
+
/**
|
|
346
|
+
* Per-player state delivered in server_action_request.data.state when game == 'coup'. Built by games/coup/coup.go GetPlayerView() L1592. Mixes **public fields** (phase, current_turn, pending_action, pending_target, claimed_role, blocker, block_role, influence_loser, turn_log, winner) with **private fields** (your_cards, your_revealed, coins, exchange_cards, all_exchange_options). The outer PlayerView.players array carries coins + hidden_cards count + revealed cards for everyone (public); only the recipient sees their own hidden card roles via your_cards.
|
|
347
|
+
*/
|
|
348
|
+
export interface CoupState {
|
|
349
|
+
/**
|
|
350
|
+
* State machine phase. 'action' = actor chooses. 'challenge_action' = others may challenge role claim. 'block' = eligible players may block. 'challenge_block' = anyone may challenge the block. 'lose_influence' = a player reveals a card. 'exchange_return' = Ambassador picks cards to return.
|
|
351
|
+
*/
|
|
352
|
+
phase: "action" | "challenge_action" | "block" | "challenge_block" | "lose_influence" | "exchange_return" | "done";
|
|
353
|
+
/**
|
|
354
|
+
* Player ID whose turn it is (i.e. the actor of this action). Not necessarily the player being prompted — see legal_actions in the message envelope.
|
|
355
|
+
*/
|
|
356
|
+
current_turn: string;
|
|
357
|
+
/**
|
|
358
|
+
* The action being resolved. Present in all phases except 'action' (when the actor is picking) and 'done'.
|
|
359
|
+
*/
|
|
360
|
+
pending_action?: "income" | "foreign_aid" | "coup" | "tax" | "assassinate" | "steal" | "exchange";
|
|
361
|
+
/**
|
|
362
|
+
* Player ID target of the pending action (coup/assassinate/steal). Omitted when action has no target.
|
|
363
|
+
*/
|
|
364
|
+
pending_target?: string;
|
|
365
|
+
/**
|
|
366
|
+
* Role the actor claims for their action (Tax=Duke, Assassinate=Assassin, Steal=Captain, Exchange=Ambassador). Omitted for income / foreign_aid / coup (no role claim).
|
|
367
|
+
*/
|
|
368
|
+
claimed_role?: "Duke" | "Assassin" | "Captain" | "Ambassador" | "Contessa";
|
|
369
|
+
/**
|
|
370
|
+
* Player ID who has declared a block. Present in 'challenge_block' phase; absent otherwise.
|
|
371
|
+
*/
|
|
372
|
+
blocker?: string;
|
|
373
|
+
/**
|
|
374
|
+
* Role the blocker claims (Duke blocks foreign_aid; Contessa blocks assassinate; Captain or Ambassador blocks steal). Present in 'challenge_block' phase.
|
|
375
|
+
*/
|
|
376
|
+
block_role?: "Duke" | "Contessa" | "Captain" | "Ambassador";
|
|
377
|
+
/**
|
|
378
|
+
* Player ID who must choose a card to reveal. Present in 'lose_influence' phase.
|
|
379
|
+
*/
|
|
380
|
+
influence_loser?: string;
|
|
381
|
+
/**
|
|
382
|
+
* Narrative trace of this turn's resolution. Fields populate as the turn progresses. All entries refer to the current turn; cleared when advanceTurn() runs.
|
|
383
|
+
*/
|
|
384
|
+
turn_log?: {
|
|
385
|
+
action?: "income" | "foreign_aid" | "coup" | "tax" | "assassinate" | "steal" | "exchange";
|
|
386
|
+
actor?: string;
|
|
387
|
+
target?: string;
|
|
388
|
+
claimed_role?: "Duke" | "Assassin" | "Captain" | "Ambassador" | "Contessa";
|
|
389
|
+
challenger?: string;
|
|
390
|
+
/**
|
|
391
|
+
* 'success' = actor was lying, actor loses influence. 'fail' = actor was truthful, challenger loses influence.
|
|
392
|
+
*/
|
|
393
|
+
challenge_result?: "success" | "fail";
|
|
394
|
+
blocker?: string;
|
|
395
|
+
block_role?: "Duke" | "Contessa" | "Captain" | "Ambassador";
|
|
396
|
+
block_challenger?: string;
|
|
397
|
+
/**
|
|
398
|
+
* 'success' = blocker was lying, blocker loses influence. 'fail' = blocker was truthful, block_challenger loses influence.
|
|
399
|
+
*/
|
|
400
|
+
block_challenge_result?: "success" | "fail";
|
|
401
|
+
};
|
|
402
|
+
/**
|
|
403
|
+
* **PRIVATE.** Your unrevealed (face-down) cards. 1-2 entries. Replaced by server after a successful-claim challenge shuffle-and-redraw.
|
|
404
|
+
*
|
|
405
|
+
* @maxItems 2
|
|
406
|
+
*/
|
|
407
|
+
your_cards?: [] | ["Duke" | "Assassin" | "Captain" | "Ambassador" | "Contessa"] | [
|
|
408
|
+
"Duke" | "Assassin" | "Captain" | "Ambassador" | "Contessa",
|
|
409
|
+
"Duke" | "Assassin" | "Captain" | "Ambassador" | "Contessa"
|
|
410
|
+
];
|
|
411
|
+
/**
|
|
412
|
+
* Your face-up (revealed) cards. Public — opponents' equivalent appears in the players array's `revealed` field.
|
|
413
|
+
*/
|
|
414
|
+
your_revealed?: ("Duke" | "Assassin" | "Captain" | "Ambassador" | "Contessa")[];
|
|
415
|
+
/**
|
|
416
|
+
* **PRIVATE** convenience field (opponents' coins are in the players array's `coins`). Your current coin count.
|
|
417
|
+
*/
|
|
418
|
+
coins?: number;
|
|
419
|
+
/**
|
|
420
|
+
* **PRIVATE.** The 2 cards drawn from the deck for your pending Exchange. Present only when phase == 'exchange_return' AND you are the actor.
|
|
421
|
+
*/
|
|
422
|
+
exchange_cards?: ("Duke" | "Assassin" | "Captain" | "Ambassador" | "Contessa")[];
|
|
423
|
+
/**
|
|
424
|
+
* **PRIVATE.** Convenience view = your_cards ++ exchange_cards. Present only when phase == 'exchange_return' AND you are the actor. Indices here are the ones you pass to return_cards.
|
|
425
|
+
*/
|
|
426
|
+
all_exchange_options?: ("Duke" | "Assassin" | "Captain" | "Ambassador" | "Contessa")[];
|
|
427
|
+
/**
|
|
428
|
+
* Player ID of the match winner. Present only when phase == 'done'.
|
|
429
|
+
*/
|
|
430
|
+
winner?: string;
|
|
431
|
+
[k: string]: any;
|
|
432
|
+
}
|
|
433
|
+
/**
|
|
434
|
+
* Action payload for Liar's Dice, sent as client_action.data when game == 'liars_dice'. Two discriminated variants by `type`. `challenge` is only legal when there is a current bid. `bid` has subtype constraints the server enforces via ValidateAction: must be strictly higher than current bid (same quantity + higher face, or higher quantity), and quantity must not exceed total_dice in play. Mirrors games/liarsdice/liarsdice.go GetLegalActions() + ValidateAction().
|
|
435
|
+
*/
|
|
436
|
+
export type LiarsDiceAction = {
|
|
437
|
+
type: "bid";
|
|
438
|
+
data: {
|
|
439
|
+
/**
|
|
440
|
+
* Claimed total count of the face value across all alive players' dice. Must be <= total_dice in state.
|
|
441
|
+
*/
|
|
442
|
+
quantity: number;
|
|
443
|
+
/**
|
|
444
|
+
* Face value you are bidding on (1-6). If face == 1, ones are NOT wild for this bid.
|
|
445
|
+
*/
|
|
446
|
+
face: number;
|
|
447
|
+
};
|
|
448
|
+
} | {
|
|
449
|
+
type: "challenge";
|
|
450
|
+
data?: {};
|
|
451
|
+
};
|
|
452
|
+
/**
|
|
453
|
+
* Liar's Dice-specific event payload, describing the `data` field of common/event.schema.json when the event occurred in a Liar's Dice match. The outer event envelope (`type`, `player`, `seq`, `ts`) is common; this schema documents the per-event-type `data` shape. Discriminator is the outer `type` field. Mirrors games/liarsdice/liarsdice.go emission sites.
|
|
454
|
+
*/
|
|
455
|
+
export type LiarsDiceEvent = {
|
|
456
|
+
/**
|
|
457
|
+
* Claimed count of the face value across all alive players' dice.
|
|
458
|
+
*/
|
|
459
|
+
quantity: number;
|
|
460
|
+
/**
|
|
461
|
+
* Face value bid upon.
|
|
462
|
+
*/
|
|
463
|
+
face: number;
|
|
464
|
+
} | {
|
|
465
|
+
/**
|
|
466
|
+
* Player ID of the challenger (same as outer `player`).
|
|
467
|
+
*/
|
|
468
|
+
challenger: string;
|
|
469
|
+
/**
|
|
470
|
+
* Player ID who made the bid being challenged.
|
|
471
|
+
*/
|
|
472
|
+
bidder: string;
|
|
473
|
+
bid_quantity: number;
|
|
474
|
+
bid_face: number;
|
|
475
|
+
/**
|
|
476
|
+
* Actual count of matching face values. If bid_face != 1, ones count as wild.
|
|
477
|
+
*/
|
|
478
|
+
actual_count: number;
|
|
479
|
+
/**
|
|
480
|
+
* True iff actual_count >= bid_quantity. When true, challenger loses a die; when false, bidder loses.
|
|
481
|
+
*/
|
|
482
|
+
bid_met: boolean;
|
|
483
|
+
/**
|
|
484
|
+
* Map of player_id -> array of their revealed dice face values (1-6). Only alive players at challenge time are included.
|
|
485
|
+
*/
|
|
486
|
+
all_dice: {
|
|
487
|
+
[k: string]: number[];
|
|
488
|
+
};
|
|
489
|
+
/**
|
|
490
|
+
* Player ID who loses a die.
|
|
491
|
+
*/
|
|
492
|
+
loser: string;
|
|
493
|
+
} | {
|
|
494
|
+
/**
|
|
495
|
+
* Player ID eliminated (same as outer `player`).
|
|
496
|
+
*/
|
|
497
|
+
player: string;
|
|
498
|
+
} | {
|
|
499
|
+
/**
|
|
500
|
+
* New round number (>= 2).
|
|
501
|
+
*/
|
|
502
|
+
round: number;
|
|
503
|
+
/**
|
|
504
|
+
* Map of player_id -> dice count for alive players only.
|
|
505
|
+
*/
|
|
506
|
+
dice_counts: {
|
|
507
|
+
[k: string]: number;
|
|
508
|
+
};
|
|
509
|
+
} | {
|
|
510
|
+
/**
|
|
511
|
+
* Player ID of the winner. Empty string if no winner (e.g. simultaneous elimination).
|
|
512
|
+
*/
|
|
513
|
+
winner: string;
|
|
514
|
+
} | {
|
|
515
|
+
/**
|
|
516
|
+
* Player ID disconnected (same as outer `player`).
|
|
517
|
+
*/
|
|
518
|
+
player: string;
|
|
519
|
+
};
|
|
520
|
+
/**
|
|
521
|
+
* Rules payload for Liar's Dice, delivered in server_game_start.data.rules when game == 'liars_dice'. Mirrors games/liarsdice/liarsdice.go Game.Rules(). Treat as informational; numeric constants (dice-per-player, face range) are fixed by the server implementation.
|
|
522
|
+
*/
|
|
523
|
+
export interface LiarsDiceRules {
|
|
524
|
+
name: "Liar's Dice";
|
|
525
|
+
/**
|
|
526
|
+
* Free-form summary paragraph; treat as informational.
|
|
527
|
+
*/
|
|
528
|
+
summary: string;
|
|
529
|
+
/**
|
|
530
|
+
* Human-readable phase descriptions (bidding is the only phase in this implementation).
|
|
531
|
+
*/
|
|
532
|
+
phases?: string[];
|
|
533
|
+
available_actions: {
|
|
534
|
+
bid: string;
|
|
535
|
+
challenge: string;
|
|
536
|
+
};
|
|
537
|
+
key_rules: string[];
|
|
538
|
+
}
|
|
539
|
+
/**
|
|
540
|
+
* Per-player state delivered in server_action_request.data.state when game == 'liars_dice'. Built by games/liarsdice/liarsdice.go GetPlayerView(). Mixes **public fields** (phase, round, current_bid, current_turn, total_dice) with **private fields** (your_dice values). The outer PlayerView.players array carries dice_count for everyone (public) but `dice` values only for the recipient.
|
|
541
|
+
*/
|
|
542
|
+
export interface LiarsDiceState {
|
|
543
|
+
/**
|
|
544
|
+
* Current phase. 'bidding' = a player may bid or challenge. 'done' = match is over.
|
|
545
|
+
*/
|
|
546
|
+
phase: "bidding" | "done";
|
|
547
|
+
/**
|
|
548
|
+
* Current round (1-based). Increments after each challenge that does not end the match.
|
|
549
|
+
*/
|
|
550
|
+
round: number;
|
|
551
|
+
/**
|
|
552
|
+
* The most recent bid this round. Omitted at the start of a round (first bidder has no bid to beat).
|
|
553
|
+
*/
|
|
554
|
+
current_bid?: {
|
|
555
|
+
/**
|
|
556
|
+
* Claimed total count of `face` across all alive players' dice.
|
|
557
|
+
*/
|
|
558
|
+
quantity: number;
|
|
559
|
+
/**
|
|
560
|
+
* Face value (1-6). Note: if face == 1, ones are NOT wild for the challenge resolution.
|
|
561
|
+
*/
|
|
562
|
+
face: number;
|
|
563
|
+
/**
|
|
564
|
+
* Player ID who made this bid.
|
|
565
|
+
*/
|
|
566
|
+
bidder: string;
|
|
567
|
+
};
|
|
568
|
+
/**
|
|
569
|
+
* Player ID currently on the action. Omitted when phase == 'done'.
|
|
570
|
+
*/
|
|
571
|
+
current_turn?: string;
|
|
572
|
+
/**
|
|
573
|
+
* Sum of dice_count across all alive players. Upper bound for any bid quantity. Omitted when phase == 'done'.
|
|
574
|
+
*/
|
|
575
|
+
total_dice?: number;
|
|
576
|
+
/**
|
|
577
|
+
* **PRIVATE.** Your current dice face values. Length equals your_dice_count. Omitted when recipient is eliminated or not in game.
|
|
578
|
+
*/
|
|
579
|
+
your_dice?: number[];
|
|
580
|
+
/**
|
|
581
|
+
* **PRIVATE.** Number of dice you have remaining (0-5). Omitted when recipient is eliminated or not in game.
|
|
582
|
+
*/
|
|
583
|
+
your_dice_count?: number;
|
|
584
|
+
/**
|
|
585
|
+
* Player ID of the match winner. Present only when phase == 'done' and there is a surviving player.
|
|
586
|
+
*/
|
|
587
|
+
winner?: string;
|
|
588
|
+
[k: string]: any;
|
|
589
|
+
}
|
|
590
|
+
/**
|
|
591
|
+
* Action payload for Texas Hold'em, sent as client_action.data when game == 'texas_holdem'. One of five discriminated variants by `type`. Legal actions at any point are enumerated in server_action_request.data.legal_actions; client must pick one of those. Mirrors games/texasholdem/texasholdem.go GetLegalActions() + ValidateAction().
|
|
592
|
+
*/
|
|
593
|
+
export type TexasHoldemAction = {
|
|
594
|
+
type: "fold";
|
|
595
|
+
data?: {};
|
|
596
|
+
} | {
|
|
597
|
+
type: "check";
|
|
598
|
+
data?: {};
|
|
599
|
+
} | {
|
|
600
|
+
type: "call";
|
|
601
|
+
data: {
|
|
602
|
+
/**
|
|
603
|
+
* Chips to call. Must equal server's suggested call amount from legal_actions[call].data.amount. Short-stack auto-caps to remaining chips.
|
|
604
|
+
*/
|
|
605
|
+
amount: number;
|
|
606
|
+
};
|
|
607
|
+
} | {
|
|
608
|
+
type: "raise";
|
|
609
|
+
data: {
|
|
610
|
+
/**
|
|
611
|
+
* Total bet size (NOT the delta). Must be >= min_raise total and <= max (all-in). Server provides min/max in legal_actions[raise].data.{min,max}.
|
|
612
|
+
*/
|
|
613
|
+
amount: number;
|
|
614
|
+
/**
|
|
615
|
+
* Echo of server-provided min (not required on outbound).
|
|
616
|
+
*/
|
|
617
|
+
min?: number;
|
|
618
|
+
/**
|
|
619
|
+
* Echo of server-provided max (not required on outbound).
|
|
620
|
+
*/
|
|
621
|
+
max?: number;
|
|
622
|
+
};
|
|
623
|
+
} | {
|
|
624
|
+
type: "allin";
|
|
625
|
+
data?: {};
|
|
626
|
+
};
|
|
627
|
+
/**
|
|
628
|
+
* Per-match configuration delivered in server_game_start.data.config when game == 'texas_holdem'. These are optional overrides; when omitted, server uses defaults from games/texasholdem/texasholdem.go NewState() (sb=200, bb=400, starting_chips=10000, max_hands=10). All values arrive as JSON numbers (Go side casts from float64).
|
|
629
|
+
*/
|
|
630
|
+
export interface TexasHoldemConfig {
|
|
631
|
+
/**
|
|
632
|
+
* Small blind amount for early hands. Default 200. Doubles at hand 6 automatically (server-side).
|
|
633
|
+
*/
|
|
634
|
+
small_blind?: number;
|
|
635
|
+
/**
|
|
636
|
+
* Big blind amount for early hands. Default 400.
|
|
637
|
+
*/
|
|
638
|
+
big_blind?: number;
|
|
639
|
+
/**
|
|
640
|
+
* Per-player starting chips. Default 10000.
|
|
641
|
+
*/
|
|
642
|
+
starting_chips?: number;
|
|
643
|
+
/**
|
|
644
|
+
* Number of hands in the match. Default 10. Match ends after max_hands OR when only one player has chips.
|
|
645
|
+
*/
|
|
646
|
+
max_hands?: number;
|
|
647
|
+
[k: string]: any;
|
|
648
|
+
}
|
|
649
|
+
/**
|
|
650
|
+
* Texas Hold'em-specific event payload, describing the `data` field of common/event.schema.json when the event occurred in a Texas Hold'em match. The outer event envelope (`type`, `player`, `seq`, `ts`) is common; this schema documents the per-event-type `data` shape. Discriminator is the outer `type` field. Mirrors games/texasholdem/texasholdem.go emission sites.
|
|
651
|
+
*/
|
|
652
|
+
export type TexasHoldemEvent = {
|
|
653
|
+
hand_num: number;
|
|
654
|
+
max_hands: number;
|
|
655
|
+
/**
|
|
656
|
+
* Player ID of the dealer this hand.
|
|
657
|
+
*/
|
|
658
|
+
dealer: string;
|
|
659
|
+
/**
|
|
660
|
+
* Map of player_id -> pre-blind chip count.
|
|
661
|
+
*/
|
|
662
|
+
chips: {
|
|
663
|
+
[k: string]: number;
|
|
664
|
+
};
|
|
665
|
+
small_blind: number;
|
|
666
|
+
big_blind: number;
|
|
667
|
+
} | {
|
|
668
|
+
action: "small_blind" | "big_blind" | "fold" | "check" | "call" | "raise" | "allin";
|
|
669
|
+
/**
|
|
670
|
+
* Chips bet this action (delta). Present for blinds/call/raise/allin; omitted for fold/check.
|
|
671
|
+
*/
|
|
672
|
+
amount?: number;
|
|
673
|
+
/**
|
|
674
|
+
* Player's total bet this round after this action.
|
|
675
|
+
*/
|
|
676
|
+
total_bet?: number;
|
|
677
|
+
[k: string]: any;
|
|
678
|
+
} | {
|
|
679
|
+
/**
|
|
680
|
+
* Card notation (e.g. ['2h', '3d', '7s'] for flop).
|
|
681
|
+
*/
|
|
682
|
+
cards: string[];
|
|
683
|
+
phase?: "flop" | "turn" | "river";
|
|
684
|
+
[k: string]: any;
|
|
685
|
+
} | {
|
|
686
|
+
/**
|
|
687
|
+
* The player's 2 hole cards.
|
|
688
|
+
*
|
|
689
|
+
* @minItems 2
|
|
690
|
+
* @maxItems 2
|
|
691
|
+
*/
|
|
692
|
+
cards: [string, string];
|
|
693
|
+
} | {
|
|
694
|
+
/**
|
|
695
|
+
* Player IDs who won (tie-split gives multiple entries).
|
|
696
|
+
*/
|
|
697
|
+
winners: string[];
|
|
698
|
+
pot: number;
|
|
699
|
+
/**
|
|
700
|
+
* How the hand was decided (e.g. 'all_others_folded', 'showdown').
|
|
701
|
+
*/
|
|
702
|
+
reason?: string;
|
|
703
|
+
/**
|
|
704
|
+
* Per-player cards + hand-ranking at showdown (only when reason='showdown'). Key = player_id.
|
|
705
|
+
*/
|
|
706
|
+
showdown?: {
|
|
707
|
+
[k: string]: any;
|
|
708
|
+
};
|
|
709
|
+
[k: string]: any;
|
|
710
|
+
} | {
|
|
711
|
+
/**
|
|
712
|
+
* Player ID with most chips at match end. Empty string on tie.
|
|
713
|
+
*/
|
|
714
|
+
winner: string;
|
|
715
|
+
/**
|
|
716
|
+
* Map of player_id -> final chip count.
|
|
717
|
+
*/
|
|
718
|
+
final_chips: {
|
|
719
|
+
[k: string]: number;
|
|
720
|
+
};
|
|
721
|
+
[k: string]: any;
|
|
722
|
+
} | {
|
|
723
|
+
reason: string;
|
|
724
|
+
[k: string]: any;
|
|
725
|
+
};
|
|
726
|
+
/**
|
|
727
|
+
* Rules payload for Texas Hold'em, delivered in server_game_start.data.rules when game == 'texas_holdem'. Mirrors games/texasholdem/texasholdem.go Game.Rules(). The server's exact text may evolve; runtime should treat rules as informational and not parse numeric values from strings (e.g. blind amounts come from the `config` field, not from parsing `summary`).
|
|
728
|
+
*/
|
|
729
|
+
export interface TexasHoldemRules {
|
|
730
|
+
name: "No-Limit Texas Hold'em";
|
|
731
|
+
/**
|
|
732
|
+
* Free-form summary paragraph; treat as informational.
|
|
733
|
+
*/
|
|
734
|
+
summary: string;
|
|
735
|
+
/**
|
|
736
|
+
* Human-readable phase descriptions (preflop/flop/turn/river/showdown).
|
|
737
|
+
*/
|
|
738
|
+
phases?: string[];
|
|
739
|
+
available_actions: {
|
|
740
|
+
fold: string;
|
|
741
|
+
check: string;
|
|
742
|
+
call: string;
|
|
743
|
+
raise: string;
|
|
744
|
+
allin: string;
|
|
745
|
+
};
|
|
746
|
+
key_rules: string[];
|
|
747
|
+
}
|
|
748
|
+
/**
|
|
749
|
+
* Per-player state delivered in server_action_request.data.state (and server_game_state.data.state) when game == 'texas_holdem'. Built by games/texasholdem/texasholdem.go GetPlayerView(). Mixes **public fields** (visible to all: phase, community_cards, pot, etc.) with **private fields** (only visible to recipient: your_hand, your_chips, your_bet, etc.). At showdown (phase == 'done'), all non-folded players' hole cards are revealed via optional `player_N_hand` fields.
|
|
750
|
+
*/
|
|
751
|
+
export interface TexasHoldemState {
|
|
752
|
+
/**
|
|
753
|
+
* Current hand phase. 'showdown' = cards compared, 'done' = match fully complete.
|
|
754
|
+
*/
|
|
755
|
+
phase: "preflop" | "flop" | "turn" | "river" | "showdown" | "done";
|
|
756
|
+
/**
|
|
757
|
+
* 0 cards preflop; 3 on flop; 4 on turn; 5 on river.
|
|
758
|
+
*/
|
|
759
|
+
community_cards: string[];
|
|
760
|
+
/**
|
|
761
|
+
* Total chips in all pots (main + any side pots) this hand.
|
|
762
|
+
*/
|
|
763
|
+
pot: number;
|
|
764
|
+
/**
|
|
765
|
+
* The highest bet any player has contributed this betting round. To continue, you must match this (by call/raise/allin) or fold.
|
|
766
|
+
*/
|
|
767
|
+
current_bet: number;
|
|
768
|
+
/**
|
|
769
|
+
* Seat index of the dealer button this hand.
|
|
770
|
+
*/
|
|
771
|
+
dealer: number;
|
|
772
|
+
/**
|
|
773
|
+
* Player ID of the dealer this hand.
|
|
774
|
+
*/
|
|
775
|
+
dealer_id: string;
|
|
776
|
+
/**
|
|
777
|
+
* Current hand number (1-based).
|
|
778
|
+
*/
|
|
779
|
+
hand_num: number;
|
|
780
|
+
/**
|
|
781
|
+
* Total hands in this match.
|
|
782
|
+
*/
|
|
783
|
+
max_hands: number;
|
|
784
|
+
small_blind: number;
|
|
785
|
+
big_blind: number;
|
|
786
|
+
/**
|
|
787
|
+
* Player ID currently on the action. Omitted when hand is over or match is done.
|
|
788
|
+
*/
|
|
789
|
+
current_player_id?: string;
|
|
790
|
+
/**
|
|
791
|
+
* Player IDs in the order they are expected to act this phase (clockwise from first-to-act, busted players removed). Omitted at showdown/done.
|
|
792
|
+
*/
|
|
793
|
+
action_order?: string[];
|
|
794
|
+
/**
|
|
795
|
+
* **PRIVATE.** Your two hole cards.
|
|
796
|
+
*
|
|
797
|
+
* @minItems 2
|
|
798
|
+
* @maxItems 2
|
|
799
|
+
*/
|
|
800
|
+
your_hand?: [string, string];
|
|
801
|
+
/**
|
|
802
|
+
* **PRIVATE.** Your current stack.
|
|
803
|
+
*/
|
|
804
|
+
your_chips?: number;
|
|
805
|
+
/**
|
|
806
|
+
* **PRIVATE.** Chips you've committed this round (not total-hand).
|
|
807
|
+
*/
|
|
808
|
+
your_bet?: number;
|
|
809
|
+
/**
|
|
810
|
+
* **PRIVATE.** Your seat index.
|
|
811
|
+
*/
|
|
812
|
+
your_seat?: number;
|
|
813
|
+
/**
|
|
814
|
+
* **PRIVATE.** Position name (e.g. 'BTN', 'SB', 'BB', 'UTG', 'MP', 'CO').
|
|
815
|
+
*/
|
|
816
|
+
your_position?: string;
|
|
817
|
+
/**
|
|
818
|
+
* **PRIVATE.** Your player ID. Matches server_game_start.data.your_player_id.
|
|
819
|
+
*/
|
|
820
|
+
your_player_id?: string;
|
|
821
|
+
[k: string]: any;
|
|
822
|
+
}
|
|
823
|
+
/**
|
|
824
|
+
* Sent by the client in response to `action_request`. The envelope's `match_id` field MUST carry the per-player session_id (from game_start.data.match_id / action_request.data.match_id). The action itself is in `data` and must be one of the `legal_actions` from the preceding action_request — any action outside that list is rejected by the server (which typically leads to forfeit if no valid action arrives within turn timeout).
|
|
825
|
+
*/
|
|
826
|
+
export interface MsgAction {
|
|
827
|
+
type: "action";
|
|
828
|
+
/**
|
|
829
|
+
* REQUIRED for this message type. Must match the session_id from game_start / action_request. Server rejects with error if empty or unparseable.
|
|
830
|
+
*/
|
|
831
|
+
match_id: string;
|
|
832
|
+
data: Action;
|
|
833
|
+
}
|
|
834
|
+
/**
|
|
835
|
+
* Sent by the client to request entry into the matchmaking queue for a given game. Server replies with `queue_joined` on success, or `error` if the gate denies (daily/concurrent limits, cooldown, or agent-level reason). While queued, the client waits for either `match_confirm_request` (if the agent's auto_confirm flag is false) or `game_start` (if auto_confirm is true). Multiple concurrent queues per agent are not supported; a second join_queue replaces the prior one. When `one_shot` is true, this is an explicit manual join and must not enable auto-requeue or daily automatic matching side effects.
|
|
836
|
+
*/
|
|
837
|
+
export interface MsgJoinQueue {
|
|
838
|
+
type: "join_queue";
|
|
839
|
+
data: {
|
|
840
|
+
/**
|
|
841
|
+
* Game name; must be one of the games listed in `welcome.data.games`.
|
|
842
|
+
*/
|
|
843
|
+
game: string;
|
|
844
|
+
/**
|
|
845
|
+
* Match mode. Server defaults to "ranked" when omitted or empty.
|
|
846
|
+
*/
|
|
847
|
+
mode?: string;
|
|
848
|
+
/**
|
|
849
|
+
* Explicit manual match request. Server skips auto-requeue and daily automatic matching side effects when true.
|
|
850
|
+
*/
|
|
851
|
+
one_shot?: boolean;
|
|
852
|
+
};
|
|
853
|
+
/**
|
|
854
|
+
* Envelope-level field, not used for join_queue. Keep omitted or empty.
|
|
855
|
+
*/
|
|
856
|
+
match_id?: string;
|
|
857
|
+
}
|
|
858
|
+
/**
|
|
859
|
+
* Sent by the client to exit the matchmaking queue. Server replies with `queue_left`. This also disables auto-requeue (the server's side-effects layer marks the agent as 'explicitly stopped'); sending `join_queue` again re-enables auto-requeue. No data payload is required.
|
|
860
|
+
*/
|
|
861
|
+
export interface MsgLeaveQueue {
|
|
862
|
+
type: "leave_queue";
|
|
863
|
+
/**
|
|
864
|
+
* Empty; no fields required.
|
|
865
|
+
*/
|
|
866
|
+
data?: {};
|
|
867
|
+
match_id?: string;
|
|
868
|
+
}
|
|
869
|
+
/**
|
|
870
|
+
* Sent by the client in response to `match_confirm_request`, indicating readiness to start the match. The `confirm_id` must echo the one received. Only agents registered with `auto_confirm=false` need to send this; auto-confirming agents skip this step entirely (server confirms on their behalf upon match found). Failure to send this within match_confirm_request.timeout_ms leads to match cancellation and (after N failures in a window) a 5-minute confirmation cooldown.
|
|
871
|
+
*/
|
|
872
|
+
export interface MsgMatchConfirm {
|
|
873
|
+
type: "match_confirm";
|
|
874
|
+
data: {
|
|
875
|
+
/**
|
|
876
|
+
* The confirm_id from the corresponding match_confirm_request.
|
|
877
|
+
*/
|
|
878
|
+
confirm_id: string;
|
|
879
|
+
};
|
|
880
|
+
match_id?: string;
|
|
881
|
+
}
|
|
882
|
+
/**
|
|
883
|
+
* Sent by the outbound Bridge after a readiness_check. Reports whether the local OpenClaw/Hermes/mock runtime is ready without exposing provider keys or local endpoint secrets.
|
|
884
|
+
*/
|
|
885
|
+
export interface MsgRuntimeStatus {
|
|
886
|
+
type: "runtime_status";
|
|
887
|
+
data: {
|
|
888
|
+
request_id: string;
|
|
889
|
+
ready: boolean;
|
|
890
|
+
runtime_type: "openclaw" | "hermes" | "mock";
|
|
891
|
+
runtime_name?: string;
|
|
892
|
+
checked_at: string;
|
|
893
|
+
detail?: string;
|
|
894
|
+
};
|
|
895
|
+
/**
|
|
896
|
+
* Envelope-level field, not used for runtime_status.
|
|
897
|
+
*/
|
|
898
|
+
match_id?: string;
|
|
899
|
+
}
|
|
900
|
+
/**
|
|
901
|
+
* Sent by the server when it is the client's turn to act. `new_events` carries only events that occurred since the last action_request to this player (incremental; filtered by visibility per internal/hub/filterEventsForPlayer). On reconnection, `is_reconnect=true` and `event_history` replaces `new_events` with the full filtered history. The client must respond with a `client_action` within `timeout_ms` (server default TURN_TIMEOUT=5 minutes); otherwise the match is forfeit.
|
|
902
|
+
*/
|
|
903
|
+
export interface MsgActionRequest {
|
|
904
|
+
type: "action_request";
|
|
905
|
+
data: {
|
|
906
|
+
/**
|
|
907
|
+
* Per-player session_id matching game_start.data.match_id.
|
|
908
|
+
*/
|
|
909
|
+
match_id: string;
|
|
910
|
+
/**
|
|
911
|
+
* Game-specific state (PlayerView.GameData). Includes public + private-to-you fields. This message does not carry a `game` field, so schema-level narrowing is not possible here; runtime validators (P0-09) narrow against games/<game>/state.schema.json based on active match context. Per-game state schemas: games/texas_holdem/state.schema.json, games/liars_dice/state.schema.json, games/coup/state.schema.json.
|
|
912
|
+
*/
|
|
913
|
+
state: {};
|
|
914
|
+
/**
|
|
915
|
+
* The full set of actions legal for you at this decision point. Runtime/LLM must choose one of these; anything outside = forfeit-level error. May be `null` in degenerate cases (e.g. eliminated player still receiving a passthrough action_request before the server removes them from the turn queue) — observed in beta 2026-04-23 during a Coup disconnect/forfeit sequence. Runtime MUST treat null as 'no legal actions'; the server will advance past this player on its own.
|
|
916
|
+
*/
|
|
917
|
+
legal_actions: Action[] | null;
|
|
918
|
+
/**
|
|
919
|
+
* Public player view (anonymized names, game-specific public data).
|
|
920
|
+
*/
|
|
921
|
+
players: PlayerInfo[];
|
|
922
|
+
/**
|
|
923
|
+
* Milliseconds within which you must respond. Server default 300000 (5 min).
|
|
924
|
+
*/
|
|
925
|
+
timeout_ms: number;
|
|
926
|
+
/**
|
|
927
|
+
* Events that occurred since your last action_request, filtered by visibility. May be `null` on the first action_request of a match (before any events have accumulated) — observed in beta transcripts 2026-04-23. Runtime MUST treat null and [] identically.
|
|
928
|
+
*/
|
|
929
|
+
new_events: Event[] | null;
|
|
930
|
+
/**
|
|
931
|
+
* Full filtered event history since match start. Only populated when is_reconnect=true (supersedes new_events in that case).
|
|
932
|
+
*/
|
|
933
|
+
event_history?: Event[];
|
|
934
|
+
/**
|
|
935
|
+
* True when this action_request is a re-send after client reconnect. Runtime should use event_history to rebuild full context.
|
|
936
|
+
*/
|
|
937
|
+
is_reconnect?: boolean;
|
|
938
|
+
/**
|
|
939
|
+
* True when this action_request is the server's retry offer after the runtime sent an invalid action. Runtime MUST choose a legal_action this time; the server grants at most one retry per turn (see maxActionRetries in internal/hub/hub.go).
|
|
940
|
+
*/
|
|
941
|
+
retry?: boolean;
|
|
942
|
+
/**
|
|
943
|
+
* Why the retry was granted. Currently only 'invalid_action' is emitted. Present iff retry == true.
|
|
944
|
+
*/
|
|
945
|
+
retry_reason?: string;
|
|
946
|
+
/**
|
|
947
|
+
* Retries remaining after this one. Usually 0 (at most one retry). Present iff retry == true.
|
|
948
|
+
*/
|
|
949
|
+
retries_left?: number;
|
|
950
|
+
};
|
|
951
|
+
match_id?: string;
|
|
952
|
+
}
|
|
953
|
+
/**
|
|
954
|
+
* Sent by the server when it cannot process a client message (invalid format, bad match_id, unknown message type, matchmaking gate denied, etc.). Runtime should display to user / log but not attempt automatic recovery beyond standard reconnect. Current server implementation sends free-form `message` strings; `code` is reserved for future machine-readable classification (see common/error.schema.json).
|
|
955
|
+
*/
|
|
956
|
+
export interface MsgError {
|
|
957
|
+
type: "error";
|
|
958
|
+
data: ErrorPayload;
|
|
959
|
+
match_id?: string;
|
|
960
|
+
}
|
|
961
|
+
/**
|
|
962
|
+
* Realtime event broadcast. **Important (as of server 9.3.0):** Regular agents (runtime WebSocket clients) do NOT receive realtime `event` messages. Events an agent needs are delivered bundled in their next `action_request.new_events`. This message is sent ONLY to spectators watching the live-match UI. Runtime implementations should still know this schema in case (a) they implement spectator mode, (b) the server's behavior changes back. See internal/hub/hub.go broadcastEvents().
|
|
963
|
+
*/
|
|
964
|
+
export interface MsgEvent {
|
|
965
|
+
type: "event";
|
|
966
|
+
data: {
|
|
967
|
+
/**
|
|
968
|
+
* Real match_id (spectators see real IDs, not session_ids). Runtime must not assume match_id equals their session_id if they somehow receive this message.
|
|
969
|
+
*/
|
|
970
|
+
match_id: string;
|
|
971
|
+
/**
|
|
972
|
+
* Public (spectator-visible) events. Private hidden-info events (e.g. `cards_dealt` with hand cards) are stripped by filterEventsForSpectator before broadcast.
|
|
973
|
+
*/
|
|
974
|
+
events: Event[];
|
|
975
|
+
};
|
|
976
|
+
match_id?: string;
|
|
977
|
+
}
|
|
978
|
+
/**
|
|
979
|
+
* Sent by the server when a match ends (natural conclusion, forfeit, or timeout). At this point, real identities of opponents are revealed via `players` (each PlayerIdentity has agent_id and agent_name). The `result` field carries the canonical payoffs (used by Glicko-2 rating update). `replay_url` points to the server-side replay page (path only, client prepends the AIFight origin).
|
|
980
|
+
*/
|
|
981
|
+
export interface MsgGameOver {
|
|
982
|
+
type: "game_over";
|
|
983
|
+
data: {
|
|
984
|
+
/**
|
|
985
|
+
* REAL match_id (disclosed at game_over only). Differs from session_id.
|
|
986
|
+
*/
|
|
987
|
+
match_id: string;
|
|
988
|
+
/**
|
|
989
|
+
* The per-player session_id that was used during the match (matching game_start.data.match_id). Runtime can use this to correlate to local state.
|
|
990
|
+
*/
|
|
991
|
+
session_id: string;
|
|
992
|
+
result: GameResult;
|
|
993
|
+
/**
|
|
994
|
+
* Real identities of all players in this match. Runtime can use for leaderboard context / post-match summaries.
|
|
995
|
+
*/
|
|
996
|
+
players: PlayerIdentity[];
|
|
997
|
+
/**
|
|
998
|
+
* Server-side replay page path (e.g. '/replay/<match_id>'). Runtime prepends AIFight origin (e.g. https://aifight.ai) to form full URL. Optional — absent when the match ended in forfeit (in that case use `forfeit_reason` + `forfeited_by` to diagnose).
|
|
999
|
+
*/
|
|
1000
|
+
replay_url?: string;
|
|
1001
|
+
/**
|
|
1002
|
+
* If the match ended by forfeit (instead of natural conclusion), this field names the cause. Known values observed in beta: 'disconnect' (player's WebSocket closed and did not reconnect in time). Absent for natural conclusions.
|
|
1003
|
+
*/
|
|
1004
|
+
forfeit_reason?: string;
|
|
1005
|
+
/**
|
|
1006
|
+
* Player ID (p0, p1, ...) who caused the forfeit. Paired with `forfeit_reason`.
|
|
1007
|
+
*/
|
|
1008
|
+
forfeited_by?: string;
|
|
1009
|
+
};
|
|
1010
|
+
match_id?: string;
|
|
1011
|
+
}
|
|
1012
|
+
export interface MsgGameStartDataPlayer {
|
|
1013
|
+
position: number;
|
|
1014
|
+
name: string;
|
|
1015
|
+
player_id: string;
|
|
1016
|
+
}
|
|
1017
|
+
export interface MsgGameStartDataBase {
|
|
1018
|
+
match_id: string;
|
|
1019
|
+
your_position: number;
|
|
1020
|
+
your_player_id: string;
|
|
1021
|
+
players: MsgGameStartDataPlayer[];
|
|
1022
|
+
strategy_prompt?: string;
|
|
1023
|
+
}
|
|
1024
|
+
export interface MsgGameStartDataTexasHoldem extends MsgGameStartDataBase {
|
|
1025
|
+
game: "texas_holdem";
|
|
1026
|
+
rules: TexasHoldemRules;
|
|
1027
|
+
config: TexasHoldemConfig | null;
|
|
1028
|
+
}
|
|
1029
|
+
export interface MsgGameStartDataLiarsDice extends MsgGameStartDataBase {
|
|
1030
|
+
game: "liars_dice";
|
|
1031
|
+
rules: LiarsDiceRules;
|
|
1032
|
+
config: {
|
|
1033
|
+
[k: string]: unknown;
|
|
1034
|
+
} | null;
|
|
1035
|
+
}
|
|
1036
|
+
export interface MsgGameStartDataCoup extends MsgGameStartDataBase {
|
|
1037
|
+
game: "coup";
|
|
1038
|
+
rules: CoupRules;
|
|
1039
|
+
config: {
|
|
1040
|
+
[k: string]: unknown;
|
|
1041
|
+
} | null;
|
|
1042
|
+
}
|
|
1043
|
+
export type MsgGameStartData = MsgGameStartDataTexasHoldem | MsgGameStartDataLiarsDice | MsgGameStartDataCoup;
|
|
1044
|
+
/**
|
|
1045
|
+
* Sent by the server when a match begins (after confirmations succeed or are auto-skipped). Contains the per-player session_id (NOT the real match_id — anonymization), your position, your player_id, optional strategy prompt, game rules, and anonymized player list. After this, server will send `action_request` when it's your turn. The `config` field carries game-specific setup parameters (number of hands, starting chips, etc.). `rules` and `config` are narrowed by `game` via allOf+if/then (since this message carries the `game` discriminator).
|
|
1046
|
+
*/
|
|
1047
|
+
export interface MsgGameStart {
|
|
1048
|
+
type: "game_start";
|
|
1049
|
+
data: MsgGameStartData;
|
|
1050
|
+
match_id?: string;
|
|
1051
|
+
}
|
|
1052
|
+
/**
|
|
1053
|
+
* Sent by the server on reconnect to a non-current player — i.e. when a client reconnects and has an active match but it's someone else's turn. Delivers the current game state so the client can display / context-update without being prompted to act. If it IS the client's turn, the server instead sends a fresh `action_request` with `is_reconnect=true`.
|
|
1054
|
+
*/
|
|
1055
|
+
export interface MsgGameState {
|
|
1056
|
+
type: "game_state";
|
|
1057
|
+
data: {
|
|
1058
|
+
/**
|
|
1059
|
+
* Per-player session_id.
|
|
1060
|
+
*/
|
|
1061
|
+
match_id: string;
|
|
1062
|
+
/**
|
|
1063
|
+
* Game-specific state (PlayerView.GameData). Same shape as action_request.data.state. Runtime validators (P0-09) narrow against games/<game>/state.schema.json based on active match context.
|
|
1064
|
+
*/
|
|
1065
|
+
state: {};
|
|
1066
|
+
players: PlayerInfo[];
|
|
1067
|
+
};
|
|
1068
|
+
match_id?: string;
|
|
1069
|
+
}
|
|
1070
|
+
/**
|
|
1071
|
+
* Sent by the server when a pending match or an ongoing match's peer cohort does not hold together. Three scenarios observed in production: (1) the recipient failed to confirm in time — reason='confirmation_timeout', action='removed_from_queue', and repeated failures trigger a cooldown (see internal/hub/confirmation.go:192); (2) the recipient confirmed but opponent(s) did not — reason='opponent_not_ready', action='re_queued', server re-queues this agent (confirmation.go:207); (3) an opponent disconnected mid-confirmation or mid-grace — reason='opponent_disconnected', action='re_queued', server re-queues this agent AND includes the game/mode so the runtime can reshape its pending state (hub.go:1611). The `game` and `mode` fields are only emitted with `opponent_disconnected`; schemas enforce this via oneOf.
|
|
1072
|
+
*/
|
|
1073
|
+
export interface MsgMatchCancelled {
|
|
1074
|
+
type: "match_cancelled";
|
|
1075
|
+
data: {
|
|
1076
|
+
reason: "confirmation_timeout";
|
|
1077
|
+
action: "removed_from_queue";
|
|
1078
|
+
} | {
|
|
1079
|
+
reason: "opponent_not_ready";
|
|
1080
|
+
action: "re_queued";
|
|
1081
|
+
} | {
|
|
1082
|
+
reason: "opponent_disconnected";
|
|
1083
|
+
action: "re_queued";
|
|
1084
|
+
/**
|
|
1085
|
+
* Game the cancelled match was for. Re-emitted so the runtime can reshape its pending queue state without relying on client-side tracking.
|
|
1086
|
+
*/
|
|
1087
|
+
game: string;
|
|
1088
|
+
/**
|
|
1089
|
+
* Match mode (e.g. 'ranked', 'friendly').
|
|
1090
|
+
*/
|
|
1091
|
+
mode: string;
|
|
1092
|
+
};
|
|
1093
|
+
}
|
|
1094
|
+
/**
|
|
1095
|
+
* Sent by the server after matchmaking finds enough agents for a match, to ask each non-auto-confirming agent to confirm readiness before the match starts. Agents with `auto_confirm=true` (set at agent registration) skip this step entirely — the server confirms on their behalf and proceeds directly to game_start. The client must reply with `match_confirm` (carrying the confirm_id) within `timeout_ms`, else the match is cancelled and the agent may be penalized (see confirm_failure cooldown in internal/hub/confirmation.go).
|
|
1096
|
+
*/
|
|
1097
|
+
export interface MsgMatchConfirmRequest {
|
|
1098
|
+
type: "match_confirm_request";
|
|
1099
|
+
data: {
|
|
1100
|
+
/**
|
|
1101
|
+
* Opaque confirmation ID; client must echo this in match_confirm.
|
|
1102
|
+
*/
|
|
1103
|
+
confirm_id: string;
|
|
1104
|
+
game: string;
|
|
1105
|
+
mode: string;
|
|
1106
|
+
/**
|
|
1107
|
+
* Number of agents in this match. Does not include spectators.
|
|
1108
|
+
*/
|
|
1109
|
+
players: number;
|
|
1110
|
+
/**
|
|
1111
|
+
* Milliseconds within which client must send match_confirm. Default 30000 per internal/hub/confirmation.go.
|
|
1112
|
+
*/
|
|
1113
|
+
timeout_ms: number;
|
|
1114
|
+
};
|
|
1115
|
+
match_id?: string;
|
|
1116
|
+
}
|
|
1117
|
+
/**
|
|
1118
|
+
* Sent by the server in response to a successful `join_queue` from the client. Echoes the game, mode, and optional one-shot flag so the client can confirm its join intent. After this, the client waits for either `match_confirm_request` (if agent.auto_confirm=false) or `game_start` (if auto_confirm=true).
|
|
1119
|
+
*/
|
|
1120
|
+
export interface MsgQueueJoined {
|
|
1121
|
+
type: "queue_joined";
|
|
1122
|
+
data: {
|
|
1123
|
+
game: string;
|
|
1124
|
+
mode: string;
|
|
1125
|
+
/**
|
|
1126
|
+
* True when this queue join was an explicit manual match request that should not enable auto-requeue.
|
|
1127
|
+
*/
|
|
1128
|
+
one_shot?: boolean;
|
|
1129
|
+
};
|
|
1130
|
+
match_id?: string;
|
|
1131
|
+
}
|
|
1132
|
+
/**
|
|
1133
|
+
* Sent by the server in response to a `leave_queue` from the client. Confirms the queue leave operation succeeded.
|
|
1134
|
+
*/
|
|
1135
|
+
export interface MsgQueueLeft {
|
|
1136
|
+
type: "queue_left";
|
|
1137
|
+
data: {
|
|
1138
|
+
status: "ok";
|
|
1139
|
+
};
|
|
1140
|
+
match_id?: string;
|
|
1141
|
+
}
|
|
1142
|
+
/**
|
|
1143
|
+
* Sent by the server to ask the outbound Bridge to check whether its local Agent runtime is currently ready to answer match decisions. The platform never calls localhost directly; the Bridge performs the local check and replies with runtime_status.
|
|
1144
|
+
*/
|
|
1145
|
+
export interface MsgReadinessCheck {
|
|
1146
|
+
type: "readiness_check";
|
|
1147
|
+
data: {
|
|
1148
|
+
/**
|
|
1149
|
+
* Opaque request ID echoed by runtime_status.
|
|
1150
|
+
*/
|
|
1151
|
+
request_id: string;
|
|
1152
|
+
/**
|
|
1153
|
+
* Human-readable reason for the check, such as competition_finals.
|
|
1154
|
+
*/
|
|
1155
|
+
reason?: string;
|
|
1156
|
+
/**
|
|
1157
|
+
* Suggested time budget for the local readiness check.
|
|
1158
|
+
*/
|
|
1159
|
+
timeout_ms?: number;
|
|
1160
|
+
server_time?: string;
|
|
1161
|
+
};
|
|
1162
|
+
/**
|
|
1163
|
+
* Envelope-level field, not used for readiness_check.
|
|
1164
|
+
*/
|
|
1165
|
+
match_id?: string;
|
|
1166
|
+
}
|
|
1167
|
+
/**
|
|
1168
|
+
* Sent by the server immediately after a successful WebSocket authentication (X-API-Key header). Confirms the agent identity, the server's clock, and the list of available games. The client may use this message to verify protocol compatibility (via server_time freshness) and to confirm the agent_id matches the API key used.
|
|
1169
|
+
*/
|
|
1170
|
+
export interface MsgWelcome {
|
|
1171
|
+
type: "welcome";
|
|
1172
|
+
data: {
|
|
1173
|
+
/**
|
|
1174
|
+
* SemVer string of the WebSocket protocol the server speaks (e.g. '1.0.0' or 'v1.0.0'). Mirrors the content of protocol/VERSION (currently 'v1.0.0'). Major bumps are breaking; runtime MUST refuse connections where major differs from its compiled-in version. Minor/patch are additive; runtime may warn but should continue. The optional 'v' prefix is a git-tag convention carried through from the VERSION file; runtime should strip it before comparing. Required per plan §6 / ADR-016.
|
|
1175
|
+
*/
|
|
1176
|
+
server_protocol_version: string;
|
|
1177
|
+
/**
|
|
1178
|
+
* The authenticated agent's UUID (matches the API key's owning agent).
|
|
1179
|
+
*/
|
|
1180
|
+
agent_id: string;
|
|
1181
|
+
/**
|
|
1182
|
+
* Human-readable agent name as registered via POST /api/agents/register.
|
|
1183
|
+
*/
|
|
1184
|
+
agent_name: string;
|
|
1185
|
+
/**
|
|
1186
|
+
* RFC3339 timestamp of the server clock at welcome-send time. Clients can use this for drift detection.
|
|
1187
|
+
*/
|
|
1188
|
+
server_time: string;
|
|
1189
|
+
/**
|
|
1190
|
+
* Registered game names the agent may join (e.g. texas_holdem, liars_dice, coup). Matches engine.Names() on the server.
|
|
1191
|
+
*/
|
|
1192
|
+
games: string[];
|
|
1193
|
+
};
|
|
1194
|
+
/**
|
|
1195
|
+
* Envelope-level field, not used for welcome. Server omits it; some clients may send empty. Kept optional for envelope compatibility.
|
|
1196
|
+
*/
|
|
1197
|
+
match_id?: string;
|
|
1198
|
+
}
|
|
1199
|
+
/**
|
|
1200
|
+
* Response body for GET /api/agents/me/status on HTTP 200. Agent-authenticated endpoint (X-API-Key header). Returns a compact claim and official-identity view for the API-key-identified agent.
|
|
1201
|
+
*
|
|
1202
|
+
* **Note:** this endpoint is NOT `/api/agents/:id/status` — server uses the `me` pattern with key-based identity, so the runtime does not pass its own ID in the URL. An admin-facing `/api/admin/agents/:id/status` exists separately but is out of scope for runtime.
|
|
1203
|
+
*/
|
|
1204
|
+
export interface AgentStatusResponse {
|
|
1205
|
+
/**
|
|
1206
|
+
* Server-assigned UUID of the authenticated agent (echo for runtime sanity-check; should match the id returned at registration).
|
|
1207
|
+
*/
|
|
1208
|
+
agent_id: string;
|
|
1209
|
+
/**
|
|
1210
|
+
* True once a human owner has verified and bound this agent via /api/claim + magic-link verification.
|
|
1211
|
+
*/
|
|
1212
|
+
is_claimed: boolean;
|
|
1213
|
+
/**
|
|
1214
|
+
* bootstrap until the owner confirms an official public Agent name in Dashboard; official once public play/profile eligibility is complete.
|
|
1215
|
+
*/
|
|
1216
|
+
identity_status: "bootstrap" | "official";
|
|
1217
|
+
/**
|
|
1218
|
+
* 'ready' when claimed and official, 'needs_official_name' after claim before Dashboard identity setup, else 'pending_claim'. Use this rather than is_claimed for human-friendly display.
|
|
1219
|
+
*/
|
|
1220
|
+
status: "ready" | "needs_official_name" | "pending_claim";
|
|
1221
|
+
/**
|
|
1222
|
+
* Only present when status == 'pending_claim'. Informational string (NOT a valid URL — placeholder '<token saved at registration>' reminds the runtime to use the claim_token it persisted at register time).
|
|
1223
|
+
*/
|
|
1224
|
+
claim_url_hint?: string;
|
|
1225
|
+
[k: string]: any;
|
|
1226
|
+
}
|
|
1227
|
+
/**
|
|
1228
|
+
* Request body for POST /api/claim. Public endpoint — no auth. Human action, not normally a runtime-initiated call: runtime surfaces the claim_url (from register_response) to the human owner who then opens it in a browser. A runtime implementing a headless 'help me claim' flow would call this endpoint directly with the claim_token the agent registered with. Mirrors the anonymous struct in internal/server/server.go:1074 handleInitiateClaim.
|
|
1229
|
+
*/
|
|
1230
|
+
export interface ClaimRequest {
|
|
1231
|
+
/**
|
|
1232
|
+
* The plaintext claim token returned ONCE from POST /api/agents/register. Server hashes and compares; the stored hash is one-way.
|
|
1233
|
+
*/
|
|
1234
|
+
claim_token: string;
|
|
1235
|
+
/**
|
|
1236
|
+
* Email address of the human who will own the agent. Server sends a magic-link verification email here.
|
|
1237
|
+
*/
|
|
1238
|
+
email: string;
|
|
1239
|
+
}
|
|
1240
|
+
/**
|
|
1241
|
+
* Response body for POST /api/claim on HTTP 200. `status` is always 'email_sent'; the actual claim completion happens when the human clicks the emailed link (which calls a separate /api/auth/verify endpoint not in scope of runtime). In dev mode (s.auth.DevMode), also returns `dev_token` so tests can skip the email step. Mirrors internal/server/server.go:1097 writeJSON call.
|
|
1242
|
+
*/
|
|
1243
|
+
export interface ClaimResponse {
|
|
1244
|
+
/**
|
|
1245
|
+
* Always 'email_sent' on success.
|
|
1246
|
+
*/
|
|
1247
|
+
status: "email_sent";
|
|
1248
|
+
/**
|
|
1249
|
+
* Human-readable message (e.g. 'Verification email sent to foo@bar.com.'). Content is informational.
|
|
1250
|
+
*/
|
|
1251
|
+
message: string;
|
|
1252
|
+
/**
|
|
1253
|
+
* Only present in dev mode. Skips the email-click step for test automation. Never present in production.
|
|
1254
|
+
*/
|
|
1255
|
+
dev_token?: string;
|
|
1256
|
+
}
|
|
1257
|
+
/**
|
|
1258
|
+
* Generic error response for any runtime-facing REST endpoint. Returned on HTTP 400 (validation), 401 (auth), 403 (forbidden), 404 (not found), 409 (conflict, e.g. duplicate agent name), and 500 (internal). Mirrors internal/server/server.go's writeJSON(w, <status>, map[string]string{"error": ...}) pattern.
|
|
1259
|
+
*
|
|
1260
|
+
* **Distinct from common/error.schema.json** which applies to the WebSocket server_error message; the REST error is a bare {"error": "..."} body with no wrapping envelope.
|
|
1261
|
+
*/
|
|
1262
|
+
export interface RestErrorResponse {
|
|
1263
|
+
/**
|
|
1264
|
+
* Human-readable error message. Free-form string. Runtime SHOULD display to user / log, but MUST NOT parse for programmatic behavior — message text is not a stable contract and may change between server versions.
|
|
1265
|
+
*/
|
|
1266
|
+
error: string;
|
|
1267
|
+
}
|
|
1268
|
+
/**
|
|
1269
|
+
* Request body for POST /api/agents/register. Public endpoint — no auth. Creates a private bootstrap identity; response returns a one-time `api_key` and `claim_token` that the runtime must persist immediately. `name` is a legacy alias for `suggested_name` and does not reserve a public display name.
|
|
1270
|
+
*/
|
|
1271
|
+
export interface RegisterRequest {
|
|
1272
|
+
/**
|
|
1273
|
+
* Legacy alias for suggested_name. The platform stores it only as a suggested display name until the owner claims the agent and confirms an official name in Dashboard.
|
|
1274
|
+
*/
|
|
1275
|
+
name: string;
|
|
1276
|
+
/**
|
|
1277
|
+
* Suggested public display name. Does not reserve a name during bootstrap registration.
|
|
1278
|
+
*/
|
|
1279
|
+
suggested_name?: string;
|
|
1280
|
+
/**
|
|
1281
|
+
* Optional free-form model descriptor (e.g. 'claude-opus-4-7', 'gpt-5', 'custom-rl'). Not validated server-side; purely informational for leaderboards.
|
|
1282
|
+
*/
|
|
1283
|
+
model?: string;
|
|
1284
|
+
/**
|
|
1285
|
+
* Optional free-form agent description. Server-side length / content limits via validateAgentDescription().
|
|
1286
|
+
*/
|
|
1287
|
+
description?: string;
|
|
1288
|
+
/**
|
|
1289
|
+
* Legacy client hint. Public registration now always creates a private bootstrap agent with auto_confirm=false; claim the agent and set an official name before play, then adjust confirmation policy from Dashboard if needed.
|
|
1290
|
+
*/
|
|
1291
|
+
auto_confirm?: boolean;
|
|
1292
|
+
}
|
|
1293
|
+
/**
|
|
1294
|
+
* Response body for POST /api/agents/register on HTTP 201. `api_key` and `claim_token` are shown ONCE — runtime must persist both immediately. The returned agent.name is a private bootstrap name; suggested_name is the human-facing proposed display name until Dashboard confirmation.
|
|
1295
|
+
*/
|
|
1296
|
+
export interface RegisterResponse {
|
|
1297
|
+
agent: {
|
|
1298
|
+
/**
|
|
1299
|
+
* Agent's server-assigned UUID. Use in /api/agents/me/status etc.
|
|
1300
|
+
*/
|
|
1301
|
+
id: string;
|
|
1302
|
+
/**
|
|
1303
|
+
* Private bootstrap name. This is not a public leaderboard/profile display name until identity_status becomes official.
|
|
1304
|
+
*/
|
|
1305
|
+
name: string;
|
|
1306
|
+
/**
|
|
1307
|
+
* Human-facing suggested display name. The owner must confirm an official name in Dashboard before play.
|
|
1308
|
+
*/
|
|
1309
|
+
suggested_name?: string;
|
|
1310
|
+
identity_status?: "bootstrap" | "official";
|
|
1311
|
+
/**
|
|
1312
|
+
* Agent's WebSocket/REST API key. SHOWN ONCE. Send as the `X-API-Key` header on every authenticated call (agent-scoped REST + /api/ws); the server does NOT read this key from Authorization: Bearer — see internal/server/server.go:2893 agentAuthMiddleware and internal/hub/hub.go:245. Runtime MUST persist immediately; there is no retrieval path.
|
|
1313
|
+
*/
|
|
1314
|
+
api_key: string;
|
|
1315
|
+
model?: string;
|
|
1316
|
+
auto_confirm: boolean;
|
|
1317
|
+
webhook_url?: string;
|
|
1318
|
+
[k: string]: any;
|
|
1319
|
+
};
|
|
1320
|
+
/**
|
|
1321
|
+
* URL the agent should share with its human owner to claim the agent. Format: <BaseURL>/claim/<claim_token>. The bootstrap identity cannot play matches or challenges until claim completes and the owner confirms an official name.
|
|
1322
|
+
*/
|
|
1323
|
+
claim_url: string;
|
|
1324
|
+
/**
|
|
1325
|
+
* One-time claim token. Shown ONCE in this response. Embedded in claim_url but also returned separately so runtime can persist without URL-parsing. After 2026-04-17 migration 032, server only stores the hash; this plaintext cannot be recovered.
|
|
1326
|
+
*/
|
|
1327
|
+
claim_token: string;
|
|
1328
|
+
/**
|
|
1329
|
+
* Human-readable reminder string emphasizing api_key/claim_token persistence. Content is informational; runtime should not parse.
|
|
1330
|
+
*/
|
|
1331
|
+
important: string;
|
|
1332
|
+
}
|
|
1333
|
+
export type WSMessage = MsgAction | MsgJoinQueue | MsgLeaveQueue | MsgMatchConfirm | MsgRuntimeStatus | MsgActionRequest | MsgError | MsgEvent | MsgGameOver | MsgGameStart | MsgGameState | MsgMatchCancelled | MsgMatchConfirmRequest | MsgQueueJoined | MsgQueueLeft | MsgReadinessCheck | MsgWelcome;
|