@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,85 @@
|
|
|
1
|
+
import { type AgentRow } from "../store/sqlite";
|
|
2
|
+
import type { DailyScheduleConfig } from "../scheduler/types";
|
|
3
|
+
import { type ControlLogEvent } from "../controlapi/types";
|
|
4
|
+
import type { StrategyProfile } from "../decision/types";
|
|
5
|
+
import { buildConnectWithGameStartCache } from "./agent-decision-adapter";
|
|
6
|
+
export interface DaemonOptions {
|
|
7
|
+
/** Default "127.0.0.1". Plan ADR-013 locks to loopback in M1; daemon
|
|
8
|
+
* validates in cli/commands/serve.ts (Step 3 wires --host argv). */
|
|
9
|
+
readonly host?: string;
|
|
10
|
+
/** Default 0 — OS picks an unused port. Resolved bound port surfaces
|
|
11
|
+
* on `DaemonHandle.bound.port`. */
|
|
12
|
+
readonly port?: number;
|
|
13
|
+
readonly onLog?: (event: DaemonLogEvent) => void;
|
|
14
|
+
readonly testHooks?: DaemonTestHooks;
|
|
15
|
+
}
|
|
16
|
+
export type DaemonLogLevel = "info" | "warn" | "error";
|
|
17
|
+
export type DaemonLogCode = "lock_acquired" | "agents_loaded" | "control_server_listening" | "runtime_files_written" | "daemon_ready" | "signal_received" | "shutdown_initiated" | "shutdown_completed" | "shutdown_forced" | "agent_load_failed" | "agent_skipped_turn" | "control_server_proxy" | "lock_release_failed" | "tmp_cleanup_failed";
|
|
18
|
+
export interface DaemonLogEvent {
|
|
19
|
+
readonly level: DaemonLogLevel;
|
|
20
|
+
readonly code: DaemonLogCode;
|
|
21
|
+
readonly message: string;
|
|
22
|
+
readonly cause?: unknown;
|
|
23
|
+
/** Only set when `code === "control_server_proxy"` — forwarded
|
|
24
|
+
* M1-16 ControlLogEvent payload. */
|
|
25
|
+
readonly controlEvent?: ControlLogEvent;
|
|
26
|
+
}
|
|
27
|
+
export interface DaemonTestHooks {
|
|
28
|
+
/** Override timer functions (force-exit timer, etc). */
|
|
29
|
+
readonly setTimeout?: typeof globalThis.setTimeout;
|
|
30
|
+
readonly clearTimeout?: typeof globalThis.clearTimeout;
|
|
31
|
+
/** Override process.on signal subscription. Default attaches to
|
|
32
|
+
* process; tests inject a fake emitter so signals can be simulated
|
|
33
|
+
* without sending real SIGINT to the test runner. The returned
|
|
34
|
+
* function detaches the listener. */
|
|
35
|
+
readonly onSignal?: (sig: NodeJS.Signals, listener: () => void) => () => void;
|
|
36
|
+
/** Override `process.exit`. Production path uses `process.exit`;
|
|
37
|
+
* tests inject a recorder so the test runner is never killed. Used
|
|
38
|
+
* only on force-exit / second-signal paths (rev3 fix #3). */
|
|
39
|
+
readonly exit?: (code: number) => void;
|
|
40
|
+
/** Override agent row loading. Production reads SQLite via
|
|
41
|
+
* openDatabase().listAgents(). Tests inject fixtures without a real
|
|
42
|
+
* DB. */
|
|
43
|
+
readonly loadAgents?: () => readonly AgentRow[];
|
|
44
|
+
/** Override strategy profile loading. Production reads
|
|
45
|
+
* `getRuntimeHome()/agents/<name>/strategy.json` (post-Step-2 path
|
|
46
|
+
* detail; Step 2 minimum is testHook-driven and tests inject
|
|
47
|
+
* fixtures). Throw to trigger per-agent skip. */
|
|
48
|
+
readonly loadStrategy?: (agentName: string) => StrategyProfile;
|
|
49
|
+
/** Override daily-schedule config loading. Returning null = no
|
|
50
|
+
* scheduler. */
|
|
51
|
+
readonly loadDailyConfig?: (agentName: string) => DailyScheduleConfig | null;
|
|
52
|
+
/** Override `os.platform()` for case 26 (Windows SIGTERM omission). */
|
|
53
|
+
readonly platform?: NodeJS.Platform;
|
|
54
|
+
/** Override the wsclient connect factory used by AgentInstance.
|
|
55
|
+
* Default = `createReconnectingWSClient` from M1-07. Tests inject
|
|
56
|
+
* to capture wsclient options (asserts apiKey === platformKey, etc)
|
|
57
|
+
* without opening a real socket. */
|
|
58
|
+
readonly wsConnectFactory?: Parameters<typeof buildConnectWithGameStartCache>[1];
|
|
59
|
+
/** Force-exit timeout in ms. Default 30000 (TED 拍板点 #7).
|
|
60
|
+
* Tests use a small value (e.g. 50ms) to validate timeout behavior
|
|
61
|
+
* without making the suite slow. */
|
|
62
|
+
readonly forceExitTimeoutMs?: number;
|
|
63
|
+
}
|
|
64
|
+
export type ShutdownReason = {
|
|
65
|
+
readonly source: "signal";
|
|
66
|
+
readonly signal: NodeJS.Signals;
|
|
67
|
+
} | {
|
|
68
|
+
readonly source: "control_api";
|
|
69
|
+
} | {
|
|
70
|
+
readonly source: "startup_failure";
|
|
71
|
+
readonly cause: unknown;
|
|
72
|
+
};
|
|
73
|
+
export interface DaemonHandle {
|
|
74
|
+
readonly bound: {
|
|
75
|
+
readonly host: string;
|
|
76
|
+
readonly port: number;
|
|
77
|
+
};
|
|
78
|
+
/** Idempotent — second call returns the same promise as the first. */
|
|
79
|
+
requestShutdown(reason: ShutdownReason): Promise<number>;
|
|
80
|
+
/** Long-lived completion. Resolves with the final exit code; never
|
|
81
|
+
* rejects. runServe() awaits this to keep the foreground process
|
|
82
|
+
* alive (rev2 fix #1). */
|
|
83
|
+
readonly closed: Promise<number>;
|
|
84
|
+
}
|
|
85
|
+
export declare function startDaemon(opts?: DaemonOptions): Promise<DaemonHandle>;
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import type { AgentInstanceSnapshot } from "../agents/agent";
|
|
2
|
+
export interface RouterAgentConfig {
|
|
3
|
+
readonly name: string;
|
|
4
|
+
readonly id?: string;
|
|
5
|
+
readonly enabled?: boolean;
|
|
6
|
+
readonly metadata?: Readonly<Record<string, unknown>>;
|
|
7
|
+
}
|
|
8
|
+
export interface RouterAgentRuntime {
|
|
9
|
+
start(): Promise<AgentInstanceSnapshot>;
|
|
10
|
+
stop(reason?: string): Promise<void>;
|
|
11
|
+
joinQueue(game: string, mode?: string, opts?: {
|
|
12
|
+
readonly oneShot?: boolean;
|
|
13
|
+
readonly count?: number;
|
|
14
|
+
}): void;
|
|
15
|
+
leaveQueue(): void;
|
|
16
|
+
confirmMatch(confirmId?: string): void;
|
|
17
|
+
snapshot(): AgentInstanceSnapshot;
|
|
18
|
+
onState(handler: (snapshot: AgentInstanceSnapshot) => void): () => void;
|
|
19
|
+
}
|
|
20
|
+
export type RouterAgentFactory = (config: RouterAgentConfig) => RouterAgentRuntime;
|
|
21
|
+
export type RouterAgentSelector = string | {
|
|
22
|
+
readonly name?: string;
|
|
23
|
+
readonly id?: string;
|
|
24
|
+
};
|
|
25
|
+
export interface RouterSnapshot {
|
|
26
|
+
readonly agents: readonly AgentInstanceSnapshot[];
|
|
27
|
+
}
|
|
28
|
+
export interface MultiAgentRouterOptions {
|
|
29
|
+
readonly agents?: readonly RouterAgentConfig[];
|
|
30
|
+
readonly agentFactory: RouterAgentFactory;
|
|
31
|
+
readonly onNotify?: (event: RouterNotifyEvent) => void;
|
|
32
|
+
}
|
|
33
|
+
export interface RouterNotifyEvent {
|
|
34
|
+
readonly level: "info" | "warning" | "error";
|
|
35
|
+
readonly code: string;
|
|
36
|
+
readonly message: string;
|
|
37
|
+
readonly agent?: string;
|
|
38
|
+
readonly cause?: unknown;
|
|
39
|
+
}
|
|
40
|
+
export type RouterErrorKind = "router_duplicate_agent" | "router_agent_not_found" | "router_selector_mismatch" | "router_agent_factory" | "router_agent_lifecycle";
|
|
41
|
+
export declare abstract class RouterError extends Error {
|
|
42
|
+
abstract readonly kind: RouterErrorKind;
|
|
43
|
+
readonly cause: unknown;
|
|
44
|
+
protected constructor(message: string, cause?: unknown);
|
|
45
|
+
}
|
|
46
|
+
export declare class RouterDuplicateAgentError extends RouterError {
|
|
47
|
+
readonly name = "RouterDuplicateAgentError";
|
|
48
|
+
readonly kind: "router_duplicate_agent";
|
|
49
|
+
readonly field: "name" | "id";
|
|
50
|
+
readonly value: string;
|
|
51
|
+
constructor(field: "name" | "id", value: string);
|
|
52
|
+
}
|
|
53
|
+
export declare class RouterAgentNotFoundError extends RouterError {
|
|
54
|
+
readonly name = "RouterAgentNotFoundError";
|
|
55
|
+
readonly kind: "router_agent_not_found";
|
|
56
|
+
readonly selector: RouterAgentSelector;
|
|
57
|
+
constructor(selector: RouterAgentSelector);
|
|
58
|
+
}
|
|
59
|
+
export declare class RouterSelectorMismatchError extends RouterError {
|
|
60
|
+
readonly name = "RouterSelectorMismatchError";
|
|
61
|
+
readonly kind: "router_selector_mismatch";
|
|
62
|
+
readonly nameSelector: string;
|
|
63
|
+
readonly idSelector: string;
|
|
64
|
+
constructor(nameSelector: string, idSelector: string);
|
|
65
|
+
}
|
|
66
|
+
export declare class RouterAgentFactoryError extends RouterError {
|
|
67
|
+
readonly name = "RouterAgentFactoryError";
|
|
68
|
+
readonly kind: "router_agent_factory";
|
|
69
|
+
readonly agentName: string;
|
|
70
|
+
constructor(agentName: string, cause: unknown);
|
|
71
|
+
}
|
|
72
|
+
export declare class RouterAgentLifecycleError extends RouterError {
|
|
73
|
+
readonly name = "RouterAgentLifecycleError";
|
|
74
|
+
readonly kind: "router_agent_lifecycle";
|
|
75
|
+
readonly agentName: string;
|
|
76
|
+
readonly operation: "start" | "stop" | "remove";
|
|
77
|
+
constructor(agentName: string, operation: "start" | "stop" | "remove", cause: unknown);
|
|
78
|
+
}
|
|
79
|
+
export declare class MultiAgentRouter {
|
|
80
|
+
#private;
|
|
81
|
+
constructor(opts: MultiAgentRouterOptions);
|
|
82
|
+
addAgent(config: RouterAgentConfig): void;
|
|
83
|
+
removeAgent(selector: RouterAgentSelector): Promise<void>;
|
|
84
|
+
getAgent(selector: RouterAgentSelector): RouterAgentRuntime;
|
|
85
|
+
listAgents(): readonly AgentInstanceSnapshot[];
|
|
86
|
+
snapshot(): RouterSnapshot;
|
|
87
|
+
startAgent(selector: RouterAgentSelector): Promise<AgentInstanceSnapshot>;
|
|
88
|
+
stopAgent(selector: RouterAgentSelector, reason?: string): Promise<void>;
|
|
89
|
+
startAll(): Promise<RouterSnapshot>;
|
|
90
|
+
stopAll(reason?: string): Promise<void>;
|
|
91
|
+
joinQueue(selector: RouterAgentSelector, game: string, mode?: string, opts?: {
|
|
92
|
+
readonly oneShot?: boolean;
|
|
93
|
+
readonly count?: number;
|
|
94
|
+
}): void;
|
|
95
|
+
leaveQueue(selector: RouterAgentSelector): void;
|
|
96
|
+
confirmMatch(selector: RouterAgentSelector, confirmId?: string): void;
|
|
97
|
+
}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
export type RuntimeFilesWriteErrorKind = "write_failed" | "lock_held_by_other" | "lock_acquire_failed";
|
|
2
|
+
export declare class RuntimeFilesWriteError extends Error {
|
|
3
|
+
readonly name = "RuntimeFilesWriteError";
|
|
4
|
+
readonly kind: RuntimeFilesWriteErrorKind;
|
|
5
|
+
readonly filePath: string;
|
|
6
|
+
/** Set when kind === "lock_held_by_other"; the holding process's PID
|
|
7
|
+
* as recorded in the pid file. Caller maps to exit-6 + user message. */
|
|
8
|
+
readonly heldByPid?: number;
|
|
9
|
+
readonly cause?: unknown;
|
|
10
|
+
constructor(kind: RuntimeFilesWriteErrorKind, filePath: string, message: string, init?: {
|
|
11
|
+
heldByPid?: number;
|
|
12
|
+
cause?: unknown;
|
|
13
|
+
});
|
|
14
|
+
}
|
|
15
|
+
/** Generates a fresh 64-char hex token (32 random bytes encoded). */
|
|
16
|
+
export declare function generateToken(): string;
|
|
17
|
+
/** Atomic write: token file at `getRuntimeHome()/token` mode 0600.
|
|
18
|
+
* Internal: writes to `<path>.<pid>.<counter>.tmp` then `fs.renameSync`.
|
|
19
|
+
* Asserts token matches /^[0-9a-f]{64}$/ before write (TED Q2 — hex
|
|
20
|
+
* literal assertion to defeat future regressions that swap the random
|
|
21
|
+
* source for one emitting non-printable bytes / mixed case). */
|
|
22
|
+
export declare function writeToken(token: string): void;
|
|
23
|
+
/** Atomic write: port file at `getRuntimeHome()/port` mode 0644.
|
|
24
|
+
* Content = `String(port)` no trailing newline. Range checked
|
|
25
|
+
* [1, 65535] (matches M1-17 read-side validator). */
|
|
26
|
+
export declare function writePort(port: number): void;
|
|
27
|
+
/** Atomic write: pid file at `getRuntimeHome()/pid` mode 0644.
|
|
28
|
+
* Content = `String(pid)` no trailing newline. */
|
|
29
|
+
export declare function writePid(pid: number): void;
|
|
30
|
+
/** Best-effort unlink of token + port + pid files on graceful shutdown.
|
|
31
|
+
* ENOENT is silent (file already gone). Other failures only log via
|
|
32
|
+
* onLog so shutdown sequence never throws on cleanup. */
|
|
33
|
+
export declare function unlinkRuntimeFiles(opts: {
|
|
34
|
+
onLog?: (msg: string) => void;
|
|
35
|
+
}): void;
|
|
36
|
+
/** Cleans up `*.tmp` files in `getRuntimeHome()` left over from a
|
|
37
|
+
* previous daemon crash. Called once at startup before any write.
|
|
38
|
+
* Failures silent — best-effort only. */
|
|
39
|
+
export declare function cleanupStaleTmpFiles(): void;
|
|
40
|
+
export interface LockHandle {
|
|
41
|
+
/** Releases lock + unlinks lock file. Idempotent — second call no-op. */
|
|
42
|
+
release(): void;
|
|
43
|
+
}
|
|
44
|
+
export interface AcquireDaemonLockOptions {
|
|
45
|
+
/** Override `process.kill(pid, 0)` liveness probe for tests. Default
|
|
46
|
+
* uses `process.kill(pid, 0)` and treats EPERM (cross-user, can't
|
|
47
|
+
* signal) as `true` (alive) so we never overwrite a foreign daemon's
|
|
48
|
+
* lock — TED 拍板点 #6 + Group 2 case 17 "EPERM 不能确认 → safe
|
|
49
|
+
* 保留". Production callers omit this option. */
|
|
50
|
+
readonly processIsAlive?: (pid: number) => boolean;
|
|
51
|
+
}
|
|
52
|
+
/** Acquire exclusive lock at `getRuntimeHome()/lock` (`O_EXCL` create).
|
|
53
|
+
*
|
|
54
|
+
* Outcomes when the lock file already exists (EEXIST):
|
|
55
|
+
* - **valid pid + alive (per probe)** → throw `lock_held_by_other`
|
|
56
|
+
* with `heldByPid` set; lock + pid files preserved.
|
|
57
|
+
* - **valid pid + dead** → STALE; clean lock + pid + retry once.
|
|
58
|
+
* - **pid file missing / corrupt content / read error** → AMBIGUOUS;
|
|
59
|
+
* throw `lock_acquire_failed`, **preserve lock + pid files**, do
|
|
60
|
+
* not invoke the liveness probe. This window is exactly when a
|
|
61
|
+
* racing daemon has just acquired the lock but has not yet written
|
|
62
|
+
* its pid (Step 2 startup order: `acquireDaemonLock()` then
|
|
63
|
+
* `writePid(process.pid)`); collapsing it into stale-cleanup would
|
|
64
|
+
* let daemon B steal daemon A's live lock and acquire its own
|
|
65
|
+
* (TED rev8 review-fix — multi-instance guarantee P1).
|
|
66
|
+
* - **stale-cleanup retry STILL races (EEXIST again)** → throw
|
|
67
|
+
* `lock_acquire_failed` (rare; another daemon snuck in between
|
|
68
|
+
* our unlink and our second openSync).
|
|
69
|
+
* - **non-EEXIST FS error on openSync** (permission denied, ENOSPC,
|
|
70
|
+
* etc.) → throw `lock_acquire_failed`.
|
|
71
|
+
* - **same process already holds this exact lock** → throw
|
|
72
|
+
* `lock_acquire_failed` (reentrancy guard, TED Group 2 case 19).
|
|
73
|
+
*
|
|
74
|
+
* Caller maps `lock_held_by_other` to exit 6 ("daemon already
|
|
75
|
+
* running"); `lock_acquire_failed` to exit 1 (TED 拍板点 #8). */
|
|
76
|
+
export declare function acquireDaemonLock(opts?: AcquireDaemonLockOptions): LockHandle;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { DirectModelClient } from "./types";
|
|
2
|
+
export interface AnthropicClientOptions {
|
|
3
|
+
readonly apiKey: string;
|
|
4
|
+
readonly model: string;
|
|
5
|
+
/** Default "https://api.anthropic.com". Trailing slashes are stripped. */
|
|
6
|
+
readonly baseURL?: string;
|
|
7
|
+
/** Default "2023-06-01" (current Messages API). */
|
|
8
|
+
readonly anthropicVersion?: string;
|
|
9
|
+
/** Test injection point. Defaults to globalThis.fetch. */
|
|
10
|
+
readonly fetchImpl?: typeof fetch;
|
|
11
|
+
}
|
|
12
|
+
export declare function createAnthropicClient(opts: AnthropicClientOptions): DirectModelClient;
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import type { DirectModelProviderName } from "./types";
|
|
2
|
+
export type DirectModelErrorKind = "direct_model_network" | "direct_model_http" | "direct_model_aborted" | "direct_model_invalid_response" | "direct_model_unsupported";
|
|
3
|
+
export declare abstract class DirectModelError extends Error {
|
|
4
|
+
abstract readonly kind: DirectModelErrorKind;
|
|
5
|
+
readonly provider: DirectModelProviderName;
|
|
6
|
+
readonly cause: unknown;
|
|
7
|
+
protected constructor(provider: DirectModelProviderName, message: string, cause?: unknown);
|
|
8
|
+
}
|
|
9
|
+
/** fetch() threw before producing a Response. Wraps the underlying
|
|
10
|
+
* Node net / TLS / DNS error (or whatever fetch surfaced). */
|
|
11
|
+
export declare class DirectModelNetworkError extends DirectModelError {
|
|
12
|
+
readonly name = "DirectModelNetworkError";
|
|
13
|
+
readonly kind: "direct_model_network";
|
|
14
|
+
constructor(provider: DirectModelProviderName, message: string, cause?: unknown);
|
|
15
|
+
}
|
|
16
|
+
/** HTTP response with non-2xx status. `bodySnippet` is the response
|
|
17
|
+
* payload after redaction + truncation (≤ SNIPPET_MAX); callers
|
|
18
|
+
* SHOULD NOT JSON.parse it without checking Content-Type. */
|
|
19
|
+
export declare class DirectModelHttpError extends DirectModelError {
|
|
20
|
+
readonly name = "DirectModelHttpError";
|
|
21
|
+
readonly kind: "direct_model_http";
|
|
22
|
+
readonly status: number;
|
|
23
|
+
readonly bodySnippet?: string;
|
|
24
|
+
constructor(provider: DirectModelProviderName, status: number, message: string, bodySnippet?: string, cause?: unknown);
|
|
25
|
+
}
|
|
26
|
+
/** Caller-supplied AbortSignal fired (either pre-aborted or
|
|
27
|
+
* mid-flight). Distinguished from DirectModelNetworkError so the
|
|
28
|
+
* caller can suppress retry on intentional cancel. */
|
|
29
|
+
export declare class DirectModelAbortedError extends DirectModelError {
|
|
30
|
+
readonly name = "DirectModelAbortedError";
|
|
31
|
+
readonly kind: "direct_model_aborted";
|
|
32
|
+
constructor(provider: DirectModelProviderName, message: string, cause?: unknown);
|
|
33
|
+
}
|
|
34
|
+
/** 2xx response but the body could not be parsed as JSON, or the
|
|
35
|
+
* parsed shape did not match the expected provider envelope (e.g.
|
|
36
|
+
* Anthropic missing `content[0].text`, OpenAI missing
|
|
37
|
+
* `choices[0].message.content`). `responseSnippet` is redacted +
|
|
38
|
+
* truncated. */
|
|
39
|
+
export declare class DirectModelInvalidResponseError extends DirectModelError {
|
|
40
|
+
readonly name = "DirectModelInvalidResponseError";
|
|
41
|
+
readonly kind: "direct_model_invalid_response";
|
|
42
|
+
readonly responseSnippet?: string;
|
|
43
|
+
constructor(provider: DirectModelProviderName, message: string, responseSnippet?: string, cause?: unknown);
|
|
44
|
+
}
|
|
45
|
+
/** Caller passed an option that fails synchronous validation
|
|
46
|
+
* (empty apiKey, empty model, maxTokens <= 0, etc). Thrown before
|
|
47
|
+
* any network call. `field` names the offending option for
|
|
48
|
+
* programmatic handling (don't parse message text). */
|
|
49
|
+
export declare class DirectModelUnsupportedError extends DirectModelError {
|
|
50
|
+
readonly name = "DirectModelUnsupportedError";
|
|
51
|
+
readonly kind: "direct_model_unsupported";
|
|
52
|
+
readonly field: string;
|
|
53
|
+
constructor(provider: DirectModelProviderName, field: string, message: string);
|
|
54
|
+
}
|
|
55
|
+
export declare const SNIPPET_MAX = 2048;
|
|
56
|
+
export declare const REDACTED_PLACEHOLDER = "[REDACTED]";
|
|
57
|
+
export declare function redactSecrets(s: string, secrets: readonly string[]): string;
|
|
58
|
+
export declare function truncateSnippet(s: string, max?: number): string;
|
|
59
|
+
export declare function sanitizeSnippet(raw: string | undefined, secrets: readonly string[]): string | undefined;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { DirectModelClient } from "./types";
|
|
2
|
+
export interface OpenAIClientOptions {
|
|
3
|
+
readonly apiKey: string;
|
|
4
|
+
readonly model: string;
|
|
5
|
+
/** Default "https://api.openai.com/v1". Trailing slashes stripped. */
|
|
6
|
+
readonly baseURL?: string;
|
|
7
|
+
/** Optional OpenAI-Organization header. */
|
|
8
|
+
readonly organization?: string;
|
|
9
|
+
/** Test injection point. Defaults to globalThis.fetch. */
|
|
10
|
+
readonly fetchImpl?: typeof fetch;
|
|
11
|
+
}
|
|
12
|
+
export declare function createOpenAIClient(opts: OpenAIClientOptions): DirectModelClient;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
export type DirectModelProviderName = "anthropic" | "openai";
|
|
2
|
+
export interface DirectModelGenerateRequest {
|
|
3
|
+
readonly systemPrompt: string;
|
|
4
|
+
readonly userPrompt: string;
|
|
5
|
+
readonly temperature?: number;
|
|
6
|
+
readonly maxTokens: number;
|
|
7
|
+
readonly signal?: AbortSignal;
|
|
8
|
+
}
|
|
9
|
+
export interface DirectModelGenerateResponse {
|
|
10
|
+
readonly text: string;
|
|
11
|
+
readonly inputTokens?: number;
|
|
12
|
+
readonly outputTokens?: number;
|
|
13
|
+
readonly latencyMs: number;
|
|
14
|
+
readonly raw: unknown;
|
|
15
|
+
}
|
|
16
|
+
export interface DirectModelClient {
|
|
17
|
+
readonly provider: DirectModelProviderName;
|
|
18
|
+
readonly model: string;
|
|
19
|
+
generate(req: DirectModelGenerateRequest): Promise<DirectModelGenerateResponse>;
|
|
20
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import type { LegalAction } from "./types";
|
|
2
|
+
export type ParseInvalidReason = "json_parse" | "missing_fields" | "unknown_action_type" | "action_not_legal" | "data_validation";
|
|
3
|
+
export type ParseResult = {
|
|
4
|
+
readonly kind: "ok";
|
|
5
|
+
/**
|
|
6
|
+
* For simple / server-enumerated actions, this is the original
|
|
7
|
+
* server-provided `LegalAction` reference (reference equality
|
|
8
|
+
* holds against the matching entry in `legalActions`). For
|
|
9
|
+
* Texas Hold'em `raise` and Liar's Dice `bid`, the LLM picks
|
|
10
|
+
* the concrete amount / quantity-face within the server hints,
|
|
11
|
+
* so the parser constructs a fresh `{ type, data }` object —
|
|
12
|
+
* reference equality with `legalActions[i]` does NOT hold for
|
|
13
|
+
* those two cases (M1-14 拍板点 #5 + Risks #10).
|
|
14
|
+
*/
|
|
15
|
+
readonly action: LegalAction;
|
|
16
|
+
/**
|
|
17
|
+
* Optional one-line reasoning extracted from the LLM JSON
|
|
18
|
+
* (`{"summary": ...}`). M1-14 provider passes this through to
|
|
19
|
+
* `DecisionResponse.summary` without re-parsing.
|
|
20
|
+
*/
|
|
21
|
+
readonly summary?: string;
|
|
22
|
+
} | {
|
|
23
|
+
readonly kind: "invalid";
|
|
24
|
+
readonly reason: ParseInvalidReason;
|
|
25
|
+
/**
|
|
26
|
+
* Up to `parseRetryHintCharCap` chars (default 500) of the raw
|
|
27
|
+
* LLM output, used to populate the corrective re-prompt. Parser
|
|
28
|
+
* is responsible for truncation; provider does not re-truncate.
|
|
29
|
+
*/
|
|
30
|
+
readonly rawSnippet?: string;
|
|
31
|
+
};
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { DecisionRequest } from "./types";
|
|
2
|
+
export interface PromptBuilderOptions {
|
|
3
|
+
/** Hard cap on assembled userPrompt length (chars). Default 16384. */
|
|
4
|
+
readonly userPromptCharCap?: number;
|
|
5
|
+
}
|
|
6
|
+
export interface BuiltPrompt {
|
|
7
|
+
readonly systemPrompt: string;
|
|
8
|
+
readonly userPrompt: string;
|
|
9
|
+
}
|
|
10
|
+
export declare function buildPrompt(req: DecisionRequest, options?: PromptBuilderOptions): BuiltPrompt;
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { createAnthropicClient } from "./direct-model/anthropic";
|
|
2
|
+
import { createOpenAIClient } from "./direct-model/openai";
|
|
3
|
+
import type { DirectModelProviderName } from "./direct-model/types";
|
|
4
|
+
import type { DecisionRequest, DecisionResponse } from "./types";
|
|
5
|
+
export type { DirectModelProviderName } from "./direct-model/types";
|
|
6
|
+
export interface DecisionProvider {
|
|
7
|
+
readonly name: string;
|
|
8
|
+
decide(req: DecisionRequest): Promise<DecisionResponse>;
|
|
9
|
+
healthCheck(): Promise<boolean>;
|
|
10
|
+
}
|
|
11
|
+
export interface DirectModelProviderOptions {
|
|
12
|
+
/** Identifier for this provider instance. plan §5.5
|
|
13
|
+
* DecisionProvider.name. */
|
|
14
|
+
readonly name: string;
|
|
15
|
+
/** Returns API key for the given (provider, model). Caller decides
|
|
16
|
+
* the source (env / keychain / file per plan §5.7 layer 2). Must be
|
|
17
|
+
* synchronous so the factory itself stays sync. Returning an empty
|
|
18
|
+
* string causes `decide()` to throw a fatal_unsupported error and
|
|
19
|
+
* `healthCheck()` to return false. */
|
|
20
|
+
readonly apiKeyResolver: (provider: DirectModelProviderName, model: string) => string;
|
|
21
|
+
/** Override for the direct-model client factories (testing). When
|
|
22
|
+
* omitted, defaults to the M1-11 `createAnthropicClient` /
|
|
23
|
+
* `createOpenAIClient`. */
|
|
24
|
+
readonly clientFactory?: {
|
|
25
|
+
readonly anthropic?: typeof createAnthropicClient;
|
|
26
|
+
readonly openai?: typeof createOpenAIClient;
|
|
27
|
+
};
|
|
28
|
+
/** Default 2. Total LLM calls = 1 + retryBudget. */
|
|
29
|
+
readonly retryBudget?: number;
|
|
30
|
+
/** Default 500. Max chars of raw LLM output threaded into the
|
|
31
|
+
* corrective re-prompt. */
|
|
32
|
+
readonly parseRetryHintCharCap?: number;
|
|
33
|
+
/** Override for transport. Passed through to the client factory. */
|
|
34
|
+
readonly fetchImpl?: typeof fetch;
|
|
35
|
+
/** Explicit healthCheck target. When omitted, `healthCheck()`
|
|
36
|
+
* returns false (catch-all consistent with the
|
|
37
|
+
* `Promise<boolean>` contract). M1-14 rev3 锁:无 profile → false。 */
|
|
38
|
+
readonly healthCheckProfile?: {
|
|
39
|
+
readonly provider: DirectModelProviderName;
|
|
40
|
+
readonly model: string;
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
export type DecisionProviderErrorKind = "fatal_http" | "fatal_aborted" | "fatal_unsupported" | "fatal_caller_bug";
|
|
44
|
+
export declare class DecisionProviderError extends Error {
|
|
45
|
+
readonly name = "DecisionProviderError";
|
|
46
|
+
readonly kind: DecisionProviderErrorKind;
|
|
47
|
+
readonly cause: unknown;
|
|
48
|
+
constructor(kind: DecisionProviderErrorKind, message: string, cause?: unknown);
|
|
49
|
+
}
|
|
50
|
+
export declare function createDirectModelProvider(opts: DirectModelProviderOptions): DecisionProvider;
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import type { Action, CoupRules, Event, LiarsDiceRules, PlayerInfo, TexasHoldemRules } from "../protocol/types";
|
|
2
|
+
export type GameType = "texas_holdem" | "liars_dice" | "coup";
|
|
3
|
+
export type GameRules = {
|
|
4
|
+
readonly game: "texas_holdem";
|
|
5
|
+
readonly rules: TexasHoldemRules;
|
|
6
|
+
} | {
|
|
7
|
+
readonly game: "liars_dice";
|
|
8
|
+
readonly rules: LiarsDiceRules;
|
|
9
|
+
} | {
|
|
10
|
+
readonly game: "coup";
|
|
11
|
+
readonly rules: CoupRules;
|
|
12
|
+
};
|
|
13
|
+
export type LegalAction = Action;
|
|
14
|
+
export interface GameSpecificProfile {
|
|
15
|
+
readonly extraPrompt?: string;
|
|
16
|
+
/**
|
|
17
|
+
* [0..1] risk-aversion hyperparameter. Information-only for M1-12;
|
|
18
|
+
* consumed by M1-14 (rev3 锁:M1-13 fallback 也不读).
|
|
19
|
+
*/
|
|
20
|
+
readonly riskAversion?: number;
|
|
21
|
+
}
|
|
22
|
+
export interface StrategyProfile {
|
|
23
|
+
readonly name: string;
|
|
24
|
+
readonly version: number;
|
|
25
|
+
readonly provider: "anthropic" | "openai";
|
|
26
|
+
readonly model: string;
|
|
27
|
+
readonly systemPrompt: string;
|
|
28
|
+
readonly temperature?: number;
|
|
29
|
+
readonly maxTokens: number;
|
|
30
|
+
readonly costCapUSDPerMatch?: number;
|
|
31
|
+
readonly gameSpecific?: Partial<Record<GameType, GameSpecificProfile>>;
|
|
32
|
+
}
|
|
33
|
+
export interface DecisionRequest {
|
|
34
|
+
readonly game: GameType;
|
|
35
|
+
readonly matchId: string;
|
|
36
|
+
readonly playerId: string;
|
|
37
|
+
/**
|
|
38
|
+
* Game-specific rules from server_game_start.data.rules. Caller
|
|
39
|
+
* must ensure shape matches the `game` discriminator
|
|
40
|
+
* (TexasHoldemRules / LiarsDiceRules / CoupRules per
|
|
41
|
+
* protocol/types.ts MsgGameStartDataTexasHoldem / LiarsDice / Coup).
|
|
42
|
+
*/
|
|
43
|
+
readonly rules: GameRules["rules"];
|
|
44
|
+
readonly legalActions: readonly LegalAction[];
|
|
45
|
+
/**
|
|
46
|
+
* Game-specific state from action_request.data.state. Protocol-
|
|
47
|
+
* level shape is opaque (`state: {}` per messages/server_action_
|
|
48
|
+
* request.schema.json); narrowing is per-game. M1-12 prompt-
|
|
49
|
+
* builder dispatches on `game` and treats this as the per-game
|
|
50
|
+
* state shape (TexasHoldemState / LiarsDiceState / CoupState).
|
|
51
|
+
*/
|
|
52
|
+
readonly publicState: unknown;
|
|
53
|
+
/**
|
|
54
|
+
* Reserved for future private-narrowed fields. Server currently
|
|
55
|
+
* embeds your_hand / your_dice / your_cards / coins inside
|
|
56
|
+
* publicState; this slot stays optional unknown for forward
|
|
57
|
+
* compatibility (M1-12 Risks #4).
|
|
58
|
+
*/
|
|
59
|
+
readonly privateState?: unknown;
|
|
60
|
+
readonly players: readonly PlayerInfo[];
|
|
61
|
+
/**
|
|
62
|
+
* Incremental events since the player's last action_request
|
|
63
|
+
* (action_request.data.new_events). Caller MUST normalize null →
|
|
64
|
+
* [] before constructing DecisionRequest (M1-12 Risks #11; protocol
|
|
65
|
+
* spec allows `new_events: null` on first action_request).
|
|
66
|
+
*/
|
|
67
|
+
readonly recentEvents: readonly Event[];
|
|
68
|
+
readonly strategyProfile: StrategyProfile;
|
|
69
|
+
readonly turnTimeoutMs: number;
|
|
70
|
+
readonly decisionBudgetMs: number;
|
|
71
|
+
}
|
|
72
|
+
export interface DecisionResponseProviderMetadata {
|
|
73
|
+
readonly provider: string;
|
|
74
|
+
readonly model: string;
|
|
75
|
+
readonly inputTokens?: number;
|
|
76
|
+
readonly outputTokens?: number;
|
|
77
|
+
readonly costUSD?: number;
|
|
78
|
+
readonly latencyMs: number;
|
|
79
|
+
readonly retries?: number;
|
|
80
|
+
readonly fallback?: boolean;
|
|
81
|
+
}
|
|
82
|
+
export interface DecisionResponse {
|
|
83
|
+
readonly action: string;
|
|
84
|
+
readonly params?: Record<string, unknown>;
|
|
85
|
+
readonly summary?: string;
|
|
86
|
+
readonly providerMetadata: DecisionResponseProviderMetadata;
|
|
87
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Read `data[key]` as a finite number. Returns `undefined` if `data` is
|
|
3
|
+
* not a non-null object, the field is missing, the value is not a
|
|
4
|
+
* number, or the value is NaN / Infinity / -Infinity. Caller must omit
|
|
5
|
+
* the output field on `undefined` (never default to 0).
|
|
6
|
+
*/
|
|
7
|
+
export declare function readNumberField(data: unknown, key: string): number | undefined;
|
|
8
|
+
/**
|
|
9
|
+
* Read `data[key]` as `string[]`. Returns `undefined` if `data` is not a
|
|
10
|
+
* non-null object, the field is missing, the value is not an array, or
|
|
11
|
+
* any element is not a string. Returns the array reference (no copy) —
|
|
12
|
+
* read-only by convention; caller must NOT mutate.
|
|
13
|
+
*/
|
|
14
|
+
export declare function readStringArrayField(data: unknown, key: string): string[] | undefined;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { LegalAction } from "../../decision/types";
|
|
2
|
+
import type { CoupState } from "../../protocol/types";
|
|
3
|
+
export interface CoupFallbackInput {
|
|
4
|
+
readonly publicState: CoupState;
|
|
5
|
+
readonly legalActions: readonly LegalAction[];
|
|
6
|
+
readonly yourPlayerId: string;
|
|
7
|
+
}
|
|
8
|
+
export declare function fallbackCoup(input: CoupFallbackInput): LegalAction;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { CoupRules, CoupState, Event, PlayerInfo } from "../../protocol/types";
|
|
2
|
+
export interface CoupFormatterInput {
|
|
3
|
+
readonly publicState: CoupState;
|
|
4
|
+
readonly privateState?: unknown;
|
|
5
|
+
readonly rules: CoupRules;
|
|
6
|
+
readonly players: readonly PlayerInfo[];
|
|
7
|
+
readonly recentEvents: readonly Event[];
|
|
8
|
+
readonly yourPlayerId: string;
|
|
9
|
+
}
|
|
10
|
+
export interface StateFormatterOutput {
|
|
11
|
+
readonly stateBlock: string;
|
|
12
|
+
readonly recentEventsBlock: string;
|
|
13
|
+
}
|
|
14
|
+
export declare function formatCoupState(input: CoupFormatterInput): StateFormatterOutput;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { LegalAction } from "../../decision/types";
|
|
2
|
+
import type { LiarsDiceState } from "../../protocol/types";
|
|
3
|
+
export interface LiarsDiceFallbackInput {
|
|
4
|
+
readonly publicState: LiarsDiceState;
|
|
5
|
+
readonly legalActions: readonly LegalAction[];
|
|
6
|
+
readonly yourPlayerId: string;
|
|
7
|
+
}
|
|
8
|
+
export declare function fallbackLiarsDice(input: LiarsDiceFallbackInput): LegalAction;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { Event, LiarsDiceRules, LiarsDiceState, PlayerInfo } from "../../protocol/types";
|
|
2
|
+
export interface LiarsDiceFormatterInput {
|
|
3
|
+
readonly publicState: LiarsDiceState;
|
|
4
|
+
readonly privateState?: unknown;
|
|
5
|
+
readonly rules: LiarsDiceRules;
|
|
6
|
+
readonly players: readonly PlayerInfo[];
|
|
7
|
+
readonly recentEvents: readonly Event[];
|
|
8
|
+
readonly yourPlayerId: string;
|
|
9
|
+
}
|
|
10
|
+
export interface StateFormatterOutput {
|
|
11
|
+
readonly stateBlock: string;
|
|
12
|
+
readonly recentEventsBlock: string;
|
|
13
|
+
}
|
|
14
|
+
export declare function formatLiarsDiceState(input: LiarsDiceFormatterInput): StateFormatterOutput;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { LegalAction } from "../../decision/types";
|
|
2
|
+
import type { TexasHoldemState } from "../../protocol/types";
|
|
3
|
+
export interface TexasHoldemFallbackInput {
|
|
4
|
+
readonly publicState: TexasHoldemState;
|
|
5
|
+
readonly legalActions: readonly LegalAction[];
|
|
6
|
+
readonly yourPlayerId: string;
|
|
7
|
+
}
|
|
8
|
+
export declare function fallbackTexasHoldem(input: TexasHoldemFallbackInput): LegalAction;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { Event, PlayerInfo, TexasHoldemRules, TexasHoldemState } from "../../protocol/types";
|
|
2
|
+
export interface TexasHoldemFormatterInput {
|
|
3
|
+
readonly publicState: TexasHoldemState;
|
|
4
|
+
readonly privateState?: unknown;
|
|
5
|
+
readonly rules: TexasHoldemRules;
|
|
6
|
+
readonly players: readonly PlayerInfo[];
|
|
7
|
+
readonly recentEvents: readonly Event[];
|
|
8
|
+
readonly yourPlayerId: string;
|
|
9
|
+
}
|
|
10
|
+
export interface StateFormatterOutput {
|
|
11
|
+
readonly stateBlock: string;
|
|
12
|
+
readonly recentEventsBlock: string;
|
|
13
|
+
}
|
|
14
|
+
export declare function formatTexasHoldemState(input: TexasHoldemFormatterInput): StateFormatterOutput;
|