@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,50 @@
|
|
|
1
|
+
import type { ReflectionProposal } from "./reflection-engine.js";
|
|
2
|
+
export declare class ProposalStoreError extends Error {
|
|
3
|
+
readonly name = "ProposalStoreError";
|
|
4
|
+
readonly kind: "not_found" | "already_applied" | "patch_failed" | "validation_failed" | "io_error";
|
|
5
|
+
readonly cause?: unknown;
|
|
6
|
+
constructor(kind: ProposalStoreError["kind"], message: string, cause?: unknown);
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* Serialises a proposal to
|
|
10
|
+
* `~/.aifight/agents/<slug>/proposals/<timestamp>-<matchId>.proposal.json`.
|
|
11
|
+
*
|
|
12
|
+
* Creates the proposals directory if it does not exist.
|
|
13
|
+
* Returns the absolute path of the written file.
|
|
14
|
+
*/
|
|
15
|
+
export declare function saveProposal(agentSlug: string, proposal: ReflectionProposal): Promise<string>;
|
|
16
|
+
export interface ListProposalsFilter {
|
|
17
|
+
status?: ReflectionProposal["status"];
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Returns all proposals for an agent, optionally filtered by status.
|
|
21
|
+
* Results are sorted by createdAt ascending (oldest first).
|
|
22
|
+
* Returns [] when the proposals directory does not exist.
|
|
23
|
+
*/
|
|
24
|
+
export declare function listProposals(agentSlug: string, filter?: ListProposalsFilter): Promise<ReflectionProposal[]>;
|
|
25
|
+
/**
|
|
26
|
+
* Reads a specific proposal by proposalId.
|
|
27
|
+
* Scans the proposals directory (linear scan; proposal counts are small).
|
|
28
|
+
* Throws ProposalStoreError("not_found") when no match is found.
|
|
29
|
+
*/
|
|
30
|
+
export declare function getProposal(agentSlug: string, proposalId: string): Promise<ReflectionProposal>;
|
|
31
|
+
/**
|
|
32
|
+
* Applies a pending proposal to the agent's profile files.
|
|
33
|
+
*
|
|
34
|
+
* For each target:
|
|
35
|
+
* - Reads the current file.
|
|
36
|
+
* - Applies the patch (json_patch or text_replace).
|
|
37
|
+
* - Validates the result (validateStrategy / validateSoul).
|
|
38
|
+
* - Backs up the old file to versions/<name>.v<N>.<ext>.
|
|
39
|
+
* - Atomically writes the new file.
|
|
40
|
+
*
|
|
41
|
+
* Updates the proposal status to "applied" and sets appliedAt.
|
|
42
|
+
* Throws ProposalStoreError on any failure (no partial writes on error).
|
|
43
|
+
*/
|
|
44
|
+
export declare function applyProposal(agentSlug: string, proposalId: string): Promise<void>;
|
|
45
|
+
/**
|
|
46
|
+
* Marks a proposal as rejected without modifying any profile files.
|
|
47
|
+
* reason is ignored (proposals are immutable JSON; rejection just sets status).
|
|
48
|
+
*/
|
|
49
|
+
export declare function rejectProposal(agentSlug: string, proposalId: string, _reason?: string): Promise<void>;
|
|
50
|
+
export type { ReflectionProposal, ProposalTarget } from "./reflection-engine.js";
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
/** One turn's decision, as stored in decisions.jsonl by the daemon. */
|
|
2
|
+
export interface DecisionRecord {
|
|
3
|
+
/** Zero-based turn index within the match. */
|
|
4
|
+
turnIndex: number;
|
|
5
|
+
/** The action string that was ultimately submitted. */
|
|
6
|
+
selectedAction: string;
|
|
7
|
+
/** Whether the action was accepted by the server as legal. */
|
|
8
|
+
actionValid: boolean;
|
|
9
|
+
/** True when the LLM failed and the runtime fell back to heuristics. */
|
|
10
|
+
fallbackUsed: boolean;
|
|
11
|
+
/** Short prose summary of the LLM's stated reasoning, if captured. */
|
|
12
|
+
reasonSummary?: string;
|
|
13
|
+
/** Wall-clock ms from action_request receipt to action submission. */
|
|
14
|
+
latencyMs: number;
|
|
15
|
+
}
|
|
16
|
+
export interface MatchReflectionInput {
|
|
17
|
+
agentSlug: string;
|
|
18
|
+
matchId: string;
|
|
19
|
+
game: string;
|
|
20
|
+
result: "win" | "loss" | "draw";
|
|
21
|
+
ratingDelta: number;
|
|
22
|
+
newRating: number;
|
|
23
|
+
opponentName: string;
|
|
24
|
+
opponentModel?: string;
|
|
25
|
+
replayUrl: string;
|
|
26
|
+
/** All decisions recorded during the match (from decisions.jsonl). */
|
|
27
|
+
decisions: DecisionRecord[];
|
|
28
|
+
/** Raw event log from events.jsonl (opaque; used for pattern detection). */
|
|
29
|
+
events: unknown[];
|
|
30
|
+
totalCostUSD?: number;
|
|
31
|
+
totalLatencyMs?: number;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Generates a concise Markdown match recap suitable for writing to summary.md.
|
|
35
|
+
*
|
|
36
|
+
* Language: Chinese primary, English technical terms.
|
|
37
|
+
* Target length: ~20-35 lines regardless of match length.
|
|
38
|
+
*/
|
|
39
|
+
export declare function generateMatchSummary(input: MatchReflectionInput): string;
|
|
40
|
+
export interface ProposalTarget {
|
|
41
|
+
/** Which file this patch applies to. */
|
|
42
|
+
file: "strategy.json" | "soul.md";
|
|
43
|
+
/**
|
|
44
|
+
* "json_patch" → patch is a JSON Patch array (RFC 6902).
|
|
45
|
+
* "text_replace" → patch is { old: string; new: string }.
|
|
46
|
+
*/
|
|
47
|
+
type: "json_patch" | "text_replace";
|
|
48
|
+
patch: unknown;
|
|
49
|
+
}
|
|
50
|
+
export interface ReflectionProposal {
|
|
51
|
+
schemaVersion: 1;
|
|
52
|
+
/** UUID v4 generated at creation time. */
|
|
53
|
+
proposalId: string;
|
|
54
|
+
/** The daemon's session ID when the match was played. */
|
|
55
|
+
localSessionId: string;
|
|
56
|
+
agentSlug: string;
|
|
57
|
+
matchId: string;
|
|
58
|
+
targets: ProposalTarget[];
|
|
59
|
+
/** Human-readable explanation of why this proposal was generated. */
|
|
60
|
+
rationale: string;
|
|
61
|
+
/** Description of what could go wrong if applied. */
|
|
62
|
+
risk: string;
|
|
63
|
+
status: "pending" | "applied" | "rejected";
|
|
64
|
+
createdAt: string;
|
|
65
|
+
appliedAt?: string;
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Analyses a completed match and produces a strategy improvement proposal,
|
|
69
|
+
* or returns null when no confident improvement can be identified.
|
|
70
|
+
*
|
|
71
|
+
* Heuristics (in priority order):
|
|
72
|
+
* 1. High fallback rate (>20%) → propose lowering riskAversion for the game
|
|
73
|
+
* to avoid timeout-prone positions.
|
|
74
|
+
* 2. Loss with zero fallbacks → inspect riskAversion; if too aggressive
|
|
75
|
+
* propose nudging it up slightly.
|
|
76
|
+
* 3. Win with high invalid-action rate → propose adding strategy notes.
|
|
77
|
+
* 4. Very slow average latency → propose a soul.md note on timeout awareness.
|
|
78
|
+
*
|
|
79
|
+
* Returns null when no heuristic fires with sufficient confidence.
|
|
80
|
+
*/
|
|
81
|
+
export declare function generateReflectionProposal(input: MatchReflectionInput, localSessionId?: string): ReflectionProposal | null;
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import type { AgentInstanceSnapshot } from "../agents/agent";
|
|
2
|
+
import type { DailyScheduleConfig, DailySchedulerNotifyEvent, DailySchedulerSnapshot } from "./types";
|
|
3
|
+
export interface SchedulerAgentTarget {
|
|
4
|
+
readonly name: string;
|
|
5
|
+
joinQueue(game: string, mode?: string): void;
|
|
6
|
+
snapshot(): AgentInstanceSnapshot;
|
|
7
|
+
onState(handler: (snapshot: AgentInstanceSnapshot) => void): () => void;
|
|
8
|
+
}
|
|
9
|
+
export type SchedulerTimerHandle = unknown;
|
|
10
|
+
export interface SchedulerClock {
|
|
11
|
+
readonly now: () => number;
|
|
12
|
+
readonly setTimeout: (cb: () => void, ms: number) => SchedulerTimerHandle;
|
|
13
|
+
readonly clearTimeout: (h: SchedulerTimerHandle) => void;
|
|
14
|
+
}
|
|
15
|
+
export interface DailySchedulerOptions {
|
|
16
|
+
readonly agent: SchedulerAgentTarget;
|
|
17
|
+
/** Initial schedule snapshot taken once at construction; copied into
|
|
18
|
+
* the scheduler's internal `currentSchedule` field. After construction
|
|
19
|
+
* the only way to change schedule is `scheduler.setSchedule(cfg)`.
|
|
20
|
+
* rev2 fix #3 single authority. */
|
|
21
|
+
readonly initialSchedule?: DailyScheduleConfig | null;
|
|
22
|
+
/** Optional health gate. Resolves true → join allowed; false / throw →
|
|
23
|
+
* skip + notify. Scheduler does NOT hold a DecisionProvider instance
|
|
24
|
+
* (rev1 decision #7). */
|
|
25
|
+
readonly healthCheck?: () => Promise<boolean>;
|
|
26
|
+
/** Default = real wall clock + globalThis.{setTimeout, clearTimeout}. */
|
|
27
|
+
readonly clock?: SchedulerClock;
|
|
28
|
+
readonly onNotify?: (event: DailySchedulerNotifyEvent) => void;
|
|
29
|
+
}
|
|
30
|
+
export interface DailyScheduler {
|
|
31
|
+
start(): void;
|
|
32
|
+
stop(): void;
|
|
33
|
+
snapshot(): DailySchedulerSnapshot;
|
|
34
|
+
/** rev2 fix #3 — single authority: replace internal `currentSchedule`.
|
|
35
|
+
* `cfg` is sync-validated; invalid throws DailySchedulerError. `null`
|
|
36
|
+
* means "no schedule" (scheduler keeps running; every fire goes to
|
|
37
|
+
* skip_disabled). NOT equivalent to stop(). */
|
|
38
|
+
setSchedule(cfg: DailyScheduleConfig | null): void;
|
|
39
|
+
}
|
|
40
|
+
export type DailySchedulerErrorKind = "invalid_timezone" | "invalid_count" | "invalid_min_interval" | "invalid_state";
|
|
41
|
+
export declare class DailySchedulerError extends Error {
|
|
42
|
+
readonly name = "DailySchedulerError";
|
|
43
|
+
readonly kind: DailySchedulerErrorKind;
|
|
44
|
+
readonly cause: unknown;
|
|
45
|
+
constructor(kind: DailySchedulerErrorKind, message: string, cause?: unknown);
|
|
46
|
+
}
|
|
47
|
+
export declare function createDailyScheduler(opts: DailySchedulerOptions): DailyScheduler;
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import type { GameType } from "../decision/types";
|
|
2
|
+
export interface DailyGameQuota {
|
|
3
|
+
/** Non-negative integer. 0 = this game is configured but not scheduled. */
|
|
4
|
+
readonly count: number;
|
|
5
|
+
}
|
|
6
|
+
export interface DailyScheduleConfig {
|
|
7
|
+
/** Master toggle. false → scheduler stays idle; existing config retained. */
|
|
8
|
+
readonly enabled: boolean;
|
|
9
|
+
/** IANA timezone name, e.g. "Asia/Shanghai" / "UTC". Day boundary is computed in this timezone. */
|
|
10
|
+
readonly timezone: string;
|
|
11
|
+
/** Per-game daily count. Empty object ⇔ disabled (no work). */
|
|
12
|
+
readonly days: Partial<Record<GameType, DailyGameQuota>>;
|
|
13
|
+
/** Minimum delay between any two `joinQueue` calls. Default 60. */
|
|
14
|
+
readonly minIntervalSec?: number;
|
|
15
|
+
}
|
|
16
|
+
export interface DailySchedulerSnapshot {
|
|
17
|
+
/** Whether start() has been called and stop() has not. */
|
|
18
|
+
readonly running: boolean;
|
|
19
|
+
/** Local YYYY-MM-DD in opts.config.timezone (or null when scheduler stopped). */
|
|
20
|
+
readonly today: string | null;
|
|
21
|
+
/** Remaining quota per game today (config.days minus today's fired count). */
|
|
22
|
+
readonly remaining: Partial<Record<GameType, number>>;
|
|
23
|
+
/** Most recent fire attempt outcome (or null pre-first-fire). */
|
|
24
|
+
readonly lastAttempt: DailySchedulerLastAttempt | null;
|
|
25
|
+
/** Estimated millis until next fire (relative to clock.now()), or null when no fire scheduled. */
|
|
26
|
+
readonly nextFireInMs: number | null;
|
|
27
|
+
}
|
|
28
|
+
export interface DailySchedulerLastAttempt {
|
|
29
|
+
readonly atMs: number;
|
|
30
|
+
readonly game: GameType;
|
|
31
|
+
readonly outcome: "join_succeeded" | "join_threw" | `skip_${string}`;
|
|
32
|
+
readonly cause?: unknown;
|
|
33
|
+
}
|
|
34
|
+
export interface DailySchedulerNotifyEvent {
|
|
35
|
+
readonly level: "info" | "warning" | "error";
|
|
36
|
+
readonly code: DailySchedulerNotifyCode;
|
|
37
|
+
readonly message: string;
|
|
38
|
+
readonly agent?: string;
|
|
39
|
+
readonly game?: GameType;
|
|
40
|
+
readonly cause?: unknown;
|
|
41
|
+
}
|
|
42
|
+
export type DailySchedulerNotifyCode = "started" | "stopped" | "schedule_changed" | "day_rolled_over" | "join_attempted" | "join_succeeded" | "join_threw" | "skip_disabled" | "skip_no_quota" | "skip_agent_not_started" | "skip_agent_stopped" | "skip_state_unavailable" | "skip_transport_disconnected" | "skip_state_busy" | "skip_min_interval" | "skip_health_check" | "health_check_threw" | "snapshot_threw" | "internal_error";
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
import type { UsageRecord } from "../llm/adapters/types.js";
|
|
2
|
+
export type SessionStatus = "created" | "active" | "waiting_action" | "completed" | "abandoned";
|
|
3
|
+
export interface MatchSession {
|
|
4
|
+
/** Locally generated UUID — stable across reconnects */
|
|
5
|
+
localSessionId: string;
|
|
6
|
+
/** Platform match ID from match_found / game_start */
|
|
7
|
+
platformMatchId: string;
|
|
8
|
+
/** Platform per-player session ID (present after game_start) */
|
|
9
|
+
platformSessionId?: string;
|
|
10
|
+
/** Agent slug (matches directory name) */
|
|
11
|
+
agentSlug: string;
|
|
12
|
+
/** Game identifier, e.g. "texas_holdem" */
|
|
13
|
+
gameId: string;
|
|
14
|
+
/** Environment tag: "production" | "beta" | "local" */
|
|
15
|
+
environment: string;
|
|
16
|
+
/** Lifecycle status */
|
|
17
|
+
status: SessionStatus;
|
|
18
|
+
/** SHA-256 of config.json at session creation time */
|
|
19
|
+
configHash: string;
|
|
20
|
+
/** SHA-256 of strategy.json (current game section) at session creation time */
|
|
21
|
+
strategyHash: string;
|
|
22
|
+
/** SHA-256 of soul.md at session creation time */
|
|
23
|
+
soulHash: string;
|
|
24
|
+
/** Provider profile ID used for this session */
|
|
25
|
+
providerProfileId: string;
|
|
26
|
+
/** ISO-8601 creation timestamp */
|
|
27
|
+
createdAt: string;
|
|
28
|
+
/** ISO-8601 last-update timestamp */
|
|
29
|
+
updatedAt: string;
|
|
30
|
+
}
|
|
31
|
+
export interface DecisionRecord {
|
|
32
|
+
/** Zero-based turn index within the match */
|
|
33
|
+
turnIndex: number;
|
|
34
|
+
/** Raw JSON string of legal actions array (stored as string to avoid parsing issues) */
|
|
35
|
+
legalActionsJson: string;
|
|
36
|
+
/** The action string returned to the platform */
|
|
37
|
+
selectedAction: string;
|
|
38
|
+
/** Whether the action passed platform validation */
|
|
39
|
+
actionValid: boolean;
|
|
40
|
+
/** True if a fallback action was used (LLM failed, timed out, or returned invalid) */
|
|
41
|
+
fallbackUsed: boolean;
|
|
42
|
+
/** Provider profile ID used for this decision */
|
|
43
|
+
providerProfileId: string;
|
|
44
|
+
/** Short one-line rationale extracted from LLM response (if available) */
|
|
45
|
+
reasonSummary?: string;
|
|
46
|
+
/** End-to-end decision latency in ms (LLM call + parse) */
|
|
47
|
+
latencyMs: number;
|
|
48
|
+
/** ISO-8601 timestamp */
|
|
49
|
+
timestamp: string;
|
|
50
|
+
}
|
|
51
|
+
/** Resolve the session directory for a given agent slug + match ID. */
|
|
52
|
+
export declare function resolveSessionDir(agentSlug: string, matchId: string): string;
|
|
53
|
+
export interface CreateSessionOpts {
|
|
54
|
+
platformMatchId: string;
|
|
55
|
+
platformSessionId?: string;
|
|
56
|
+
agentSlug: string;
|
|
57
|
+
gameId: string;
|
|
58
|
+
environment: string;
|
|
59
|
+
configHash: string;
|
|
60
|
+
strategyHash: string;
|
|
61
|
+
soulHash: string;
|
|
62
|
+
providerProfileId: string;
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Creates the session directory and writes session.json.
|
|
66
|
+
* Returns the newly created MatchSession and the resolved session directory.
|
|
67
|
+
*/
|
|
68
|
+
export declare function createSession(opts: CreateSessionOpts): Promise<{
|
|
69
|
+
session: MatchSession;
|
|
70
|
+
sessionDir: string;
|
|
71
|
+
}>;
|
|
72
|
+
/**
|
|
73
|
+
* Loads an existing session from session.json.
|
|
74
|
+
* Throws if session.json is missing or malformed.
|
|
75
|
+
*/
|
|
76
|
+
export declare function loadSession(sessionDir: string): Promise<MatchSession>;
|
|
77
|
+
/**
|
|
78
|
+
* Updates only the `status` and `updatedAt` fields of session.json.
|
|
79
|
+
*/
|
|
80
|
+
export declare function updateSessionStatus(sessionDir: string, status: SessionStatus): Promise<void>;
|
|
81
|
+
/**
|
|
82
|
+
* Appends a raw platform event (any object) to events.jsonl.
|
|
83
|
+
* The event is stored as-is; no schema is enforced here.
|
|
84
|
+
*/
|
|
85
|
+
export declare function appendEvent(sessionDir: string, event: unknown): Promise<void>;
|
|
86
|
+
/**
|
|
87
|
+
* Appends a decision record to decisions.jsonl.
|
|
88
|
+
*/
|
|
89
|
+
export declare function appendDecision(sessionDir: string, decision: DecisionRecord): Promise<void>;
|
|
90
|
+
/**
|
|
91
|
+
* Appends a usage record to usage.jsonl.
|
|
92
|
+
*/
|
|
93
|
+
export declare function appendUsage(sessionDir: string, usage: UsageRecord): Promise<void>;
|
|
94
|
+
/**
|
|
95
|
+
* Saves provider-specific continuation state (e.g. conversation thread IDs).
|
|
96
|
+
* Scoped to this match session only — never persisted globally.
|
|
97
|
+
*/
|
|
98
|
+
export declare function saveProviderState(sessionDir: string, state: unknown): Promise<void>;
|
|
99
|
+
/**
|
|
100
|
+
* Loads provider continuation state.
|
|
101
|
+
* Returns null if provider-state.json does not exist yet.
|
|
102
|
+
*/
|
|
103
|
+
export declare function loadProviderState(sessionDir: string): Promise<unknown | null>;
|
|
104
|
+
/**
|
|
105
|
+
* Writes the human-readable post-match summary to summary.md.
|
|
106
|
+
* Called once on game_over.
|
|
107
|
+
*/
|
|
108
|
+
export declare function writeSummary(sessionDir: string, summaryMd: string): Promise<void>;
|
|
109
|
+
/**
|
|
110
|
+
* Lists all session directories for an agent, sorted by name (match ID).
|
|
111
|
+
* Returns absolute paths.
|
|
112
|
+
*/
|
|
113
|
+
export declare function listSessions(agentSlug: string): Promise<string[]>;
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The JSON object structure the LLM must return for every decision.
|
|
3
|
+
* Stored as a constant so it can be embedded verbatim in the prompt and
|
|
4
|
+
* referenced from tests without duplication.
|
|
5
|
+
*/
|
|
6
|
+
export declare const DECISION_OUTPUT_SCHEMA: {
|
|
7
|
+
readonly action: "string — exact action token from the legal_actions list";
|
|
8
|
+
readonly args: "object | null — action-specific parameters (omit or null if none required)";
|
|
9
|
+
readonly confidence: "number 0.0–1.0 — your confidence in this action being correct";
|
|
10
|
+
readonly reason_summary: "string — one short sentence: what you chose and the primary reason";
|
|
11
|
+
readonly risk_assessment: "low | medium | high — expected downside risk of this move";
|
|
12
|
+
};
|
|
13
|
+
export interface SessionContext {
|
|
14
|
+
/** Full system prompt (blocks 1–4 + 7: invariants, soul, strategy, anti-injection) */
|
|
15
|
+
systemPrompt: string;
|
|
16
|
+
/** Full user prompt (blocks 5–6: current state + legal actions + output contract) */
|
|
17
|
+
userPrompt: string;
|
|
18
|
+
/** Number of characters used by recent events (for diagnostics) */
|
|
19
|
+
recentEventsChars: number;
|
|
20
|
+
/** Whether recent events were truncated */
|
|
21
|
+
recentEventsTruncated: boolean;
|
|
22
|
+
}
|
|
23
|
+
export interface BuildSessionContextOpts {
|
|
24
|
+
/** Agent soul capsule: full text of soul.md */
|
|
25
|
+
soulMd: string;
|
|
26
|
+
/** Game strategy: the section of strategy.json relevant to this game (serialized) */
|
|
27
|
+
strategyText: string;
|
|
28
|
+
/** Game ID, e.g. "texas_holdem" */
|
|
29
|
+
gameId: string;
|
|
30
|
+
/** Platform match ID (for logging context, never injected into trusted block) */
|
|
31
|
+
platformMatchId: string;
|
|
32
|
+
/**
|
|
33
|
+
* Recent platform events from this session's events.jsonl, serialized to a
|
|
34
|
+
* human-readable string. The caller is responsible for summarizing / selecting
|
|
35
|
+
* which events to include. This text is wrapped in untrusted delimiters.
|
|
36
|
+
*/
|
|
37
|
+
recentEventsText: string;
|
|
38
|
+
/**
|
|
39
|
+
* Current game state from the action_request message.
|
|
40
|
+
* Typically a JSON-serializable object; passed as JSON string.
|
|
41
|
+
*/
|
|
42
|
+
currentStateJson: string;
|
|
43
|
+
/**
|
|
44
|
+
* Legal actions array from the action_request message.
|
|
45
|
+
* Must be a valid JSON array string.
|
|
46
|
+
*/
|
|
47
|
+
legalActionsJson: string;
|
|
48
|
+
/** Turn index within the match (zero-based) */
|
|
49
|
+
turnIndex: number;
|
|
50
|
+
/** Provider profile ID (included in context for transparency) */
|
|
51
|
+
providerProfileId: string;
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Assembles the complete system + user prompt pair for a single decision.
|
|
55
|
+
*
|
|
56
|
+
* Prompt assembly order:
|
|
57
|
+
* System:
|
|
58
|
+
* 1. Invariant instructions (AIFight decision engine contract)
|
|
59
|
+
* 2. Agent soul capsule (soul.md)
|
|
60
|
+
* 3. Game strategy (strategy.json section for current game)
|
|
61
|
+
* 4. Anti-injection rule
|
|
62
|
+
* 7. Output contract (required JSON response schema)
|
|
63
|
+
* User:
|
|
64
|
+
* 5. Match context (recent events from this session only)
|
|
65
|
+
* 6. Current state from platform (action_request.state)
|
|
66
|
+
* + Legal actions (strict JSON array)
|
|
67
|
+
*/
|
|
68
|
+
export declare function buildSessionContext(opts: BuildSessionContextOpts): SessionContext;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
export type StoreErrorKind = "open" | "migration" | "query";
|
|
2
|
+
export declare abstract class StoreError extends Error {
|
|
3
|
+
abstract readonly kind: StoreErrorKind;
|
|
4
|
+
}
|
|
5
|
+
export declare class StoreOpenError extends StoreError {
|
|
6
|
+
readonly kind: "open";
|
|
7
|
+
readonly path: string;
|
|
8
|
+
readonly cause?: unknown;
|
|
9
|
+
constructor(path: string, cause: unknown, message: string);
|
|
10
|
+
}
|
|
11
|
+
export declare class StoreMigrationError extends StoreError {
|
|
12
|
+
readonly kind: "migration";
|
|
13
|
+
readonly fromVersion: number;
|
|
14
|
+
readonly toVersion: number;
|
|
15
|
+
readonly cause?: unknown;
|
|
16
|
+
constructor(fromVersion: number, toVersion: number, cause: unknown, message: string);
|
|
17
|
+
}
|
|
18
|
+
export declare class StoreQueryError extends StoreError {
|
|
19
|
+
readonly kind: "query";
|
|
20
|
+
readonly sql: string;
|
|
21
|
+
readonly cause?: unknown;
|
|
22
|
+
constructor(sql: string, cause: unknown, message: string);
|
|
23
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const SCHEMA_SQL_V1 = "-- runtime/src/store/schema.sql\n-- AUTO-APPLIED by src/store/sqlite.ts as the v1 migration step.\n-- DO NOT edit this file by hand \u2014 this is v1's BYTE SOURCE (bundled\n-- into SCHEMA_SQL_V1 by bundle-schema.mjs). M1-05 appended a v2\n-- migration step inside sqlite.ts that re-creates the agents table\n-- with BLOB columns for encrypted api_key / claim_token. Current DB\n-- state after full migration: see sqlite.ts's \"Current schema (v2)\"\n-- header comment.\n--\n-- Tracked via `PRAGMA user_version`. This file defines user_version = 1;\n-- sqlite.ts's MIGRATIONS array brings it to 2.\n--\n-- OUT-OF-SCOPE for this file (DO NOT add here):\n-- * notifications \u2014 v1.1.1 durable event stream (M2 when broker lands)\n-- * match_history \u2014 M1-15 / M1-21\n-- * schedules \u2014 M1-15\n-- * encrypted column DDL \u2014 lives in sqlite.ts's v2 migration step,\n-- NOT here (mutating this file would break SCHEMA_SQL_V1's byte\n-- identity and thus the v1 migration contract).\n--\n-- When adding a new migration in a later TED, APPEND a new migration\n-- step to sqlite.ts's MIGRATIONS array; DO NOT mutate this file's v1\n-- block. Past installs will keep their v1 body and only run the delta.\n\nCREATE TABLE IF NOT EXISTS agents (\n id TEXT NOT NULL PRIMARY KEY, -- UUID v4 from server\n name TEXT NOT NULL UNIQUE, -- Public agent name\n api_key TEXT NOT NULL, -- v1 plaintext; v2 migration re-creates as BLOB\n claim_token TEXT NOT NULL, -- v1 plaintext; v2 migration re-creates as BLOB\n model TEXT NOT NULL DEFAULT '',\n created_at INTEGER NOT NULL, -- unix ms\n updated_at INTEGER NOT NULL -- unix ms\n);\n\nCREATE INDEX IF NOT EXISTS idx_agents_name ON agents(name);\n";
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import type { Database as DatabaseType } from "better-sqlite3";
|
|
2
|
+
export interface OpenDatabaseOptions {
|
|
3
|
+
/** Default: getDefaultDbPath(). Pass ":memory:" for tests. */
|
|
4
|
+
path?: string;
|
|
5
|
+
/** Skip ensureRuntimeHome(); tests with in-memory or mkdtemp DBs use this. */
|
|
6
|
+
skipEnsureHome?: boolean;
|
|
7
|
+
/** Override CURRENT_SCHEMA_VERSION. Tests use this to assert
|
|
8
|
+
* downgrade-detection. Production callers MUST omit. */
|
|
9
|
+
targetVersion?: number;
|
|
10
|
+
}
|
|
11
|
+
export interface AgentRow {
|
|
12
|
+
id: string;
|
|
13
|
+
name: string;
|
|
14
|
+
/** Encrypted BLOB; produced by account/credentials.ts#encryptForStorage. */
|
|
15
|
+
api_key: Buffer;
|
|
16
|
+
/** Encrypted BLOB; produced by account/credentials.ts#encryptForStorage. */
|
|
17
|
+
claim_token: Buffer;
|
|
18
|
+
model: string;
|
|
19
|
+
created_at: number;
|
|
20
|
+
updated_at: number;
|
|
21
|
+
}
|
|
22
|
+
export type UpsertAgentInput = Omit<AgentRow, "created_at" | "updated_at"> & {
|
|
23
|
+
created_at?: number;
|
|
24
|
+
updated_at?: number;
|
|
25
|
+
};
|
|
26
|
+
export interface StoreHandle {
|
|
27
|
+
readonly path: string;
|
|
28
|
+
readonly schemaVersion: number;
|
|
29
|
+
close(): void;
|
|
30
|
+
getAgentByName(name: string): AgentRow | undefined;
|
|
31
|
+
upsertAgent(row: UpsertAgentInput): AgentRow;
|
|
32
|
+
listAgents(): AgentRow[];
|
|
33
|
+
deleteAgent(name: string): boolean;
|
|
34
|
+
raw(): DatabaseType;
|
|
35
|
+
}
|
|
36
|
+
export declare function openDatabase(opts?: OpenDatabaseOptions): StoreHandle;
|