@whitesands/agent-player 1.2.0 → 1.3.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 +10 -0
- package/README.md +23 -0
- package/dist/index.cjs +749 -8
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +312 -4
- package/dist/index.d.ts +312 -4
- package/dist/index.js +747 -8
- package/dist/index.js.map +1 -1
- package/dist/protocol.cjs +1 -1
- package/dist/protocol.cjs.map +1 -1
- package/dist/protocol.d.cts +27 -3
- package/dist/protocol.d.ts +27 -3
- package/dist/protocol.js +1 -1
- package/dist/protocol.js.map +1 -1
- package/dist/testing.cjs +1 -1
- package/dist/testing.cjs.map +1 -1
- package/dist/testing.d.cts +2 -2
- package/dist/testing.d.ts +2 -2
- package/dist/testing.js +1 -1
- package/dist/testing.js.map +1 -1
- package/dist/{types-DXqkV7YA.d.ts → types-BcH7_ozx.d.ts} +37 -2
- package/dist/{types-Zi-2YmF2.d.cts → types-gmAkYoQr.d.cts} +37 -2
- package/package.json +4 -3
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../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":["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 requirePlayerId,\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 const playerId = requirePlayerId(options.playerId);\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 this.sessions.set(sessionId, record);\n try {\n if (this.inline) {\n const [serverTransport, clientTransport] = InMemoryTransport.createLinkedPair();\n await server.connect(serverTransport);\n record.transport = serverTransport;\n await this.inline.startSession({\n sessionId,\n sessionToken,\n playerId,\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 const started = this.connection.waitForSessionEvent(sessionId, \"start\");\n try {\n this.connection.send({\n type: \"start_session\",\n sessionId,\n sessionToken,\n playerId,\n name,\n tools: reflected.tools,\n instructions,\n ...(options.goal ? { goal: options.goal } : {}),\n });\n await started;\n } catch (error) {\n const wrapped = error instanceof Error ? error : new Error(String(error));\n this.connection.failSessionEvent(sessionId, \"start\", wrapped);\n await started.catch(() => undefined);\n throw wrapped;\n }\n }\n } catch (error) {\n await this.stopSession(sessionId);\n throw error;\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 if (envelope.sessionId) {\n this.connection?.failSessionEvent(envelope.sessionId, \"start\", new Error(envelope.message));\n }\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 /** Reject a start, stop, or resume wait. No-op when nothing is waiting. */\n failSessionEvent(sessionId: string, kind: \"start\" | \"stop\" | \"resume\", error: Error): void {\n const key = `session:${sessionId}:${kind}`;\n const waiter = this.pending.get(key);\n if (!waiter) return;\n this.pending.delete(key);\n waiter.reject(error);\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.2.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 /** Character id. One platform key can start every character in that game. */\n playerId: 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\nconst PLAYER_ID = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;\n\n/** Trim and check the character id `start_session` must send. */\nexport function requirePlayerId(value: string | undefined): string {\n const id = value?.trim() ?? \"\";\n if (id.length === 0) {\n throw new Error(\"playerId is required. Copy the character ID from the web app\");\n }\n if (!PLAYER_ID.test(id)) {\n throw new Error(`playerId \"${id}\" is not a character ID. Copy the ID from the character in the web app`);\n }\n return id;\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\ntype DynamicCallback = (args: Record<string, unknown>) => unknown | Promise<unknown>;\n\ntype DynamicBinding = {\n name: string;\n description: string;\n args?: ZodRawShape;\n callback: DynamicCallback;\n};\n\nconst dynamicTools = new WeakMap<object, Map<string, DynamicBinding>>();\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 rejectDynamicName(name: string): void {\n if (name.length === 0 || name === \"wait\" || name.startsWith(\"_\")) {\n throw new Error(`cannot publish action \"${name}\"`);\n }\n}\n\nfunction dynamicBindings(player: object): Map<string, DynamicBinding> {\n return dynamicTools.get(player) ?? new Map();\n}\n\n/**\n * Register one tool from data. `see` is allowed. `wait`, an empty name, a name\n * starting with `_`, and a missing callback are not. An empty description\n * becomes `Action: {name}`. The same name replaces the previous tool.\n * Arguments are checked the same way as a declared method before the callback runs.\n */\nexport function bindDynamic(\n player: object,\n name: string,\n description: string,\n args: ZodRawShape | undefined,\n callback?: DynamicCallback,\n): void {\n rejectDynamicName(name);\n if (typeof callback !== \"function\") {\n throw new Error(`cannot publish action \"${name}\"`);\n }\n const shape = args && Object.keys(args).length > 0 ? { ...args } : undefined;\n let tools = dynamicTools.get(player);\n if (!tools) {\n tools = new Map();\n dynamicTools.set(player, tools);\n }\n tools.set(name, {\n name,\n description: description.length > 0 ? description : `Action: ${name}`,\n ...(shape ? { args: shape } : {}),\n callback,\n });\n}\n\nfunction buildDynamicTool(binding: DynamicBinding): PlayerTool {\n const shape = binding.args;\n const paramNames = shape ? Object.keys(shape) : [];\n const argsSchema = shape ? z.object(shape) : undefined;\n const inputSchema: JsonSchema = argsSchema\n ? toJsonSchema(argsSchema)\n : { type: \"object\", properties: {} };\n\n return {\n name: binding.name,\n description: binding.description,\n paramNames,\n ...(argsSchema ? { argsSchema } : {}),\n descriptor: { name: binding.name, description: binding.description, inputSchema },\n async invoke(args: Record<string, unknown>) {\n let parsed: Record<string, unknown> = {};\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 return await Promise.resolve(binding.callback(parsed));\n },\n };\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), from a method or `bindDynamic`.\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 * - `bindDynamic` adds or replaces a tool when the action is data rather than a method.\n */\nexport function reflectPlayer(instance: object): ReflectedPlayer {\n const names = collectMethodNames(instance);\n const dynamic = dynamicBindings(instance);\n if (!names.includes(\"see\") && !dynamic.has(\"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 (name === \"see\" || (!names.includes(name) && !dynamic.has(name))) {\n throw new Error(`Declared action \"${name}\" is not a public method on ${className}`);\n }\n }\n\n const dynamicSee = dynamic.get(\"see\");\n const see = dynamicSee ? buildDynamicTool(dynamicSee) : buildTool(instance, \"see\", SEE_DESCRIPTION);\n const actions: PlayerTool[] = [];\n for (const name of names) {\n if (name === \"see\" || dynamic.has(name)) continue;\n const spec = declared[name];\n const description = spec?.description ?? `Action: ${name}`;\n actions.push(buildTool(instance, name, description, spec));\n }\n for (const [name, binding] of dynamic) {\n if (name === \"see\") continue;\n actions.push(buildDynamicTool(binding));\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":["randomUUID","resolve","resolve","randomUUID"]}
|
|
1
|
+
{"version":3,"sources":["../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","../src/world.ts"],"sourcesContent":["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 requirePlayerId,\n type Envelope,\n type Relationship,\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 memory: boolean;\n relationships: Map<string, Relationship>;\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 const playerId = requirePlayerId(options.playerId);\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 = options?.memory ? null : 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 = [\n options?.ownInstructions ? undefined : this.options.instructions ?? DEFAULT_AGENT_INSTRUCTIONS,\n options?.instructions,\n ]\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 memory: options?.memory === true,\n relationships: new Map(),\n };\n\n const onTurnResult = (result: TurnReport) => {\n gate.completeTurn(result);\n };\n const onEvent = (event: AgentEvent) => this.emit(event);\n\n this.sessions.set(sessionId, record);\n try {\n if (this.inline) {\n const [serverTransport, clientTransport] = InMemoryTransport.createLinkedPair();\n await server.connect(serverTransport);\n record.transport = serverTransport;\n await this.inline.startSession({\n sessionId,\n sessionToken,\n playerId,\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 const started = this.connection.waitForSessionEvent(sessionId, \"start\");\n try {\n this.connection.send({\n type: \"start_session\",\n sessionId,\n sessionToken,\n playerId,\n name,\n tools: reflected.tools,\n instructions,\n ...(options.goal ? { goal: options.goal } : {}),\n ...(options.memory ? { memory: true } : {}),\n ...(options.maxActions ? { maxActions: options.maxActions } : {}),\n ...(options.subgoals === false ? { subgoals: false } : {}),\n });\n const ack = await started;\n if (ack.type === \"session_started\") {\n for (const relationship of ack.relationships ?? []) {\n record.relationships.set(relationship.about.toLowerCase(), relationship);\n }\n }\n } catch (error) {\n const wrapped = error instanceof Error ? error : new Error(String(error));\n this.connection.failSessionEvent(sessionId, \"start\", wrapped);\n await started.catch(() => undefined);\n throw wrapped;\n }\n }\n } catch (error) {\n await this.stopSession(sessionId);\n throw error;\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 observe: (text: string, about?: string) => {\n if (!record.memory || !text || !this.connection || !this.sessions.has(sessionId)) return;\n try {\n this.connection.send({ type: \"observe\", sessionId, text, ...(about ? { about } : {}) });\n } catch {\n // The event is lost while the connection is down.\n }\n },\n relationships: () => Object.fromEntries(record.relationships),\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 ...(outcome.steps ? { steps: outcome.steps } : {}),\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 if (envelope.event === \"relationship\" || envelope.event === \"memory\") {\n if (envelope.error) return;\n const args = envelope.args ?? {};\n const about = typeof args.about === \"string\" ? args.about : \"\";\n if (envelope.event === \"memory\") {\n this.emit({ type: \"memory\", sessionId: envelope.sessionId, about, note: String(args.note ?? \"\") });\n return;\n }\n const relationship: Relationship = {\n about,\n affinity: Number(args.affinity ?? 0),\n label: String(args.label ?? \"stranger\"),\n note: String(args.because ?? \"\"),\n };\n this.sessions.get(envelope.sessionId)?.relationships.set(about.toLowerCase(), relationship);\n this.emit({\n type: \"relationship\",\n sessionId: envelope.sessionId,\n about,\n affinity: relationship.affinity,\n label: relationship.label,\n change: Number(args.change ?? 0),\n because: relationship.note ?? \"\",\n });\n return;\n }\n if (envelope.event !== \"turnFailed\") return;\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 if (envelope.sessionId) {\n this.connection?.failSessionEvent(envelope.sessionId, \"start\", new Error(envelope.message));\n }\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 case \"observe\":\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 /** Reject a start, stop, or resume wait. No-op when nothing is waiting. */\n failSessionEvent(sessionId: string, kind: \"start\" | \"stop\" | \"resume\", error: Error): void {\n const key = `session:${sessionId}:${kind}`;\n const waiter = this.pending.get(key);\n if (!waiter) return;\n this.pending.delete(key);\n waiter.reject(error);\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 // A start the platform refuses (unknown character ID, for one) fails at\n // once with the platform's reason instead of timing out.\n if (envelope.type === \"error\" && envelope.sessionId) {\n const key = `session:${envelope.sessionId}:start`;\n const waiter = this.pending.get(key);\n if (waiter) {\n this.pending.delete(key);\n waiter.reject(new Error(envelope.message));\n }\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 // If the send below throws, nothing awaits this promise, and its\n // timeout must not end the process as an unhandled rejection.\n resumed.catch(() => {});\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.3.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 /** Every action played, when the turn played more than one. */\n steps?: StepRecord[];\n};\n\nexport type StepRecord = {\n action: string;\n args: Record<string, unknown>;\n result?: unknown;\n error?: string;\n};\n\n/** How a character feels about one person. affinity runs from -100 to 100. */\nexport type Relationship = {\n about: string;\n affinity: number;\n label: string;\n note?: string;\n};\n\nexport type SessionEventName = \"action\" | \"retry\" | \"turnFailed\" | \"subgoal\" | \"memory\" | \"relationship\";\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 /** Character id. One platform key can start every character in that game. */\n playerId: string;\n tools: ToolDescriptor[];\n instructions: string;\n goal?: string;\n name?: string;\n memory?: boolean;\n maxActions?: number;\n subgoals?: boolean;\n }\n | {\n type: \"session_started\";\n sessionId: string;\n relationships?: Relationship[];\n }\n | {\n type: \"observe\";\n sessionId: string;\n text: string;\n about?: 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\nconst PLAYER_ID = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;\n\n/** Trim and check the character id `start_session` must send. */\nexport function requirePlayerId(value: string | undefined): string {\n const id = value?.trim() ?? \"\";\n if (id.length === 0) {\n throw new Error(\"playerId is required. Copy the character ID from the web app\");\n }\n if (!PLAYER_ID.test(id)) {\n throw new Error(`playerId \"${id}\" is not a character ID. Copy the ID from the character in the web app`);\n }\n return id;\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\ntype DynamicCallback = (args: Record<string, unknown>) => unknown | Promise<unknown>;\n\ntype DynamicBinding = {\n name: string;\n description: string;\n args?: ZodRawShape;\n callback: DynamicCallback;\n};\n\nconst dynamicTools = new WeakMap<object, Map<string, DynamicBinding>>();\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 rejectDynamicName(name: string): void {\n if (name.length === 0 || name === \"wait\" || name.startsWith(\"_\")) {\n throw new Error(`cannot publish action \"${name}\"`);\n }\n}\n\nfunction dynamicBindings(player: object): Map<string, DynamicBinding> {\n return dynamicTools.get(player) ?? new Map();\n}\n\n/**\n * Register one tool from data. `see` is allowed. `wait`, an empty name, a name\n * starting with `_`, and a missing callback are not. An empty description\n * becomes `Action: {name}`. The same name replaces the previous tool.\n * Arguments are checked the same way as a declared method before the callback runs.\n */\nexport function bindDynamic(\n player: object,\n name: string,\n description: string,\n args: ZodRawShape | undefined,\n callback?: DynamicCallback,\n): void {\n rejectDynamicName(name);\n if (typeof callback !== \"function\") {\n throw new Error(`cannot publish action \"${name}\"`);\n }\n const shape = args && Object.keys(args).length > 0 ? { ...args } : undefined;\n let tools = dynamicTools.get(player);\n if (!tools) {\n tools = new Map();\n dynamicTools.set(player, tools);\n }\n tools.set(name, {\n name,\n description: description.length > 0 ? description : `Action: ${name}`,\n ...(shape ? { args: shape } : {}),\n callback,\n });\n}\n\nfunction buildDynamicTool(binding: DynamicBinding): PlayerTool {\n const shape = binding.args;\n const paramNames = shape ? Object.keys(shape) : [];\n const argsSchema = shape ? z.object(shape) : undefined;\n const inputSchema: JsonSchema = argsSchema\n ? toJsonSchema(argsSchema)\n : { type: \"object\", properties: {} };\n\n return {\n name: binding.name,\n description: binding.description,\n paramNames,\n ...(argsSchema ? { argsSchema } : {}),\n descriptor: { name: binding.name, description: binding.description, inputSchema },\n async invoke(args: Record<string, unknown>) {\n let parsed: Record<string, unknown> = {};\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 return await Promise.resolve(binding.callback(parsed));\n },\n };\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), from a method or `bindDynamic`.\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 * - `bindDynamic` adds or replaces a tool when the action is data rather than a method.\n */\nexport function reflectPlayer(instance: object): ReflectedPlayer {\n const names = collectMethodNames(instance);\n const dynamic = dynamicBindings(instance);\n if (!names.includes(\"see\") && !dynamic.has(\"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 (name === \"see\" || (!names.includes(name) && !dynamic.has(name))) {\n throw new Error(`Declared action \"${name}\" is not a public method on ${className}`);\n }\n }\n\n const dynamicSee = dynamic.get(\"see\");\n const see = dynamicSee ? buildDynamicTool(dynamicSee) : buildTool(instance, \"see\", SEE_DESCRIPTION);\n const actions: PlayerTool[] = [];\n for (const name of names) {\n if (name === \"see\" || dynamic.has(name)) continue;\n const spec = declared[name];\n const description = spec?.description ?? `Action: ${name}`;\n actions.push(buildTool(instance, name, description, spec));\n }\n for (const [name, binding] of dynamic) {\n if (name === \"see\") continue;\n actions.push(buildDynamicTool(binding));\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","/**\n * World: a living world on top of the agent player.\n *\n * A game describes its world once: places, things characters can use, and the\n * characters themselves. World turns that into what each character sees and\n * can do, decides when a character needs a turn, and carries speech and\n * events between characters and human players. The game does not write a view\n * or an action per character. Who a character is comes from its story in the\n * White Sands web app.\n *\n * This is the TypeScript port of WSI.World in the Luau SDK. It uses no engine\n * API: a body is any object with getPosition, moveTo, stop and say.\n */\nimport { z } from \"zod\";\nimport type { AgentServer } from \"./agent-server.js\";\nimport type { AgentMetadata } from \"./reflect.js\";\nimport type { AgentHandle, TurnResult } from \"./types.js\";\n\nexport type Position = { x: number; y: number; z?: number };\n\nexport type Body = {\n getPosition(): Position;\n /** Walk to a position. Resolves true on arrival, false if interrupted or unreachable. */\n moveTo(goal: Position): Promise<boolean>;\n stop(): void;\n /** Show a spoken line. May return the text as shown, when the game filters it. */\n say(text: string, towards?: Position): string | void;\n emote?(name: string): void;\n face?(position: Position): void;\n setStatus?(status: string | null): void;\n emotes?: string[];\n};\n\nexport type Activity = {\n description: string;\n /** How long it takes. Default 5. */\n seconds?: number;\n /** Shown while it runs, such as \"making coffee\". Defaults to the activity name. */\n status?: string;\n /** Change to the character's needs when it finishes, such as { food: 40 }. */\n effects?: Record<string, number>;\n /** An item the character carries afterwards. */\n gives?: string;\n /** An item the character must carry. It is used up. */\n needs?: string;\n /** Emote played while it runs. */\n emote?: string;\n};\n\nexport type WorldOptions = {\n name: string;\n /** One or two sentences about the world, for every character. */\n about?: string;\n /** Extra rules of the game, in plain words. */\n rules?: string;\n /** The time of day as text, such as \"Tuesday 14:30, afternoon\". */\n clock?: () => string;\n /** How far speech carries, and how far a character sees. Defaults 35 and 80. */\n hearing?: number;\n sight?: number;\n /** A character with nothing to react to gets a turn about this often, in seconds. Default 45. */\n idleSeconds?: number;\n /** Idle turns are this many times rarer when no human is within activeRadius. Defaults 3 and 120. */\n farSlowdown?: number;\n activeRadius?: number;\n /** A character no human can see waits this long before a turn for something it did itself. Default 20. */\n farDelay?: number;\n /** A human who comes this close is noticed. Default 12. 0 turns it off. */\n greetDistance?: number;\n /** Cap on turns per minute for the whole world. Default 30. */\n turnsPerMinute?: number;\n /** Actions per turn, 1 to 4. Default 3. */\n maxActions?: number;\n /** Needs every character has. 100 is satisfied, 0 is desperate. perMinute is how fast it falls. */\n needs?: Record<string, { perMinute: number; start?: number }>;\n /** Each character replies at most chatReplies times per chatPause seconds to another character. Defaults 2 and 90. */\n chatReplies?: number;\n chatPause?: number;\n /** Keep memory and relationships on the platform. Default true. */\n memory?: boolean;\n /** Receives warnings. */\n warn?: (message: string) => void;\n};\n\nexport type WorldEvent =\n | { type: \"speech\"; speaker: string; text: string; to?: string }\n | { type: \"status\"; character: string; status: string | null }\n | { type: \"relationship\"; character: string; about: string; affinity: number; label: string; change: number; because: string }\n | { type: \"memory\"; character: string; about: string; note: string }\n | { type: \"action\"; character: string; action: string; args: Record<string, unknown> }\n | { type: \"thinking\"; character: string; on: boolean }\n | { type: \"give\"; from: string; to: string; item: string }\n | { type: \"emote\"; character: string; emote: string }\n | { type: \"turn\"; character: string; ok: boolean; result?: TurnResult; error?: string };\n\ntype Place = { name: string; description: string; position: Position; radius: number };\ntype Thing = { id: string; name: string; place?: string; position: Position; activities: Record<string, Activity>; usedBy: string | null };\ntype Person = { name: string; getPosition: () => Position | null; carrying: string[] };\ntype NoticeOptions = { about?: string; turn?: boolean; urgent?: boolean };\n\nconst DEFAULT_EMOTES = [\"wave\", \"laugh\", \"cheer\", \"dance\", \"point\", \"shrug\"];\n\nfunction distance(a: Position, b: Position): number {\n return Math.hypot(a.x - b.x, a.y - b.y, (a.z ?? 0) - (b.z ?? 0));\n}\n\nfunction clip(text: string, limit: number): string {\n return text.length <= limit ? text : `${text.slice(0, limit - 3)}...`;\n}\n\nconst now = () => performance.now() / 1000;\nconst sleep = (seconds: number) => new Promise<void>((resolve) => setTimeout(resolve, seconds * 1000));\n\n/** The tools one character serves to the platform. Method names are the tool names. */\nclass CharacterTools {\n static agent: AgentMetadata = {\n actions: {\n say: {\n description: \"Say one or two short sentences out loud. Set to when you are talking to one person.\",\n args: {\n text: z.string().describe(\"What you say, in your own voice.\"),\n to: z.string().describe(\"Name of the person you are talking to. Empty to talk to everyone near you.\"),\n },\n },\n go_to: {\n description: \"Walk to a place. You are told when you arrive.\",\n args: { place: z.string().describe(\"One of the places you know.\") },\n },\n approach: {\n description: \"Walk up to someone you can see, to talk or do something together.\",\n args: { person: z.string() },\n },\n use: {\n description: \"Do an activity with a thing listed in things_here. You walk to it first. You are told when you finish.\",\n args: { thing: z.string(), activity: z.string() },\n },\n give: {\n description: \"Give something you are carrying to someone next to you.\",\n args: { item: z.string(), to: z.string() },\n },\n emote: {\n description: \"Show a feeling with your body.\",\n args: { emote: z.string().describe(\"wave, laugh, cheer, dance, point or shrug.\") },\n },\n idle: { description: \"Do nothing new for now and carry on as you are.\" },\n },\n };\n\n constructor(private readonly character: Character) {}\n\n see() {\n return this.character.view();\n }\n say(text: string, to: string) {\n return this.character.doSay(text, to);\n }\n go_to(place: string) {\n return this.character.doGoTo(place);\n }\n approach(person: string) {\n return this.character.doApproach(person);\n }\n use(thing: string, activity: string) {\n return this.character.doUse(thing, activity);\n }\n give(item: string, to: string) {\n return this.character.doGive(item, to);\n }\n emote(emote: string) {\n return this.character.doEmote(emote);\n }\n idle() {\n return { ok: true };\n }\n}\n\nexport class Character {\n readonly kind = \"resident\";\n status: string | null = null;\n carrying: string[];\n needs: Record<string, number> = {};\n turns = 0;\n tokens = 0;\n agent!: AgentHandle;\n /** @internal */ inbox: string[] = [];\n /** @internal */ wake: number | null = now() + 2 + Math.random() * 6;\n /** @internal */ busy = false;\n /** @internal */ greeted = new Map<string, number>();\n /** @internal */ needWarned = new Set<string>();\n private task = 0;\n private using: Thing | null = null;\n private chat = { count: 0, resetAt: 0 };\n\n constructor(\n readonly world: World,\n readonly name: string,\n readonly body: Body,\n readonly home: string | undefined,\n carrying: string[],\n ) {\n this.carrying = [...carrying];\n }\n\n position(): Position {\n return this.body.getPosition();\n }\n\n place(): string | null {\n return this.world.placeAt(this.position());\n }\n\n setStatus(status: string | null): void {\n this.status = status;\n this.body.setStatus?.(status);\n this.world.emit({ type: \"status\", character: this.name, status });\n }\n\n /**\n * Tell this character something happened. It goes into its memory and its\n * next view. turn asks for a turn; urgent asks for one now.\n */\n notice(text: string, options: NoticeOptions = {}): void {\n this.inbox.push(text);\n while (this.inbox.length > 12) this.inbox.shift();\n this.agent?.observe(text, options.about);\n if (options.urgent) {\n this.wakeIn(0.2);\n } else if (options.turn) {\n // Nobody is watching a character far from every human, so its\n // follow-up turns (arrived, finished an activity) can wait.\n const world = this.world;\n const far = world.farDelay > 0 && !world.humanNear(this.position(), world.activeRadius);\n this.wakeIn(far ? world.farDelay : 2.5);\n }\n }\n\n /** @internal */\n wakeIn(seconds: number): void {\n const at = now() + seconds;\n if (this.wake === null || at < this.wake) this.wake = at;\n }\n\n /** How this character feels about someone, from the platform. */\n feelingFor(name: string): { affinity: number; label: string; note?: string } {\n const relationship = this.agent?.relationships()[name.toLowerCase()];\n return relationship\n ? { affinity: relationship.affinity, label: relationship.label, ...(relationship.note ? { note: relationship.note } : {}) }\n : { affinity: 0, label: \"stranger\" };\n }\n\n /** @internal Returns true when another character's line should get a reply. */\n mayReplyToCharacter(): boolean {\n if (now() > this.chat.resetAt) {\n this.chat.count = 0;\n this.chat.resetAt = now() + this.world.chatPause;\n }\n this.chat.count += 1;\n return this.chat.count <= this.world.chatReplies;\n }\n\n /** @internal */\n view(): Record<string, unknown> {\n const world = this.world;\n const here = this.position();\n const place = world.placeAt(here);\n const why = this.inbox.length > 0 ? this.inbox : [\"Nothing new has happened. Carry on with your day.\"];\n this.inbox = [];\n\n const nearby: Record<string, unknown>[] = [];\n const add = (name: string, who: string, at: Position | null, doing: string | null) => {\n if (!at) return;\n const d = distance(at, here);\n if (d > world.sight) return;\n nearby.push({\n name,\n who,\n steps_away: Math.round(d),\n can_hear_you: d <= world.hearing,\n ...(doing ? { doing } : {}),\n you_feel: this.feelingFor(name).label,\n });\n };\n for (const other of world.characters.values()) {\n if (other !== this) add(other.name, \"resident\", other.position(), other.status);\n }\n for (const person of world.people.values()) add(person.name, \"player\", person.getPosition(), null);\n nearby.sort((a, b) => (a.steps_away as number) - (b.steps_away as number));\n\n const things: Record<string, unknown>[] = [];\n for (const thing of world.things.values()) {\n if (things.length >= 12) break;\n if (!((place && thing.place === place) || distance(thing.position, here) <= 30)) continue;\n const activities = Object.entries(thing.activities)\n .map(([name, activity]) => `${name}: ${activity.description}${activity.needs ? ` (needs ${activity.needs})` : \"\"}`)\n .sort();\n things.push({\n thing: thing.id,\n activities,\n ...(thing.usedBy && thing.usedBy !== this.name ? { in_use_by: thing.usedBy } : {}),\n });\n }\n\n const needs = Object.fromEntries(Object.entries(this.needs).map(([need, value]) => [need, Math.floor(value)]));\n return {\n ...(world.clock ? { time: world.clock() } : {}),\n why_you_are_acting_now: why,\n you: {\n at: place ?? \"outdoors, between places\",\n doing: this.status ?? \"nothing in particular\",\n ...(Object.keys(needs).length > 0 ? { needs } : {}),\n ...(this.carrying.length > 0 ? { carrying: this.carrying } : {}),\n },\n people_nearby: nearby.slice(0, 8),\n things_here: things,\n };\n }\n\n // Stop whatever the body is doing so a new movement can start.\n private interrupt(): number {\n this.task += 1;\n if (this.using) {\n this.using.usedBy = null;\n this.using = null;\n }\n this.body.stop();\n return this.task;\n }\n\n private async walk(token: number, goal: Position, status: string): Promise<boolean> {\n this.setStatus(status);\n const reached = await this.body.moveTo(goal);\n if (this.task !== token) return false;\n this.setStatus(null);\n return reached;\n }\n\n /** @internal */\n doSay(rawText: string, to: string) {\n let text = clip(String(rawText ?? \"\").trim(), 240);\n if (!text) throw new Error(\"say needs some text\");\n const world = this.world;\n const target = world.resolve(to);\n const towards = target ? world.positionOf(target) : null;\n const shown = this.body.say(text, towards ?? undefined);\n if (typeof shown === \"string\" && shown) text = shown;\n const heard = world.speech(this.name, text, target);\n return heard === 0 ? { said: text, note: \"Nobody was close enough to hear you.\" } : { said: text };\n }\n\n /** @internal */\n doGoTo(placeName: string) {\n const place = this.world.places.get(placeName);\n if (!place) throw new Error(`no such place: ${placeName}. Places: ${[...this.world.places.keys()].join(\", \")}`);\n if (this.place() === placeName && !this.status) throw new Error(`you are already at ${placeName}`);\n const token = this.interrupt();\n void this.walk(token, place.position, `walking to ${placeName}`).then((reached) => {\n if (reached) this.notice(`You arrived at ${placeName}.`, { turn: true });\n else if (this.task === token) this.notice(`You could not get to ${placeName}.`, { turn: true });\n });\n return { walking_to: placeName };\n }\n\n /** @internal */\n doApproach(person: string) {\n const world = this.world;\n const name = world.resolve(person);\n const at = name ? world.positionOf(name) : null;\n if (!name || !at || name === this.name) throw new Error(`you cannot see anyone called ${person}`);\n const gap = distance(at, this.position());\n if (gap > world.sight) throw new Error(`${name} is too far away to see`);\n if (gap <= 7) return { note: `You are already next to ${name}.` };\n const token = this.interrupt();\n const here = this.position();\n const goal = { x: at.x + ((here.x - at.x) / gap) * 4, y: at.y + ((here.y - at.y) / gap) * 4 };\n void this.walk(token, goal, `walking over to ${name}`).then((reached) => {\n if (reached) this.notice(`You walked up to ${name}.`, { turn: true });\n });\n return { walking_to: name };\n }\n\n /** @internal */\n doUse(thingId: string, activityName: string) {\n const thing = this.world.things.get(thingId);\n if (!thing) throw new Error(`there is no thing called ${thingId}`);\n const activity = thing.activities[activityName];\n if (!activity) {\n throw new Error(`${thingId} has no activity ${activityName}. It has: ${Object.keys(thing.activities).sort().join(\", \")}`);\n }\n if (thing.usedBy && thing.usedBy !== this.name) throw new Error(`${thing.usedBy} is using ${thingId} right now`);\n if (activity.needs && !this.carrying.includes(activity.needs)) throw new Error(`you need ${activity.needs} to do that`);\n const token = this.interrupt();\n const seconds = activity.seconds ?? 5;\n thing.usedBy = this.name;\n this.using = thing;\n void (async () => {\n if (distance(thing.position, this.position()) > 6 && !(await this.walk(token, thing.position, `walking to ${thing.name}`))) {\n if (this.task === token) {\n thing.usedBy = null;\n this.using = null;\n this.notice(`You could not reach ${thingId}.`, { turn: true });\n }\n return;\n }\n this.body.face?.(thing.position);\n this.setStatus(activity.status ?? activityName.replaceAll(\"_\", \" \"));\n if (activity.emote) this.body.emote?.(activity.emote);\n await sleep(seconds);\n if (this.task !== token) return;\n thing.usedBy = null;\n this.using = null;\n this.setStatus(null);\n const outcome: string[] = [];\n if (activity.needs) {\n const index = this.carrying.indexOf(activity.needs);\n if (index >= 0) this.carrying.splice(index, 1);\n }\n for (const [need, change] of Object.entries(activity.effects ?? {})) {\n const current = this.needs[need];\n if (current === undefined) continue;\n this.needs[need] = Math.min(100, Math.max(0, current + change));\n outcome.push(`${need} is now ${Math.floor(this.needs[need])}`);\n }\n if (activity.gives) {\n this.carrying.push(activity.gives);\n outcome.push(`you now carry ${activity.gives}`);\n }\n const summary = outcome.length > 0 ? ` (${outcome.join(\", \")})` : \"\";\n this.notice(`You finished: ${activityName.replaceAll(\"_\", \" \")} at ${thing.name}${summary}.`, { turn: true });\n })();\n return { started: activityName, takes_seconds: seconds };\n }\n\n /** @internal */\n doGive(item: string, to: string) {\n const world = this.world;\n const index = this.carrying.indexOf(item);\n if (index < 0) throw new Error(`you are not carrying ${item}`);\n const name = world.resolve(to);\n const at = name ? world.positionOf(name) : null;\n if (!name || !at) throw new Error(`you cannot see anyone called ${to}`);\n if (distance(at, this.position()) > 12) throw new Error(`${name} is too far away. Use approach first.`);\n this.carrying.splice(index, 1);\n const other = world.characters.get(name);\n if (other) {\n other.carrying.push(item);\n other.notice(`${this.name} gave you ${item}.`, { about: this.name, urgent: true });\n } else {\n world.people.get(name)?.carrying.push(item);\n }\n world.emit({ type: \"give\", from: this.name, to: name, item });\n return { gave: item, to: name };\n }\n\n /** @internal */\n doEmote(name: string) {\n const emotes = this.body.emotes ?? DEFAULT_EMOTES;\n if (!emotes.includes(name)) throw new Error(`no such emote. Choose one of: ${emotes.join(\", \")}`);\n this.body.emote?.(name);\n this.world.emit({ type: \"emote\", character: this.name, emote: name });\n return { did: name };\n }\n}\n\nexport class World {\n readonly name: string;\n readonly about: string;\n readonly rules: string;\n readonly clock: (() => string) | undefined;\n readonly hearing: number;\n readonly sight: number;\n readonly idleSeconds: number;\n readonly farSlowdown: number;\n readonly activeRadius: number;\n readonly farDelay: number;\n readonly greetDistance: number;\n readonly turnsPerMinute: number;\n readonly maxActions: number;\n readonly chatReplies: number;\n readonly chatPause: number;\n readonly places = new Map<string, Place>();\n readonly things = new Map<string, Thing>();\n readonly characters = new Map<string, Character>();\n readonly people = new Map<string, Person>();\n turnsUsed = 0;\n private readonly needDefs: Record<string, { perMinute: number; start?: number }>;\n private readonly memory: boolean;\n private readonly warn: (message: string) => void;\n private readonly listeners = new Set<(event: WorldEvent) => void>();\n private timer: ReturnType<typeof setInterval> | null = null;\n private budget = 0;\n private budgetAt = now();\n private lastTick = now();\n\n constructor(private readonly server: AgentServer, options: WorldOptions) {\n this.name = options.name;\n this.about = options.about ?? \"\";\n this.rules = options.rules ?? \"\";\n this.clock = options.clock;\n this.hearing = options.hearing ?? 35;\n this.sight = options.sight ?? 80;\n this.idleSeconds = options.idleSeconds ?? 45;\n this.farSlowdown = options.farSlowdown ?? 3;\n this.activeRadius = options.activeRadius ?? 120;\n this.farDelay = options.farDelay ?? 20;\n this.greetDistance = options.greetDistance ?? 12;\n this.turnsPerMinute = options.turnsPerMinute ?? 30;\n this.maxActions = options.maxActions ?? 3;\n this.chatReplies = options.chatReplies ?? 2;\n this.chatPause = options.chatPause ?? 90;\n this.needDefs = options.needs ?? {};\n this.memory = options.memory !== false;\n this.warn = options.warn ?? (() => undefined);\n }\n\n /** Listen for world events. Returns a function that unsubscribes. */\n on(listener: (event: WorldEvent) => void): () => void {\n this.listeners.add(listener);\n return () => this.listeners.delete(listener);\n }\n\n /** @internal */\n emit(event: WorldEvent): void {\n for (const listener of [...this.listeners]) {\n try {\n listener(event);\n } catch (error) {\n this.warn(`world listener failed: ${error instanceof Error ? error.message : String(error)}`);\n }\n }\n }\n\n addPlace(name: string, place: { description?: string; position: Position; radius?: number }): void {\n if (this.places.has(name)) throw new Error(`place already exists: ${name}`);\n this.places.set(name, { name, description: place.description ?? \"\", position: place.position, radius: place.radius ?? 22 });\n }\n\n addThing(id: string, thing: { name?: string; place?: string; position: Position; activities: Record<string, Activity> }): void {\n if (this.things.has(id)) throw new Error(`thing already exists: ${id}`);\n this.things.set(id, {\n id,\n name: thing.name ?? id.replaceAll(\"_\", \" \"),\n ...(thing.place ? { place: thing.place } : {}),\n position: thing.position,\n activities: thing.activities,\n usedBy: null,\n });\n }\n\n /** Add a human player. getPosition returns null while they have no body. */\n addPerson(person: { name: string; getPosition: () => Position | null }): void {\n this.people.set(person.name, { name: person.name, getPosition: person.getPosition, carrying: [] });\n }\n\n removePerson(name: string): void {\n this.people.delete(name);\n }\n\n placeAt(position: Position): string | null {\n let best: string | null = null;\n let bestDistance = Infinity;\n for (const place of this.places.values()) {\n const d = distance(place.position, position);\n if (d <= place.radius && d < bestDistance) {\n best = place.name;\n bestDistance = d;\n }\n }\n return best;\n }\n\n positionOf(name: string): Position | null {\n return this.characters.get(name)?.position() ?? this.people.get(name)?.getPosition() ?? null;\n }\n\n /** Match a name the model wrote to someone in the world, ignoring case. */\n resolve(name: string | undefined): string | undefined {\n if (!name) return undefined;\n const lower = name.trim().toLowerCase();\n for (const known of [...this.characters.keys(), ...this.people.keys()]) {\n if (known.toLowerCase() === lower) return known;\n }\n return undefined;\n }\n\n /** @internal */\n humanNear(position: Position, range: number): boolean {\n for (const person of this.people.values()) {\n const at = person.getPosition();\n if (at && distance(at, position) <= range) return true;\n }\n return false;\n }\n\n /** The instructions every character gets about this world. */\n guide(home?: string): string {\n const lines = [\n `You are a character who lives in ${this.name}. ${this.about}`,\n \"You are not an assistant. You are a person with your own life, moods, and plans. Stay in character at all times.\",\n \"\",\n \"How you act:\",\n \"- You act only through tools. To speak, call say. Keep a line to one or two short sentences, the way people talk.\",\n \"- Each turn shows why you are acting now, who is near you, and what you can use where you are.\",\n \"- You can speak and then act in the same turn, for example say and then go_to. When you agree to do something, do it in that same turn: say yes, then go_to or use.\",\n \"- go_to, approach and use take time. You are told when they finish. Do not repeat them while they are under way.\",\n \"- use walks you to the thing by itself. To give something to someone who is not next to you, call approach and stop there; give it on your next turn, once you have arrived.\",\n \"- When someone speaks to you, answer them. When nothing needs doing, carry on with your day the way your story says, or call idle.\",\n \"- A chat between neighbours is a few lines, then you both get on with your day. Do not answer a goodbye or a line that needs no answer.\",\n \"- If someone does not answer you, leave them be and get on with your day. Do not keep talking to a person who stays silent.\",\n \"- Do not repeat yourself. Check your recent events before you speak.\",\n \"- People you do not know are strangers. Treat people the way you feel about them.\",\n \"\",\n \"Places:\",\n ];\n for (const place of this.places.values()) {\n lines.push(`- ${place.name}${place.description ? `: ${place.description}` : \"\"}${home === place.name ? \" (your home)\" : \"\"}`);\n }\n if (Object.keys(this.needDefs).length > 0) {\n lines.push(\"\", \"Your needs run from 0 (desperate) to 100 (satisfied) and fall over time. Look after them with the things around you.\");\n }\n if (this.rules) lines.push(\"\", this.rules);\n return lines.join(\"\\n\");\n }\n\n /** Add a character and start its session. id is the character ID from the web app. */\n async addCharacter(def: {\n id: string;\n name: string;\n body: Body;\n home?: string;\n goal?: string;\n instructions?: string;\n carrying?: string[];\n }): Promise<Character> {\n if (this.characters.has(def.name)) throw new Error(`character already exists: ${def.name}`);\n const character = new Character(this, def.name, def.body, def.home, def.carrying ?? []);\n for (const [need, spec] of Object.entries(this.needDefs)) {\n character.needs[need] = spec.start ?? 55 + Math.floor(Math.random() * 36);\n }\n const instructions = [this.guide(def.home), def.instructions].filter(Boolean).join(\"\\n\\n\");\n character.agent = await this.server.start(new CharacterTools(character), {\n name: def.name,\n playerId: def.id,\n instructions,\n ownInstructions: true,\n memory: this.memory,\n maxActions: this.maxActions,\n subgoals: false,\n ...(def.goal ? { goal: def.goal } : {}),\n });\n this.characters.set(def.name, character);\n character.agent.on((event) => {\n if (event.type === \"relationship\") {\n this.emit({\n type: \"relationship\",\n character: character.name,\n about: this.resolve(event.about) ?? event.about,\n affinity: event.affinity,\n label: event.label,\n change: event.change,\n because: event.because,\n });\n } else if (event.type === \"memory\") {\n this.emit({ type: \"memory\", character: character.name, about: event.about, note: event.note });\n } else if (event.type === \"action\") {\n this.emit({ type: \"action\", character: character.name, action: event.action, args: event.args });\n }\n });\n return character;\n }\n\n /** @internal Carry a spoken line to everyone who can hear it. Returns how many heard it. */\n speech(speaker: string, text: string, to: string | undefined): number {\n const from = this.positionOf(speaker);\n if (!from) return 0;\n const speakerIsCharacter = this.characters.has(speaker);\n let heard = 0;\n for (const person of this.people.values()) {\n const at = person.getPosition();\n if (person.name !== speaker && at && distance(at, from) <= this.hearing) heard += 1;\n }\n // A line with no addressee is taken by the closest resident in talking range.\n let closest: string | undefined;\n if (!to) {\n let closestDistance = 16;\n for (const other of this.characters.values()) {\n const d = distance(other.position(), from);\n if (other.name !== speaker && d < closestDistance) {\n closest = other.name;\n closestDistance = d;\n }\n }\n }\n for (const other of this.characters.values()) {\n if (other.name === speaker || distance(other.position(), from) > this.hearing) continue;\n heard += 1;\n const addressed = to === other.name || (!to && closest === other.name);\n const line = addressed\n ? `${speaker} said to you: \"${text}\"`\n : to\n ? `${speaker} said to ${to}: \"${text}\"`\n : `${speaker} said: \"${text}\"`;\n // Two residents talking stop after a few exchanges, so a chat cannot run forever.\n const turn = addressed && (!speakerIsCharacter || other.mayReplyToCharacter());\n if (addressed && !other.status) other.body.face?.(from);\n // A human gets an answer at once; a neighbour waits a breath.\n other.notice(line, { about: speaker, urgent: turn && !speakerIsCharacter, turn });\n }\n this.emit({ type: \"speech\", speaker, text, ...(to ? { to } : {}) });\n return heard;\n }\n\n /** A human player said something. Without to, the closest resident in talking range takes it. */\n say(speaker: string, text: string, to?: string): number {\n const line = clip(text.trim(), 300);\n if (!line || !this.people.has(speaker)) return 0;\n return this.speech(speaker, line, this.resolve(to));\n }\n\n /** Tell one character something happened, in plain words. */\n tell(characterName: string, text: string, options: NoticeOptions = { turn: true }): void {\n this.characters.get(characterName)?.notice(text, options);\n }\n\n /** Tell every character within range of a position that something happened. */\n announce(text: string, position?: Position, range?: number): void {\n for (const character of this.characters.values()) {\n if (!position || distance(character.position(), position) <= (range ?? this.sight)) {\n character.notice(text, { turn: true });\n }\n }\n }\n\n /** A human player hands an item to a character. */\n give(from: string, characterName: string, item: string): boolean {\n const character = this.characters.get(characterName);\n if (!character) return false;\n character.carrying.push(item);\n character.notice(`${from} gave you ${item}.`, { about: from, urgent: true });\n this.emit({ type: \"give\", from, to: characterName, item });\n return true;\n }\n\n private spend(): boolean {\n const at = now();\n this.budget = Math.min(this.turnsPerMinute, this.budget + ((at - this.budgetAt) * this.turnsPerMinute) / 60);\n this.budgetAt = at;\n if (this.budget < 1) return false;\n this.budget -= 1;\n return true;\n }\n\n private idleDelay(character: Character): number {\n const delay = this.idleSeconds * (0.75 + Math.random() * 0.5);\n return this.humanNear(character.position(), this.activeRadius) ? delay : delay * this.farSlowdown;\n }\n\n private runTurn(character: Character): void {\n character.wake = null;\n character.busy = true;\n this.emit({ type: \"thinking\", character: character.name, on: true });\n character.agent\n .turn()\n .then((result) => {\n character.tokens += result.usage.promptTokens + result.usage.completionTokens;\n this.emit({ type: \"turn\", character: character.name, ok: true, result });\n character.wakeIn(character.inbox.length > 0 ? 1 : this.idleDelay(character));\n })\n .catch((error: unknown) => {\n const message = error instanceof Error ? error.message : String(error);\n this.warn(`${character.name} turn failed: ${message}`);\n this.emit({ type: \"turn\", character: character.name, ok: false, error: message });\n character.wakeIn(Math.max(20, this.idleSeconds));\n })\n .finally(() => {\n character.busy = false;\n character.turns += 1;\n this.turnsUsed += 1;\n this.emit({ type: \"thinking\", character: character.name, on: false });\n });\n }\n\n private tick(): void {\n const at = now();\n const dt = at - this.lastTick;\n this.lastTick = at;\n for (const character of this.characters.values()) {\n // Needs fall over time. A need that gets low is worth a turn.\n for (const [need, spec] of Object.entries(this.needDefs)) {\n const value = Math.max(0, (character.needs[need] ?? 0) - (spec.perMinute * dt) / 60);\n character.needs[need] = value;\n if (value < 25 && !character.needWarned.has(need)) {\n character.needWarned.add(need);\n character.notice(`Your ${need} is getting low (${Math.floor(value)}).`, { turn: true });\n } else if (value > 50) {\n character.needWarned.delete(need);\n }\n }\n // Notice a human who walks up.\n if (this.greetDistance > 0) {\n const here = character.position();\n for (const person of this.people.values()) {\n const where = person.getPosition();\n if (!where || distance(where, here) > this.greetDistance) continue;\n const last = character.greeted.get(person.name);\n character.greeted.set(person.name, at);\n if (last === undefined || at - last > 150) {\n character.notice(`${person.name} walked up to you.`, { about: person.name, turn: true });\n }\n }\n }\n // A character that is walking or busy gets no idle turns, only turns\n // for things that happened.\n if (character.wake !== null && at >= character.wake && !character.busy) {\n if (character.status && character.inbox.length === 0) {\n character.wake = at + 5;\n } else if (this.spend()) {\n this.runTurn(character);\n }\n }\n }\n }\n\n /** Start giving characters turns. Call it once, after adding the characters. */\n start(): void {\n if (this.timer) return;\n this.budget = Math.min(this.turnsPerMinute, 6);\n this.budgetAt = now();\n this.lastTick = now();\n this.timer = setInterval(() => {\n try {\n this.tick();\n } catch (error) {\n this.warn(`world tick failed: ${error instanceof Error ? error.message : String(error)}`);\n }\n }, 500);\n }\n\n /** Stop giving turns. Sessions stay open until the server closes. */\n stop(): void {\n if (this.timer) clearInterval(this.timer);\n this.timer = null;\n }\n}\n"],"mappings":"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","names":["randomUUID","resolve","resolve","randomUUID","z","resolve"]}
|
package/dist/protocol.cjs
CHANGED
|
@@ -29,7 +29,7 @@ __export(protocol_exports, {
|
|
|
29
29
|
});
|
|
30
30
|
module.exports = __toCommonJS(protocol_exports);
|
|
31
31
|
var PROTOCOL_VERSION = 1;
|
|
32
|
-
var SDK_VERSION = "1.
|
|
32
|
+
var SDK_VERSION = "1.3.0";
|
|
33
33
|
var SESSION_RESUME_GRACE_MS = 3e4;
|
|
34
34
|
var DEFAULT_AGENT_INSTRUCTIONS = [
|
|
35
35
|
"You are a remote game agent. Tools are provided by the game.",
|
package/dist/protocol.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/protocol.ts"],"sourcesContent":["/**\n * Wire protocol between AgentServer (SDK) and the platform. Version 1.\n */\n\nexport const PROTOCOL_VERSION = 1;\nexport const SDK_VERSION = \"1.
|
|
1
|
+
{"version":3,"sources":["../src/protocol.ts"],"sourcesContent":["/**\n * Wire protocol between AgentServer (SDK) and the platform. Version 1.\n */\n\nexport const PROTOCOL_VERSION = 1;\nexport const SDK_VERSION = \"1.3.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 /** Every action played, when the turn played more than one. */\n steps?: StepRecord[];\n};\n\nexport type StepRecord = {\n action: string;\n args: Record<string, unknown>;\n result?: unknown;\n error?: string;\n};\n\n/** How a character feels about one person. affinity runs from -100 to 100. */\nexport type Relationship = {\n about: string;\n affinity: number;\n label: string;\n note?: string;\n};\n\nexport type SessionEventName = \"action\" | \"retry\" | \"turnFailed\" | \"subgoal\" | \"memory\" | \"relationship\";\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 /** Character id. One platform key can start every character in that game. */\n playerId: string;\n tools: ToolDescriptor[];\n instructions: string;\n goal?: string;\n name?: string;\n memory?: boolean;\n maxActions?: number;\n subgoals?: boolean;\n }\n | {\n type: \"session_started\";\n sessionId: string;\n relationships?: Relationship[];\n }\n | {\n type: \"observe\";\n sessionId: string;\n text: string;\n about?: 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\nconst PLAYER_ID = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;\n\n/** Trim and check the character id `start_session` must send. */\nexport function requirePlayerId(value: string | undefined): string {\n const id = value?.trim() ?? \"\";\n if (id.length === 0) {\n throw new Error(\"playerId is required. Copy the character ID from the web app\");\n }\n if (!PLAYER_ID.test(id)) {\n throw new Error(`playerId \"${id}\" is not a character ID. Copy the ID from the character in the web app`);\n }\n return id;\n}\n\nexport function assertNever(value: never): never {\n throw new Error(`Unhandled protocol message: ${JSON.stringify(value)}`);\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAIO,IAAM,mBAAmB;AACzB,IAAM,cAAc;AAGpB,IAAM,0BAA0B;AA2JhC,IAAM,6BAA6B;AAAA,EACxC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,EAAE,KAAK,IAAI;AAEX,IAAM,YAAY;AAGX,SAAS,gBAAgB,OAAmC;AACjE,QAAM,KAAK,OAAO,KAAK,KAAK;AAC5B,MAAI,GAAG,WAAW,GAAG;AACnB,UAAM,IAAI,MAAM,8DAA8D;AAAA,EAChF;AACA,MAAI,CAAC,UAAU,KAAK,EAAE,GAAG;AACvB,UAAM,IAAI,MAAM,aAAa,EAAE,wEAAwE;AAAA,EACzG;AACA,SAAO;AACT;AAEO,SAAS,YAAY,OAAqB;AAC/C,QAAM,IAAI,MAAM,+BAA+B,KAAK,UAAU,KAAK,CAAC,EAAE;AACxE;","names":[]}
|
package/dist/protocol.d.cts
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* Wire protocol between AgentServer (SDK) and the platform. Version 1.
|
|
3
3
|
*/
|
|
4
4
|
declare const PROTOCOL_VERSION = 1;
|
|
5
|
-
declare const SDK_VERSION = "1.
|
|
5
|
+
declare const SDK_VERSION = "1.3.0";
|
|
6
6
|
/** How long a disconnected session can be resumed. Shared by both sides. */
|
|
7
7
|
declare const SESSION_RESUME_GRACE_MS = 30000;
|
|
8
8
|
type JsonSchema = {
|
|
@@ -37,8 +37,23 @@ type TurnReport = {
|
|
|
37
37
|
attemptDetails?: AttemptRecord[];
|
|
38
38
|
usage?: TokenUsage;
|
|
39
39
|
connectionLost?: boolean;
|
|
40
|
+
/** Every action played, when the turn played more than one. */
|
|
41
|
+
steps?: StepRecord[];
|
|
40
42
|
};
|
|
41
|
-
type
|
|
43
|
+
type StepRecord = {
|
|
44
|
+
action: string;
|
|
45
|
+
args: Record<string, unknown>;
|
|
46
|
+
result?: unknown;
|
|
47
|
+
error?: string;
|
|
48
|
+
};
|
|
49
|
+
/** How a character feels about one person. affinity runs from -100 to 100. */
|
|
50
|
+
type Relationship = {
|
|
51
|
+
about: string;
|
|
52
|
+
affinity: number;
|
|
53
|
+
label: string;
|
|
54
|
+
note?: string;
|
|
55
|
+
};
|
|
56
|
+
type SessionEventName = "action" | "retry" | "turnFailed" | "subgoal" | "memory" | "relationship";
|
|
42
57
|
type Envelope = {
|
|
43
58
|
type: "hello";
|
|
44
59
|
platformKey: string;
|
|
@@ -63,9 +78,18 @@ type Envelope = {
|
|
|
63
78
|
instructions: string;
|
|
64
79
|
goal?: string;
|
|
65
80
|
name?: string;
|
|
81
|
+
memory?: boolean;
|
|
82
|
+
maxActions?: number;
|
|
83
|
+
subgoals?: boolean;
|
|
66
84
|
} | {
|
|
67
85
|
type: "session_started";
|
|
68
86
|
sessionId: string;
|
|
87
|
+
relationships?: Relationship[];
|
|
88
|
+
} | {
|
|
89
|
+
type: "observe";
|
|
90
|
+
sessionId: string;
|
|
91
|
+
text: string;
|
|
92
|
+
about?: string;
|
|
69
93
|
} | {
|
|
70
94
|
type: "stop_session";
|
|
71
95
|
sessionId: string;
|
|
@@ -113,4 +137,4 @@ declare const DEFAULT_AGENT_INSTRUCTIONS: string;
|
|
|
113
137
|
declare function requirePlayerId(value: string | undefined): string;
|
|
114
138
|
declare function assertNever(value: never): never;
|
|
115
139
|
|
|
116
|
-
export { type AttemptRecord, DEFAULT_AGENT_INSTRUCTIONS, type Envelope, type JsonSchema, PROTOCOL_VERSION, SDK_VERSION, SESSION_RESUME_GRACE_MS, type SessionEventName, type TokenUsage, type ToolDescriptor, type TurnReport, assertNever, requirePlayerId };
|
|
140
|
+
export { type AttemptRecord, DEFAULT_AGENT_INSTRUCTIONS, type Envelope, type JsonSchema, PROTOCOL_VERSION, type Relationship, SDK_VERSION, SESSION_RESUME_GRACE_MS, type SessionEventName, type StepRecord, type TokenUsage, type ToolDescriptor, type TurnReport, assertNever, requirePlayerId };
|