@whitesands/agent-player 1.0.0 → 1.1.0

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/CHANGELOG.md CHANGED
@@ -1,5 +1,11 @@
1
1
  # Changelog
2
2
 
3
+ ## 1.1.0
4
+
5
+ ### Minor Changes
6
+
7
+ - The SDK connects to `wss://api.whitesandsint.com`. The platform URL is no longer read from the environment.
8
+
3
9
  ## 1.0.0
4
10
 
5
11
  ### Major Changes
package/README.md CHANGED
@@ -1,9 +1,9 @@
1
1
  # WSI Agent Player
2
2
 
3
3
  [![npm version](https://img.shields.io/npm/v/@whitesands/agent-player.svg)](https://www.npmjs.com/package/@whitesands/agent-player)
4
- [![Build Status](https://github.com/White-Sands-Interactive/WSI-Node-Framework/actions/workflows/ci.yml/badge.svg)](https://github.com/White-Sands-Interactive/WSI-Node-Framework/actions/workflows/ci.yml)
4
+ [![Build Status](https://github.com/White-Sands-Interactive/WSI-Node/actions/workflows/ci.yml/badge.svg)](https://github.com/White-Sands-Interactive/WSI-Node/actions/workflows/ci.yml)
5
5
 
6
- The library starts a remote game agent from a player class. The game calls `start` and `turn`. The SDK publishes that class as tools. The model runs on the [platform](https://github.com/White-Sands-Interactive/Platform), so the game process never holds the model key.
6
+ The library starts a remote game agent from a player class. The game calls `start` and `turn`. The SDK publishes that class as tools. The model runs on the platform, so the game process never holds the model key.
7
7
 
8
8
  The library also provides:
9
9
 
@@ -44,10 +44,9 @@ Set the platform key, then start one agent per character. `turn()` grants that c
44
44
 
45
45
  ```sh
46
46
  export WSI_PLATFORM_KEY=pk_...
47
- export WSI_PLATFORM_URL=ws://127.0.0.1:8787
48
47
  ```
49
48
 
50
- `WSI_PLATFORM_URL` defaults to `ws://127.0.0.1:8787` when it is unset.
49
+ The SDK connects to `wss://api.whitesandsint.com`.
51
50
 
52
51
  ```ts
53
52
  import { AgentServer } from "@whitesands/agent-player";
@@ -62,7 +61,7 @@ const result = await ada.turn();
62
61
  // { action: "move", args: { dx: 1, dy: 0 }, result, attempts: 1, usage }
63
62
  ```
64
63
 
65
- `new AgentServer({ platformKey, platformUrl })` overrides the environment variables.
64
+ `new AgentServer({ platformKey })` overrides `WSI_PLATFORM_KEY`.
66
65
 
67
66
  ### The player class
68
67
 
@@ -283,7 +282,7 @@ const agents = new AgentServer({
283
282
 
284
283
  ### Protocol
285
284
 
286
- `@whitesands/agent-player/protocol` exports the wire types and `PROTOCOL_VERSION`. The platform's copy is `internal/protocol` in [White-Sands-Interactive/Platform](https://github.com/White-Sands-Interactive/Platform). A change to the wire format has to land in both places. Game code uses the main entry and does not import the protocol.
285
+ `@whitesands/agent-player/protocol` exports the wire types and `PROTOCOL_VERSION`. Game code uses the main entry and does not import the protocol.
287
286
 
288
287
  ## This repository
289
288
 
@@ -303,12 +302,10 @@ npm run courier
303
302
  npm run ferry
304
303
  ```
305
304
 
306
- Each example replays a script. Add `-- --remote` to use a platform that is already serving:
305
+ Each example replays a script. Forest and ferry can also call the hosted platform:
307
306
 
308
307
  ```sh
309
- ./platform create-key demo
310
- MODEL_API_KEY=... MODEL_BASE_URL=... MODEL_NAME=... ./platform serve
311
308
  PLATFORM_KEY=pk_... npm run forest -- --remote
312
309
  ```
313
310
 
314
- `./platform` is the Go server from the Platform repository. Releases are recorded in [CHANGELOG.md](CHANGELOG.md).
311
+ Releases are recorded in [CHANGELOG.md](CHANGELOG.md).
package/dist/index.cjs CHANGED
@@ -158,7 +158,7 @@ var import_ws = __toESM(require("ws"), 1);
158
158
 
159
159
  // src/protocol.ts
160
160
  var PROTOCOL_VERSION = 1;
161
- var SDK_VERSION = "1.0.0";
161
+ var SDK_VERSION = "1.1.0";
162
162
  var SESSION_RESUME_GRACE_MS = 3e4;
163
163
  var DEFAULT_AGENT_INSTRUCTIONS = [
164
164
  "You are a remote game agent. Tools are provided by the game.",
@@ -774,7 +774,7 @@ var TurnGate = class {
774
774
 
775
775
  // src/agent-server.ts
776
776
  var DEFAULT_TURN_TIMEOUT_MS = 6e4;
777
- var DEFAULT_PLATFORM_URL = "ws://127.0.0.1:8787";
777
+ var PLATFORM_URL = "wss://api.whitesandsint.com";
778
778
  var AgentServer = class {
779
779
  options;
780
780
  platformKey;
@@ -794,7 +794,7 @@ var AgentServer = class {
794
794
  }
795
795
  this.options = options;
796
796
  this.platformKey = platformKey || "inline";
797
- this.platformUrl = options.platformUrl ?? process.env.WSI_PLATFORM_URL ?? DEFAULT_PLATFORM_URL;
797
+ this.platformUrl = options.platformUrl ?? PLATFORM_URL;
798
798
  this.logger = options.logger;
799
799
  this.inline = options.inline;
800
800
  if (options.onEvent) this.listeners.add(options.onEvent);
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/agent-server.ts","../src/errors.ts","../src/logger.ts","../src/memory.ts","../src/platform-connection.ts","../src/protocol.ts","../src/ws-transport.ts","../src/reflect.ts","../src/session-mcp.ts","../src/turn-gate.ts"],"sourcesContent":["export { AgentServer } from \"./agent-server.js\";\nexport {\n ConnectionLostError,\n PlatformAuthError,\n ProtocolVersionError,\n TurnFailedError,\n TurnTimeoutError,\n} from \"./errors.js\";\nexport type { AgentMetadata, ActionSpec } from \"./reflect.js\";\nexport type { Logger } from \"./logger.js\";\nexport type {\n AgentEvent,\n AgentHandle,\n AgentServerOptions,\n EventListener,\n StartOptions,\n TurnOptions,\n TurnResult,\n} from \"./types.js\";\nexport type { AttemptRecord, TokenUsage } from \"./protocol.js\";\n","import { randomUUID } from \"node:crypto\";\nimport { InMemoryTransport } from \"@modelcontextprotocol/sdk/inMemory.js\";\nimport type { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport type { Transport } from \"@modelcontextprotocol/sdk/shared/transport.js\";\nimport { ConnectionLostError, TurnFailedError } from \"./errors.js\";\nimport type { Logger } from \"./logger.js\";\nimport { log } from \"./logger.js\";\nimport { defaultMemoryPath, SessionMemory } from \"./memory.js\";\nimport { PlatformConnection } from \"./platform-connection.js\";\nimport {\n DEFAULT_AGENT_INSTRUCTIONS,\n assertNever,\n type Envelope,\n type TurnReport,\n} from \"./protocol.js\";\nimport { reflectPlayer } from \"./reflect.js\";\nimport { createSessionMcpServer } from \"./session-mcp.js\";\nimport { TurnGate } from \"./turn-gate.js\";\nimport type {\n AgentEvent,\n AgentHandle,\n AgentServerOptions,\n EventListener,\n InlinePlatform,\n StartOptions,\n TurnOptions,\n TurnResult,\n} from \"./types.js\";\nimport { SessionMuxTransport } from \"./ws-transport.js\";\n\nconst DEFAULT_TURN_TIMEOUT_MS = 60_000;\nconst DEFAULT_PLATFORM_URL = \"ws://127.0.0.1:8787\";\n\ntype SessionRecord = {\n id: string;\n token: string;\n name: string;\n gate: TurnGate;\n server: McpServer;\n transport: Transport;\n mux?: SessionMuxTransport;\n listeners: Set<EventListener>;\n};\n\n/**\n * One in-process MCP server and one outbound connection to the platform.\n * Every `start()` is its own session and token. The game calls `turn()` to\n * decide whose turn it is; the platform chooses the action.\n */\nexport class AgentServer {\n private readonly options: AgentServerOptions;\n private readonly platformKey: string;\n private readonly platformUrl: string;\n private readonly logger: Logger | undefined;\n private connection: PlatformConnection | null = null;\n private readonly sessions = new Map<string, SessionRecord>();\n private readonly listeners = new Set<EventListener>();\n private readonly inline: InlinePlatform | undefined;\n private memory: SessionMemory | null = null;\n private started = false;\n private closing = false;\n\n constructor(options: AgentServerOptions = {}) {\n const platformKey = options.platformKey ?? process.env.WSI_PLATFORM_KEY;\n if (!options.inline && !platformKey) {\n throw new Error(\"Set WSI_PLATFORM_KEY or pass platformKey, unless an inline platform is provided\");\n }\n this.options = options;\n this.platformKey = platformKey || \"inline\";\n this.platformUrl = options.platformUrl ?? process.env.WSI_PLATFORM_URL ?? DEFAULT_PLATFORM_URL;\n this.logger = options.logger;\n this.inline = options.inline;\n if (options.onEvent) this.listeners.add(options.onEvent);\n }\n\n /** Ensure the outbound platform connection. No-op for an inline platform. */\n async connect(): Promise<void> {\n if (this.inline || this.started) {\n this.started = true;\n return;\n }\n this.connection = new PlatformConnection(this.platformUrl, this.platformKey, {\n onEnvelope: (envelope) => this.handleEnvelope(envelope),\n onDisconnect: () => this.emit({ type: \"disconnected\" }),\n onReconnect: () => this.emit({ type: \"reconnected\" }),\n onError: (error) => {\n log(this.logger, \"error\", error.message);\n if (error instanceof ConnectionLostError) this.failInflight(error);\n },\n sessions: () => [...this.sessions.values()].map((session) => ({\n sessionId: session.id,\n sessionToken: session.token,\n })),\n }, this.logger);\n await this.connection.connect();\n this.started = true;\n }\n\n /**\n * Reflect the player into tools, register a session, and return a handle.\n * `turn()` on that handle lets the remote model act once.\n */\n async start(instance: object, options?: StartOptions): Promise<AgentHandle> {\n await this.connect();\n\n const reflected = reflectPlayer(instance);\n const sessionId = randomUUID();\n const sessionToken = randomUUID();\n const gate = new TurnGate();\n const name = options?.name ?? instance.constructor?.name ?? \"player\";\n const memory = this.actionMemory();\n const server = createSessionMcpServer(reflected, gate, {\n name: `agent-player:${name}`,\n ...(memory\n ? {\n actions: {\n record: (entry) => memory.record(sessionId, name, entry),\n done: () => memory.done(sessionId),\n },\n }\n : {}),\n });\n const instructions = [this.options.instructions ?? DEFAULT_AGENT_INSTRUCTIONS, options?.instructions]\n .filter((part): part is string => Boolean(part && part.length > 0))\n .join(\"\\n\\n\");\n\n const listeners = new Set<EventListener>();\n const record: SessionRecord = {\n id: sessionId,\n token: sessionToken,\n name,\n gate,\n server,\n transport: undefined as unknown as Transport,\n listeners,\n };\n\n const onTurnResult = (result: TurnReport) => {\n gate.completeTurn(result);\n };\n const onEvent = (event: AgentEvent) => this.emit(event);\n\n if (this.inline) {\n const [serverTransport, clientTransport] = InMemoryTransport.createLinkedPair();\n await server.connect(serverTransport);\n record.transport = serverTransport;\n this.sessions.set(sessionId, record);\n await this.inline.startSession({\n sessionId,\n sessionToken,\n name,\n tools: reflected.tools,\n instructions,\n ...(options?.goal ? { goal: options.goal } : {}),\n ...(this.logger ? { logger: this.logger } : {}),\n transport: clientTransport,\n onTurnResult,\n onEvent,\n });\n } else {\n if (!this.connection) throw new Error(\"Not connected\");\n const mux = this.connection.createTransport(sessionId);\n await server.connect(mux);\n record.transport = mux;\n record.mux = mux;\n this.sessions.set(sessionId, record);\n const started = this.connection.waitForSessionEvent(sessionId, \"start\");\n this.connection.send({\n type: \"start_session\",\n sessionId,\n sessionToken,\n name,\n tools: reflected.tools,\n instructions,\n ...(options?.goal ? { goal: options.goal } : {}),\n });\n await started;\n }\n\n return {\n sessionId,\n turn: (turnOptions?: TurnOptions) => this.turn(sessionId, turnOptions),\n stop: () => this.stopSession(sessionId),\n on: (listener: EventListener) => {\n listeners.add(listener);\n return () => listeners.delete(listener);\n },\n };\n }\n\n /** Subscribe to every session plus connection events. Returns unsubscribe. */\n on(listener: EventListener): () => void {\n this.listeners.add(listener);\n return () => this.listeners.delete(listener);\n }\n\n private async turn(sessionId: string, options?: TurnOptions): Promise<TurnResult> {\n const session = this.sessions.get(sessionId);\n if (!session) throw new Error(`Unknown session ${sessionId}`);\n const timeoutMs = options?.timeoutMs ?? this.options.turnTimeoutMs ?? DEFAULT_TURN_TIMEOUT_MS;\n let outcome: TurnReport;\n try {\n outcome = await session.gate.runTurn({\n timeoutMs,\n ...(options?.signal ? { signal: options.signal } : {}),\n });\n } catch (error) {\n if (error instanceof ConnectionLostError) throw error;\n throw error;\n }\n if (!outcome.ok) {\n if (outcome.connectionLost) {\n throw new ConnectionLostError(outcome.error ?? \"Connection to the platform was lost\");\n }\n throw new TurnFailedError(outcome.error ?? \"turn failed\", outcome.attemptDetails ?? []);\n }\n return {\n action: outcome.action ?? \"unknown\",\n args: outcome.args ?? {},\n result: outcome.result,\n attempts: outcome.attempts ?? 1,\n usage: outcome.usage ?? { promptTokens: 0, completionTokens: 0 },\n };\n }\n\n private emit(event: AgentEvent): void {\n for (const listener of this.listeners) listener(event);\n if (event.type === \"disconnected\" || event.type === \"reconnected\") return;\n const session = this.sessions.get(event.sessionId);\n if (!session) return;\n for (const listener of session.listeners) listener(event);\n }\n\n private failInflight(error: ConnectionLostError): void {\n for (const session of this.sessions.values()) {\n session.gate.failTurn(error);\n }\n }\n\n private handleEnvelope(envelope: Envelope): void {\n switch (envelope.type) {\n case \"mcp\": {\n const session = this.sessions.get(envelope.sessionId);\n session?.mux?.receive(envelope.message);\n return;\n }\n case \"turn_result\": {\n const session = this.sessions.get(envelope.sessionId);\n session?.gate.completeTurn(envelope);\n return;\n }\n case \"session_event\": {\n if (envelope.event === \"action\") {\n this.emit({\n type: \"action\",\n sessionId: envelope.sessionId,\n action: envelope.action ?? \"unknown\",\n args: envelope.args ?? {},\n });\n return;\n }\n if (envelope.event === \"retry\") {\n this.emit({\n type: \"retry\",\n sessionId: envelope.sessionId,\n action: envelope.action ?? \"unknown\",\n args: envelope.args ?? {},\n error: envelope.error ?? \"action failed\",\n });\n return;\n }\n this.emit({\n type: \"turnFailed\",\n sessionId: envelope.sessionId,\n error: envelope.error ?? \"turn failed\",\n ...(envelope.action ? { action: envelope.action } : {}),\n ...(envelope.args ? { args: envelope.args } : {}),\n });\n return;\n }\n case \"error\":\n log(this.logger, \"error\", envelope.message);\n return;\n case \"session_started\":\n case \"session_stopped\":\n case \"session_resumed\":\n case \"resume_err\":\n case \"hello_ok\":\n case \"hello_err\":\n case \"hello\":\n case \"start_session\":\n case \"stop_session\":\n case \"ping\":\n case \"pong\":\n case \"resume_session\":\n return;\n default: {\n assertNever(envelope);\n }\n }\n }\n\n private async stopSession(sessionId: string): Promise<void> {\n const session = this.sessions.get(sessionId);\n if (!session) return;\n this.sessions.delete(sessionId);\n session.gate.reset();\n\n if (this.inline) {\n await this.inline.stopSession(sessionId);\n } else if (this.connection) {\n const stopped = this.connection.waitForSessionEvent(sessionId, \"stop\").catch(() => null);\n try {\n this.connection.send({ type: \"stop_session\", sessionId });\n } catch {\n // connection may already be down\n }\n await stopped;\n }\n\n try {\n await session.server.close();\n } catch {\n // ignore\n }\n }\n\n /** Stop every session and close the platform connection. */\n async close(): Promise<void> {\n if (this.closing) return;\n this.closing = true;\n const ids = [...this.sessions.keys()];\n for (const id of ids) {\n await this.stopSession(id);\n }\n if (this.inline?.close) await this.inline.close();\n if (this.connection) {\n await this.connection.close();\n this.connection = null;\n }\n this.memory?.close();\n this.memory = null;\n this.started = false;\n this.closing = false;\n }\n\n private actionMemory(): SessionMemory | null {\n if (this.options.memoryPath === false) return null;\n if (!this.memory) {\n const path = this.options.memoryPath ?? defaultMemoryPath();\n this.memory = new SessionMemory(path);\n }\n return this.memory;\n }\n\n async [Symbol.asyncDispose](): Promise<void> {\n await this.close();\n }\n}\n","import type { AttemptRecord } from \"./protocol.js\";\n\nexport class PlatformAuthError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"PlatformAuthError\";\n }\n}\n\nexport class ProtocolVersionError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"ProtocolVersionError\";\n }\n}\n\nexport class TurnFailedError extends Error {\n readonly attempts: AttemptRecord[];\n\n constructor(message: string, attempts: AttemptRecord[] = []) {\n super(message);\n this.name = \"TurnFailedError\";\n this.attempts = attempts;\n }\n}\n\nexport class TurnTimeoutError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"TurnTimeoutError\";\n }\n}\n\nexport class ConnectionLostError extends Error {\n constructor(message = \"Connection to the platform was lost\") {\n super(message);\n this.name = \"ConnectionLostError\";\n }\n}\n","export type Logger = {\n debug?: (message: string, extra?: unknown) => void;\n info?: (message: string, extra?: unknown) => void;\n warn?: (message: string, extra?: unknown) => void;\n error?: (message: string, extra?: unknown) => void;\n};\n\nexport function log(logger: Logger | undefined, level: keyof Logger, message: string, extra?: unknown): void {\n logger?.[level]?.(message, extra);\n}\n","import { mkdirSync } from \"node:fs\";\nimport { dirname, resolve } from \"node:path\";\nimport Database from \"better-sqlite3\";\n\n/** Actions kept on the view. Older rows stay in the file and drop off the prompt. */\nconst MAX_DONE = 50;\n\nexport type DoneAction = {\n action: string;\n args: Record<string, unknown>;\n ok: boolean;\n error?: string;\n};\n\ntype ActionRow = {\n action: string;\n args: string;\n ok: number;\n error: string | null;\n};\n\n/**\n * SQLite log of actions one game process has already called.\n * Each session reads only its own rows, so a new run starts with an empty list.\n */\nexport class SessionMemory {\n private readonly db: Database.Database;\n\n constructor(path: string) {\n mkdirSync(dirname(path), { recursive: true });\n this.db = new Database(path, { timeout: 5000 });\n this.db.exec(`\n CREATE TABLE IF NOT EXISTS actions (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n session_id TEXT NOT NULL,\n character TEXT NOT NULL,\n action TEXT NOT NULL,\n args TEXT NOT NULL,\n ok INTEGER NOT NULL,\n error TEXT\n );\n CREATE INDEX IF NOT EXISTS actions_by_session ON actions(session_id, id);\n `);\n }\n\n record(sessionId: string, character: string, entry: DoneAction): void {\n this.db\n .prepare(\n `INSERT INTO actions (session_id, character, action, args, ok, error)\n VALUES (@sessionId, @character, @action, @args, @ok, @error)`,\n )\n .run({\n sessionId,\n character,\n action: entry.action,\n args: JSON.stringify(entry.args),\n ok: entry.ok ? 1 : 0,\n error: entry.error ?? null,\n });\n }\n\n /** Oldest first, capped to the most recent actions for this session. */\n done(sessionId: string): DoneAction[] {\n const rows = this.db\n .prepare(\n `SELECT action, args, ok, error FROM (\n SELECT id, action, args, ok, error FROM actions\n WHERE session_id = ?\n ORDER BY id DESC\n LIMIT ?\n ) ORDER BY id ASC`,\n )\n .all(sessionId, MAX_DONE) as ActionRow[];\n return rows.map((row) => {\n const entry: DoneAction = {\n action: row.action,\n args: JSON.parse(row.args) as Record<string, unknown>,\n ok: row.ok === 1,\n };\n if (row.error) entry.error = row.error;\n return entry;\n });\n }\n\n close(): void {\n this.db.close();\n }\n}\n\nexport function defaultMemoryPath(): string {\n return resolve(process.cwd(), \".wsi\", \"agent-memory.sqlite\");\n}\n\n/** Attach this session's action log to a see() payload. */\nexport function viewWithDone(view: unknown, done: DoneAction[]): unknown {\n if (view && typeof view === \"object\" && !Array.isArray(view)) {\n return { ...(view as Record<string, unknown>), done };\n }\n return { view, done };\n}\n","import { randomUUID } from \"node:crypto\";\nimport WebSocket from \"ws\";\nimport { ConnectionLostError, PlatformAuthError, ProtocolVersionError } from \"./errors.js\";\nimport type { Logger } from \"./logger.js\";\nimport { log } from \"./logger.js\";\nimport {\n PROTOCOL_VERSION,\n SDK_VERSION,\n SESSION_RESUME_GRACE_MS,\n type Envelope,\n} from \"./protocol.js\";\nimport { SessionMuxTransport } from \"./ws-transport.js\";\n\nexport type ResumableSession = {\n sessionId: string;\n sessionToken: string;\n};\n\nexport type PlatformConnectionHandlers = {\n onEnvelope: (envelope: Envelope) => void;\n onDisconnect?: () => void;\n onReconnect?: () => void;\n onError?: (error: Error) => void;\n sessions?: () => ResumableSession[];\n};\n\nconst HEARTBEAT_MS = 15_000;\nconst PONG_TIMEOUT_MS = 10_000;\nconst MAX_RECONNECT_ATTEMPTS = 8;\n\n/**\n * Outbound WebSocket to the platform. The game never listens on a public URL.\n * After the first successful hello, a dropped socket reconnects and resumes sessions.\n */\nexport class PlatformConnection {\n private ws: WebSocket | null = null;\n private readonly url: string;\n private readonly platformKey: string;\n readonly clientId = randomUUID();\n private readonly handlers: PlatformConnectionHandlers;\n private readonly logger: Logger | undefined;\n private readonly pending = new Map<\n string,\n { resolve: (envelope: Envelope) => void; reject: (error: Error) => void }\n >();\n private readonly outbox: Envelope[] = [];\n private accountName: string | null = null;\n private closed = false;\n private everConnected = false;\n private reconnecting = false;\n private reconnectAttempt = 0;\n private reconnectTimer: ReturnType<typeof setTimeout> | undefined;\n private heartbeat: ReturnType<typeof setInterval> | undefined;\n private pongTimer: ReturnType<typeof setTimeout> | undefined;\n private pendingPong: string | null = null;\n\n constructor(\n url: string,\n platformKey: string,\n handlers: PlatformConnectionHandlers,\n logger?: Logger,\n ) {\n this.url = url;\n this.platformKey = platformKey;\n this.handlers = handlers;\n this.logger = logger;\n }\n\n get connected(): boolean {\n return this.ws?.readyState === WebSocket.OPEN;\n }\n\n async connect(): Promise<string> {\n if (this.closed) throw new Error(\"Platform connection is closed\");\n if (this.connected && this.accountName) return this.accountName;\n const account = await this.openSocket();\n this.everConnected = true;\n this.reconnectAttempt = 0;\n return account;\n }\n\n send(envelope: Envelope): void {\n if (this.connected && this.ws) {\n this.ws.send(JSON.stringify(envelope));\n return;\n }\n if (envelope.type === \"mcp\" || envelope.type === \"ping\") {\n this.outbox.push(envelope);\n return;\n }\n throw new Error(\"Not connected to platform\");\n }\n\n waitForSessionEvent(\n sessionId: string,\n kind: \"start\" | \"stop\" | \"resume\",\n timeoutMs = 15_000,\n ): Promise<Envelope> {\n const key = `session:${sessionId}:${kind}`;\n return new Promise((resolve, reject) => {\n const timer = setTimeout(() => {\n this.pending.delete(key);\n reject(new Error(`Timed out waiting for session ${kind}`));\n }, timeoutMs);\n this.pending.set(key, {\n resolve: (envelope) => {\n clearTimeout(timer);\n resolve(envelope);\n },\n reject: (error) => {\n clearTimeout(timer);\n reject(error);\n },\n });\n });\n }\n\n createTransport(sessionId: string): SessionMuxTransport {\n return new SessionMuxTransport(sessionId, (envelope) => this.send(envelope));\n }\n\n async close(): Promise<void> {\n this.closed = true;\n this.stopHeartbeat();\n if (this.reconnectTimer) clearTimeout(this.reconnectTimer);\n this.reconnectTimer = undefined;\n this.reconnecting = false;\n this.failWaiters(new Error(\"platform connection closed\"));\n if (!this.ws) return;\n const ws = this.ws;\n this.ws = null;\n await new Promise<void>((resolve) => {\n ws.once(\"close\", () => resolve());\n ws.close();\n });\n }\n\n private openSocket(): Promise<string> {\n return new Promise((resolve, reject) => {\n const ws = new WebSocket(this.url);\n this.ws = ws;\n let settled = false;\n\n const fail = (error: Error) => {\n if (settled) return;\n settled = true;\n reject(error);\n };\n\n ws.on(\"open\", () => {\n ws.send(JSON.stringify({\n type: \"hello\",\n platformKey: this.platformKey,\n clientId: this.clientId,\n protocolVersion: PROTOCOL_VERSION,\n sdkVersion: SDK_VERSION,\n } satisfies Envelope));\n });\n\n ws.on(\"message\", (data) => {\n let envelope: Envelope;\n try {\n envelope = JSON.parse(data.toString()) as Envelope;\n } catch (error) {\n const parsed = error instanceof Error ? error : new Error(\"Invalid platform message\");\n this.handlers.onError?.(parsed);\n return;\n }\n\n if (!settled && (envelope.type === \"hello_ok\" || envelope.type === \"hello_err\")) {\n settled = true;\n if (envelope.type === \"hello_err\") {\n const error = envelope.code === \"PROTOCOL\"\n ? new ProtocolVersionError(envelope.message)\n : new PlatformAuthError(envelope.message);\n this.closed = true;\n reject(error);\n ws.close();\n return;\n }\n this.accountName = envelope.accountName;\n this.startHeartbeat();\n this.flushOutbox();\n resolve(envelope.accountName);\n return;\n }\n\n if (envelope.type === \"pong\") {\n if (this.pendingPong === envelope.id) {\n this.pendingPong = null;\n if (this.pongTimer) clearTimeout(this.pongTimer);\n this.pongTimer = undefined;\n }\n return;\n }\n\n this.resolveSessionWaiter(envelope);\n this.handlers.onEnvelope(envelope);\n });\n\n ws.on(\"error\", (error) => {\n this.handlers.onError?.(error);\n fail(error);\n });\n\n ws.on(\"close\", () => {\n this.stopHeartbeat();\n if (this.ws === ws) this.ws = null;\n if (!settled) fail(new Error(\"platform connection closed before hello\"));\n if (this.closed || !this.everConnected) {\n this.failWaiters(new Error(\"platform connection closed\"));\n return;\n }\n this.handlers.onDisconnect?.();\n this.scheduleReconnect();\n });\n });\n }\n\n private resolveSessionWaiter(envelope: Envelope): void {\n if (envelope.type === \"session_started\" || envelope.type === \"session_stopped\") {\n const kind = envelope.type === \"session_started\" ? \"start\" : \"stop\";\n const waiter = this.pending.get(`session:${envelope.sessionId}:${kind}`);\n if (!waiter) return;\n this.pending.delete(`session:${envelope.sessionId}:${kind}`);\n waiter.resolve(envelope);\n return;\n }\n if (envelope.type === \"session_resumed\" || envelope.type === \"resume_err\") {\n const waiter = this.pending.get(`session:${envelope.sessionId}:resume`);\n if (!waiter) return;\n this.pending.delete(`session:${envelope.sessionId}:resume`);\n if (envelope.type === \"resume_err\") {\n waiter.reject(new ConnectionLostError(envelope.message));\n return;\n }\n waiter.resolve(envelope);\n }\n }\n\n private scheduleReconnect(): void {\n if (this.closed || this.reconnecting) return;\n if (this.reconnectAttempt >= MAX_RECONNECT_ATTEMPTS) {\n this.closed = true;\n const error = new ConnectionLostError(\"Could not reconnect to the platform\");\n this.handlers.onError?.(error);\n this.failWaiters(error);\n return;\n }\n const delay = Math.min(SESSION_RESUME_GRACE_MS, 250 * 2 ** this.reconnectAttempt);\n this.reconnectAttempt += 1;\n this.reconnecting = true;\n log(this.logger, \"warn\", `platform connection dropped; retrying in ${delay}ms`);\n this.reconnectTimer = setTimeout(() => {\n this.reconnectTimer = undefined;\n void this.reconnect();\n }, delay);\n this.reconnectTimer.unref?.();\n }\n\n private async reconnect(): Promise<void> {\n try {\n await this.openSocket();\n this.everConnected = true;\n this.reconnectAttempt = 0;\n this.reconnecting = false;\n const sessions = this.handlers.sessions?.() ?? [];\n for (const session of sessions) {\n const resumed = this.waitForSessionEvent(session.sessionId, \"resume\");\n this.send({\n type: \"resume_session\",\n sessionId: session.sessionId,\n sessionToken: session.sessionToken,\n });\n await resumed;\n }\n this.handlers.onReconnect?.();\n } catch (error) {\n this.reconnecting = false;\n if (this.closed) return;\n const wrapped = error instanceof Error ? error : new Error(String(error));\n if (wrapped instanceof PlatformAuthError || wrapped instanceof ProtocolVersionError) {\n this.closed = true;\n this.handlers.onError?.(wrapped);\n this.failWaiters(wrapped);\n return;\n }\n this.scheduleReconnect();\n }\n }\n\n private flushOutbox(): void {\n if (!this.ws || !this.connected) return;\n const pending = this.outbox.splice(0, this.outbox.length);\n for (const envelope of pending) {\n this.ws.send(JSON.stringify(envelope));\n }\n }\n\n private startHeartbeat(): void {\n this.stopHeartbeat();\n this.heartbeat = setInterval(() => {\n if (!this.connected) return;\n const id = randomUUID();\n this.pendingPong = id;\n try {\n this.send({ type: \"ping\", id });\n } catch {\n return;\n }\n this.pongTimer = setTimeout(() => {\n if (this.pendingPong === id) {\n log(this.logger, \"warn\", \"platform heartbeat timed out\");\n this.ws?.terminate();\n }\n }, PONG_TIMEOUT_MS);\n this.pongTimer.unref?.();\n }, HEARTBEAT_MS);\n this.heartbeat.unref?.();\n }\n\n private stopHeartbeat(): void {\n if (this.heartbeat) clearInterval(this.heartbeat);\n if (this.pongTimer) clearTimeout(this.pongTimer);\n this.heartbeat = undefined;\n this.pongTimer = undefined;\n this.pendingPong = null;\n }\n\n private failWaiters(error: Error): void {\n for (const [, waiter] of this.pending) waiter.reject(error);\n this.pending.clear();\n }\n}\n","/**\n * Wire protocol between AgentServer (SDK) and the platform. Version 1.\n * The platform's Go copy lives in White-Sands-Interactive/Platform, internal/protocol.\n */\n\nexport const PROTOCOL_VERSION = 1;\nexport const SDK_VERSION = \"1.0.0\";\n\n/** How long a disconnected session can be resumed. Shared by both sides. */\nexport const SESSION_RESUME_GRACE_MS = 30_000;\n\nexport type JsonSchema = {\n type?: string | string[];\n properties?: Record<string, JsonSchema>;\n required?: string[];\n description?: string;\n additionalProperties?: boolean;\n [key: string]: unknown;\n};\n\nexport type ToolDescriptor = {\n name: string;\n description: string;\n inputSchema: JsonSchema;\n};\n\nexport type TokenUsage = {\n promptTokens: number;\n completionTokens: number;\n};\n\nexport type AttemptRecord = {\n action: string;\n args: Record<string, unknown>;\n error: string;\n};\n\nexport type TurnReport = {\n ok: boolean;\n error?: string;\n action?: string;\n args?: Record<string, unknown>;\n result?: unknown;\n attempts?: number;\n attemptDetails?: AttemptRecord[];\n usage?: TokenUsage;\n connectionLost?: boolean;\n};\n\nexport type SessionEventName = \"action\" | \"retry\" | \"turnFailed\";\n\nexport type Envelope =\n | {\n type: \"hello\";\n platformKey: string;\n clientId: string;\n protocolVersion: number;\n sdkVersion: string;\n }\n | {\n type: \"hello_ok\";\n accountName: string;\n protocolVersion: number;\n }\n | {\n type: \"hello_err\";\n message: string;\n code?: \"AUTH\" | \"PROTOCOL\";\n }\n | {\n type: \"start_session\";\n sessionId: string;\n sessionToken: string;\n tools: ToolDescriptor[];\n instructions: string;\n goal?: string;\n name?: string;\n }\n | {\n type: \"session_started\";\n sessionId: string;\n }\n | {\n type: \"stop_session\";\n sessionId: string;\n }\n | {\n type: \"session_stopped\";\n sessionId: string;\n }\n | {\n type: \"mcp\";\n sessionId: string;\n message: unknown;\n }\n | ({\n type: \"turn_result\";\n sessionId: string;\n } & TurnReport)\n | {\n type: \"session_event\";\n sessionId: string;\n event: SessionEventName;\n action?: string;\n args?: Record<string, unknown>;\n error?: string;\n }\n | {\n type: \"ping\";\n id: string;\n }\n | {\n type: \"pong\";\n id: string;\n }\n | {\n type: \"resume_session\";\n sessionId: string;\n sessionToken: string;\n }\n | {\n type: \"session_resumed\";\n sessionId: string;\n }\n | {\n type: \"resume_err\";\n sessionId: string;\n message: string;\n }\n | {\n type: \"error\";\n message: string;\n sessionId?: string;\n };\n\nexport const DEFAULT_AGENT_INSTRUCTIONS = [\n \"You are a remote game agent. Tools are provided by the game.\",\n \"On every turn: call wait first. It blocks until the game grants your turn and then returns the current view from see.\",\n \"After wait returns, call exactly one action tool (not see, not wait).\",\n \"The view's done list is what this character has already called in this session, oldest first. Use it when choosing the next action.\",\n \"If an action tool returns an error, retry once with a corrected action. A second failure ends the turn as failed.\",\n].join(\"\\n\");\n\nexport function assertNever(value: never): never {\n throw new Error(`Unhandled protocol message: ${JSON.stringify(value)}`);\n}\n","import type { Transport } from \"@modelcontextprotocol/sdk/shared/transport.js\";\nimport type { JSONRPCMessage } from \"@modelcontextprotocol/sdk/types.js\";\nimport type { Envelope } from \"./protocol.js\";\n\nexport type EnvelopeSender = (envelope: Envelope) => void;\n\n/**\n * MCP Transport that multiplexes JSON-RPC over a shared envelope channel,\n * keyed by sessionId.\n */\nexport class SessionMuxTransport implements Transport {\n onclose?: () => void;\n onerror?: (error: Error) => void;\n onmessage?: (message: JSONRPCMessage) => void;\n sessionId?: string;\n\n private readonly sid: string;\n private readonly sendEnvelope: EnvelopeSender;\n private started = false;\n private closed = false;\n\n constructor(sessionId: string, sendEnvelope: EnvelopeSender) {\n this.sid = sessionId;\n this.sessionId = sessionId;\n this.sendEnvelope = sendEnvelope;\n }\n\n async start(): Promise<void> {\n if (this.closed) throw new Error(\"Transport already closed\");\n this.started = true;\n }\n\n async close(): Promise<void> {\n if (this.closed) return;\n this.closed = true;\n this.onclose?.();\n }\n\n async send(message: JSONRPCMessage): Promise<void> {\n if (this.closed) throw new Error(\"Transport closed\");\n this.sendEnvelope({ type: \"mcp\", sessionId: this.sid, message });\n }\n\n /** Deliver an inbound MCP message from the platform. */\n receive(message: unknown): void {\n if (this.closed || !this.started) return;\n try {\n this.onmessage?.(message as JSONRPCMessage);\n } catch (error) {\n this.onerror?.(error instanceof Error ? error : new Error(String(error)));\n }\n }\n}\n","import { z, type ZodRawShape, type ZodTypeAny } from \"zod\";\nimport { zodToJsonSchema } from \"zod-to-json-schema\";\nimport type { JsonSchema, ToolDescriptor } from \"./protocol.js\";\n\nexport type ActionSpec = {\n description: string;\n args?: ZodRawShape;\n};\n\nexport type AgentMetadata = {\n description?: string;\n actions?: Record<string, ActionSpec>;\n};\n\nexport type PlayerTool = {\n name: string;\n description: string;\n paramNames: string[];\n argsSchema?: z.ZodObject<ZodRawShape>;\n descriptor: ToolDescriptor;\n invoke: (args: Record<string, unknown>) => Promise<unknown>;\n};\n\nexport type ReflectedPlayer = {\n /** Class-level description, when the player declared `static agent`. */\n description?: string;\n see: PlayerTool;\n actions: PlayerTool[];\n tools: ToolDescriptor[];\n};\n\nconst SKIP = new Set([\"constructor\"]);\n\nexport const SEE_DESCRIPTION = \"Read the current game view for this player. Prefer wait, which returns this after the game grants a turn.\";\nexport const WAIT_DESCRIPTION = \"Block until the game calls turn() for this session, then return the current see() view.\";\n\n/** Parse parameter names from a function's source. Used only when no arg schema is declared. */\nexport function getParamNames(fn: (...args: never[]) => unknown): string[] {\n const src = fn.toString().replace(/\\/\\*[\\s\\S]*?\\*\\//g, \"\").replace(/\\/\\/.*$/gm, \"\");\n const header =\n src.match(/(?:async\\s+)?(?:function\\s*)?(?:\\w*)\\s*\\(([^)]*)\\)/) ??\n src.match(/^(?:async\\s*)?\\(?([^)=]*)\\)?\\s*=>/);\n if (!header) return [];\n const raw = header[1]?.trim() ?? \"\";\n if (!raw) return [];\n return raw\n .split(\",\")\n .map((part) => part.trim())\n .filter(Boolean)\n .map((part) => {\n const cleaned = part.replace(/\\s*=\\s*[^,]+$/, \"\").trim();\n const name = cleaned.split(/[:\\s]/)[0]?.replace(/^\\.\\.\\./, \"\") ?? \"\";\n return name;\n })\n .filter((name) => name.length > 0 && name !== \"this\");\n}\n\nfunction collectMethodNames(instance: object): string[] {\n const names = new Set<string>();\n let proto: object | null = Object.getPrototypeOf(instance);\n while (proto && proto !== Object.prototype) {\n for (const name of Object.getOwnPropertyNames(proto)) {\n if (SKIP.has(name) || name.startsWith(\"_\")) continue;\n const desc = Object.getOwnPropertyDescriptor(proto, name);\n if (!desc || typeof desc.value !== \"function\") continue;\n names.add(name);\n }\n proto = Object.getPrototypeOf(proto);\n }\n return [...names].sort();\n}\n\nfunction readMetadata(instance: object): AgentMetadata | undefined {\n const ctor = instance.constructor as { agent?: AgentMetadata };\n return ctor.agent;\n}\n\nfunction toJsonSchema(schema: ZodTypeAny): JsonSchema {\n const json = zodToJsonSchema(schema, { target: \"jsonSchema7\", $refStrategy: \"none\" }) as JsonSchema;\n delete json.$schema;\n return json;\n}\n\nfunction formatZodError(error: z.ZodError): string {\n return error.issues\n .map((issue) => {\n const path = issue.path.length > 0 ? issue.path.join(\".\") : \"arguments\";\n return `${path}: ${issue.message}`;\n })\n .join(\"; \");\n}\n\nfunction buildTool(\n instance: object,\n name: string,\n description: string,\n spec?: ActionSpec,\n): PlayerTool {\n const fn = (instance as Record<string, unknown>)[name];\n if (typeof fn !== \"function\") {\n throw new Error(`Expected method ${name}`);\n }\n const paramNames = spec?.args ? Object.keys(spec.args) : getParamNames(fn as (...args: never[]) => unknown);\n const shape: ZodRawShape = spec?.args ?? Object.fromEntries(paramNames.map((param) => [param, z.any()]));\n const argsSchema = paramNames.length > 0 || spec?.args ? z.object(shape) : undefined;\n const inputSchema: JsonSchema = spec?.args && argsSchema\n ? toJsonSchema(argsSchema)\n : {\n type: \"object\",\n properties: Object.fromEntries(paramNames.map((param) => [param, {}])),\n ...(paramNames.length > 0 ? { required: paramNames } : {}),\n };\n\n return {\n name,\n description,\n paramNames,\n ...(argsSchema ? { argsSchema } : {}),\n descriptor: { name, description, inputSchema },\n async invoke(args: Record<string, unknown>) {\n let parsed: Record<string, unknown> = args ?? {};\n if (argsSchema) {\n const result = argsSchema.safeParse(args ?? {});\n if (!result.success) {\n throw new Error(formatZodError(result.error));\n }\n parsed = result.data as Record<string, unknown>;\n }\n const ordered = paramNames.map((param) => parsed[param]);\n return await Promise.resolve((fn as (...params: unknown[]) => unknown).apply(instance, ordered));\n },\n };\n}\n\n/**\n * Publish tools from a player instance.\n * - `see` is the state tool (required).\n * - Every other public method is an action tool.\n * - Names starting with `_` and the constructor are skipped.\n * - `static agent` supplies descriptions and zod argument schemas. Undeclared methods stay tools,\n * with unconstrained JSON arguments (no type guessed from the parameter name).\n */\nexport function reflectPlayer(instance: object): ReflectedPlayer {\n const names = collectMethodNames(instance);\n if (!names.includes(\"see\")) {\n throw new Error(\"Player must implement a public see() method\");\n }\n\n const metadata = readMetadata(instance);\n const declared = metadata?.actions ?? {};\n const className = instance.constructor?.name || \"Player\";\n for (const name of Object.keys(declared)) {\n if (!names.includes(name) || name === \"see\") {\n throw new Error(`Declared action \"${name}\" is not a public method on ${className}`);\n }\n }\n\n const see = buildTool(instance, \"see\", SEE_DESCRIPTION);\n const actionNames = names.filter((name) => name !== \"see\");\n const actions = actionNames.map((name) => {\n const spec = declared[name];\n const description = spec?.description ?? `Action: ${name}`;\n return buildTool(instance, name, description, spec);\n });\n\n const wait: ToolDescriptor = {\n name: \"wait\",\n description: WAIT_DESCRIPTION,\n inputSchema: { type: \"object\", properties: {} },\n };\n\n return {\n ...(metadata?.description ? { description: metadata.description } : {}),\n see,\n actions,\n tools: [see.descriptor, ...actions.map((action) => action.descriptor), wait],\n };\n}\n","import { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport type { DoneAction } from \"./memory.js\";\nimport { viewWithDone } from \"./memory.js\";\nimport type { ReflectedPlayer } from \"./reflect.js\";\nimport { WAIT_DESCRIPTION } from \"./reflect.js\";\nimport type { TurnGate } from \"./turn-gate.js\";\nimport { SDK_VERSION } from \"./protocol.js\";\n\nfunction jsonResult(payload: unknown, isError = false) {\n return {\n isError,\n content: [{ type: \"text\" as const, text: JSON.stringify(payload) }],\n };\n}\n\nfunction toolError(error: unknown) {\n const message = error instanceof Error ? error.message : String(error);\n return jsonResult({ error: message }, true);\n}\n\nexport type SessionActionLog = {\n record(entry: DoneAction): void;\n done(): DoneAction[];\n};\n\n/**\n * Build an in-process MCP server for one player session.\n * Tools come from one definition: see, wait, and every public action.\n * When an action log is set, see and wait include what this character already called.\n */\nexport function createSessionMcpServer(\n player: ReflectedPlayer,\n gate: TurnGate,\n options?: { name?: string; actions?: SessionActionLog },\n): McpServer {\n const server = new McpServer(\n { name: options?.name ?? \"agent-player\", version: SDK_VERSION },\n { capabilities: { tools: {} } },\n );\n const actions = options?.actions;\n\n const viewed = async () => {\n const view = await player.see.invoke({});\n return actions ? viewWithDone(view, actions.done()) : view;\n };\n\n server.registerTool(\n \"see\",\n { description: player.see.description },\n async () => {\n try {\n return jsonResult(await viewed());\n } catch (error) {\n return toolError(error);\n }\n },\n );\n\n server.registerTool(\n \"wait\",\n { description: WAIT_DESCRIPTION },\n async () => {\n try {\n await gate.waitForTurn();\n return jsonResult(await viewed());\n } catch (error) {\n return toolError(error);\n }\n },\n );\n\n for (const action of player.actions) {\n const handler = async (args: Record<string, unknown>) => {\n try {\n const result = await action.invoke(args);\n actions?.record({ action: action.name, args, ok: true });\n return jsonResult(result ?? { ok: true });\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n actions?.record({ action: action.name, args, ok: false, error: message });\n return toolError(error);\n }\n };\n\n if (action.argsSchema) {\n server.registerTool(\n action.name,\n {\n description: action.description,\n inputSchema: action.argsSchema.shape,\n },\n async (args) => handler(args as Record<string, unknown>),\n );\n } else {\n server.registerTool(\n action.name,\n { description: action.description },\n async () => handler({}),\n );\n }\n }\n\n return server;\n}\n","import { TurnTimeoutError } from \"./errors.js\";\nimport type { TurnReport } from \"./protocol.js\";\n\nexport type TurnOutcome = TurnReport;\n\nfunction abortError(signal: AbortSignal): Error {\n const reason: unknown = signal.reason;\n if (reason instanceof Error) return reason;\n if (typeof reason === \"string\" && reason.length > 0) return new Error(reason);\n return new Error(\"turn aborted\");\n}\n\n/**\n * Coordinates game-side turn() with the agent's wait tool.\n * turn() releases wait, then resolves when the platform reports the turn finished.\n */\nexport class TurnGate {\n private waitResolve: (() => void) | null = null;\n private waitPromise: Promise<void> | null = null;\n private turnResolve: ((result: TurnOutcome) => void) | null = null;\n private turnReject: ((error: Error) => void) | null = null;\n private turnPromise: Promise<TurnOutcome> | null = null;\n private released = false;\n\n /** Called by the wait tool. Blocks until turn() releases this session. */\n async waitForTurn(): Promise<void> {\n if (this.released) {\n this.released = false;\n return;\n }\n if (!this.waitPromise) {\n this.waitPromise = new Promise<void>((resolve) => {\n this.waitResolve = resolve;\n });\n }\n await this.waitPromise;\n this.waitPromise = null;\n this.waitResolve = null;\n this.released = false;\n }\n\n /**\n * Unblock wait and wait for the platform's turn report.\n * Rejects on timeout or abort; those do not produce a TurnOutcome.\n */\n async runTurn(options?: { timeoutMs?: number; signal?: AbortSignal }): Promise<TurnOutcome> {\n if (this.turnPromise) {\n throw new Error(\"turn() already in progress for this session\");\n }\n if (options?.signal?.aborted) {\n throw abortError(options.signal);\n }\n\n let timeoutId: ReturnType<typeof setTimeout> | undefined;\n let onAbort: (() => void) | undefined;\n const signal = options?.signal;\n\n this.turnPromise = new Promise<TurnOutcome>((resolve, reject) => {\n this.turnResolve = resolve;\n this.turnReject = reject;\n if (options?.timeoutMs != null) {\n timeoutId = setTimeout(() => {\n this.rejectTurn(new TurnTimeoutError(`turn() timed out after ${options.timeoutMs}ms`));\n }, options.timeoutMs);\n }\n if (signal) {\n if (signal.aborted) {\n this.rejectTurn(abortError(signal));\n return;\n }\n onAbort = () => this.rejectTurn(abortError(signal));\n signal.addEventListener(\"abort\", onAbort, { once: true });\n }\n });\n\n this.released = true;\n const release = this.waitResolve;\n this.waitResolve = null;\n this.waitPromise = null;\n release?.();\n\n try {\n return await this.turnPromise;\n } finally {\n if (timeoutId) clearTimeout(timeoutId);\n if (signal && onAbort) signal.removeEventListener(\"abort\", onAbort);\n this.turnPromise = null;\n this.turnResolve = null;\n this.turnReject = null;\n }\n }\n\n /** Platform finished one action cycle (success or second failure). */\n completeTurn(outcome: TurnOutcome): void {\n const resolve = this.turnResolve;\n if (!resolve) return;\n this.turnResolve = null;\n this.turnReject = null;\n resolve(outcome);\n }\n\n /** Fail an in-flight turn, for example when the connection cannot be resumed. */\n failTurn(error: Error): void {\n this.rejectTurn(error);\n }\n\n reset(): void {\n this.waitResolve?.();\n this.completeTurn({ ok: false, error: \"session stopped\" });\n this.waitResolve = null;\n this.waitPromise = null;\n this.released = false;\n }\n\n private rejectTurn(error: Error): void {\n const reject = this.turnReject;\n if (!reject) return;\n this.turnResolve = null;\n this.turnReject = null;\n reject(error);\n }\n}\n"],"mappings":"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","names":["import_node_crypto","Database","WebSocket","resolve","resolve"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/agent-server.ts","../src/errors.ts","../src/logger.ts","../src/memory.ts","../src/platform-connection.ts","../src/protocol.ts","../src/ws-transport.ts","../src/reflect.ts","../src/session-mcp.ts","../src/turn-gate.ts"],"sourcesContent":["export { AgentServer } from \"./agent-server.js\";\nexport {\n ConnectionLostError,\n PlatformAuthError,\n ProtocolVersionError,\n TurnFailedError,\n TurnTimeoutError,\n} from \"./errors.js\";\nexport type { AgentMetadata, ActionSpec } from \"./reflect.js\";\nexport type { Logger } from \"./logger.js\";\nexport type {\n AgentEvent,\n AgentHandle,\n AgentServerOptions,\n EventListener,\n StartOptions,\n TurnOptions,\n TurnResult,\n} from \"./types.js\";\nexport type { AttemptRecord, TokenUsage } from \"./protocol.js\";\n","import { randomUUID } from \"node:crypto\";\nimport { InMemoryTransport } from \"@modelcontextprotocol/sdk/inMemory.js\";\nimport type { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport type { Transport } from \"@modelcontextprotocol/sdk/shared/transport.js\";\nimport { ConnectionLostError, TurnFailedError } from \"./errors.js\";\nimport type { Logger } from \"./logger.js\";\nimport { log } from \"./logger.js\";\nimport { defaultMemoryPath, SessionMemory } from \"./memory.js\";\nimport { PlatformConnection } from \"./platform-connection.js\";\nimport {\n DEFAULT_AGENT_INSTRUCTIONS,\n assertNever,\n type Envelope,\n type TurnReport,\n} from \"./protocol.js\";\nimport { reflectPlayer } from \"./reflect.js\";\nimport { createSessionMcpServer } from \"./session-mcp.js\";\nimport { TurnGate } from \"./turn-gate.js\";\nimport type {\n AgentEvent,\n AgentHandle,\n AgentServerOptions,\n EventListener,\n InlinePlatform,\n StartOptions,\n TurnOptions,\n TurnResult,\n} from \"./types.js\";\nimport { SessionMuxTransport } from \"./ws-transport.js\";\n\nconst DEFAULT_TURN_TIMEOUT_MS = 60_000;\nconst PLATFORM_URL = \"wss://api.whitesandsint.com\";\n\ntype SessionRecord = {\n id: string;\n token: string;\n name: string;\n gate: TurnGate;\n server: McpServer;\n transport: Transport;\n mux?: SessionMuxTransport;\n listeners: Set<EventListener>;\n};\n\n/**\n * One in-process MCP server and one outbound connection to the platform.\n * Every `start()` is its own session and token. The game calls `turn()` to\n * decide whose turn it is; the platform chooses the action.\n */\nexport class AgentServer {\n private readonly options: AgentServerOptions;\n private readonly platformKey: string;\n private readonly platformUrl: string;\n private readonly logger: Logger | undefined;\n private connection: PlatformConnection | null = null;\n private readonly sessions = new Map<string, SessionRecord>();\n private readonly listeners = new Set<EventListener>();\n private readonly inline: InlinePlatform | undefined;\n private memory: SessionMemory | null = null;\n private started = false;\n private closing = false;\n\n constructor(options: AgentServerOptions = {}) {\n const platformKey = options.platformKey ?? process.env.WSI_PLATFORM_KEY;\n if (!options.inline && !platformKey) {\n throw new Error(\"Set WSI_PLATFORM_KEY or pass platformKey, unless an inline platform is provided\");\n }\n this.options = options;\n this.platformKey = platformKey || \"inline\";\n this.platformUrl = options.platformUrl ?? PLATFORM_URL;\n this.logger = options.logger;\n this.inline = options.inline;\n if (options.onEvent) this.listeners.add(options.onEvent);\n }\n\n /** Ensure the outbound platform connection. No-op for an inline platform. */\n async connect(): Promise<void> {\n if (this.inline || this.started) {\n this.started = true;\n return;\n }\n this.connection = new PlatformConnection(this.platformUrl, this.platformKey, {\n onEnvelope: (envelope) => this.handleEnvelope(envelope),\n onDisconnect: () => this.emit({ type: \"disconnected\" }),\n onReconnect: () => this.emit({ type: \"reconnected\" }),\n onError: (error) => {\n log(this.logger, \"error\", error.message);\n if (error instanceof ConnectionLostError) this.failInflight(error);\n },\n sessions: () => [...this.sessions.values()].map((session) => ({\n sessionId: session.id,\n sessionToken: session.token,\n })),\n }, this.logger);\n await this.connection.connect();\n this.started = true;\n }\n\n /**\n * Reflect the player into tools, register a session, and return a handle.\n * `turn()` on that handle lets the remote model act once.\n */\n async start(instance: object, options?: StartOptions): Promise<AgentHandle> {\n await this.connect();\n\n const reflected = reflectPlayer(instance);\n const sessionId = randomUUID();\n const sessionToken = randomUUID();\n const gate = new TurnGate();\n const name = options?.name ?? instance.constructor?.name ?? \"player\";\n const memory = this.actionMemory();\n const server = createSessionMcpServer(reflected, gate, {\n name: `agent-player:${name}`,\n ...(memory\n ? {\n actions: {\n record: (entry) => memory.record(sessionId, name, entry),\n done: () => memory.done(sessionId),\n },\n }\n : {}),\n });\n const instructions = [this.options.instructions ?? DEFAULT_AGENT_INSTRUCTIONS, options?.instructions]\n .filter((part): part is string => Boolean(part && part.length > 0))\n .join(\"\\n\\n\");\n\n const listeners = new Set<EventListener>();\n const record: SessionRecord = {\n id: sessionId,\n token: sessionToken,\n name,\n gate,\n server,\n transport: undefined as unknown as Transport,\n listeners,\n };\n\n const onTurnResult = (result: TurnReport) => {\n gate.completeTurn(result);\n };\n const onEvent = (event: AgentEvent) => this.emit(event);\n\n if (this.inline) {\n const [serverTransport, clientTransport] = InMemoryTransport.createLinkedPair();\n await server.connect(serverTransport);\n record.transport = serverTransport;\n this.sessions.set(sessionId, record);\n await this.inline.startSession({\n sessionId,\n sessionToken,\n name,\n tools: reflected.tools,\n instructions,\n ...(options?.goal ? { goal: options.goal } : {}),\n ...(this.logger ? { logger: this.logger } : {}),\n transport: clientTransport,\n onTurnResult,\n onEvent,\n });\n } else {\n if (!this.connection) throw new Error(\"Not connected\");\n const mux = this.connection.createTransport(sessionId);\n await server.connect(mux);\n record.transport = mux;\n record.mux = mux;\n this.sessions.set(sessionId, record);\n const started = this.connection.waitForSessionEvent(sessionId, \"start\");\n this.connection.send({\n type: \"start_session\",\n sessionId,\n sessionToken,\n name,\n tools: reflected.tools,\n instructions,\n ...(options?.goal ? { goal: options.goal } : {}),\n });\n await started;\n }\n\n return {\n sessionId,\n turn: (turnOptions?: TurnOptions) => this.turn(sessionId, turnOptions),\n stop: () => this.stopSession(sessionId),\n on: (listener: EventListener) => {\n listeners.add(listener);\n return () => listeners.delete(listener);\n },\n };\n }\n\n /** Subscribe to every session plus connection events. Returns unsubscribe. */\n on(listener: EventListener): () => void {\n this.listeners.add(listener);\n return () => this.listeners.delete(listener);\n }\n\n private async turn(sessionId: string, options?: TurnOptions): Promise<TurnResult> {\n const session = this.sessions.get(sessionId);\n if (!session) throw new Error(`Unknown session ${sessionId}`);\n const timeoutMs = options?.timeoutMs ?? this.options.turnTimeoutMs ?? DEFAULT_TURN_TIMEOUT_MS;\n let outcome: TurnReport;\n try {\n outcome = await session.gate.runTurn({\n timeoutMs,\n ...(options?.signal ? { signal: options.signal } : {}),\n });\n } catch (error) {\n if (error instanceof ConnectionLostError) throw error;\n throw error;\n }\n if (!outcome.ok) {\n if (outcome.connectionLost) {\n throw new ConnectionLostError(outcome.error ?? \"Connection to the platform was lost\");\n }\n throw new TurnFailedError(outcome.error ?? \"turn failed\", outcome.attemptDetails ?? []);\n }\n return {\n action: outcome.action ?? \"unknown\",\n args: outcome.args ?? {},\n result: outcome.result,\n attempts: outcome.attempts ?? 1,\n usage: outcome.usage ?? { promptTokens: 0, completionTokens: 0 },\n };\n }\n\n private emit(event: AgentEvent): void {\n for (const listener of this.listeners) listener(event);\n if (event.type === \"disconnected\" || event.type === \"reconnected\") return;\n const session = this.sessions.get(event.sessionId);\n if (!session) return;\n for (const listener of session.listeners) listener(event);\n }\n\n private failInflight(error: ConnectionLostError): void {\n for (const session of this.sessions.values()) {\n session.gate.failTurn(error);\n }\n }\n\n private handleEnvelope(envelope: Envelope): void {\n switch (envelope.type) {\n case \"mcp\": {\n const session = this.sessions.get(envelope.sessionId);\n session?.mux?.receive(envelope.message);\n return;\n }\n case \"turn_result\": {\n const session = this.sessions.get(envelope.sessionId);\n session?.gate.completeTurn(envelope);\n return;\n }\n case \"session_event\": {\n if (envelope.event === \"action\") {\n this.emit({\n type: \"action\",\n sessionId: envelope.sessionId,\n action: envelope.action ?? \"unknown\",\n args: envelope.args ?? {},\n });\n return;\n }\n if (envelope.event === \"retry\") {\n this.emit({\n type: \"retry\",\n sessionId: envelope.sessionId,\n action: envelope.action ?? \"unknown\",\n args: envelope.args ?? {},\n error: envelope.error ?? \"action failed\",\n });\n return;\n }\n this.emit({\n type: \"turnFailed\",\n sessionId: envelope.sessionId,\n error: envelope.error ?? \"turn failed\",\n ...(envelope.action ? { action: envelope.action } : {}),\n ...(envelope.args ? { args: envelope.args } : {}),\n });\n return;\n }\n case \"error\":\n log(this.logger, \"error\", envelope.message);\n return;\n case \"session_started\":\n case \"session_stopped\":\n case \"session_resumed\":\n case \"resume_err\":\n case \"hello_ok\":\n case \"hello_err\":\n case \"hello\":\n case \"start_session\":\n case \"stop_session\":\n case \"ping\":\n case \"pong\":\n case \"resume_session\":\n return;\n default: {\n assertNever(envelope);\n }\n }\n }\n\n private async stopSession(sessionId: string): Promise<void> {\n const session = this.sessions.get(sessionId);\n if (!session) return;\n this.sessions.delete(sessionId);\n session.gate.reset();\n\n if (this.inline) {\n await this.inline.stopSession(sessionId);\n } else if (this.connection) {\n const stopped = this.connection.waitForSessionEvent(sessionId, \"stop\").catch(() => null);\n try {\n this.connection.send({ type: \"stop_session\", sessionId });\n } catch {\n // connection may already be down\n }\n await stopped;\n }\n\n try {\n await session.server.close();\n } catch {\n // ignore\n }\n }\n\n /** Stop every session and close the platform connection. */\n async close(): Promise<void> {\n if (this.closing) return;\n this.closing = true;\n const ids = [...this.sessions.keys()];\n for (const id of ids) {\n await this.stopSession(id);\n }\n if (this.inline?.close) await this.inline.close();\n if (this.connection) {\n await this.connection.close();\n this.connection = null;\n }\n this.memory?.close();\n this.memory = null;\n this.started = false;\n this.closing = false;\n }\n\n private actionMemory(): SessionMemory | null {\n if (this.options.memoryPath === false) return null;\n if (!this.memory) {\n const path = this.options.memoryPath ?? defaultMemoryPath();\n this.memory = new SessionMemory(path);\n }\n return this.memory;\n }\n\n async [Symbol.asyncDispose](): Promise<void> {\n await this.close();\n }\n}\n","import type { AttemptRecord } from \"./protocol.js\";\n\nexport class PlatformAuthError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"PlatformAuthError\";\n }\n}\n\nexport class ProtocolVersionError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"ProtocolVersionError\";\n }\n}\n\nexport class TurnFailedError extends Error {\n readonly attempts: AttemptRecord[];\n\n constructor(message: string, attempts: AttemptRecord[] = []) {\n super(message);\n this.name = \"TurnFailedError\";\n this.attempts = attempts;\n }\n}\n\nexport class TurnTimeoutError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"TurnTimeoutError\";\n }\n}\n\nexport class ConnectionLostError extends Error {\n constructor(message = \"Connection to the platform was lost\") {\n super(message);\n this.name = \"ConnectionLostError\";\n }\n}\n","export type Logger = {\n debug?: (message: string, extra?: unknown) => void;\n info?: (message: string, extra?: unknown) => void;\n warn?: (message: string, extra?: unknown) => void;\n error?: (message: string, extra?: unknown) => void;\n};\n\nexport function log(logger: Logger | undefined, level: keyof Logger, message: string, extra?: unknown): void {\n logger?.[level]?.(message, extra);\n}\n","import { mkdirSync } from \"node:fs\";\nimport { dirname, resolve } from \"node:path\";\nimport Database from \"better-sqlite3\";\n\n/** Actions kept on the view. Older rows stay in the file and drop off the prompt. */\nconst MAX_DONE = 50;\n\nexport type DoneAction = {\n action: string;\n args: Record<string, unknown>;\n ok: boolean;\n error?: string;\n};\n\ntype ActionRow = {\n action: string;\n args: string;\n ok: number;\n error: string | null;\n};\n\n/**\n * SQLite log of actions one game process has already called.\n * Each session reads only its own rows, so a new run starts with an empty list.\n */\nexport class SessionMemory {\n private readonly db: Database.Database;\n\n constructor(path: string) {\n mkdirSync(dirname(path), { recursive: true });\n this.db = new Database(path, { timeout: 5000 });\n this.db.exec(`\n CREATE TABLE IF NOT EXISTS actions (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n session_id TEXT NOT NULL,\n character TEXT NOT NULL,\n action TEXT NOT NULL,\n args TEXT NOT NULL,\n ok INTEGER NOT NULL,\n error TEXT\n );\n CREATE INDEX IF NOT EXISTS actions_by_session ON actions(session_id, id);\n `);\n }\n\n record(sessionId: string, character: string, entry: DoneAction): void {\n this.db\n .prepare(\n `INSERT INTO actions (session_id, character, action, args, ok, error)\n VALUES (@sessionId, @character, @action, @args, @ok, @error)`,\n )\n .run({\n sessionId,\n character,\n action: entry.action,\n args: JSON.stringify(entry.args),\n ok: entry.ok ? 1 : 0,\n error: entry.error ?? null,\n });\n }\n\n /** Oldest first, capped to the most recent actions for this session. */\n done(sessionId: string): DoneAction[] {\n const rows = this.db\n .prepare(\n `SELECT action, args, ok, error FROM (\n SELECT id, action, args, ok, error FROM actions\n WHERE session_id = ?\n ORDER BY id DESC\n LIMIT ?\n ) ORDER BY id ASC`,\n )\n .all(sessionId, MAX_DONE) as ActionRow[];\n return rows.map((row) => {\n const entry: DoneAction = {\n action: row.action,\n args: JSON.parse(row.args) as Record<string, unknown>,\n ok: row.ok === 1,\n };\n if (row.error) entry.error = row.error;\n return entry;\n });\n }\n\n close(): void {\n this.db.close();\n }\n}\n\nexport function defaultMemoryPath(): string {\n return resolve(process.cwd(), \".wsi\", \"agent-memory.sqlite\");\n}\n\n/** Attach this session's action log to a see() payload. */\nexport function viewWithDone(view: unknown, done: DoneAction[]): unknown {\n if (view && typeof view === \"object\" && !Array.isArray(view)) {\n return { ...(view as Record<string, unknown>), done };\n }\n return { view, done };\n}\n","import { randomUUID } from \"node:crypto\";\nimport WebSocket from \"ws\";\nimport { ConnectionLostError, PlatformAuthError, ProtocolVersionError } from \"./errors.js\";\nimport type { Logger } from \"./logger.js\";\nimport { log } from \"./logger.js\";\nimport {\n PROTOCOL_VERSION,\n SDK_VERSION,\n SESSION_RESUME_GRACE_MS,\n type Envelope,\n} from \"./protocol.js\";\nimport { SessionMuxTransport } from \"./ws-transport.js\";\n\nexport type ResumableSession = {\n sessionId: string;\n sessionToken: string;\n};\n\nexport type PlatformConnectionHandlers = {\n onEnvelope: (envelope: Envelope) => void;\n onDisconnect?: () => void;\n onReconnect?: () => void;\n onError?: (error: Error) => void;\n sessions?: () => ResumableSession[];\n};\n\nconst HEARTBEAT_MS = 15_000;\nconst PONG_TIMEOUT_MS = 10_000;\nconst MAX_RECONNECT_ATTEMPTS = 8;\n\n/**\n * Outbound WebSocket to the platform. The game never listens on a public URL.\n * After the first successful hello, a dropped socket reconnects and resumes sessions.\n */\nexport class PlatformConnection {\n private ws: WebSocket | null = null;\n private readonly url: string;\n private readonly platformKey: string;\n readonly clientId = randomUUID();\n private readonly handlers: PlatformConnectionHandlers;\n private readonly logger: Logger | undefined;\n private readonly pending = new Map<\n string,\n { resolve: (envelope: Envelope) => void; reject: (error: Error) => void }\n >();\n private readonly outbox: Envelope[] = [];\n private accountName: string | null = null;\n private closed = false;\n private everConnected = false;\n private reconnecting = false;\n private reconnectAttempt = 0;\n private reconnectTimer: ReturnType<typeof setTimeout> | undefined;\n private heartbeat: ReturnType<typeof setInterval> | undefined;\n private pongTimer: ReturnType<typeof setTimeout> | undefined;\n private pendingPong: string | null = null;\n\n constructor(\n url: string,\n platformKey: string,\n handlers: PlatformConnectionHandlers,\n logger?: Logger,\n ) {\n this.url = url;\n this.platformKey = platformKey;\n this.handlers = handlers;\n this.logger = logger;\n }\n\n get connected(): boolean {\n return this.ws?.readyState === WebSocket.OPEN;\n }\n\n async connect(): Promise<string> {\n if (this.closed) throw new Error(\"Platform connection is closed\");\n if (this.connected && this.accountName) return this.accountName;\n const account = await this.openSocket();\n this.everConnected = true;\n this.reconnectAttempt = 0;\n return account;\n }\n\n send(envelope: Envelope): void {\n if (this.connected && this.ws) {\n this.ws.send(JSON.stringify(envelope));\n return;\n }\n if (envelope.type === \"mcp\" || envelope.type === \"ping\") {\n this.outbox.push(envelope);\n return;\n }\n throw new Error(\"Not connected to platform\");\n }\n\n waitForSessionEvent(\n sessionId: string,\n kind: \"start\" | \"stop\" | \"resume\",\n timeoutMs = 15_000,\n ): Promise<Envelope> {\n const key = `session:${sessionId}:${kind}`;\n return new Promise((resolve, reject) => {\n const timer = setTimeout(() => {\n this.pending.delete(key);\n reject(new Error(`Timed out waiting for session ${kind}`));\n }, timeoutMs);\n this.pending.set(key, {\n resolve: (envelope) => {\n clearTimeout(timer);\n resolve(envelope);\n },\n reject: (error) => {\n clearTimeout(timer);\n reject(error);\n },\n });\n });\n }\n\n createTransport(sessionId: string): SessionMuxTransport {\n return new SessionMuxTransport(sessionId, (envelope) => this.send(envelope));\n }\n\n async close(): Promise<void> {\n this.closed = true;\n this.stopHeartbeat();\n if (this.reconnectTimer) clearTimeout(this.reconnectTimer);\n this.reconnectTimer = undefined;\n this.reconnecting = false;\n this.failWaiters(new Error(\"platform connection closed\"));\n if (!this.ws) return;\n const ws = this.ws;\n this.ws = null;\n await new Promise<void>((resolve) => {\n ws.once(\"close\", () => resolve());\n ws.close();\n });\n }\n\n private openSocket(): Promise<string> {\n return new Promise((resolve, reject) => {\n const ws = new WebSocket(this.url);\n this.ws = ws;\n let settled = false;\n\n const fail = (error: Error) => {\n if (settled) return;\n settled = true;\n reject(error);\n };\n\n ws.on(\"open\", () => {\n ws.send(JSON.stringify({\n type: \"hello\",\n platformKey: this.platformKey,\n clientId: this.clientId,\n protocolVersion: PROTOCOL_VERSION,\n sdkVersion: SDK_VERSION,\n } satisfies Envelope));\n });\n\n ws.on(\"message\", (data) => {\n let envelope: Envelope;\n try {\n envelope = JSON.parse(data.toString()) as Envelope;\n } catch (error) {\n const parsed = error instanceof Error ? error : new Error(\"Invalid platform message\");\n this.handlers.onError?.(parsed);\n return;\n }\n\n if (!settled && (envelope.type === \"hello_ok\" || envelope.type === \"hello_err\")) {\n settled = true;\n if (envelope.type === \"hello_err\") {\n const error = envelope.code === \"PROTOCOL\"\n ? new ProtocolVersionError(envelope.message)\n : new PlatformAuthError(envelope.message);\n this.closed = true;\n reject(error);\n ws.close();\n return;\n }\n this.accountName = envelope.accountName;\n this.startHeartbeat();\n this.flushOutbox();\n resolve(envelope.accountName);\n return;\n }\n\n if (envelope.type === \"pong\") {\n if (this.pendingPong === envelope.id) {\n this.pendingPong = null;\n if (this.pongTimer) clearTimeout(this.pongTimer);\n this.pongTimer = undefined;\n }\n return;\n }\n\n this.resolveSessionWaiter(envelope);\n this.handlers.onEnvelope(envelope);\n });\n\n ws.on(\"error\", (error) => {\n this.handlers.onError?.(error);\n fail(error);\n });\n\n ws.on(\"close\", () => {\n this.stopHeartbeat();\n if (this.ws === ws) this.ws = null;\n if (!settled) fail(new Error(\"platform connection closed before hello\"));\n if (this.closed || !this.everConnected) {\n this.failWaiters(new Error(\"platform connection closed\"));\n return;\n }\n this.handlers.onDisconnect?.();\n this.scheduleReconnect();\n });\n });\n }\n\n private resolveSessionWaiter(envelope: Envelope): void {\n if (envelope.type === \"session_started\" || envelope.type === \"session_stopped\") {\n const kind = envelope.type === \"session_started\" ? \"start\" : \"stop\";\n const waiter = this.pending.get(`session:${envelope.sessionId}:${kind}`);\n if (!waiter) return;\n this.pending.delete(`session:${envelope.sessionId}:${kind}`);\n waiter.resolve(envelope);\n return;\n }\n if (envelope.type === \"session_resumed\" || envelope.type === \"resume_err\") {\n const waiter = this.pending.get(`session:${envelope.sessionId}:resume`);\n if (!waiter) return;\n this.pending.delete(`session:${envelope.sessionId}:resume`);\n if (envelope.type === \"resume_err\") {\n waiter.reject(new ConnectionLostError(envelope.message));\n return;\n }\n waiter.resolve(envelope);\n }\n }\n\n private scheduleReconnect(): void {\n if (this.closed || this.reconnecting) return;\n if (this.reconnectAttempt >= MAX_RECONNECT_ATTEMPTS) {\n this.closed = true;\n const error = new ConnectionLostError(\"Could not reconnect to the platform\");\n this.handlers.onError?.(error);\n this.failWaiters(error);\n return;\n }\n const delay = Math.min(SESSION_RESUME_GRACE_MS, 250 * 2 ** this.reconnectAttempt);\n this.reconnectAttempt += 1;\n this.reconnecting = true;\n log(this.logger, \"warn\", `platform connection dropped; retrying in ${delay}ms`);\n this.reconnectTimer = setTimeout(() => {\n this.reconnectTimer = undefined;\n void this.reconnect();\n }, delay);\n this.reconnectTimer.unref?.();\n }\n\n private async reconnect(): Promise<void> {\n try {\n await this.openSocket();\n this.everConnected = true;\n this.reconnectAttempt = 0;\n this.reconnecting = false;\n const sessions = this.handlers.sessions?.() ?? [];\n for (const session of sessions) {\n const resumed = this.waitForSessionEvent(session.sessionId, \"resume\");\n this.send({\n type: \"resume_session\",\n sessionId: session.sessionId,\n sessionToken: session.sessionToken,\n });\n await resumed;\n }\n this.handlers.onReconnect?.();\n } catch (error) {\n this.reconnecting = false;\n if (this.closed) return;\n const wrapped = error instanceof Error ? error : new Error(String(error));\n if (wrapped instanceof PlatformAuthError || wrapped instanceof ProtocolVersionError) {\n this.closed = true;\n this.handlers.onError?.(wrapped);\n this.failWaiters(wrapped);\n return;\n }\n this.scheduleReconnect();\n }\n }\n\n private flushOutbox(): void {\n if (!this.ws || !this.connected) return;\n const pending = this.outbox.splice(0, this.outbox.length);\n for (const envelope of pending) {\n this.ws.send(JSON.stringify(envelope));\n }\n }\n\n private startHeartbeat(): void {\n this.stopHeartbeat();\n this.heartbeat = setInterval(() => {\n if (!this.connected) return;\n const id = randomUUID();\n this.pendingPong = id;\n try {\n this.send({ type: \"ping\", id });\n } catch {\n return;\n }\n this.pongTimer = setTimeout(() => {\n if (this.pendingPong === id) {\n log(this.logger, \"warn\", \"platform heartbeat timed out\");\n this.ws?.terminate();\n }\n }, PONG_TIMEOUT_MS);\n this.pongTimer.unref?.();\n }, HEARTBEAT_MS);\n this.heartbeat.unref?.();\n }\n\n private stopHeartbeat(): void {\n if (this.heartbeat) clearInterval(this.heartbeat);\n if (this.pongTimer) clearTimeout(this.pongTimer);\n this.heartbeat = undefined;\n this.pongTimer = undefined;\n this.pendingPong = null;\n }\n\n private failWaiters(error: Error): void {\n for (const [, waiter] of this.pending) waiter.reject(error);\n this.pending.clear();\n }\n}\n","/**\n * Wire protocol between AgentServer (SDK) and the platform. Version 1.\n */\n\nexport const PROTOCOL_VERSION = 1;\nexport const SDK_VERSION = \"1.1.0\";\n\n/** How long a disconnected session can be resumed. Shared by both sides. */\nexport const SESSION_RESUME_GRACE_MS = 30_000;\n\nexport type JsonSchema = {\n type?: string | string[];\n properties?: Record<string, JsonSchema>;\n required?: string[];\n description?: string;\n additionalProperties?: boolean;\n [key: string]: unknown;\n};\n\nexport type ToolDescriptor = {\n name: string;\n description: string;\n inputSchema: JsonSchema;\n};\n\nexport type TokenUsage = {\n promptTokens: number;\n completionTokens: number;\n};\n\nexport type AttemptRecord = {\n action: string;\n args: Record<string, unknown>;\n error: string;\n};\n\nexport type TurnReport = {\n ok: boolean;\n error?: string;\n action?: string;\n args?: Record<string, unknown>;\n result?: unknown;\n attempts?: number;\n attemptDetails?: AttemptRecord[];\n usage?: TokenUsage;\n connectionLost?: boolean;\n};\n\nexport type SessionEventName = \"action\" | \"retry\" | \"turnFailed\";\n\nexport type Envelope =\n | {\n type: \"hello\";\n platformKey: string;\n clientId: string;\n protocolVersion: number;\n sdkVersion: string;\n }\n | {\n type: \"hello_ok\";\n accountName: string;\n protocolVersion: number;\n }\n | {\n type: \"hello_err\";\n message: string;\n code?: \"AUTH\" | \"PROTOCOL\";\n }\n | {\n type: \"start_session\";\n sessionId: string;\n sessionToken: string;\n tools: ToolDescriptor[];\n instructions: string;\n goal?: string;\n name?: string;\n }\n | {\n type: \"session_started\";\n sessionId: string;\n }\n | {\n type: \"stop_session\";\n sessionId: string;\n }\n | {\n type: \"session_stopped\";\n sessionId: string;\n }\n | {\n type: \"mcp\";\n sessionId: string;\n message: unknown;\n }\n | ({\n type: \"turn_result\";\n sessionId: string;\n } & TurnReport)\n | {\n type: \"session_event\";\n sessionId: string;\n event: SessionEventName;\n action?: string;\n args?: Record<string, unknown>;\n error?: string;\n }\n | {\n type: \"ping\";\n id: string;\n }\n | {\n type: \"pong\";\n id: string;\n }\n | {\n type: \"resume_session\";\n sessionId: string;\n sessionToken: string;\n }\n | {\n type: \"session_resumed\";\n sessionId: string;\n }\n | {\n type: \"resume_err\";\n sessionId: string;\n message: string;\n }\n | {\n type: \"error\";\n message: string;\n sessionId?: string;\n };\n\nexport const DEFAULT_AGENT_INSTRUCTIONS = [\n \"You are a remote game agent. Tools are provided by the game.\",\n \"On every turn: call wait first. It blocks until the game grants your turn and then returns the current view from see.\",\n \"After wait returns, call exactly one action tool (not see, not wait).\",\n \"The view's done list is what this character has already called in this session, oldest first. Use it when choosing the next action.\",\n \"If an action tool returns an error, retry once with a corrected action. A second failure ends the turn as failed.\",\n].join(\"\\n\");\n\nexport function assertNever(value: never): never {\n throw new Error(`Unhandled protocol message: ${JSON.stringify(value)}`);\n}\n","import type { Transport } from \"@modelcontextprotocol/sdk/shared/transport.js\";\nimport type { JSONRPCMessage } from \"@modelcontextprotocol/sdk/types.js\";\nimport type { Envelope } from \"./protocol.js\";\n\nexport type EnvelopeSender = (envelope: Envelope) => void;\n\n/**\n * MCP Transport that multiplexes JSON-RPC over a shared envelope channel,\n * keyed by sessionId.\n */\nexport class SessionMuxTransport implements Transport {\n onclose?: () => void;\n onerror?: (error: Error) => void;\n onmessage?: (message: JSONRPCMessage) => void;\n sessionId?: string;\n\n private readonly sid: string;\n private readonly sendEnvelope: EnvelopeSender;\n private started = false;\n private closed = false;\n\n constructor(sessionId: string, sendEnvelope: EnvelopeSender) {\n this.sid = sessionId;\n this.sessionId = sessionId;\n this.sendEnvelope = sendEnvelope;\n }\n\n async start(): Promise<void> {\n if (this.closed) throw new Error(\"Transport already closed\");\n this.started = true;\n }\n\n async close(): Promise<void> {\n if (this.closed) return;\n this.closed = true;\n this.onclose?.();\n }\n\n async send(message: JSONRPCMessage): Promise<void> {\n if (this.closed) throw new Error(\"Transport closed\");\n this.sendEnvelope({ type: \"mcp\", sessionId: this.sid, message });\n }\n\n /** Deliver an inbound MCP message from the platform. */\n receive(message: unknown): void {\n if (this.closed || !this.started) return;\n try {\n this.onmessage?.(message as JSONRPCMessage);\n } catch (error) {\n this.onerror?.(error instanceof Error ? error : new Error(String(error)));\n }\n }\n}\n","import { z, type ZodRawShape, type ZodTypeAny } from \"zod\";\nimport { zodToJsonSchema } from \"zod-to-json-schema\";\nimport type { JsonSchema, ToolDescriptor } from \"./protocol.js\";\n\nexport type ActionSpec = {\n description: string;\n args?: ZodRawShape;\n};\n\nexport type AgentMetadata = {\n description?: string;\n actions?: Record<string, ActionSpec>;\n};\n\nexport type PlayerTool = {\n name: string;\n description: string;\n paramNames: string[];\n argsSchema?: z.ZodObject<ZodRawShape>;\n descriptor: ToolDescriptor;\n invoke: (args: Record<string, unknown>) => Promise<unknown>;\n};\n\nexport type ReflectedPlayer = {\n /** Class-level description, when the player declared `static agent`. */\n description?: string;\n see: PlayerTool;\n actions: PlayerTool[];\n tools: ToolDescriptor[];\n};\n\nconst SKIP = new Set([\"constructor\"]);\n\nexport const SEE_DESCRIPTION = \"Read the current game view for this player. Prefer wait, which returns this after the game grants a turn.\";\nexport const WAIT_DESCRIPTION = \"Block until the game calls turn() for this session, then return the current see() view.\";\n\n/** Parse parameter names from a function's source. Used only when no arg schema is declared. */\nexport function getParamNames(fn: (...args: never[]) => unknown): string[] {\n const src = fn.toString().replace(/\\/\\*[\\s\\S]*?\\*\\//g, \"\").replace(/\\/\\/.*$/gm, \"\");\n const header =\n src.match(/(?:async\\s+)?(?:function\\s*)?(?:\\w*)\\s*\\(([^)]*)\\)/) ??\n src.match(/^(?:async\\s*)?\\(?([^)=]*)\\)?\\s*=>/);\n if (!header) return [];\n const raw = header[1]?.trim() ?? \"\";\n if (!raw) return [];\n return raw\n .split(\",\")\n .map((part) => part.trim())\n .filter(Boolean)\n .map((part) => {\n const cleaned = part.replace(/\\s*=\\s*[^,]+$/, \"\").trim();\n const name = cleaned.split(/[:\\s]/)[0]?.replace(/^\\.\\.\\./, \"\") ?? \"\";\n return name;\n })\n .filter((name) => name.length > 0 && name !== \"this\");\n}\n\nfunction collectMethodNames(instance: object): string[] {\n const names = new Set<string>();\n let proto: object | null = Object.getPrototypeOf(instance);\n while (proto && proto !== Object.prototype) {\n for (const name of Object.getOwnPropertyNames(proto)) {\n if (SKIP.has(name) || name.startsWith(\"_\")) continue;\n const desc = Object.getOwnPropertyDescriptor(proto, name);\n if (!desc || typeof desc.value !== \"function\") continue;\n names.add(name);\n }\n proto = Object.getPrototypeOf(proto);\n }\n return [...names].sort();\n}\n\nfunction readMetadata(instance: object): AgentMetadata | undefined {\n const ctor = instance.constructor as { agent?: AgentMetadata };\n return ctor.agent;\n}\n\nfunction toJsonSchema(schema: ZodTypeAny): JsonSchema {\n const json = zodToJsonSchema(schema, { target: \"jsonSchema7\", $refStrategy: \"none\" }) as JsonSchema;\n delete json.$schema;\n return json;\n}\n\nfunction formatZodError(error: z.ZodError): string {\n return error.issues\n .map((issue) => {\n const path = issue.path.length > 0 ? issue.path.join(\".\") : \"arguments\";\n return `${path}: ${issue.message}`;\n })\n .join(\"; \");\n}\n\nfunction buildTool(\n instance: object,\n name: string,\n description: string,\n spec?: ActionSpec,\n): PlayerTool {\n const fn = (instance as Record<string, unknown>)[name];\n if (typeof fn !== \"function\") {\n throw new Error(`Expected method ${name}`);\n }\n const paramNames = spec?.args ? Object.keys(spec.args) : getParamNames(fn as (...args: never[]) => unknown);\n const shape: ZodRawShape = spec?.args ?? Object.fromEntries(paramNames.map((param) => [param, z.any()]));\n const argsSchema = paramNames.length > 0 || spec?.args ? z.object(shape) : undefined;\n const inputSchema: JsonSchema = spec?.args && argsSchema\n ? toJsonSchema(argsSchema)\n : {\n type: \"object\",\n properties: Object.fromEntries(paramNames.map((param) => [param, {}])),\n ...(paramNames.length > 0 ? { required: paramNames } : {}),\n };\n\n return {\n name,\n description,\n paramNames,\n ...(argsSchema ? { argsSchema } : {}),\n descriptor: { name, description, inputSchema },\n async invoke(args: Record<string, unknown>) {\n let parsed: Record<string, unknown> = args ?? {};\n if (argsSchema) {\n const result = argsSchema.safeParse(args ?? {});\n if (!result.success) {\n throw new Error(formatZodError(result.error));\n }\n parsed = result.data as Record<string, unknown>;\n }\n const ordered = paramNames.map((param) => parsed[param]);\n return await Promise.resolve((fn as (...params: unknown[]) => unknown).apply(instance, ordered));\n },\n };\n}\n\n/**\n * Publish tools from a player instance.\n * - `see` is the state tool (required).\n * - Every other public method is an action tool.\n * - Names starting with `_` and the constructor are skipped.\n * - `static agent` supplies descriptions and zod argument schemas. Undeclared methods stay tools,\n * with unconstrained JSON arguments (no type guessed from the parameter name).\n */\nexport function reflectPlayer(instance: object): ReflectedPlayer {\n const names = collectMethodNames(instance);\n if (!names.includes(\"see\")) {\n throw new Error(\"Player must implement a public see() method\");\n }\n\n const metadata = readMetadata(instance);\n const declared = metadata?.actions ?? {};\n const className = instance.constructor?.name || \"Player\";\n for (const name of Object.keys(declared)) {\n if (!names.includes(name) || name === \"see\") {\n throw new Error(`Declared action \"${name}\" is not a public method on ${className}`);\n }\n }\n\n const see = buildTool(instance, \"see\", SEE_DESCRIPTION);\n const actionNames = names.filter((name) => name !== \"see\");\n const actions = actionNames.map((name) => {\n const spec = declared[name];\n const description = spec?.description ?? `Action: ${name}`;\n return buildTool(instance, name, description, spec);\n });\n\n const wait: ToolDescriptor = {\n name: \"wait\",\n description: WAIT_DESCRIPTION,\n inputSchema: { type: \"object\", properties: {} },\n };\n\n return {\n ...(metadata?.description ? { description: metadata.description } : {}),\n see,\n actions,\n tools: [see.descriptor, ...actions.map((action) => action.descriptor), wait],\n };\n}\n","import { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport type { DoneAction } from \"./memory.js\";\nimport { viewWithDone } from \"./memory.js\";\nimport type { ReflectedPlayer } from \"./reflect.js\";\nimport { WAIT_DESCRIPTION } from \"./reflect.js\";\nimport type { TurnGate } from \"./turn-gate.js\";\nimport { SDK_VERSION } from \"./protocol.js\";\n\nfunction jsonResult(payload: unknown, isError = false) {\n return {\n isError,\n content: [{ type: \"text\" as const, text: JSON.stringify(payload) }],\n };\n}\n\nfunction toolError(error: unknown) {\n const message = error instanceof Error ? error.message : String(error);\n return jsonResult({ error: message }, true);\n}\n\nexport type SessionActionLog = {\n record(entry: DoneAction): void;\n done(): DoneAction[];\n};\n\n/**\n * Build an in-process MCP server for one player session.\n * Tools come from one definition: see, wait, and every public action.\n * When an action log is set, see and wait include what this character already called.\n */\nexport function createSessionMcpServer(\n player: ReflectedPlayer,\n gate: TurnGate,\n options?: { name?: string; actions?: SessionActionLog },\n): McpServer {\n const server = new McpServer(\n { name: options?.name ?? \"agent-player\", version: SDK_VERSION },\n { capabilities: { tools: {} } },\n );\n const actions = options?.actions;\n\n const viewed = async () => {\n const view = await player.see.invoke({});\n return actions ? viewWithDone(view, actions.done()) : view;\n };\n\n server.registerTool(\n \"see\",\n { description: player.see.description },\n async () => {\n try {\n return jsonResult(await viewed());\n } catch (error) {\n return toolError(error);\n }\n },\n );\n\n server.registerTool(\n \"wait\",\n { description: WAIT_DESCRIPTION },\n async () => {\n try {\n await gate.waitForTurn();\n return jsonResult(await viewed());\n } catch (error) {\n return toolError(error);\n }\n },\n );\n\n for (const action of player.actions) {\n const handler = async (args: Record<string, unknown>) => {\n try {\n const result = await action.invoke(args);\n actions?.record({ action: action.name, args, ok: true });\n return jsonResult(result ?? { ok: true });\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n actions?.record({ action: action.name, args, ok: false, error: message });\n return toolError(error);\n }\n };\n\n if (action.argsSchema) {\n server.registerTool(\n action.name,\n {\n description: action.description,\n inputSchema: action.argsSchema.shape,\n },\n async (args) => handler(args as Record<string, unknown>),\n );\n } else {\n server.registerTool(\n action.name,\n { description: action.description },\n async () => handler({}),\n );\n }\n }\n\n return server;\n}\n","import { TurnTimeoutError } from \"./errors.js\";\nimport type { TurnReport } from \"./protocol.js\";\n\nexport type TurnOutcome = TurnReport;\n\nfunction abortError(signal: AbortSignal): Error {\n const reason: unknown = signal.reason;\n if (reason instanceof Error) return reason;\n if (typeof reason === \"string\" && reason.length > 0) return new Error(reason);\n return new Error(\"turn aborted\");\n}\n\n/**\n * Coordinates game-side turn() with the agent's wait tool.\n * turn() releases wait, then resolves when the platform reports the turn finished.\n */\nexport class TurnGate {\n private waitResolve: (() => void) | null = null;\n private waitPromise: Promise<void> | null = null;\n private turnResolve: ((result: TurnOutcome) => void) | null = null;\n private turnReject: ((error: Error) => void) | null = null;\n private turnPromise: Promise<TurnOutcome> | null = null;\n private released = false;\n\n /** Called by the wait tool. Blocks until turn() releases this session. */\n async waitForTurn(): Promise<void> {\n if (this.released) {\n this.released = false;\n return;\n }\n if (!this.waitPromise) {\n this.waitPromise = new Promise<void>((resolve) => {\n this.waitResolve = resolve;\n });\n }\n await this.waitPromise;\n this.waitPromise = null;\n this.waitResolve = null;\n this.released = false;\n }\n\n /**\n * Unblock wait and wait for the platform's turn report.\n * Rejects on timeout or abort; those do not produce a TurnOutcome.\n */\n async runTurn(options?: { timeoutMs?: number; signal?: AbortSignal }): Promise<TurnOutcome> {\n if (this.turnPromise) {\n throw new Error(\"turn() already in progress for this session\");\n }\n if (options?.signal?.aborted) {\n throw abortError(options.signal);\n }\n\n let timeoutId: ReturnType<typeof setTimeout> | undefined;\n let onAbort: (() => void) | undefined;\n const signal = options?.signal;\n\n this.turnPromise = new Promise<TurnOutcome>((resolve, reject) => {\n this.turnResolve = resolve;\n this.turnReject = reject;\n if (options?.timeoutMs != null) {\n timeoutId = setTimeout(() => {\n this.rejectTurn(new TurnTimeoutError(`turn() timed out after ${options.timeoutMs}ms`));\n }, options.timeoutMs);\n }\n if (signal) {\n if (signal.aborted) {\n this.rejectTurn(abortError(signal));\n return;\n }\n onAbort = () => this.rejectTurn(abortError(signal));\n signal.addEventListener(\"abort\", onAbort, { once: true });\n }\n });\n\n this.released = true;\n const release = this.waitResolve;\n this.waitResolve = null;\n this.waitPromise = null;\n release?.();\n\n try {\n return await this.turnPromise;\n } finally {\n if (timeoutId) clearTimeout(timeoutId);\n if (signal && onAbort) signal.removeEventListener(\"abort\", onAbort);\n this.turnPromise = null;\n this.turnResolve = null;\n this.turnReject = null;\n }\n }\n\n /** Platform finished one action cycle (success or second failure). */\n completeTurn(outcome: TurnOutcome): void {\n const resolve = this.turnResolve;\n if (!resolve) return;\n this.turnResolve = null;\n this.turnReject = null;\n resolve(outcome);\n }\n\n /** Fail an in-flight turn, for example when the connection cannot be resumed. */\n failTurn(error: Error): void {\n this.rejectTurn(error);\n }\n\n reset(): void {\n this.waitResolve?.();\n this.completeTurn({ ok: false, error: \"session stopped\" });\n this.waitResolve = null;\n this.waitPromise = null;\n this.released = false;\n }\n\n private rejectTurn(error: Error): void {\n const reject = this.turnReject;\n if (!reject) return;\n this.turnResolve = null;\n this.turnReject = null;\n reject(error);\n }\n}\n"],"mappings":"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","names":["import_node_crypto","Database","WebSocket","resolve","resolve"]}
package/dist/index.d.cts CHANGED
@@ -1,5 +1,5 @@
1
- import { A as AgentServerOptions, S as StartOptions, a as AgentHandle, E as EventListener } from './types-B4iGtwwk.cjs';
2
- export { b as AgentEvent, L as Logger, T as TurnOptions, c as TurnResult } from './types-B4iGtwwk.cjs';
1
+ import { A as AgentServerOptions, S as StartOptions, a as AgentHandle, E as EventListener } from './types-D0p6GrVs.cjs';
2
+ export { b as AgentEvent, L as Logger, T as TurnOptions, c as TurnResult } from './types-D0p6GrVs.cjs';
3
3
  import { AttemptRecord } from './protocol.cjs';
4
4
  export { TokenUsage } from './protocol.cjs';
5
5
  import { ZodRawShape } from 'zod';
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- import { A as AgentServerOptions, S as StartOptions, a as AgentHandle, E as EventListener } from './types-BgUxWDKm.js';
2
- export { b as AgentEvent, L as Logger, T as TurnOptions, c as TurnResult } from './types-BgUxWDKm.js';
1
+ import { A as AgentServerOptions, S as StartOptions, a as AgentHandle, E as EventListener } from './types-DXM_HZHu.js';
2
+ export { b as AgentEvent, L as Logger, T as TurnOptions, c as TurnResult } from './types-DXM_HZHu.js';
3
3
  import { AttemptRecord } from './protocol.js';
4
4
  export { TokenUsage } from './protocol.js';
5
5
  import { ZodRawShape } from 'zod';
package/dist/index.js CHANGED
@@ -117,7 +117,7 @@ import WebSocket from "ws";
117
117
 
118
118
  // src/protocol.ts
119
119
  var PROTOCOL_VERSION = 1;
120
- var SDK_VERSION = "1.0.0";
120
+ var SDK_VERSION = "1.1.0";
121
121
  var SESSION_RESUME_GRACE_MS = 3e4;
122
122
  var DEFAULT_AGENT_INSTRUCTIONS = [
123
123
  "You are a remote game agent. Tools are provided by the game.",
@@ -733,7 +733,7 @@ var TurnGate = class {
733
733
 
734
734
  // src/agent-server.ts
735
735
  var DEFAULT_TURN_TIMEOUT_MS = 6e4;
736
- var DEFAULT_PLATFORM_URL = "ws://127.0.0.1:8787";
736
+ var PLATFORM_URL = "wss://api.whitesandsint.com";
737
737
  var AgentServer = class {
738
738
  options;
739
739
  platformKey;
@@ -753,7 +753,7 @@ var AgentServer = class {
753
753
  }
754
754
  this.options = options;
755
755
  this.platformKey = platformKey || "inline";
756
- this.platformUrl = options.platformUrl ?? process.env.WSI_PLATFORM_URL ?? DEFAULT_PLATFORM_URL;
756
+ this.platformUrl = options.platformUrl ?? PLATFORM_URL;
757
757
  this.logger = options.logger;
758
758
  this.inline = options.inline;
759
759
  if (options.onEvent) this.listeners.add(options.onEvent);