@agent-play/sdk 3.0.0 → 3.0.2

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/dist/index.js CHANGED
@@ -307,7 +307,7 @@ function mergeSnapshotWithPlayerChainNode(snapshot, node) {
307
307
  }
308
308
  };
309
309
  }
310
- if (node.removed) {
310
+ if (node.removed === true) {
311
311
  return {
312
312
  ...snapshot,
313
313
  worldMap: {
@@ -318,7 +318,11 @@ function mergeSnapshotWithPlayerChainNode(snapshot, node) {
318
318
  }
319
319
  };
320
320
  }
321
- const key = stableOccupantSortKey(node.occupant);
321
+ if (node.removed !== false) {
322
+ throw new Error("mergeSnapshotWithPlayerChainNode: invalid occupant node");
323
+ }
324
+ const occ = node.occupant;
325
+ const key = stableOccupantSortKey(occ);
322
326
  const occupants = snapshot.worldMap.occupants.filter(
323
327
  (o) => stableOccupantSortKey(o) !== key
324
328
  );
@@ -326,7 +330,7 @@ function mergeSnapshotWithPlayerChainNode(snapshot, node) {
326
330
  ...snapshot,
327
331
  worldMap: {
328
332
  ...snapshot.worldMap,
329
- occupants: [...occupants, node.occupant]
333
+ occupants: [...occupants, occ]
330
334
  }
331
335
  };
332
336
  }
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/world-events.ts","../src/lib/world-bounds.ts","../src/lib/agent-play-debug.ts","../src/platforms/langchain.ts","../src/lib/parse-occupant-row.ts","../src/lib/world-chain-keys.ts","../src/lib/player-chain-merge.ts","../src/lib/remote-play-world.ts"],"sourcesContent":["/**\n * String constants and payload shapes for SSE and in-process world events.\n *\n * @remarks **Emitters:** server `PlayWorld` and Redis fanout. **Consumers:** watch UI `EventSource`,\n * integration tests, and any host that forwards `POST` events.\n */\nimport type { WorldInteractionRole } from \"./public-types.js\";\n\n/** Fired when `addPlayer` completes; payload includes snapshot row for the new player. */\nexport const PLAYER_ADDED_EVENT = \"world:player_added\";\n\n/** Fired for each new chat/interaction line. */\nexport const WORLD_INTERACTION_EVENT = \"world:interaction\";\n\n/** Lightweight signals (zone, yield, assist, journey metadata, etc.). */\nexport const WORLD_AGENT_SIGNAL_EVENT = \"world:agent_signal\";\n\n/** Full journey + path update for a player. */\nexport const WORLD_JOURNEY_EVENT = \"world:journey\";\n\n/**\n * Payload for {@link WORLD_AGENT_SIGNAL_EVENT}.\n *\n * @property playerId - Target player.\n * @property kind - Signal category; `journey` often carries `{ stepCount }` in `data`.\n * @property data - Optional free-form metadata.\n */\nexport type WorldAgentSignalPayload = {\n playerId: string;\n kind: \"zone\" | \"yield\" | \"assist\" | \"chat\" | \"metadata\" | \"journey\";\n data?: Record<string, unknown>;\n};\n\n/**\n * Payload for {@link WORLD_INTERACTION_EVENT}.\n *\n * @property seq - Monotonic sequence for ordering in the UI.\n */\nexport type WorldInteractionPayload = {\n playerId: string;\n role: WorldInteractionRole;\n text: string;\n at: string;\n seq: number;\n};\n","/**\n * Axis-aligned rectangle in world coordinates (grid units). Used by the server to clamp paths\n * and by the watch UI to clamp joystick-driven movement.\n *\n * @remarks **Consumers:** {@link clampWorldPosition}, {@link boundsContain}; server `PlayWorld` and\n * play-ui canvas both import these helpers from `@agent-play/sdk`.\n */\nexport type WorldBounds = {\n /** Inclusive minimum X. */\n minX: number;\n /** Inclusive minimum Y. */\n minY: number;\n /** Inclusive maximum X. */\n maxX: number;\n /** Inclusive maximum Y. */\n maxY: number;\n};\n\n/**\n * Clamps a point to lie inside `bounds` along both axes.\n *\n * @param p - Position with `x` and `y` in world units.\n * @param bounds - Valid rectangle (`min` ≤ `max` per axis).\n * @returns Same point if inside, otherwise clamped to the nearest edge.\n *\n * @remarks **Callers:** server `PlayWorld` path enrichment; play-ui joystick and preview. **Callees:** `Math.min/Math.max`.\n */\nexport function clampWorldPosition(\n p: { x: number; y: number },\n bounds: WorldBounds\n): { x: number; y: number } {\n return {\n x: Math.min(Math.max(p.x, bounds.minX), bounds.maxX),\n y: Math.min(Math.max(p.y, bounds.minY), bounds.maxY),\n };\n}\n\n/**\n * @returns Whether `p` lies inside or on the border of `bounds`.\n *\n * @remarks **Callers:** optional UI checks. **Callees:** none.\n */\nexport function boundsContain(\n bounds: WorldBounds,\n p: { x: number; y: number }\n): boolean {\n return (\n p.x >= bounds.minX &&\n p.x <= bounds.maxX &&\n p.y >= bounds.minY &&\n p.y <= bounds.maxY\n );\n}\n","/**\n * Optional structured `console.debug` for SDK internals; gated by {@link configureAgentPlayDebug} or `AGENT_PLAY_DEBUG=1`.\n */\ntype DebugConfigure = {\n /** When set, overrides environment: `true` forces debug on, `false` forces off. */\n debug?: boolean;\n};\n\n/**\n * In-memory override for debug enablement (undefined = follow env only).\n *\n * @remarks **Writers:** {@link configureAgentPlayDebug}, {@link resetAgentPlayDebug}.\n * **Readers:** {@link isAgentPlayDebugEnabled}.\n */\nlet configuredDebug: boolean | undefined;\n\n/**\n * Sets whether SDK debug logging is enabled regardless of `AGENT_PLAY_DEBUG`.\n *\n * @param opts.debug - `true` / `false` to force; omit to clear override.\n *\n * @remarks **Callers:** tests and user code. **Callees:** none.\n */\nexport function configureAgentPlayDebug(opts: DebugConfigure): void {\n configuredDebug = opts.debug ?? undefined;\n}\n\n/**\n * Clears the in-memory override so only `AGENT_PLAY_DEBUG` applies.\n *\n * @remarks **Callers:** tests. **Callees:** none.\n */\nexport function resetAgentPlayDebug(): void {\n configuredDebug = undefined;\n}\n\n/**\n * @returns Whether debug logging should run: override wins, else `AGENT_PLAY_DEBUG === \"1\"`.\n *\n * @remarks **Callers:** {@link agentPlayDebug}. **Callees:** `process.env` read.\n */\nexport function isAgentPlayDebugEnabled(): boolean {\n if (configuredDebug === false) return false;\n if (configuredDebug === true) return true;\n return process.env.AGENT_PLAY_DEBUG === \"1\";\n}\n\n/** Max length of JSON detail string before truncation in {@link safeSerialize}. */\nconst MAX_JSON_LENGTH = 2000;\n\n/**\n * Serializes `detail` for log lines, truncating long JSON and handling circular refs.\n *\n * @internal\n * @remarks **Callers:** {@link agentPlayDebug} only. **Callees:** `JSON.stringify` with replacer.\n */\nfunction safeSerialize(detail: unknown): string {\n if (detail === undefined) return \"\";\n try {\n const seen = new WeakSet<object>();\n const json = JSON.stringify(detail, (_k, v: unknown) => {\n if (typeof v === \"object\" && v !== null) {\n if (seen.has(v)) return \"[Circular]\";\n seen.add(v);\n }\n if (typeof v === \"bigint\") return String(v);\n return v;\n });\n if (typeof json !== \"string\") return String(detail);\n return json.length > MAX_JSON_LENGTH\n ? `${json.slice(0, MAX_JSON_LENGTH)}…`\n : json;\n } catch {\n return String(detail);\n }\n}\n\n/**\n * Emits `console.debug` when {@link isAgentPlayDebugEnabled} is true.\n *\n * @param scope - Short label (e.g. `\"langchain\"`).\n * @param message - Human-readable message.\n * @param detail - Optional object serialized by {@link safeSerialize}.\n *\n * @remarks **Callers:** {@link langchainRegistration} and other SDK modules. **Callees:** {@link isAgentPlayDebugEnabled}, {@link safeSerialize}.\n */\nexport function agentPlayDebug(\n scope: string,\n message: string,\n detail?: unknown\n): void {\n if (!isAgentPlayDebugEnabled()) return;\n const tail =\n detail === undefined ? \"\" : ` ${safeSerialize(detail)}`;\n console.debug(`[agent-play:${scope}] ${message}${tail}`);\n}\n","/**\n * LangChain adapter: derives tool names and assist metadata from a LangChain agent for\n * {@link import(\"../public-types.js\").LangChainAgentRegistration}.\n *\n * @remarks **Primary export:** {@link langchainRegistration}. Private helpers build error strings and\n * `AssistToolSpec` rows from Zod schemas when available.\n */\nimport { agentPlayDebug } from \"../lib/agent-play-debug.js\";\nimport type { AssistToolSpec, LangChainAgentRegistration } from \"../public-types.js\";\n\n/** Required tool name enforced by the watch UI contract. */\nconst CHAT_TOOL = \"chat_tool\";\n\n/**\n * Error text when the agent has no `tools` array.\n *\n * @remarks **Callers:** {@link langchainRegistration}. **Callees:** none.\n */\nfunction formatMissingAgentToolsError(): string {\n return [\n \"langchainRegistration: expected a LangChain agent with a tools array.\",\n \"\",\n \" Pass the object returned from createAgent({ tools: [...] }) (or equivalent) so tool names are available for the play world.\",\n \" The tools array must include named tools; see the separate message if \\\"chat_tool\\\" or assist_* tools are missing.\",\n ].join(\"\\n\");\n}\n\n/**\n * Error text when `chat_tool` is missing from tool names.\n *\n * @remarks **Callers:** {@link langchainRegistration}. **Callees:** none.\n */\nfunction formatMissingChatToolError(): string {\n return [\n \"langchainRegistration: missing required tool \\\"chat_tool\\\".\",\n \"\",\n \" Add a tool named \\\"chat_tool\\\" to your LangChain agent so the play world can show chat and proximity interactions.\",\n \" Example: tool(() => \\\"…\\\", { name: \\\"chat_tool\\\", description: \\\"…\\\", schema: z.object({ … }) })\",\n \"\",\n \" Tools whose names start with \\\"assist_\\\" are listed as assist actions on the watch UI; give each a Zod object schema so parameters can be shown in the UI.\",\n ].join(\"\\n\");\n}\n\n/**\n * Best-effort parameter shape from a Zod object schema’s `shape()` for UI hints.\n *\n * @remarks **Callers:** {@link describeTool}. **Callees:** none.\n */\nfunction parametersFromSchema(schema: unknown): Record<string, unknown> {\n if (schema === null || typeof schema !== \"object\") {\n return {};\n }\n const z = schema as {\n _def?: { typeName?: string; shape?: () => Record<string, unknown> };\n };\n if (typeof z._def?.shape !== \"function\") {\n return { _note: \"Pass a Zod object schema on each tool for parameter hints in the watch UI.\" };\n }\n const shape = z._def.shape();\n const out: Record<string, unknown> = {};\n for (const key of Object.keys(shape)) {\n out[key] = { field: key };\n }\n return out;\n}\n\n/**\n * Builds an {@link AssistToolSpec} from a LangChain tool descriptor.\n *\n * @remarks **Callers:** {@link langchainRegistration} for `assist_*` tools only. **Callees:** {@link parametersFromSchema}.\n */\nfunction describeTool(t: {\n name: string;\n description?: string;\n schema?: unknown;\n}): AssistToolSpec {\n return {\n name: t.name,\n description:\n typeof t.description === \"string\" && t.description.length > 0\n ? t.description\n : t.name,\n parameters: parametersFromSchema(t.schema),\n };\n}\n\n/**\n * Reads `agent.tools` or `agent.options.tools` from common LangChain agent shapes.\n *\n * @returns The tools array, or `null` if not found.\n *\n * @remarks **Callers:** {@link langchainRegistration} only. **Callees:** none.\n */\nfunction extractToolsArray(agent: unknown): unknown[] | null {\n if (typeof agent !== \"object\" || agent === null) {\n return null;\n }\n const a = agent as {\n tools?: unknown;\n options?: { tools?: unknown };\n };\n if (Array.isArray(a.tools)) {\n return a.tools;\n }\n if (\n a.options !== undefined &&\n typeof a.options === \"object\" &&\n a.options !== null &&\n \"tools\" in a.options &&\n Array.isArray((a.options as { tools: unknown }).tools)\n ) {\n return (a.options as { tools: unknown[] }).tools;\n }\n return null;\n}\n\n/**\n * Validates a LangChain-style agent exposes tools (including required `chat_tool`) and returns\n * a {@link LangChainAgentRegistration} for `addPlayer`.\n *\n * @param agent - Return value from `createAgent` (or equivalent) with a `tools` array.\n * @throws Error if tools are missing or `chat_tool` is not present.\n *\n * @remarks **Callers:** user code before `RemotePlayWorld.addPlayer`. **Callees:** {@link extractToolsArray},\n * {@link formatMissingAgentToolsError}, {@link formatMissingChatToolError}, {@link describeTool}, {@link agentPlayDebug}.\n */\nexport function langchainRegistration(\n agent: unknown\n): LangChainAgentRegistration {\n const rawTools = extractToolsArray(agent);\n if (rawTools === null) {\n throw new Error(formatMissingAgentToolsError());\n }\n const tools =\n rawTools as readonly { name: string; description?: string; schema?: unknown }[];\n const names = tools.map((x) => x.name);\n if (!names.includes(CHAT_TOOL)) {\n throw new Error(formatMissingChatToolError());\n }\n const assistTools = tools\n .filter((t) => t.name.startsWith(\"assist_\"))\n .map((t) => describeTool(t));\n agentPlayDebug(\"langchain\", \"langchainRegistration\", {\n toolCount: names.length,\n assistCount: assistTools.length,\n });\n return {\n type: \"langchain\",\n toolNames: names,\n assistTools,\n };\n}\n","import type {\n AgentPlayWorldMapAgentOccupant,\n AgentPlayWorldMapMcpOccupant,\n} from \"../public-types.js\";\n\nexport function parseAgentOccupantRow(\n raw: Record<string, unknown>\n): AgentPlayWorldMapAgentOccupant {\n if (typeof raw.agentId !== \"string\" || typeof raw.name !== \"string\") {\n throw new Error(\"occupant: agent needs agentId and name\");\n }\n if (typeof raw.x !== \"number\" || typeof raw.y !== \"number\") {\n throw new Error(\"occupant: agent needs numeric x and y\");\n }\n const base: AgentPlayWorldMapAgentOccupant = {\n kind: \"agent\",\n agentId: raw.agentId,\n name: raw.name,\n x: raw.x,\n y: raw.y,\n };\n let platform: string | undefined;\n if (typeof raw.platform === \"string\") {\n platform = raw.platform;\n } else if (typeof raw.agentType === \"string\") {\n platform = raw.agentType;\n }\n if (platform !== undefined) {\n return { ...base, platform };\n }\n return base;\n}\n\nexport function parseMcpOccupantRow(\n raw: Record<string, unknown>\n): AgentPlayWorldMapMcpOccupant {\n if (typeof raw.id !== \"string\" || typeof raw.name !== \"string\") {\n throw new Error(\"occupant: mcp needs id and name\");\n }\n if (typeof raw.x !== \"number\" || typeof raw.y !== \"number\") {\n throw new Error(\"occupant: mcp needs numeric x and y\");\n }\n const base: AgentPlayWorldMapMcpOccupant = {\n kind: \"mcp\",\n id: raw.id,\n name: raw.name,\n x: raw.x,\n y: raw.y,\n };\n if (typeof raw.url === \"string\") {\n return { ...base, url: raw.url };\n }\n return base;\n}\n","export const PLAYER_CHAIN_GENESIS_STABLE_KEY = \"__genesis__\" as const;\nexport const PLAYER_CHAIN_HEADER_STABLE_KEY = \"__header__\" as const;\n","/**\n * Parses **`playerChainNotify`** envelopes and merges {@link PlayerChainNodeResponse} slices into {@link AgentPlaySnapshot} (pure functions + fetch ordering for serialized RPC).\n */\n\nimport type {\n AgentPlaySnapshot,\n AgentPlayWorldMapAgentOccupant,\n AgentPlayWorldMapMcpOccupant,\n PlayerChainFanoutNotify,\n PlayerChainNotifyNodeRef,\n PlayerChainNodeResponse,\n} from \"../public-types.js\";\nimport {\n parseAgentOccupantRow,\n parseMcpOccupantRow,\n} from \"./parse-occupant-row.js\";\nimport {\n PLAYER_CHAIN_GENESIS_STABLE_KEY,\n PLAYER_CHAIN_HEADER_STABLE_KEY,\n} from \"./world-chain-keys.js\";\n\nfunction isRecord(v: unknown): v is Record<string, unknown> {\n return typeof v === \"object\" && v !== null;\n}\n\nfunction stableOccupantSortKey(\n occ: AgentPlayWorldMapAgentOccupant | AgentPlayWorldMapMcpOccupant\n): string {\n if (occ.kind === \"agent\") {\n return `agent:${occ.agentId}`;\n }\n return `mcp:${occ.id}`;\n}\n\nexport function sortNodeRefsForSerializedFetch(\n nodes: ReadonlyArray<PlayerChainNotifyNodeRef>\n): PlayerChainNotifyNodeRef[] {\n const removed = nodes.filter((n) => n.removed === true);\n const rest = nodes.filter((n) => n.removed !== true);\n removed.sort((a, b) => b.leafIndex - a.leafIndex);\n rest.sort((a, b) => a.leafIndex - b.leafIndex);\n return [...removed, ...rest];\n}\n\nexport function parsePlayerChainFanoutNotify(\n raw: unknown\n): PlayerChainFanoutNotify | undefined {\n if (!isRecord(raw)) {\n return undefined;\n }\n if (typeof raw.updatedAt !== \"string\" || raw.updatedAt.length === 0) {\n return undefined;\n }\n if (!Array.isArray(raw.nodes)) {\n return undefined;\n }\n const nodes: PlayerChainNotifyNodeRef[] = [];\n for (const row of raw.nodes) {\n if (!isRecord(row)) {\n return undefined;\n }\n if (typeof row.stableKey !== \"string\" || row.stableKey.length === 0) {\n return undefined;\n }\n if (typeof row.leafIndex !== \"number\" || !Number.isFinite(row.leafIndex)) {\n return undefined;\n }\n const ref: PlayerChainNotifyNodeRef = {\n stableKey: row.stableKey,\n leafIndex: row.leafIndex,\n };\n if (row.removed === true) {\n ref.removed = true;\n }\n if (typeof row.updatedAt === \"string\" && row.updatedAt.length > 0) {\n ref.updatedAt = row.updatedAt;\n }\n nodes.push(ref);\n }\n return { updatedAt: raw.updatedAt, nodes };\n}\n\nexport function parsePlayerChainFanoutNotifyFromSsePayload(\n sseData: unknown\n): PlayerChainFanoutNotify | undefined {\n if (!isRecord(sseData)) {\n return undefined;\n }\n return parsePlayerChainFanoutNotify(sseData.playerChainNotify);\n}\n\nexport function parsePlayerChainNodeRpcBody(json: unknown): PlayerChainNodeResponse {\n if (!isRecord(json) || !isRecord(json.node)) {\n throw new Error(\"getPlayerChainNode: invalid response shape\");\n }\n const n = json.node;\n if (n.kind === \"genesis\") {\n if (\n n.stableKey !== PLAYER_CHAIN_GENESIS_STABLE_KEY ||\n typeof n.text !== \"string\"\n ) {\n throw new Error(\"getPlayerChainNode: invalid genesis node\");\n }\n return {\n kind: \"genesis\",\n stableKey: PLAYER_CHAIN_GENESIS_STABLE_KEY,\n text: n.text,\n };\n }\n if (n.kind === \"header\") {\n if (\n n.stableKey !== PLAYER_CHAIN_HEADER_STABLE_KEY ||\n typeof n.sid !== \"string\"\n ) {\n throw new Error(\"getPlayerChainNode: invalid header node\");\n }\n const b = n.bounds;\n if (!isRecord(b)) {\n throw new Error(\"getPlayerChainNode: invalid header bounds\");\n }\n const { minX, minY, maxX, maxY } = b;\n if (\n typeof minX !== \"number\" ||\n typeof minY !== \"number\" ||\n typeof maxX !== \"number\" ||\n typeof maxY !== \"number\"\n ) {\n throw new Error(\"getPlayerChainNode: invalid header bounds\");\n }\n return {\n kind: \"header\",\n stableKey: PLAYER_CHAIN_HEADER_STABLE_KEY,\n sid: n.sid,\n bounds: { minX, minY, maxX, maxY },\n };\n }\n if (n.kind !== \"occupant\") {\n throw new Error(\"getPlayerChainNode: unknown node kind\");\n }\n if (typeof n.stableKey !== \"string\" || n.stableKey.length === 0) {\n throw new Error(\"getPlayerChainNode: invalid occupant stableKey\");\n }\n if (n.removed === true) {\n return { kind: \"occupant\", stableKey: n.stableKey, removed: true };\n }\n const occ = n.occupant;\n if (!isRecord(occ) || (occ.kind !== \"agent\" && occ.kind !== \"mcp\")) {\n throw new Error(\"getPlayerChainNode: invalid occupant payload\");\n }\n const occupant =\n occ.kind === \"agent\"\n ? parseAgentOccupantRow(occ)\n : parseMcpOccupantRow(occ);\n return {\n kind: \"occupant\",\n stableKey: n.stableKey,\n removed: false,\n occupant,\n };\n}\n\nexport function mergeSnapshotWithPlayerChainNode(\n snapshot: AgentPlaySnapshot,\n node: PlayerChainNodeResponse\n): AgentPlaySnapshot {\n if (node.kind === \"genesis\") {\n return snapshot;\n }\n if (node.kind === \"header\") {\n return {\n ...snapshot,\n sid: node.sid,\n worldMap: {\n ...snapshot.worldMap,\n bounds: node.bounds,\n },\n };\n }\n if (node.removed) {\n return {\n ...snapshot,\n worldMap: {\n ...snapshot.worldMap,\n occupants: snapshot.worldMap.occupants.filter(\n (o) => stableOccupantSortKey(o) !== node.stableKey\n ),\n },\n };\n }\n const key = stableOccupantSortKey(node.occupant);\n const occupants = snapshot.worldMap.occupants.filter(\n (o) => stableOccupantSortKey(o) !== key\n );\n return {\n ...snapshot,\n worldMap: {\n ...snapshot.worldMap,\n occupants: [...occupants, node.occupant],\n },\n };\n}\n","import type {\n AddPlayerInput,\n AgentPlaySnapshot,\n AgentPlayWorldMap,\n AgentPlayWorldMapBounds,\n Journey,\n RecordInteractionInput,\n RegisteredAgentSummary,\n RegisteredPlayer,\n PlayerChainNodeResponse,\n} from \"../public-types.js\";\nimport {\n parseAgentOccupantRow,\n parseMcpOccupantRow,\n} from \"./parse-occupant-row.js\";\nimport {\n mergeSnapshotWithPlayerChainNode,\n parsePlayerChainFanoutNotifyFromSsePayload,\n parsePlayerChainNodeRpcBody,\n sortNodeRefsForSerializedFetch,\n} from \"./player-chain-merge.js\";\n\nexport type RemotePlayWorldOptions = {\n baseUrl: string;\n apiKey: string;\n authToken?: string;\n};\n\nfunction formatMissingApiKeyError(): string {\n return [\n \"RemotePlayWorld: options.apiKey is required.\",\n \"\",\n \" Register an agent with `agent-play create` (after `agent-play login`) and use the printed API key.\",\n \" Pass it here so addPlayer can authenticate against the server repository when Redis is enabled.\",\n \" If the server has no agent repository (local dev), still pass a non-empty placeholder string.\",\n ].join(\"\\n\");\n}\n\nfunction normalizeBaseUrl(url: string): string {\n return url.replace(/\\/$/, \"\");\n}\n\nfunction isRecord(v: unknown): v is Record<string, unknown> {\n return typeof v === \"object\" && v !== null;\n}\n\nfunction parseBounds(raw: unknown): AgentPlayWorldMapBounds {\n if (!isRecord(raw)) {\n throw new Error(\"getWorldSnapshot: worldMap.bounds must be an object\");\n }\n const { minX, minY, maxX, maxY } = raw;\n if (\n typeof minX !== \"number\" ||\n typeof minY !== \"number\" ||\n typeof maxX !== \"number\" ||\n typeof maxY !== \"number\"\n ) {\n throw new Error(\n \"getWorldSnapshot: bounds need numeric minX, minY, maxX, maxY\"\n );\n }\n return { minX, minY, maxX, maxY };\n}\n\nfunction parseWorldMap(raw: unknown): AgentPlayWorldMap {\n if (!isRecord(raw)) {\n throw new Error(\"getWorldSnapshot: worldMap must be an object\");\n }\n const bounds = parseBounds(raw.bounds);\n const occ = raw.occupants;\n if (!Array.isArray(occ)) {\n throw new Error(\"getWorldSnapshot: worldMap.occupants must be an array\");\n }\n const occupants: AgentPlayWorldMap[\"occupants\"] = [];\n const coordKeys = new Set<string>();\n for (const row of occ) {\n if (!isRecord(row) || (row.kind !== \"agent\" && row.kind !== \"mcp\")) {\n throw new Error(\"getWorldSnapshot: each occupant must have kind agent or mcp\");\n }\n const xy =\n typeof row.x === \"number\" && typeof row.y === \"number\"\n ? `${row.x},${row.y}`\n : \"\";\n if (xy.length === 0) {\n throw new Error(\"getWorldSnapshot: occupant missing coordinates\");\n }\n if (coordKeys.has(xy)) {\n throw new Error(\"getWorldSnapshot: duplicate world map coordinate\");\n }\n coordKeys.add(xy);\n if (row.kind === \"agent\") {\n occupants.push(parseAgentOccupantRow(row));\n } else {\n occupants.push(parseMcpOccupantRow(row));\n }\n }\n return { bounds, occupants };\n}\n\nfunction parseAgentPlaySnapshot(snapshot: unknown): AgentPlaySnapshot {\n if (!isRecord(snapshot) || typeof snapshot.sid !== \"string\") {\n throw new Error(\"getWorldSnapshot: invalid snapshot\");\n }\n const worldMap = parseWorldMap(snapshot.worldMap);\n const out: AgentPlaySnapshot = { sid: snapshot.sid, worldMap };\n if (\"mcpServers\" in snapshot && Array.isArray(snapshot.mcpServers)) {\n const servers: NonNullable<AgentPlaySnapshot[\"mcpServers\"]> = [];\n for (const m of snapshot.mcpServers) {\n if (!isRecord(m) || typeof m.id !== \"string\" || typeof m.name !== \"string\") {\n continue;\n }\n const row: { id: string; name: string; url?: string } = {\n id: m.id,\n name: m.name,\n };\n if (typeof m.url === \"string\") row.url = m.url;\n servers.push(row);\n }\n if (servers.length > 0) out.mcpServers = servers;\n }\n return out;\n}\n\nfunction parseRegisteredAgentSummary(raw: unknown): RegisteredAgentSummary {\n if (!isRecord(raw)) {\n throw new Error(\"addPlayer: registeredAgent missing\");\n }\n if (typeof raw.agentId !== \"string\" || typeof raw.name !== \"string\") {\n throw new Error(\"addPlayer: registeredAgent.agentId and name required\");\n }\n if (!Array.isArray(raw.toolNames)) {\n throw new Error(\"addPlayer: registeredAgent.toolNames must be an array\");\n }\n const toolNames: string[] = [];\n for (const t of raw.toolNames) {\n if (typeof t !== \"string\") {\n throw new Error(\"addPlayer: registeredAgent.toolNames must be strings\");\n }\n toolNames.push(t);\n }\n if (\n typeof raw.zoneCount !== \"number\" ||\n typeof raw.yieldCount !== \"number\" ||\n typeof raw.flagged !== \"boolean\"\n ) {\n throw new Error(\"addPlayer: registeredAgent counters invalid\");\n }\n return {\n agentId: raw.agentId,\n name: raw.name,\n toolNames,\n zoneCount: raw.zoneCount,\n yieldCount: raw.yieldCount,\n flagged: raw.flagged,\n };\n}\n\nfunction formatInvalidHoldSecondsError(): string {\n return [\n \"RemotePlayWorld.hold().for(seconds): seconds must be a finite number.\",\n \"\",\n \" Example: await world.hold().for(3600)\",\n ].join(\"\\n\");\n}\n\nexport type RemotePlayWorldHold = {\n for: (seconds: number) => Promise<void>;\n};\n\n/**\n * HTTP client for the Agent Play web UI: session, snapshot RPC, mutating RPC with `sid`, and optional SSE subscription.\n *\n * Incremental updates: {@link RemotePlayWorld.subscribeWorldState} listens for **`playerChainNotify`** in SSE `data`, then fetches each changed leaf via {@link RemotePlayWorld.getPlayerChainNode} and merges with {@link mergeSnapshotWithPlayerChainNode}.\n */\nexport class RemotePlayWorld {\n private readonly apiBase: string;\n private readonly apiKey: string;\n private readonly authToken: string | undefined;\n private sid: string | null = null;\n private closed = false;\n private readonly closeListeners = new Set<() => void>();\n\n constructor(options: RemotePlayWorldOptions) {\n if (typeof options.apiKey !== \"string\" || options.apiKey.trim().length === 0) {\n throw new Error(formatMissingApiKeyError());\n }\n this.apiBase = normalizeBaseUrl(options.baseUrl);\n this.apiKey = options.apiKey.trim();\n this.authToken = options.authToken;\n }\n\n onClose(handler: () => void): () => void {\n this.closeListeners.add(handler);\n return () => {\n this.closeListeners.delete(handler);\n };\n }\n\n hold(): RemotePlayWorldHold {\n return {\n for: async (seconds: number) => {\n if (typeof seconds !== \"number\" || !Number.isFinite(seconds)) {\n throw new Error(formatInvalidHoldSecondsError());\n }\n const ms = Math.max(0, seconds) * 1000;\n await new Promise<void>((resolve) => {\n setTimeout(resolve, ms);\n });\n },\n };\n }\n\n private authHeaders(): Record<string, string> {\n if (this.authToken === undefined) return {};\n return { Authorization: `Bearer ${this.authToken}` };\n }\n\n private jsonHeaders(): Record<string, string> {\n return {\n \"content-type\": \"application/json\",\n ...this.authHeaders(),\n };\n }\n\n private mergeAuthFetch(\n input: RequestInfo | URL,\n init?: RequestInit\n ): Promise<Response> {\n const headers = new Headers(init?.headers);\n const auth = this.authHeaders();\n for (const [k, v] of Object.entries(auth)) {\n headers.set(k, v);\n }\n return fetch(input, { ...init, headers });\n }\n\n async connect(): Promise<void> {\n const res = await fetch(`${this.apiBase}/api/agent-play/session`, {\n headers: this.authHeaders(),\n });\n if (!res.ok) {\n throw new Error(`session failed: ${res.status}`);\n }\n const json: unknown = await res.json();\n if (!isRecord(json) || typeof json.sid !== \"string\" || json.sid.length === 0) {\n throw new Error(\"session: invalid response\");\n }\n this.sid = json.sid;\n }\n\n async close(): Promise<void> {\n if (this.closed) {\n return;\n }\n this.closed = true;\n for (const handler of Array.from(this.closeListeners)) {\n try {\n handler();\n } catch {\n // ignore listener errors\n }\n }\n }\n\n getSessionId(): string {\n if (this.sid === null) {\n throw new Error(\"RemotePlayWorld.connect() must be called first\");\n }\n return this.sid;\n }\n\n getPreviewUrl(): string {\n const u = new URL(\"/agent-play/watch\", this.apiBase);\n u.search = \"\";\n return u.toString();\n }\n\n async getWorldSnapshot(): Promise<AgentPlaySnapshot> {\n const res = await fetch(`${this.apiBase}/api/agent-play/sdk/rpc`, {\n method: \"POST\",\n headers: this.jsonHeaders(),\n body: JSON.stringify({ op: \"getWorldSnapshot\", payload: {} }),\n });\n const text = await res.text();\n if (!res.ok) {\n throw new Error(`getWorldSnapshot: ${res.status} ${text}`);\n }\n let json: unknown;\n try {\n json = JSON.parse(text) as unknown;\n } catch {\n throw new Error(\"getWorldSnapshot: invalid JSON\");\n }\n if (!isRecord(json) || !(\"snapshot\" in json)) {\n throw new Error(\"getWorldSnapshot: invalid response shape\");\n }\n return parseAgentPlaySnapshot(json.snapshot);\n }\n\n /**\n * Fetches one player-chain node (genesis, header, occupant row, or removal) for `stableKey`, same snapshot scope as {@link RemotePlayWorld.getWorldSnapshot}.\n */\n async getPlayerChainNode(stableKey: string): Promise<PlayerChainNodeResponse> {\n const trimmed = stableKey.trim();\n if (trimmed.length === 0) {\n throw new Error(\"getPlayerChainNode: stableKey is required\");\n }\n const res = await fetch(`${this.apiBase}/api/agent-play/sdk/rpc`, {\n method: \"POST\",\n headers: this.jsonHeaders(),\n body: JSON.stringify({\n op: \"getPlayerChainNode\",\n payload: { stableKey: trimmed },\n }),\n });\n const text = await res.text();\n if (!res.ok) {\n throw new Error(`getPlayerChainNode: ${res.status} ${text}`);\n }\n let json: unknown;\n try {\n json = JSON.parse(text) as unknown;\n } catch {\n throw new Error(\"getPlayerChainNode: invalid JSON\");\n }\n return parsePlayerChainNodeRpcBody(json);\n }\n\n /**\n * Opens the session SSE stream, emits an initial snapshot from {@link RemotePlayWorld.getWorldSnapshot}, then on each **`playerChainNotify`** merges nodes in deterministic order via {@link RemotePlayWorld.getPlayerChainNode}.\n */\n subscribeWorldState(callbacks: {\n onSnapshot: (snapshot: AgentPlaySnapshot) => void;\n onError?: (err: Error) => void;\n }): { close: () => void } {\n let closeSource: (() => void) | null = null;\n const task = (async () => {\n try {\n const { createEventSource } = await import(\"eventsource-client\");\n let snapshot = await this.getWorldSnapshot();\n callbacks.onSnapshot(snapshot);\n const source = createEventSource({\n url: `${this.apiBase}/api/agent-play/events?sid=${encodeURIComponent(\n this.getSessionId()\n )}`,\n fetch: (input, init) => this.mergeAuthFetch(input, init),\n });\n closeSource = () => {\n source.close();\n };\n for await (const msg of source) {\n if (typeof msg.data !== \"string\") {\n continue;\n }\n let data: unknown;\n try {\n data = JSON.parse(msg.data) as unknown;\n } catch {\n continue;\n }\n const notify = parsePlayerChainFanoutNotifyFromSsePayload(data);\n if (notify === undefined || notify.nodes.length === 0) {\n continue;\n }\n const ordered = sortNodeRefsForSerializedFetch(notify.nodes);\n for (const ref of ordered) {\n const node = await this.getPlayerChainNode(ref.stableKey);\n snapshot = mergeSnapshotWithPlayerChainNode(snapshot, node);\n }\n callbacks.onSnapshot(snapshot);\n }\n } catch (e) {\n callbacks.onError?.(\n e instanceof Error ? e : new Error(String(e))\n );\n }\n })();\n return {\n close: () => {\n closeSource?.();\n void task;\n },\n };\n }\n\n async addPlayer(input: AddPlayerInput): Promise<RegisteredPlayer> {\n const sid = this.getSessionId();\n const url = `${this.apiBase}/api/agent-play/players?sid=${encodeURIComponent(sid)}`;\n const res = await fetch(url, {\n method: \"POST\",\n headers: this.jsonHeaders(),\n body: JSON.stringify({\n name: input.name,\n type: input.type,\n agent: input.agent,\n apiKey: this.apiKey,\n agentId: input.agentId,\n }),\n });\n const bodyText = await res.text();\n if (!res.ok) {\n throw new Error(`addPlayer: ${res.status} ${bodyText}`);\n }\n let body: unknown;\n try {\n body = JSON.parse(bodyText) as unknown;\n } catch {\n throw new Error(\"addPlayer: invalid JSON\");\n }\n if (!isRecord(body)) {\n throw new Error(\"addPlayer: invalid response shape\");\n }\n const playerId = body.playerId;\n const previewUrl = body.previewUrl;\n if (typeof playerId !== \"string\" || typeof previewUrl !== \"string\") {\n throw new Error(\"addPlayer: missing playerId or previewUrl\");\n }\n const registeredAgent = parseRegisteredAgentSummary(body.registeredAgent);\n const now = new Date();\n return {\n id: playerId,\n name: input.name,\n sid,\n createdAt: now,\n updatedAt: now,\n previewUrl,\n registeredAgent,\n };\n }\n\n async recordInteraction(input: RecordInteractionInput): Promise<void> {\n await this.rpc(\"recordInteraction\", {\n playerId: input.playerId,\n role: input.role,\n text: input.text,\n });\n }\n\n async recordJourney(playerId: string, journey: Journey): Promise<void> {\n await this.rpc(\"recordJourney\", { playerId, journey });\n }\n\n async registerMcp(options: { name: string; url?: string }): Promise<string> {\n const sid = this.getSessionId();\n const url = `${this.apiBase}/api/agent-play/mcp/register?sid=${encodeURIComponent(sid)}`;\n const body: { name: string; url?: string } = { name: options.name };\n if (options.url !== undefined) {\n body.url = options.url;\n }\n const res = await fetch(url, {\n method: \"POST\",\n headers: this.jsonHeaders(),\n body: JSON.stringify(body),\n });\n const text = await res.text();\n if (!res.ok) {\n throw new Error(`registerMcp: ${res.status} ${text}`);\n }\n let json: unknown;\n try {\n json = JSON.parse(text) as unknown;\n } catch {\n throw new Error(\"registerMcp: invalid JSON\");\n }\n if (!isRecord(json) || typeof json.id !== \"string\") {\n throw new Error(\"registerMcp: invalid response\");\n }\n return json.id;\n }\n\n private async rpc(op: string, payload: unknown): Promise<void> {\n const sid = this.getSessionId();\n const url = `${this.apiBase}/api/agent-play/sdk/rpc?sid=${encodeURIComponent(sid)}`;\n const res = await fetch(url, {\n method: \"POST\",\n headers: this.jsonHeaders(),\n body: JSON.stringify({ op, payload }),\n });\n if (!res.ok) {\n const t = await res.text();\n throw new Error(`rpc ${op}: ${res.status} ${t}`);\n }\n }\n}\n"],"mappings":"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","names":["isRecord"]}
1
+ {"version":3,"sources":["../src/world-events.ts","../src/lib/world-bounds.ts","../src/lib/agent-play-debug.ts","../src/platforms/langchain.ts","../src/lib/parse-occupant-row.ts","../src/lib/world-chain-keys.ts","../src/lib/player-chain-merge.ts","../src/lib/remote-play-world.ts"],"sourcesContent":["/**\n * String constants and payload shapes for SSE and in-process world events.\n *\n * @remarks **Emitters:** server `PlayWorld` and Redis fanout. **Consumers:** watch UI `EventSource`,\n * integration tests, and any host that forwards `POST` events.\n */\nimport type { WorldInteractionRole } from \"./public-types.js\";\n\n/** Fired when `addPlayer` completes; payload includes snapshot row for the new player. */\nexport const PLAYER_ADDED_EVENT = \"world:player_added\";\n\n/** Fired for each new chat/interaction line. */\nexport const WORLD_INTERACTION_EVENT = \"world:interaction\";\n\n/** Lightweight signals (zone, yield, assist, journey metadata, etc.). */\nexport const WORLD_AGENT_SIGNAL_EVENT = \"world:agent_signal\";\n\n/** Full journey + path update for a player. */\nexport const WORLD_JOURNEY_EVENT = \"world:journey\";\n\n/**\n * Payload for {@link WORLD_AGENT_SIGNAL_EVENT}.\n *\n * @property playerId - Target player.\n * @property kind - Signal category; `journey` often carries `{ stepCount }` in `data`.\n * @property data - Optional free-form metadata.\n */\nexport type WorldAgentSignalPayload = {\n playerId: string;\n kind: \"zone\" | \"yield\" | \"assist\" | \"chat\" | \"metadata\" | \"journey\";\n data?: Record<string, unknown>;\n};\n\n/**\n * Payload for {@link WORLD_INTERACTION_EVENT}.\n *\n * @property seq - Monotonic sequence for ordering in the UI.\n */\nexport type WorldInteractionPayload = {\n playerId: string;\n role: WorldInteractionRole;\n text: string;\n at: string;\n seq: number;\n};\n","/**\n * Axis-aligned rectangle in world coordinates (grid units). Used by the server to clamp paths\n * and by the watch UI to clamp joystick-driven movement.\n *\n * @remarks **Consumers:** {@link clampWorldPosition}, {@link boundsContain}; server `PlayWorld` and\n * play-ui canvas both import these helpers from `@agent-play/sdk`.\n */\nexport type WorldBounds = {\n /** Inclusive minimum X. */\n minX: number;\n /** Inclusive minimum Y. */\n minY: number;\n /** Inclusive maximum X. */\n maxX: number;\n /** Inclusive maximum Y. */\n maxY: number;\n};\n\n/**\n * Clamps a point to lie inside `bounds` along both axes.\n *\n * @param p - Position with `x` and `y` in world units.\n * @param bounds - Valid rectangle (`min` ≤ `max` per axis).\n * @returns Same point if inside, otherwise clamped to the nearest edge.\n *\n * @remarks **Callers:** server `PlayWorld` path enrichment; play-ui joystick and preview. **Callees:** `Math.min/Math.max`.\n */\nexport function clampWorldPosition(\n p: { x: number; y: number },\n bounds: WorldBounds\n): { x: number; y: number } {\n return {\n x: Math.min(Math.max(p.x, bounds.minX), bounds.maxX),\n y: Math.min(Math.max(p.y, bounds.minY), bounds.maxY),\n };\n}\n\n/**\n * @returns Whether `p` lies inside or on the border of `bounds`.\n *\n * @remarks **Callers:** optional UI checks. **Callees:** none.\n */\nexport function boundsContain(\n bounds: WorldBounds,\n p: { x: number; y: number }\n): boolean {\n return (\n p.x >= bounds.minX &&\n p.x <= bounds.maxX &&\n p.y >= bounds.minY &&\n p.y <= bounds.maxY\n );\n}\n","/**\n * Optional structured `console.debug` for SDK internals; gated by {@link configureAgentPlayDebug} or `AGENT_PLAY_DEBUG=1`.\n */\ntype DebugConfigure = {\n /** When set, overrides environment: `true` forces debug on, `false` forces off. */\n debug?: boolean;\n};\n\n/**\n * In-memory override for debug enablement (undefined = follow env only).\n *\n * @remarks **Writers:** {@link configureAgentPlayDebug}, {@link resetAgentPlayDebug}.\n * **Readers:** {@link isAgentPlayDebugEnabled}.\n */\nlet configuredDebug: boolean | undefined;\n\n/**\n * Sets whether SDK debug logging is enabled regardless of `AGENT_PLAY_DEBUG`.\n *\n * @param opts.debug - `true` / `false` to force; omit to clear override.\n *\n * @remarks **Callers:** tests and user code. **Callees:** none.\n */\nexport function configureAgentPlayDebug(opts: DebugConfigure): void {\n configuredDebug = opts.debug ?? undefined;\n}\n\n/**\n * Clears the in-memory override so only `AGENT_PLAY_DEBUG` applies.\n *\n * @remarks **Callers:** tests. **Callees:** none.\n */\nexport function resetAgentPlayDebug(): void {\n configuredDebug = undefined;\n}\n\n/**\n * @returns Whether debug logging should run: override wins, else `AGENT_PLAY_DEBUG === \"1\"`.\n *\n * @remarks **Callers:** {@link agentPlayDebug}. **Callees:** `process.env` read.\n */\nexport function isAgentPlayDebugEnabled(): boolean {\n if (configuredDebug === false) return false;\n if (configuredDebug === true) return true;\n return process.env.AGENT_PLAY_DEBUG === \"1\";\n}\n\n/** Max length of JSON detail string before truncation in {@link safeSerialize}. */\nconst MAX_JSON_LENGTH = 2000;\n\n/**\n * Serializes `detail` for log lines, truncating long JSON and handling circular refs.\n *\n * @internal\n * @remarks **Callers:** {@link agentPlayDebug} only. **Callees:** `JSON.stringify` with replacer.\n */\nfunction safeSerialize(detail: unknown): string {\n if (detail === undefined) return \"\";\n try {\n const seen = new WeakSet<object>();\n const json = JSON.stringify(detail, (_k, v: unknown) => {\n if (typeof v === \"object\" && v !== null) {\n if (seen.has(v)) return \"[Circular]\";\n seen.add(v);\n }\n if (typeof v === \"bigint\") return String(v);\n return v;\n });\n if (typeof json !== \"string\") return String(detail);\n return json.length > MAX_JSON_LENGTH\n ? `${json.slice(0, MAX_JSON_LENGTH)}…`\n : json;\n } catch {\n return String(detail);\n }\n}\n\n/**\n * Emits `console.debug` when {@link isAgentPlayDebugEnabled} is true.\n *\n * @param scope - Short label (e.g. `\"langchain\"`).\n * @param message - Human-readable message.\n * @param detail - Optional object serialized by {@link safeSerialize}.\n *\n * @remarks **Callers:** {@link langchainRegistration} and other SDK modules. **Callees:** {@link isAgentPlayDebugEnabled}, {@link safeSerialize}.\n */\nexport function agentPlayDebug(\n scope: string,\n message: string,\n detail?: unknown\n): void {\n if (!isAgentPlayDebugEnabled()) return;\n const tail =\n detail === undefined ? \"\" : ` ${safeSerialize(detail)}`;\n console.debug(`[agent-play:${scope}] ${message}${tail}`);\n}\n","/**\n * LangChain adapter: derives tool names and assist metadata from a LangChain agent for\n * {@link import(\"../public-types.js\").LangChainAgentRegistration}.\n *\n * @remarks **Primary export:** {@link langchainRegistration}. Private helpers build error strings and\n * `AssistToolSpec` rows from Zod schemas when available.\n */\nimport { agentPlayDebug } from \"../lib/agent-play-debug.js\";\nimport type { AssistToolSpec, LangChainAgentRegistration } from \"../public-types.js\";\n\n/** Required tool name enforced by the watch UI contract. */\nconst CHAT_TOOL = \"chat_tool\";\n\n/**\n * Error text when the agent has no `tools` array.\n *\n * @remarks **Callers:** {@link langchainRegistration}. **Callees:** none.\n */\nfunction formatMissingAgentToolsError(): string {\n return [\n \"langchainRegistration: expected a LangChain agent with a tools array.\",\n \"\",\n \" Pass the object returned from createAgent({ tools: [...] }) (or equivalent) so tool names are available for the play world.\",\n \" The tools array must include named tools; see the separate message if \\\"chat_tool\\\" or assist_* tools are missing.\",\n ].join(\"\\n\");\n}\n\n/**\n * Error text when `chat_tool` is missing from tool names.\n *\n * @remarks **Callers:** {@link langchainRegistration}. **Callees:** none.\n */\nfunction formatMissingChatToolError(): string {\n return [\n \"langchainRegistration: missing required tool \\\"chat_tool\\\".\",\n \"\",\n \" Add a tool named \\\"chat_tool\\\" to your LangChain agent so the play world can show chat and proximity interactions.\",\n \" Example: tool(() => \\\"…\\\", { name: \\\"chat_tool\\\", description: \\\"…\\\", schema: z.object({ … }) })\",\n \"\",\n \" Tools whose names start with \\\"assist_\\\" are listed as assist actions on the watch UI; give each a Zod object schema so parameters can be shown in the UI.\",\n ].join(\"\\n\");\n}\n\n/**\n * Best-effort parameter shape from a Zod object schema’s `shape()` for UI hints.\n *\n * @remarks **Callers:** {@link describeTool}. **Callees:** none.\n */\nfunction parametersFromSchema(schema: unknown): Record<string, unknown> {\n if (schema === null || typeof schema !== \"object\") {\n return {};\n }\n const z = schema as {\n _def?: { typeName?: string; shape?: () => Record<string, unknown> };\n };\n if (typeof z._def?.shape !== \"function\") {\n return { _note: \"Pass a Zod object schema on each tool for parameter hints in the watch UI.\" };\n }\n const shape = z._def.shape();\n const out: Record<string, unknown> = {};\n for (const key of Object.keys(shape)) {\n out[key] = { field: key };\n }\n return out;\n}\n\n/**\n * Builds an {@link AssistToolSpec} from a LangChain tool descriptor.\n *\n * @remarks **Callers:** {@link langchainRegistration} for `assist_*` tools only. **Callees:** {@link parametersFromSchema}.\n */\nfunction describeTool(t: {\n name: string;\n description?: string;\n schema?: unknown;\n}): AssistToolSpec {\n return {\n name: t.name,\n description:\n typeof t.description === \"string\" && t.description.length > 0\n ? t.description\n : t.name,\n parameters: parametersFromSchema(t.schema),\n };\n}\n\n/**\n * Reads `agent.tools` or `agent.options.tools` from common LangChain agent shapes.\n *\n * @returns The tools array, or `null` if not found.\n *\n * @remarks **Callers:** {@link langchainRegistration} only. **Callees:** none.\n */\nfunction extractToolsArray(agent: unknown): unknown[] | null {\n if (typeof agent !== \"object\" || agent === null) {\n return null;\n }\n const a = agent as {\n tools?: unknown;\n options?: { tools?: unknown };\n };\n if (Array.isArray(a.tools)) {\n return a.tools;\n }\n if (\n a.options !== undefined &&\n typeof a.options === \"object\" &&\n a.options !== null &&\n \"tools\" in a.options &&\n Array.isArray((a.options as { tools: unknown }).tools)\n ) {\n return (a.options as { tools: unknown[] }).tools;\n }\n return null;\n}\n\n/**\n * Validates a LangChain-style agent exposes tools (including required `chat_tool`) and returns\n * a {@link LangChainAgentRegistration} for `addPlayer`.\n *\n * @param agent - Return value from `createAgent` (or equivalent) with a `tools` array.\n * @throws Error if tools are missing or `chat_tool` is not present.\n *\n * @remarks **Callers:** user code before `RemotePlayWorld.addPlayer`. **Callees:** {@link extractToolsArray},\n * {@link formatMissingAgentToolsError}, {@link formatMissingChatToolError}, {@link describeTool}, {@link agentPlayDebug}.\n */\nexport function langchainRegistration(\n agent: unknown\n): LangChainAgentRegistration {\n const rawTools = extractToolsArray(agent);\n if (rawTools === null) {\n throw new Error(formatMissingAgentToolsError());\n }\n const tools =\n rawTools as readonly { name: string; description?: string; schema?: unknown }[];\n const names = tools.map((x) => x.name);\n if (!names.includes(CHAT_TOOL)) {\n throw new Error(formatMissingChatToolError());\n }\n const assistTools = tools\n .filter((t) => t.name.startsWith(\"assist_\"))\n .map((t) => describeTool(t));\n agentPlayDebug(\"langchain\", \"langchainRegistration\", {\n toolCount: names.length,\n assistCount: assistTools.length,\n });\n return {\n type: \"langchain\",\n toolNames: names,\n assistTools,\n };\n}\n","import type {\n AgentPlayWorldMapAgentOccupant,\n AgentPlayWorldMapMcpOccupant,\n} from \"../public-types.js\";\n\nexport function parseAgentOccupantRow(\n raw: Record<string, unknown>\n): AgentPlayWorldMapAgentOccupant {\n if (typeof raw.agentId !== \"string\" || typeof raw.name !== \"string\") {\n throw new Error(\"occupant: agent needs agentId and name\");\n }\n if (typeof raw.x !== \"number\" || typeof raw.y !== \"number\") {\n throw new Error(\"occupant: agent needs numeric x and y\");\n }\n const base: AgentPlayWorldMapAgentOccupant = {\n kind: \"agent\",\n agentId: raw.agentId,\n name: raw.name,\n x: raw.x,\n y: raw.y,\n };\n let platform: string | undefined;\n if (typeof raw.platform === \"string\") {\n platform = raw.platform;\n } else if (typeof raw.agentType === \"string\") {\n platform = raw.agentType;\n }\n if (platform !== undefined) {\n return { ...base, platform };\n }\n return base;\n}\n\nexport function parseMcpOccupantRow(\n raw: Record<string, unknown>\n): AgentPlayWorldMapMcpOccupant {\n if (typeof raw.id !== \"string\" || typeof raw.name !== \"string\") {\n throw new Error(\"occupant: mcp needs id and name\");\n }\n if (typeof raw.x !== \"number\" || typeof raw.y !== \"number\") {\n throw new Error(\"occupant: mcp needs numeric x and y\");\n }\n const base: AgentPlayWorldMapMcpOccupant = {\n kind: \"mcp\",\n id: raw.id,\n name: raw.name,\n x: raw.x,\n y: raw.y,\n };\n if (typeof raw.url === \"string\") {\n return { ...base, url: raw.url };\n }\n return base;\n}\n","export const PLAYER_CHAIN_GENESIS_STABLE_KEY = \"__genesis__\" as const;\nexport const PLAYER_CHAIN_HEADER_STABLE_KEY = \"__header__\" as const;\n","/**\n * Parses **`playerChainNotify`** envelopes and merges {@link PlayerChainNodeResponse} slices into {@link AgentPlaySnapshot} (pure functions + fetch ordering for serialized RPC).\n */\n\nimport type {\n AgentPlaySnapshot,\n AgentPlayWorldMapAgentOccupant,\n AgentPlayWorldMapMcpOccupant,\n PlayerChainFanoutNotify,\n PlayerChainNotifyNodeRef,\n PlayerChainNodeResponse,\n} from \"../public-types.js\";\nimport {\n parseAgentOccupantRow,\n parseMcpOccupantRow,\n} from \"./parse-occupant-row.js\";\nimport {\n PLAYER_CHAIN_GENESIS_STABLE_KEY,\n PLAYER_CHAIN_HEADER_STABLE_KEY,\n} from \"./world-chain-keys.js\";\n\nfunction isRecord(v: unknown): v is Record<string, unknown> {\n return typeof v === \"object\" && v !== null;\n}\n\nfunction stableOccupantSortKey(\n occ: AgentPlayWorldMapAgentOccupant | AgentPlayWorldMapMcpOccupant\n): string {\n if (occ.kind === \"agent\") {\n return `agent:${occ.agentId}`;\n }\n return `mcp:${occ.id}`;\n}\n\nexport function sortNodeRefsForSerializedFetch(\n nodes: ReadonlyArray<PlayerChainNotifyNodeRef>\n): PlayerChainNotifyNodeRef[] {\n const removed = nodes.filter((n) => n.removed === true);\n const rest = nodes.filter((n) => n.removed !== true);\n removed.sort((a, b) => b.leafIndex - a.leafIndex);\n rest.sort((a, b) => a.leafIndex - b.leafIndex);\n return [...removed, ...rest];\n}\n\nexport function parsePlayerChainFanoutNotify(\n raw: unknown\n): PlayerChainFanoutNotify | undefined {\n if (!isRecord(raw)) {\n return undefined;\n }\n if (typeof raw.updatedAt !== \"string\" || raw.updatedAt.length === 0) {\n return undefined;\n }\n if (!Array.isArray(raw.nodes)) {\n return undefined;\n }\n const nodes: PlayerChainNotifyNodeRef[] = [];\n for (const row of raw.nodes) {\n if (!isRecord(row)) {\n return undefined;\n }\n if (typeof row.stableKey !== \"string\" || row.stableKey.length === 0) {\n return undefined;\n }\n if (typeof row.leafIndex !== \"number\" || !Number.isFinite(row.leafIndex)) {\n return undefined;\n }\n const ref: PlayerChainNotifyNodeRef = {\n stableKey: row.stableKey,\n leafIndex: row.leafIndex,\n };\n if (row.removed === true) {\n ref.removed = true;\n }\n if (typeof row.updatedAt === \"string\" && row.updatedAt.length > 0) {\n ref.updatedAt = row.updatedAt;\n }\n nodes.push(ref);\n }\n return { updatedAt: raw.updatedAt, nodes };\n}\n\nexport function parsePlayerChainFanoutNotifyFromSsePayload(\n sseData: unknown\n): PlayerChainFanoutNotify | undefined {\n if (!isRecord(sseData)) {\n return undefined;\n }\n return parsePlayerChainFanoutNotify(sseData.playerChainNotify);\n}\n\nexport function parsePlayerChainNodeRpcBody(json: unknown): PlayerChainNodeResponse {\n if (!isRecord(json) || !isRecord(json.node)) {\n throw new Error(\"getPlayerChainNode: invalid response shape\");\n }\n const n = json.node;\n if (n.kind === \"genesis\") {\n if (\n n.stableKey !== PLAYER_CHAIN_GENESIS_STABLE_KEY ||\n typeof n.text !== \"string\"\n ) {\n throw new Error(\"getPlayerChainNode: invalid genesis node\");\n }\n return {\n kind: \"genesis\",\n stableKey: PLAYER_CHAIN_GENESIS_STABLE_KEY,\n text: n.text,\n };\n }\n if (n.kind === \"header\") {\n if (\n n.stableKey !== PLAYER_CHAIN_HEADER_STABLE_KEY ||\n typeof n.sid !== \"string\"\n ) {\n throw new Error(\"getPlayerChainNode: invalid header node\");\n }\n const b = n.bounds;\n if (!isRecord(b)) {\n throw new Error(\"getPlayerChainNode: invalid header bounds\");\n }\n const { minX, minY, maxX, maxY } = b;\n if (\n typeof minX !== \"number\" ||\n typeof minY !== \"number\" ||\n typeof maxX !== \"number\" ||\n typeof maxY !== \"number\"\n ) {\n throw new Error(\"getPlayerChainNode: invalid header bounds\");\n }\n return {\n kind: \"header\",\n stableKey: PLAYER_CHAIN_HEADER_STABLE_KEY,\n sid: n.sid,\n bounds: { minX, minY, maxX, maxY },\n };\n }\n if (n.kind !== \"occupant\") {\n throw new Error(\"getPlayerChainNode: unknown node kind\");\n }\n if (typeof n.stableKey !== \"string\" || n.stableKey.length === 0) {\n throw new Error(\"getPlayerChainNode: invalid occupant stableKey\");\n }\n if (n.removed === true) {\n return { kind: \"occupant\", stableKey: n.stableKey, removed: true };\n }\n const occ = n.occupant;\n if (!isRecord(occ) || (occ.kind !== \"agent\" && occ.kind !== \"mcp\")) {\n throw new Error(\"getPlayerChainNode: invalid occupant payload\");\n }\n const occupant =\n occ.kind === \"agent\"\n ? parseAgentOccupantRow(occ)\n : parseMcpOccupantRow(occ);\n return {\n kind: \"occupant\",\n stableKey: n.stableKey,\n removed: false,\n occupant,\n };\n}\n\nexport function mergeSnapshotWithPlayerChainNode(\n snapshot: AgentPlaySnapshot,\n node: PlayerChainNodeResponse\n): AgentPlaySnapshot {\n if (node.kind === \"genesis\") {\n return snapshot;\n }\n if (node.kind === \"header\") {\n return {\n ...snapshot,\n sid: node.sid,\n worldMap: {\n ...snapshot.worldMap,\n bounds: node.bounds,\n },\n };\n }\n if (node.removed === true) {\n return {\n ...snapshot,\n worldMap: {\n ...snapshot.worldMap,\n occupants: snapshot.worldMap.occupants.filter(\n (o) => stableOccupantSortKey(o) !== node.stableKey\n ),\n },\n };\n }\n if (node.removed !== false) {\n throw new Error(\"mergeSnapshotWithPlayerChainNode: invalid occupant node\");\n }\n const occ = node.occupant;\n const key = stableOccupantSortKey(occ);\n const occupants = snapshot.worldMap.occupants.filter(\n (o) => stableOccupantSortKey(o) !== key\n );\n return {\n ...snapshot,\n worldMap: {\n ...snapshot.worldMap,\n occupants: [...occupants, occ],\n },\n };\n}\n","import type {\n AddPlayerInput,\n AgentPlaySnapshot,\n AgentPlayWorldMap,\n AgentPlayWorldMapBounds,\n Journey,\n RecordInteractionInput,\n RegisteredAgentSummary,\n RegisteredPlayer,\n PlayerChainNodeResponse,\n} from \"../public-types.js\";\nimport {\n parseAgentOccupantRow,\n parseMcpOccupantRow,\n} from \"./parse-occupant-row.js\";\nimport {\n mergeSnapshotWithPlayerChainNode,\n parsePlayerChainFanoutNotifyFromSsePayload,\n parsePlayerChainNodeRpcBody,\n sortNodeRefsForSerializedFetch,\n} from \"./player-chain-merge.js\";\n\nexport type RemotePlayWorldOptions = {\n baseUrl: string;\n apiKey: string;\n authToken?: string;\n};\n\nfunction formatMissingApiKeyError(): string {\n return [\n \"RemotePlayWorld: options.apiKey is required.\",\n \"\",\n \" Register an agent with `agent-play create` (after `agent-play login`) and use the printed API key.\",\n \" Pass it here so addPlayer can authenticate against the server repository when Redis is enabled.\",\n \" If the server has no agent repository (local dev), still pass a non-empty placeholder string.\",\n ].join(\"\\n\");\n}\n\nfunction normalizeBaseUrl(url: string): string {\n return url.replace(/\\/$/, \"\");\n}\n\nfunction isRecord(v: unknown): v is Record<string, unknown> {\n return typeof v === \"object\" && v !== null;\n}\n\nfunction parseBounds(raw: unknown): AgentPlayWorldMapBounds {\n if (!isRecord(raw)) {\n throw new Error(\"getWorldSnapshot: worldMap.bounds must be an object\");\n }\n const { minX, minY, maxX, maxY } = raw;\n if (\n typeof minX !== \"number\" ||\n typeof minY !== \"number\" ||\n typeof maxX !== \"number\" ||\n typeof maxY !== \"number\"\n ) {\n throw new Error(\n \"getWorldSnapshot: bounds need numeric minX, minY, maxX, maxY\"\n );\n }\n return { minX, minY, maxX, maxY };\n}\n\nfunction parseWorldMap(raw: unknown): AgentPlayWorldMap {\n if (!isRecord(raw)) {\n throw new Error(\"getWorldSnapshot: worldMap must be an object\");\n }\n const bounds = parseBounds(raw.bounds);\n const occ = raw.occupants;\n if (!Array.isArray(occ)) {\n throw new Error(\"getWorldSnapshot: worldMap.occupants must be an array\");\n }\n const occupants: AgentPlayWorldMap[\"occupants\"] = [];\n const coordKeys = new Set<string>();\n for (const row of occ) {\n if (!isRecord(row) || (row.kind !== \"agent\" && row.kind !== \"mcp\")) {\n throw new Error(\"getWorldSnapshot: each occupant must have kind agent or mcp\");\n }\n const xy =\n typeof row.x === \"number\" && typeof row.y === \"number\"\n ? `${row.x},${row.y}`\n : \"\";\n if (xy.length === 0) {\n throw new Error(\"getWorldSnapshot: occupant missing coordinates\");\n }\n if (coordKeys.has(xy)) {\n throw new Error(\"getWorldSnapshot: duplicate world map coordinate\");\n }\n coordKeys.add(xy);\n if (row.kind === \"agent\") {\n occupants.push(parseAgentOccupantRow(row));\n } else {\n occupants.push(parseMcpOccupantRow(row));\n }\n }\n return { bounds, occupants };\n}\n\nfunction parseAgentPlaySnapshot(snapshot: unknown): AgentPlaySnapshot {\n if (!isRecord(snapshot) || typeof snapshot.sid !== \"string\") {\n throw new Error(\"getWorldSnapshot: invalid snapshot\");\n }\n const worldMap = parseWorldMap(snapshot.worldMap);\n const out: AgentPlaySnapshot = { sid: snapshot.sid, worldMap };\n if (\"mcpServers\" in snapshot && Array.isArray(snapshot.mcpServers)) {\n const servers: NonNullable<AgentPlaySnapshot[\"mcpServers\"]> = [];\n for (const m of snapshot.mcpServers) {\n if (!isRecord(m) || typeof m.id !== \"string\" || typeof m.name !== \"string\") {\n continue;\n }\n const row: { id: string; name: string; url?: string } = {\n id: m.id,\n name: m.name,\n };\n if (typeof m.url === \"string\") row.url = m.url;\n servers.push(row);\n }\n if (servers.length > 0) out.mcpServers = servers;\n }\n return out;\n}\n\nfunction parseRegisteredAgentSummary(raw: unknown): RegisteredAgentSummary {\n if (!isRecord(raw)) {\n throw new Error(\"addPlayer: registeredAgent missing\");\n }\n if (typeof raw.agentId !== \"string\" || typeof raw.name !== \"string\") {\n throw new Error(\"addPlayer: registeredAgent.agentId and name required\");\n }\n if (!Array.isArray(raw.toolNames)) {\n throw new Error(\"addPlayer: registeredAgent.toolNames must be an array\");\n }\n const toolNames: string[] = [];\n for (const t of raw.toolNames) {\n if (typeof t !== \"string\") {\n throw new Error(\"addPlayer: registeredAgent.toolNames must be strings\");\n }\n toolNames.push(t);\n }\n if (\n typeof raw.zoneCount !== \"number\" ||\n typeof raw.yieldCount !== \"number\" ||\n typeof raw.flagged !== \"boolean\"\n ) {\n throw new Error(\"addPlayer: registeredAgent counters invalid\");\n }\n return {\n agentId: raw.agentId,\n name: raw.name,\n toolNames,\n zoneCount: raw.zoneCount,\n yieldCount: raw.yieldCount,\n flagged: raw.flagged,\n };\n}\n\nfunction formatInvalidHoldSecondsError(): string {\n return [\n \"RemotePlayWorld.hold().for(seconds): seconds must be a finite number.\",\n \"\",\n \" Example: await world.hold().for(3600)\",\n ].join(\"\\n\");\n}\n\nexport type RemotePlayWorldHold = {\n for: (seconds: number) => Promise<void>;\n};\n\n/**\n * HTTP client for the Agent Play web UI: session, snapshot RPC, mutating RPC with `sid`, and optional SSE subscription.\n *\n * Incremental updates: {@link RemotePlayWorld.subscribeWorldState} listens for **`playerChainNotify`** in SSE `data`, then fetches each changed leaf via {@link RemotePlayWorld.getPlayerChainNode} and merges with {@link mergeSnapshotWithPlayerChainNode}.\n */\nexport class RemotePlayWorld {\n private readonly apiBase: string;\n private readonly apiKey: string;\n private readonly authToken: string | undefined;\n private sid: string | null = null;\n private closed = false;\n private readonly closeListeners = new Set<() => void>();\n\n constructor(options: RemotePlayWorldOptions) {\n if (typeof options.apiKey !== \"string\" || options.apiKey.trim().length === 0) {\n throw new Error(formatMissingApiKeyError());\n }\n this.apiBase = normalizeBaseUrl(options.baseUrl);\n this.apiKey = options.apiKey.trim();\n this.authToken = options.authToken;\n }\n\n onClose(handler: () => void): () => void {\n this.closeListeners.add(handler);\n return () => {\n this.closeListeners.delete(handler);\n };\n }\n\n hold(): RemotePlayWorldHold {\n return {\n for: async (seconds: number) => {\n if (typeof seconds !== \"number\" || !Number.isFinite(seconds)) {\n throw new Error(formatInvalidHoldSecondsError());\n }\n const ms = Math.max(0, seconds) * 1000;\n await new Promise<void>((resolve) => {\n setTimeout(resolve, ms);\n });\n },\n };\n }\n\n private authHeaders(): Record<string, string> {\n if (this.authToken === undefined) return {};\n return { Authorization: `Bearer ${this.authToken}` };\n }\n\n private jsonHeaders(): Record<string, string> {\n return {\n \"content-type\": \"application/json\",\n ...this.authHeaders(),\n };\n }\n\n private mergeAuthFetch(\n input: RequestInfo | URL,\n init?: RequestInit\n ): Promise<Response> {\n const headers = new Headers(init?.headers);\n const auth = this.authHeaders();\n for (const [k, v] of Object.entries(auth)) {\n headers.set(k, v);\n }\n return fetch(input, { ...init, headers });\n }\n\n async connect(): Promise<void> {\n const res = await fetch(`${this.apiBase}/api/agent-play/session`, {\n headers: this.authHeaders(),\n });\n if (!res.ok) {\n throw new Error(`session failed: ${res.status}`);\n }\n const json: unknown = await res.json();\n if (!isRecord(json) || typeof json.sid !== \"string\" || json.sid.length === 0) {\n throw new Error(\"session: invalid response\");\n }\n this.sid = json.sid;\n }\n\n async close(): Promise<void> {\n if (this.closed) {\n return;\n }\n this.closed = true;\n for (const handler of Array.from(this.closeListeners)) {\n try {\n handler();\n } catch {\n // ignore listener errors\n }\n }\n }\n\n getSessionId(): string {\n if (this.sid === null) {\n throw new Error(\"RemotePlayWorld.connect() must be called first\");\n }\n return this.sid;\n }\n\n getPreviewUrl(): string {\n const u = new URL(\"/agent-play/watch\", this.apiBase);\n u.search = \"\";\n return u.toString();\n }\n\n async getWorldSnapshot(): Promise<AgentPlaySnapshot> {\n const res = await fetch(`${this.apiBase}/api/agent-play/sdk/rpc`, {\n method: \"POST\",\n headers: this.jsonHeaders(),\n body: JSON.stringify({ op: \"getWorldSnapshot\", payload: {} }),\n });\n const text = await res.text();\n if (!res.ok) {\n throw new Error(`getWorldSnapshot: ${res.status} ${text}`);\n }\n let json: unknown;\n try {\n json = JSON.parse(text) as unknown;\n } catch {\n throw new Error(\"getWorldSnapshot: invalid JSON\");\n }\n if (!isRecord(json) || !(\"snapshot\" in json)) {\n throw new Error(\"getWorldSnapshot: invalid response shape\");\n }\n return parseAgentPlaySnapshot(json.snapshot);\n }\n\n /**\n * Fetches one player-chain node (genesis, header, occupant row, or removal) for `stableKey`, same snapshot scope as {@link RemotePlayWorld.getWorldSnapshot}.\n */\n async getPlayerChainNode(stableKey: string): Promise<PlayerChainNodeResponse> {\n const trimmed = stableKey.trim();\n if (trimmed.length === 0) {\n throw new Error(\"getPlayerChainNode: stableKey is required\");\n }\n const res = await fetch(`${this.apiBase}/api/agent-play/sdk/rpc`, {\n method: \"POST\",\n headers: this.jsonHeaders(),\n body: JSON.stringify({\n op: \"getPlayerChainNode\",\n payload: { stableKey: trimmed },\n }),\n });\n const text = await res.text();\n if (!res.ok) {\n throw new Error(`getPlayerChainNode: ${res.status} ${text}`);\n }\n let json: unknown;\n try {\n json = JSON.parse(text) as unknown;\n } catch {\n throw new Error(\"getPlayerChainNode: invalid JSON\");\n }\n return parsePlayerChainNodeRpcBody(json);\n }\n\n /**\n * Opens the session SSE stream, emits an initial snapshot from {@link RemotePlayWorld.getWorldSnapshot}, then on each **`playerChainNotify`** merges nodes in deterministic order via {@link RemotePlayWorld.getPlayerChainNode}.\n */\n subscribeWorldState(callbacks: {\n onSnapshot: (snapshot: AgentPlaySnapshot) => void;\n onError?: (err: Error) => void;\n }): { close: () => void } {\n let closeSource: (() => void) | null = null;\n const task = (async () => {\n try {\n const { createEventSource } = await import(\"eventsource-client\");\n let snapshot = await this.getWorldSnapshot();\n callbacks.onSnapshot(snapshot);\n const source = createEventSource({\n url: `${this.apiBase}/api/agent-play/events?sid=${encodeURIComponent(\n this.getSessionId()\n )}`,\n fetch: (input, init) => this.mergeAuthFetch(input, init),\n });\n closeSource = () => {\n source.close();\n };\n for await (const msg of source) {\n if (typeof msg.data !== \"string\") {\n continue;\n }\n let data: unknown;\n try {\n data = JSON.parse(msg.data) as unknown;\n } catch {\n continue;\n }\n const notify = parsePlayerChainFanoutNotifyFromSsePayload(data);\n if (notify === undefined || notify.nodes.length === 0) {\n continue;\n }\n const ordered = sortNodeRefsForSerializedFetch(notify.nodes);\n for (const ref of ordered) {\n const node = await this.getPlayerChainNode(ref.stableKey);\n snapshot = mergeSnapshotWithPlayerChainNode(snapshot, node);\n }\n callbacks.onSnapshot(snapshot);\n }\n } catch (e) {\n callbacks.onError?.(\n e instanceof Error ? e : new Error(String(e))\n );\n }\n })();\n return {\n close: () => {\n closeSource?.();\n void task;\n },\n };\n }\n\n async addPlayer(input: AddPlayerInput): Promise<RegisteredPlayer> {\n const sid = this.getSessionId();\n const url = `${this.apiBase}/api/agent-play/players?sid=${encodeURIComponent(sid)}`;\n const res = await fetch(url, {\n method: \"POST\",\n headers: this.jsonHeaders(),\n body: JSON.stringify({\n name: input.name,\n type: input.type,\n agent: input.agent,\n apiKey: this.apiKey,\n agentId: input.agentId,\n }),\n });\n const bodyText = await res.text();\n if (!res.ok) {\n throw new Error(`addPlayer: ${res.status} ${bodyText}`);\n }\n let body: unknown;\n try {\n body = JSON.parse(bodyText) as unknown;\n } catch {\n throw new Error(\"addPlayer: invalid JSON\");\n }\n if (!isRecord(body)) {\n throw new Error(\"addPlayer: invalid response shape\");\n }\n const playerId = body.playerId;\n const previewUrl = body.previewUrl;\n if (typeof playerId !== \"string\" || typeof previewUrl !== \"string\") {\n throw new Error(\"addPlayer: missing playerId or previewUrl\");\n }\n const registeredAgent = parseRegisteredAgentSummary(body.registeredAgent);\n const now = new Date();\n return {\n id: playerId,\n name: input.name,\n sid,\n createdAt: now,\n updatedAt: now,\n previewUrl,\n registeredAgent,\n };\n }\n\n async recordInteraction(input: RecordInteractionInput): Promise<void> {\n await this.rpc(\"recordInteraction\", {\n playerId: input.playerId,\n role: input.role,\n text: input.text,\n });\n }\n\n async recordJourney(playerId: string, journey: Journey): Promise<void> {\n await this.rpc(\"recordJourney\", { playerId, journey });\n }\n\n async registerMcp(options: { name: string; url?: string }): Promise<string> {\n const sid = this.getSessionId();\n const url = `${this.apiBase}/api/agent-play/mcp/register?sid=${encodeURIComponent(sid)}`;\n const body: { name: string; url?: string } = { name: options.name };\n if (options.url !== undefined) {\n body.url = options.url;\n }\n const res = await fetch(url, {\n method: \"POST\",\n headers: this.jsonHeaders(),\n body: JSON.stringify(body),\n });\n const text = await res.text();\n if (!res.ok) {\n throw new Error(`registerMcp: ${res.status} ${text}`);\n }\n let json: unknown;\n try {\n json = JSON.parse(text) as unknown;\n } catch {\n throw new Error(\"registerMcp: invalid JSON\");\n }\n if (!isRecord(json) || typeof json.id !== \"string\") {\n throw new Error(\"registerMcp: invalid response\");\n }\n return json.id;\n }\n\n private async rpc(op: string, payload: unknown): Promise<void> {\n const sid = this.getSessionId();\n const url = `${this.apiBase}/api/agent-play/sdk/rpc?sid=${encodeURIComponent(sid)}`;\n const res = await fetch(url, {\n method: \"POST\",\n headers: this.jsonHeaders(),\n body: JSON.stringify({ op, payload }),\n });\n if (!res.ok) {\n const t = await res.text();\n throw new Error(`rpc ${op}: ${res.status} ${t}`);\n }\n }\n}\n"],"mappings":"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","names":["isRecord"]}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@agent-play/sdk",
3
3
  "type": "module",
4
- "version": "3.0.0",
4
+ "version": "3.0.2",
5
5
  "description": "Node.js SDK to register agents, stream world state, and connect to the Agent Play web UI over HTTP.",
6
6
  "main": "./dist/index.js",
7
7
  "types": "./dist/index.d.ts",