@agent-play/sdk 3.2.1 → 3.3.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/{browser-CvtF5qSC.d.ts → browser-BQR40I8R.d.ts} +104 -6
- package/dist/browser.d.ts +1 -1
- package/dist/browser.js +37 -3
- package/dist/chunk-WWIEHWZZ.js +649 -0
- package/dist/chunk-WWIEHWZZ.js.map +1 -0
- package/dist/index.d.ts +14 -10
- package/dist/index.js +107 -37
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/dist/chunk-U2M7HNYN.js +0 -303
- package/dist/chunk-U2M7HNYN.js.map +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/lib/world-bounds.ts","../src/lib/occupancy-grid-model.ts","../src/lib/world-chain-keys.ts","../src/lib/parse-occupant-row.ts","../src/lib/player-chain-merge.ts"],"sourcesContent":["/**\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/** Minimum playable span aligned with the watch canvas scrolling world (~20×20 cells). */\nexport const MINIMUM_PLAY_WORLD_BOUNDS: WorldBounds = {\n minX: 0,\n minY: 0,\n maxX: 19,\n maxY: 19,\n};\n\nexport function expandBoundsToMinimumPlayArea(bounds: WorldBounds): WorldBounds {\n return {\n minX: Math.min(bounds.minX, MINIMUM_PLAY_WORLD_BOUNDS.minX),\n minY: Math.min(bounds.minY, MINIMUM_PLAY_WORLD_BOUNDS.minY),\n maxX: Math.max(bounds.maxX, MINIMUM_PLAY_WORLD_BOUNDS.maxX),\n maxY: Math.max(bounds.maxY, MINIMUM_PLAY_WORLD_BOUNDS.maxY),\n };\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","import type { WorldBounds } from \"./world-bounds.js\";\r\nimport { MINIMUM_PLAY_WORLD_BOUNDS } from \"./world-bounds.js\";\r\n\r\nexport type OccupancyGridPoint = {\r\n x: number;\r\n y: number;\r\n};\r\n\r\nexport const OCCUPANCY_POINT_MULTIPLIER = 5;\r\nexport const CONTINUOUS_RENDER_OFFSET = 0.2;\r\nexport const DEFAULT_AGENT_SPAWN_MIN_DISTANCE = 0.9;\r\n\r\n/** Bottom-left zone Q1 — agents (spatial rectangle). */\r\nexport const SPATIAL_ZONE_INDEX_AGENTS = 0;\r\n/** Top-left zone Q3 — spaces / amenities (spatial rectangle). */\r\nexport const SPATIAL_ZONE_INDEX_SPACES = 2;\r\n\r\nexport function spatialZoneBounds(quartileIndex: number): WorldBounds {\r\n const { minX, maxX, minY, maxY } = MINIMUM_PLAY_WORLD_BOUNDS;\r\n const spanX = maxX - minX + 1;\r\n const spanY = maxY - minY + 1;\r\n const halfX = spanX / 2;\r\n const halfY = spanY / 2;\r\n const midLeftMax = minX + halfX - 1;\r\n const midRightMin = minX + halfX;\r\n const midBottomMax = minY + halfY - 1;\r\n const midTopMin = minY + halfY;\r\n\r\n switch (quartileIndex) {\r\n case 0:\r\n return { minX, maxX: midLeftMax, minY, maxY: midBottomMax };\r\n case 1:\r\n return { minX: midRightMin, maxX, minY, maxY: midBottomMax };\r\n case 2:\r\n return { minX, maxX: midLeftMax, minY: midTopMin, maxY };\r\n case 3:\r\n return { minX: midRightMin, maxX, minY: midTopMin, maxY };\r\n default:\r\n throw new Error(\r\n `spatialZoneBounds: invalid zone index ${String(quartileIndex)}`\r\n );\r\n }\r\n}\r\n\r\nexport function spatialZoneCenter(quartileIndex: number): OccupancyGridPoint {\r\n const b = spatialZoneBounds(quartileIndex);\r\n return {\r\n x: (b.minX + b.maxX + 1) / 2,\r\n y: (b.minY + b.maxY + 1) / 2,\r\n };\r\n}\r\n\r\nfunction enumerateIntegerCellsInBounds(bounds: WorldBounds): OccupancyGridPoint[] {\r\n const cells: OccupancyGridPoint[] = [];\r\n for (let x = bounds.minX; x <= bounds.maxX; x += 1) {\r\n for (let y = bounds.minY; y <= bounds.maxY; y += 1) {\r\n cells.push({ x, y });\r\n }\r\n }\r\n return cells;\r\n}\r\n\r\nexport function pointCellInSpatialZone(\r\n wx: number,\r\n wy: number,\r\n zoneIndex: number\r\n): boolean {\r\n const bounds = spatialZoneBounds(zoneIndex);\r\n const cx = Math.floor(wx);\r\n const cy = Math.floor(wy);\r\n return (\r\n cx >= bounds.minX &&\r\n cx <= bounds.maxX &&\r\n cy >= bounds.minY &&\r\n cy <= bounds.maxY\r\n );\r\n}\r\n\r\nexport function listOccupancyPointsForSpatialZone(\r\n zoneIndex: number\r\n): readonly OccupancyGridPoint[] {\r\n const bounds = spatialZoneBounds(zoneIndex);\r\n return enumerateIntegerCellsInBounds(bounds).flatMap((cell) => {\r\n const points: OccupancyGridPoint[] = [];\r\n for (let dx = 0; dx < OCCUPANCY_POINT_MULTIPLIER; dx += 1) {\r\n for (let dy = 0; dy < OCCUPANCY_POINT_MULTIPLIER; dy += 1) {\r\n points.push({\r\n x:\r\n cell.x +\r\n CONTINUOUS_RENDER_OFFSET +\r\n (dx + 0.5) / OCCUPANCY_POINT_MULTIPLIER,\r\n y:\r\n cell.y +\r\n CONTINUOUS_RENDER_OFFSET +\r\n (dy + 0.5) / OCCUPANCY_POINT_MULTIPLIER,\r\n });\r\n }\r\n }\r\n return points;\r\n });\r\n}\r\n\r\nexport function occupancyPointsGroupedBySpatialZone(): readonly (\r\n readonly OccupancyGridPoint[]\r\n)[] {\r\n return [\r\n listOccupancyPointsForSpatialZone(0),\r\n listOccupancyPointsForSpatialZone(1),\r\n listOccupancyPointsForSpatialZone(2),\r\n listOccupancyPointsForSpatialZone(3),\r\n ];\r\n}\r\n\r\n/** Agent spawns: Q1 only. */\r\nexport function listAllowedOccupancyPoints(): readonly OccupancyGridPoint[] {\r\n return listOccupancyPointsForSpatialZone(SPATIAL_ZONE_INDEX_AGENTS);\r\n}\r\n\r\nfunction quantizePosition(v: number): number {\r\n return Math.round(v * OCCUPANCY_POINT_MULTIPLIER) / OCCUPANCY_POINT_MULTIPLIER;\r\n}\r\n\r\nexport function occupancyKeyForPosition(x: number, y: number): string {\r\n return `${quantizePosition(x).toFixed(3)},${quantizePosition(y).toFixed(3)}`;\r\n}\r\n\r\nexport function buildRankedOccupancyPointsForSpatialZone(\r\n zoneIndex: number\r\n): OccupancyGridPoint[] {\r\n const center = spatialZoneCenter(zoneIndex);\r\n return [...listOccupancyPointsForSpatialZone(zoneIndex)].sort((left, right) => {\r\n const dl = Math.hypot(left.x - center.x, left.y - center.y);\r\n const dr = Math.hypot(right.x - center.x, right.y - center.y);\r\n if (dl !== dr) {\r\n return dl - dr;\r\n }\r\n if (left.x !== right.x) {\r\n return left.x - right.x;\r\n }\r\n return left.y - right.y;\r\n });\r\n}\r\n\r\n/** Back-compat: agent-zone ranking only. */\r\nexport function buildRankedOccupancyPoints(): OccupancyGridPoint[] {\r\n return buildRankedOccupancyPointsForSpatialZone(SPATIAL_ZONE_INDEX_AGENTS);\r\n}\r\n\r\nexport function boundingWorldRectForOccupancyPoints(\r\n points: readonly OccupancyGridPoint[]\r\n): { minX: number; maxX: number; minY: number; maxY: number } | null {\r\n const head = points[0];\r\n if (head === undefined) {\r\n return null;\r\n }\r\n let minX = head.x;\r\n let maxX = head.x;\r\n let minY = head.y;\r\n let maxY = head.y;\r\n for (const p of points) {\r\n if (p.x < minX) minX = p.x;\r\n if (p.x > maxX) maxX = p.x;\r\n if (p.y < minY) minY = p.y;\r\n if (p.y > maxY) maxY = p.y;\r\n }\r\n return { minX, maxX, minY, maxY };\r\n}\r\n\r\nexport function isAgentSpawnOccupancyPointAvailable(input: {\r\n point: OccupancyGridPoint;\r\n occupiedKeys: ReadonlySet<string>;\r\n existingOccupants: ReadonlyArray<{ x: number; y: number }>;\r\n minDistance?: number;\r\n}): boolean {\r\n const minDistance = input.minDistance ?? DEFAULT_AGENT_SPAWN_MIN_DISTANCE;\r\n const key = occupancyKeyForPosition(input.point.x, input.point.y);\r\n if (input.occupiedKeys.has(key)) {\r\n return false;\r\n }\r\n if (\r\n !pointCellInSpatialZone(\r\n input.point.x,\r\n input.point.y,\r\n SPATIAL_ZONE_INDEX_AGENTS\r\n )\r\n ) {\r\n return false;\r\n }\r\n for (const existing of input.existingOccupants) {\r\n const dist = Math.hypot(\r\n input.point.x - existing.x,\r\n input.point.y - existing.y\r\n );\r\n if (dist < minDistance) {\r\n return false;\r\n }\r\n }\r\n return true;\r\n}\r\n\r\nexport function isSpaceAnchorOccupancyPointAvailable(input: {\r\n point: OccupancyGridPoint;\r\n occupiedKeys: ReadonlySet<string>;\r\n existingOccupants: ReadonlyArray<{ x: number; y: number }>;\r\n structureAnchors: ReadonlyArray<{ x: number; y: number }>;\r\n minDistance: number;\r\n structureMinDistance: number;\r\n}): boolean {\r\n const key = occupancyKeyForPosition(input.point.x, input.point.y);\r\n if (input.occupiedKeys.has(key)) {\r\n return false;\r\n }\r\n if (\r\n !pointCellInSpatialZone(\r\n input.point.x,\r\n input.point.y,\r\n SPATIAL_ZONE_INDEX_SPACES\r\n )\r\n ) {\r\n return false;\r\n }\r\n for (const existing of input.existingOccupants) {\r\n const dist = Math.hypot(\r\n input.point.x - existing.x,\r\n input.point.y - existing.y\r\n );\r\n if (dist < input.minDistance) {\r\n return false;\r\n }\r\n }\r\n for (const anchor of input.structureAnchors) {\r\n const dist = Math.hypot(\r\n input.point.x - anchor.x,\r\n input.point.y - anchor.y\r\n );\r\n if (dist < input.structureMinDistance) {\r\n return false;\r\n }\r\n }\r\n return true;\r\n}\r\n\r\n","export const PLAYER_CHAIN_GENESIS_STABLE_KEY = \"__genesis__\" as const;\nexport const PLAYER_CHAIN_HEADER_STABLE_KEY = \"__header__\" as const;\n","import type {\n AgentPlaySpaceAmenityKind,\n AgentPlaySpaceCatalogEntry,\n AgentPlayWorldMapHumanOccupant,\n AgentPlayWorldMapAgentOccupant,\n AgentPlayWorldMapMcpOccupant,\n AgentPlayWorldMapStructureOccupant,\n} from \"../public-types.js\";\n\nconst SPACE_AMENITY_KINDS: readonly AgentPlaySpaceAmenityKind[] = [\n \"supermarket\",\n \"shop\",\n \"car_wash\",\n];\n\nfunction isSpaceAmenityKind(v: string): v is AgentPlaySpaceAmenityKind {\n return (SPACE_AMENITY_KINDS as readonly string[]).includes(v);\n}\n\nfunction isRecord(v: unknown): v is Record<string, unknown> {\n return typeof v === \"object\" && v !== null;\n}\n\nexport function parseHumanOccupantRow(\n raw: Record<string, unknown>\n): AgentPlayWorldMapHumanOccupant {\n if (typeof raw.id !== \"string\" || typeof raw.name !== \"string\") {\n throw new Error(\"occupant: human needs id and name\");\n }\n if (typeof raw.x !== \"number\" || typeof raw.y !== \"number\") {\n throw new Error(\"occupant: human needs numeric x and y\");\n }\n const base: AgentPlayWorldMapHumanOccupant = {\n kind: \"human\",\n id: raw.id,\n name: raw.name,\n x: raw.x,\n y: raw.y,\n };\n if (typeof raw.interactive === \"boolean\") {\n return { ...base, interactive: raw.interactive };\n }\n return base;\n}\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 if (typeof raw.nodeId === \"string\" && raw.nodeId.length > 0) {\n base.nodeId = raw.nodeId;\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 const enableP2a =\n raw.enableP2a === \"on\" || raw.enableP2a === \"off\" ? raw.enableP2a : undefined;\n const realtimeInstructions =\n typeof raw.realtimeInstructions === \"string\" &&\n raw.realtimeInstructions.trim().length > 0\n ? raw.realtimeInstructions\n : undefined;\n const realtimeRaw = raw.realtimeWebrtc;\n const realtimeWebrtc =\n typeof realtimeRaw === \"object\" &&\n realtimeRaw !== null &&\n typeof (realtimeRaw as Record<string, unknown>).clientSecret === \"string\" &&\n ((realtimeRaw as Record<string, unknown>).clientSecret as string).length > 0 &&\n typeof (realtimeRaw as Record<string, unknown>).model === \"string\" &&\n ((realtimeRaw as Record<string, unknown>).model as string).length > 0\n ? (() => {\n const record = realtimeRaw as Record<string, unknown>;\n const parsed: {\n clientSecret: string;\n model: string;\n expiresAt?: string;\n voice?: string;\n } = {\n clientSecret: record.clientSecret as string,\n model: record.model as string,\n };\n if (typeof record.expiresAt === \"string\" && record.expiresAt.length > 0) {\n parsed.expiresAt = record.expiresAt;\n }\n if (typeof record.voice === \"string\" && record.voice.length > 0) {\n parsed.voice = record.voice;\n }\n return parsed;\n })()\n : undefined;\n\n const out: AgentPlayWorldMapAgentOccupant = { ...base };\n if (platform !== undefined) {\n out.platform = platform;\n }\n if (enableP2a !== undefined) {\n out.enableP2a = enableP2a;\n }\n if (realtimeInstructions !== undefined) {\n out.realtimeInstructions = realtimeInstructions;\n }\n if (realtimeWebrtc !== undefined) {\n out.realtimeWebrtc = realtimeWebrtc;\n }\n return out;\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\nexport function parseSpaceCatalogEntry(\n raw: Record<string, unknown>\n): AgentPlaySpaceCatalogEntry {\n if (typeof raw.id !== \"string\" || typeof raw.name !== \"string\") {\n throw new Error(\"space catalog: id and name required\");\n }\n if (typeof raw.description !== \"string\") {\n throw new Error(\"space catalog: description required\");\n }\n if (typeof raw.designKey !== \"string\") {\n throw new Error(\"space catalog: designKey required\");\n }\n const ownerRaw = raw.owner;\n if (!isRecord(ownerRaw) || typeof ownerRaw.displayName !== \"string\") {\n throw new Error(\"space catalog: owner.displayName required\");\n }\n const amenitiesRaw = raw.amenities;\n if (!Array.isArray(amenitiesRaw) || amenitiesRaw.length === 0) {\n throw new Error(\"space catalog: amenities must be a non-empty array\");\n }\n const amenities: AgentPlaySpaceAmenityKind[] = [];\n for (const a of amenitiesRaw) {\n if (typeof a !== \"string\" || !isSpaceAmenityKind(a)) {\n throw new Error(\"space catalog: invalid amenity\");\n }\n amenities.push(a);\n }\n const owner: AgentPlaySpaceCatalogEntry[\"owner\"] = {\n displayName: ownerRaw.displayName,\n };\n if (typeof ownerRaw.playerId === \"string\" && ownerRaw.playerId.length > 0) {\n owner.playerId = ownerRaw.playerId;\n }\n if (typeof ownerRaw.nodeId === \"string\" && ownerRaw.nodeId.length > 0) {\n owner.nodeId = ownerRaw.nodeId;\n }\n const entry: AgentPlaySpaceCatalogEntry = {\n id: raw.id,\n name: raw.name,\n description: raw.description,\n designKey: raw.designKey,\n owner,\n amenities,\n };\n if (Array.isArray(raw.activityObjectIds)) {\n const ids: string[] = [];\n for (const x of raw.activityObjectIds) {\n if (typeof x === \"string\") {\n ids.push(x);\n }\n }\n if (ids.length > 0) {\n entry.activityObjectIds = ids;\n }\n }\n return entry;\n}\n\nexport function parseStructureOccupantRow(\n raw: Record<string, unknown>\n): AgentPlayWorldMapStructureOccupant {\n if (typeof raw.id !== \"string\" || typeof raw.name !== \"string\") {\n throw new Error(\"occupant: structure needs id and name\");\n }\n if (typeof raw.x !== \"number\" || typeof raw.y !== \"number\") {\n throw new Error(\"occupant: structure needs numeric x and y\");\n }\n if (typeof raw.worldId !== \"string\") {\n throw new Error(\"occupant: structure needs worldId\");\n }\n const spaceIdsRaw = raw.spaceIds;\n if (!Array.isArray(spaceIdsRaw) || spaceIdsRaw.length === 0) {\n throw new Error(\"occupant: structure needs non-empty spaceIds\");\n }\n const spaceIds: string[] = [];\n for (const s of spaceIdsRaw) {\n if (typeof s !== \"string\") {\n throw new Error(\"occupant: structure spaceIds must be strings\");\n }\n spaceIds.push(s);\n }\n const base: AgentPlayWorldMapStructureOccupant = {\n kind: \"structure\",\n id: raw.id,\n name: raw.name,\n x: raw.x,\n y: raw.y,\n worldId: raw.worldId,\n spaceIds,\n };\n if (raw.stationary === true) {\n base.stationary = true;\n }\n const pa = raw.primaryAmenity;\n if (typeof pa === \"string\" && isSpaceAmenityKind(pa)) {\n base.primaryAmenity = pa;\n }\n const am = raw.amenities;\n if (Array.isArray(am) && am.length > 0) {\n const list: AgentPlaySpaceAmenityKind[] = [];\n for (const x of am) {\n if (typeof x === \"string\" && isSpaceAmenityKind(x)) {\n list.push(x);\n }\n }\n if (list.length > 0) {\n base.amenities = list;\n }\n }\n return base;\n}\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 AgentPlayWorldMapHumanOccupant,\n AgentPlayWorldMapAgentOccupant,\n AgentPlayWorldMapMcpOccupant,\n AgentPlayWorldMapStructureOccupant,\n PlayerChainFanoutNotify,\n PlayerChainNotifyNodeRef,\n PlayerChainNodeResponse,\n} from \"../public-types.js\";\nimport {\n parseHumanOccupantRow,\n parseAgentOccupantRow,\n parseMcpOccupantRow,\n parseSpaceCatalogEntry,\n parseStructureOccupantRow,\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:\n | AgentPlayWorldMapHumanOccupant\n | AgentPlayWorldMapAgentOccupant\n | AgentPlayWorldMapMcpOccupant\n | AgentPlayWorldMapStructureOccupant\n): string {\n if (occ.kind === \"human\") {\n return `human:${occ.id}`;\n }\n if (occ.kind === \"agent\") {\n const nodeId = occ.nodeId;\n if (typeof nodeId !== \"string\" || nodeId.length === 0) {\n throw new Error(\"stableOccupantSortKey: invalid agent nodeId\");\n }\n return `agent:${nodeId}:${occ.agentId}`;\n }\n if (occ.kind === \"structure\") {\n return `structure:${occ.id}`;\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 === \"space\") {\n if (typeof n.stableKey !== \"string\" || n.stableKey.length === 0) {\n throw new Error(\"getPlayerChainNode: invalid space stableKey\");\n }\n if (n.removed === true) {\n return { kind: \"space\", stableKey: n.stableKey, removed: true };\n }\n const sp = n.space;\n if (!isRecord(sp)) {\n throw new Error(\"getPlayerChainNode: invalid space payload\");\n }\n return {\n kind: \"space\",\n stableKey: n.stableKey,\n removed: false,\n space: parseSpaceCatalogEntry(sp),\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 (\n !isRecord(occ) ||\n (occ.kind !== \"human\" &&\n occ.kind !== \"agent\" &&\n occ.kind !== \"mcp\" &&\n occ.kind !== \"structure\")\n ) {\n throw new Error(\"getPlayerChainNode: invalid occupant payload\");\n }\n const occupant =\n occ.kind === \"human\"\n ? parseHumanOccupantRow(occ)\n : occ.kind === \"agent\"\n ? parseAgentOccupantRow(occ)\n : occ.kind === \"mcp\"\n ? parseMcpOccupantRow(occ)\n : parseStructureOccupantRow(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 === \"space\") {\n const spaceIdFromKey = node.stableKey.startsWith(\"space:\")\n ? node.stableKey.slice(\"space:\".length)\n : \"\";\n if (node.removed === true) {\n return {\n ...snapshot,\n spaces: (snapshot.spaces ?? []).filter((s) => s.id !== spaceIdFromKey),\n };\n }\n const merged = (snapshot.spaces ?? []).filter((s) => s.id !== node.space.id);\n merged.push(node.space);\n merged.sort((a, b) => a.id.localeCompare(b.id));\n return { ...snapshot, spaces: merged };\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"],"mappings":"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","names":["isRecord"]}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { W as WorldInteractionRole, L as LangChainAgentRegistration, R as RemotePlayWorldInitAudioOptions, A as AgentPlaySnapshot, P as PlayerChainNodeResponse, a as AddAgentInput, b as RegisteredPlayer, c as AddPlayerInput, d as RecordInteractionInput, J as Journey } from './browser-
|
|
2
|
-
export { e as AgentPlayWorldMap, f as AgentPlayWorldMapAgentOccupant, g as AgentPlayWorldMapBounds, h as AgentPlayWorldMapMcpOccupant, i as AssistToolFieldType, j as AssistToolParameterSpec, k as AssistToolSpec, D as
|
|
1
|
+
import { W as WorldInteractionRole, L as LangChainAgentRegistration, R as RemotePlayWorldInitAudioOptions, A as AgentPlaySnapshot, P as PlayerChainNodeResponse, a as AddAgentInput, b as RegisteredPlayer, c as AddPlayerInput, d as RecordInteractionInput, J as Journey } from './browser-BQR40I8R.js';
|
|
2
|
+
export { e as AgentPlayWorldMap, f as AgentPlayWorldMapAgentOccupant, g as AgentPlayWorldMapBounds, h as AgentPlayWorldMapMcpOccupant, i as AssistToolFieldType, j as AssistToolParameterSpec, k as AssistToolSpec, C as CONTINUOUS_RENDER_OFFSET, D as DEFAULT_AGENT_SPAWN_MIN_DISTANCE, l as DestinationJourneyStep, m as JourneyStep, M as MINIMUM_PLAY_WORLD_BOUNDS, O as OCCUPANCY_POINT_MULTIPLIER, n as OccupancyGridPoint, o as OriginJourneyStep, p as P2aEnableFlag, q as PLAYER_CHAIN_GENESIS_STABLE_KEY, r as PLAYER_CHAIN_HEADER_STABLE_KEY, s as PlatformAgentInformation, t as PlayAgentInformation, u as PlayerChainFanoutNotify, v as PlayerChainGenesisNode, w as PlayerChainHeaderNode, x as PlayerChainNotifyNodeRef, y as PlayerChainOccupantPresentNode, z as PlayerChainOccupantRemovedNode, B as PositionedStep, E as RealtimeWebrtcClientSecret, F as RegisteredAgentSummary, G as RemotePlayWorldOpenAiAudioOptions, S as SPATIAL_ZONE_INDEX_AGENTS, H as SPATIAL_ZONE_INDEX_SPACES, I as StructureJourneyStep, K as WorldBounds, N as WorldJourneyUpdate, Y as YieldEventInfo, Z as ZoneEventInfo, Q as boundingWorldRectForOccupancyPoints, T as boundsContain, U as buildRankedOccupancyPoints, V as buildRankedOccupancyPointsForSpatialZone, X as clampWorldPosition, _ as expandBoundsToMinimumPlayArea, $ as isAgentSpawnOccupancyPointAvailable, a0 as isSpaceAnchorOccupancyPointAvailable, a1 as listAllowedOccupancyPoints, a2 as listOccupancyPointsForSpatialZone, a3 as mergeSnapshotWithPlayerChainNode, a4 as occupancyKeyForPosition, a5 as occupancyPointsGroupedBySpatialZone, a6 as parsePlayerChainFanoutNotify, a7 as parsePlayerChainFanoutNotifyFromSsePayload, a8 as parsePlayerChainNodeRpcBody, a9 as pointCellInSpatialZone, aa as sortNodeRefsForSerializedFetch, ab as spatialZoneBounds, ac as spatialZoneCenter } from './browser-BQR40I8R.js';
|
|
3
3
|
import { WorldIntercomEventPayload, IntercomResponsePayload } from '@agent-play/intercom';
|
|
4
|
-
export { AgentPlayAgentNodeEntry, AgentPlayCredentialsFile, loadAgentPlayCredentialsFileFromPath, loadAgentPlayCredentialsFileFromPathSync, loadRootKey, nodeCredentialsMaterialFromHumanPassphrase, parseAgentPlayCredentialsJson, resolveAgentPlayCredentialsPath } from '@agent-play/node-tools';
|
|
4
|
+
export { AgentPlayAgentNodeEntry, AgentPlayCredentialsFile, NodeCredentialMaterial, createNodeCredentialMaterial, loadAgentPlayCredentialsFileFromPath, loadAgentPlayCredentialsFileFromPathSync, loadRootKey, nodeCredentialFromHumanPhrase, nodeCredentialFromPasswHash, nodeCredentialsMaterialFromHumanPassphrase, parseAgentPlayCredentialsJson, resolveAgentPlayCredentialsPath, verifyStoredNodeCredential } from '@agent-play/node-tools';
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
7
|
* String constants and payload shapes for SSE and in-process world events.
|
|
@@ -111,8 +111,9 @@ declare function langchainRegistration(agent: unknown): LangChainAgentRegistrati
|
|
|
111
111
|
|
|
112
112
|
/**
|
|
113
113
|
* Root key (from `.root`) plus **human** passphrase as stored in **`~/.agent-play/credentials.json`**
|
|
114
|
-
* after **`agent-play create-main-node`**.
|
|
115
|
-
* **`
|
|
114
|
+
* after **`agent-play create-main-node`**. The SDK hashes the phrase once locally via
|
|
115
|
+
* **`nodeCredentialFromHumanPhrase`** and sends the resulting **`passwHash`** as the
|
|
116
|
+
* `x-node-passw` header and as the `passwHash` field in repository-backed requests.
|
|
116
117
|
*/
|
|
117
118
|
type RemotePlayWorldNodeCredentials = {
|
|
118
119
|
rootKey: string;
|
|
@@ -135,8 +136,8 @@ type RemotePlayWorldOptions = {
|
|
|
135
136
|
/** Options for {@link RemotePlayWorld.connect}. */
|
|
136
137
|
type RemotePlayWorldConnectOptions = {
|
|
137
138
|
/**
|
|
138
|
-
*
|
|
139
|
-
* When omitted,
|
|
139
|
+
* Main node id used for `POST /api/nodes/validate` as **`nodeId`** (not the derived credential id) and remembered for {@link RemotePlayWorld.addAgent} (`mainNodeId` on validate and register).
|
|
140
|
+
* When omitted, connect skips validate and addAgent uses the derived node id for main-parent fields.
|
|
140
141
|
*/
|
|
141
142
|
mainNodeId?: string;
|
|
142
143
|
};
|
|
@@ -180,11 +181,12 @@ declare class RemotePlayWorld {
|
|
|
180
181
|
private readonly rootKey;
|
|
181
182
|
/** Node id derived from hashed passphrase material + root (main or agent node id). */
|
|
182
183
|
private readonly derivedNodeId;
|
|
183
|
-
/** Hex
|
|
184
|
-
private readonly
|
|
184
|
+
/** Hex SHA-256 of the normalized human phrase; sent as `x-node-passw` and as `passwHash`. */
|
|
185
|
+
private readonly passwHash;
|
|
185
186
|
private readonly onSessionEvent;
|
|
186
187
|
private readonly transportLog;
|
|
187
188
|
private sid;
|
|
189
|
+
private configuredMainNodeId;
|
|
188
190
|
private closed;
|
|
189
191
|
private readonly closeListeners;
|
|
190
192
|
private readonly playerConnectionInfo;
|
|
@@ -201,7 +203,7 @@ declare class RemotePlayWorld {
|
|
|
201
203
|
private validateNodeIdentity;
|
|
202
204
|
/**
|
|
203
205
|
* Establishes the HTTP session via `GET /api/agent-play/session`. With {@link RemotePlayWorldConnectOptions.mainNodeId},
|
|
204
|
-
* validates node
|
|
206
|
+
* validates that node with `POST /api/nodes/validate` using **`nodeId: mainNodeId`** first.
|
|
205
207
|
*/
|
|
206
208
|
connect(options?: RemotePlayWorldConnectOptions): Promise<void>;
|
|
207
209
|
close(): Promise<void>;
|
|
@@ -232,6 +234,8 @@ declare class RemotePlayWorld {
|
|
|
232
234
|
/**
|
|
233
235
|
* Registers an automation agent using **agent node id** (`nodeId`), sent to the server as `agentId`.
|
|
234
236
|
*
|
|
237
|
+
* Runs `POST /api/nodes/validate` with **`nodeId`** / **`mainNodeId`** from {@link AddAgentInput} before registering.
|
|
238
|
+
*
|
|
235
239
|
* If {@link initAudio} was called and **`enableP2a`** is **`"on"`**, this call mints a per-agent
|
|
236
240
|
* OpenAI Realtime client secret and forwards it as `realtimeWebrtc`.
|
|
237
241
|
*/
|
package/dist/index.js
CHANGED
|
@@ -1,19 +1,38 @@
|
|
|
1
1
|
import {
|
|
2
|
+
CONTINUOUS_RENDER_OFFSET,
|
|
3
|
+
DEFAULT_AGENT_SPAWN_MIN_DISTANCE,
|
|
2
4
|
MINIMUM_PLAY_WORLD_BOUNDS,
|
|
5
|
+
OCCUPANCY_POINT_MULTIPLIER,
|
|
3
6
|
PLAYER_CHAIN_GENESIS_STABLE_KEY,
|
|
4
7
|
PLAYER_CHAIN_HEADER_STABLE_KEY,
|
|
8
|
+
SPATIAL_ZONE_INDEX_AGENTS,
|
|
9
|
+
SPATIAL_ZONE_INDEX_SPACES,
|
|
10
|
+
boundingWorldRectForOccupancyPoints,
|
|
5
11
|
boundsContain,
|
|
12
|
+
buildRankedOccupancyPoints,
|
|
13
|
+
buildRankedOccupancyPointsForSpatialZone,
|
|
6
14
|
clampWorldPosition,
|
|
7
15
|
expandBoundsToMinimumPlayArea,
|
|
16
|
+
isAgentSpawnOccupancyPointAvailable,
|
|
17
|
+
isSpaceAnchorOccupancyPointAvailable,
|
|
18
|
+
listAllowedOccupancyPoints,
|
|
19
|
+
listOccupancyPointsForSpatialZone,
|
|
8
20
|
mergeSnapshotWithPlayerChainNode,
|
|
21
|
+
occupancyKeyForPosition,
|
|
22
|
+
occupancyPointsGroupedBySpatialZone,
|
|
9
23
|
parseAgentOccupantRow,
|
|
10
24
|
parseHumanOccupantRow,
|
|
11
25
|
parseMcpOccupantRow,
|
|
12
26
|
parsePlayerChainFanoutNotify,
|
|
13
27
|
parsePlayerChainFanoutNotifyFromSsePayload,
|
|
14
28
|
parsePlayerChainNodeRpcBody,
|
|
15
|
-
|
|
16
|
-
|
|
29
|
+
parseSpaceCatalogEntry,
|
|
30
|
+
parseStructureOccupantRow,
|
|
31
|
+
pointCellInSpatialZone,
|
|
32
|
+
sortNodeRefsForSerializedFetch,
|
|
33
|
+
spatialZoneBounds,
|
|
34
|
+
spatialZoneCenter
|
|
35
|
+
} from "./chunk-WWIEHWZZ.js";
|
|
17
36
|
|
|
18
37
|
// src/world-events.ts
|
|
19
38
|
var SESSION_CONNECTED_EVENT = "session:connected";
|
|
@@ -90,17 +109,20 @@ function unwrapZodCell(cell) {
|
|
|
90
109
|
if (current === null || typeof current !== "object") {
|
|
91
110
|
return current;
|
|
92
111
|
}
|
|
93
|
-
const def = current._def;
|
|
94
|
-
if (!def
|
|
112
|
+
const def = current._def ?? current.def;
|
|
113
|
+
if (!def) {
|
|
95
114
|
return current;
|
|
96
115
|
}
|
|
97
|
-
const
|
|
98
|
-
if (typeName ===
|
|
116
|
+
const typeName = typeof def.typeName === "string" ? def.typeName : typeof def.type === "string" ? def.type : void 0;
|
|
117
|
+
if (typeName === void 0) {
|
|
118
|
+
return current;
|
|
119
|
+
}
|
|
120
|
+
if (typeName === "ZodOptional" || typeName === "ZodNullable" || typeName === "ZodDefault" || typeName === "optional" || typeName === "nullable" || typeName === "default") {
|
|
99
121
|
const inner = def.innerType;
|
|
100
122
|
current = inner !== null && typeof inner === "object" ? inner : void 0;
|
|
101
123
|
continue;
|
|
102
124
|
}
|
|
103
|
-
if (typeName === "ZodEffects") {
|
|
125
|
+
if (typeName === "ZodEffects" || typeName === "effects") {
|
|
104
126
|
current = def.schema;
|
|
105
127
|
continue;
|
|
106
128
|
}
|
|
@@ -113,14 +135,18 @@ function fieldTypeFromZodCell(cell) {
|
|
|
113
135
|
if (base === null || typeof base !== "object") {
|
|
114
136
|
return "string";
|
|
115
137
|
}
|
|
116
|
-
const
|
|
117
|
-
|
|
138
|
+
const def = base._def ?? base.def;
|
|
139
|
+
const typeName = def?.typeName;
|
|
140
|
+
const fallbackType = def?.type;
|
|
141
|
+
const ctorName = base.constructor?.name ?? "";
|
|
142
|
+
const kind = typeName ?? fallbackType ?? ctorName;
|
|
143
|
+
if (kind === "ZodNumber" || kind === "number") {
|
|
118
144
|
return "number";
|
|
119
145
|
}
|
|
120
|
-
if (
|
|
146
|
+
if (kind === "ZodBoolean" || kind === "boolean") {
|
|
121
147
|
return "boolean";
|
|
122
148
|
}
|
|
123
|
-
if (
|
|
149
|
+
if (kind === "ZodString" || kind === "string") {
|
|
124
150
|
return "string";
|
|
125
151
|
}
|
|
126
152
|
return "string";
|
|
@@ -130,10 +156,11 @@ function parametersFromSchema(schema) {
|
|
|
130
156
|
return {};
|
|
131
157
|
}
|
|
132
158
|
const z = schema;
|
|
133
|
-
|
|
159
|
+
const shapeRaw = z._def?.shape;
|
|
160
|
+
const shape = typeof shapeRaw === "function" ? shapeRaw() : shapeRaw !== void 0 && typeof shapeRaw === "object" ? shapeRaw : null;
|
|
161
|
+
if (shape === null) {
|
|
134
162
|
return { _note: "Pass a Zod object schema on each tool for parameter hints in the watch UI." };
|
|
135
163
|
}
|
|
136
|
-
const shape = z._def.shape();
|
|
137
164
|
const out = {};
|
|
138
165
|
for (const key of Object.keys(shape)) {
|
|
139
166
|
out[key] = {
|
|
@@ -188,10 +215,9 @@ function langchainRegistration(agent) {
|
|
|
188
215
|
// src/lib/remote-play-world.ts
|
|
189
216
|
import { randomUUID } from "crypto";
|
|
190
217
|
import {
|
|
191
|
-
deriveNodeIdFromPassword,
|
|
192
218
|
loadAgentPlayCredentialsFileFromPathSync,
|
|
193
219
|
loadRootKey,
|
|
194
|
-
|
|
220
|
+
nodeCredentialFromHumanPhrase,
|
|
195
221
|
resolveAgentPlayCredentialsPath
|
|
196
222
|
} from "@agent-play/node-tools";
|
|
197
223
|
import { HumanMessage } from "@langchain/core/messages";
|
|
@@ -357,9 +383,9 @@ function parseWorldMap(raw) {
|
|
|
357
383
|
const occupants = [];
|
|
358
384
|
const coordKeys = /* @__PURE__ */ new Set();
|
|
359
385
|
for (const row of occ) {
|
|
360
|
-
if (!isRecord(row) || row.kind !== "human" && row.kind !== "agent" && row.kind !== "mcp") {
|
|
386
|
+
if (!isRecord(row) || row.kind !== "human" && row.kind !== "agent" && row.kind !== "mcp" && row.kind !== "structure") {
|
|
361
387
|
throw new Error(
|
|
362
|
-
"getWorldSnapshot: each occupant must have kind human, agent, or
|
|
388
|
+
"getWorldSnapshot: each occupant must have kind human, agent, mcp, or structure"
|
|
363
389
|
);
|
|
364
390
|
}
|
|
365
391
|
const xy = typeof row.x === "number" && typeof row.y === "number" ? `${row.x},${row.y}` : "";
|
|
@@ -374,8 +400,10 @@ function parseWorldMap(raw) {
|
|
|
374
400
|
occupants.push(parseHumanOccupantRow(row));
|
|
375
401
|
} else if (row.kind === "agent") {
|
|
376
402
|
occupants.push(parseAgentOccupantRow(row));
|
|
377
|
-
} else {
|
|
403
|
+
} else if (row.kind === "mcp") {
|
|
378
404
|
occupants.push(parseMcpOccupantRow(row));
|
|
405
|
+
} else {
|
|
406
|
+
occupants.push(parseStructureOccupantRow(row));
|
|
379
407
|
}
|
|
380
408
|
}
|
|
381
409
|
return { bounds, occupants };
|
|
@@ -401,6 +429,18 @@ function parseAgentPlaySnapshot(snapshot) {
|
|
|
401
429
|
}
|
|
402
430
|
if (servers.length > 0) out.mcpServers = servers;
|
|
403
431
|
}
|
|
432
|
+
if ("spaces" in snapshot && Array.isArray(snapshot.spaces)) {
|
|
433
|
+
const catalog = [];
|
|
434
|
+
for (const row of snapshot.spaces) {
|
|
435
|
+
if (!isRecord(row)) {
|
|
436
|
+
continue;
|
|
437
|
+
}
|
|
438
|
+
catalog.push(parseSpaceCatalogEntry(row));
|
|
439
|
+
}
|
|
440
|
+
if (catalog.length > 0) {
|
|
441
|
+
out.spaces = catalog.sort((a, b) => a.id.localeCompare(b.id));
|
|
442
|
+
}
|
|
443
|
+
}
|
|
404
444
|
return out;
|
|
405
445
|
}
|
|
406
446
|
function parseRegisteredAgentSummary(raw) {
|
|
@@ -510,11 +550,12 @@ var RemotePlayWorld = class {
|
|
|
510
550
|
rootKey;
|
|
511
551
|
/** Node id derived from hashed passphrase material + root (main or agent node id). */
|
|
512
552
|
derivedNodeId;
|
|
513
|
-
/** Hex
|
|
514
|
-
|
|
553
|
+
/** Hex SHA-256 of the normalized human phrase; sent as `x-node-passw` and as `passwHash`. */
|
|
554
|
+
passwHash;
|
|
515
555
|
onSessionEvent;
|
|
516
556
|
transportLog;
|
|
517
557
|
sid = null;
|
|
558
|
+
configuredMainNodeId = null;
|
|
518
559
|
closed = false;
|
|
519
560
|
closeListeners = /* @__PURE__ */ new Set();
|
|
520
561
|
playerConnectionInfo = /* @__PURE__ */ new Map();
|
|
@@ -533,12 +574,12 @@ var RemotePlayWorld = class {
|
|
|
533
574
|
const nc = options.nodeCredentials ?? (creds === null ? void 0 : { rootKey: loadRootKey(), passw: creds.passw });
|
|
534
575
|
if (nc !== void 0 && typeof nc.rootKey === "string" && nc.rootKey.trim().length > 0 && typeof nc.passw === "string" && nc.passw.length > 0) {
|
|
535
576
|
this.rootKey = nc.rootKey.trim().toLowerCase();
|
|
536
|
-
const
|
|
537
|
-
|
|
538
|
-
this.derivedNodeId = deriveNodeIdFromPassword({
|
|
539
|
-
password: material,
|
|
577
|
+
const credential = nodeCredentialFromHumanPhrase({
|
|
578
|
+
phrase: nc.passw,
|
|
540
579
|
rootKey: this.rootKey
|
|
541
580
|
});
|
|
581
|
+
this.passwHash = credential.passwHash;
|
|
582
|
+
this.derivedNodeId = credential.nodeId;
|
|
542
583
|
return;
|
|
543
584
|
}
|
|
544
585
|
throw new Error(formatMissingCredentialsError());
|
|
@@ -581,7 +622,7 @@ var RemotePlayWorld = class {
|
|
|
581
622
|
authHeaders() {
|
|
582
623
|
return {
|
|
583
624
|
"x-node-id": this.derivedNodeId,
|
|
584
|
-
"x-node-passw": this.
|
|
625
|
+
"x-node-passw": this.passwHash
|
|
585
626
|
};
|
|
586
627
|
}
|
|
587
628
|
jsonHeaders() {
|
|
@@ -630,18 +671,21 @@ var RemotePlayWorld = class {
|
|
|
630
671
|
}
|
|
631
672
|
/**
|
|
632
673
|
* Establishes the HTTP session via `GET /api/agent-play/session`. With {@link RemotePlayWorldConnectOptions.mainNodeId},
|
|
633
|
-
* validates node
|
|
674
|
+
* validates that node with `POST /api/nodes/validate` using **`nodeId: mainNodeId`** first.
|
|
634
675
|
*/
|
|
635
676
|
async connect(options) {
|
|
636
677
|
const mainNodeIdOpt = options?.mainNodeId?.trim();
|
|
637
678
|
if (mainNodeIdOpt !== void 0 && mainNodeIdOpt.length > 0) {
|
|
679
|
+
this.configuredMainNodeId = mainNodeIdOpt;
|
|
638
680
|
const validation = await this.validateNodeIdentity({
|
|
639
|
-
nodeId:
|
|
640
|
-
mainNodeId:
|
|
681
|
+
nodeId: mainNodeIdOpt,
|
|
682
|
+
mainNodeId: void 0
|
|
641
683
|
});
|
|
642
684
|
console.info(
|
|
643
685
|
`[agent-play] Node identity validated (${validation.nodeKind ?? "unknown"}).`
|
|
644
686
|
);
|
|
687
|
+
} else {
|
|
688
|
+
this.configuredMainNodeId = null;
|
|
645
689
|
}
|
|
646
690
|
const res = await fetch(`${this.apiBase}/api/agent-play/session`, {
|
|
647
691
|
headers: this.authHeaders()
|
|
@@ -854,15 +898,16 @@ var RemotePlayWorld = class {
|
|
|
854
898
|
/**
|
|
855
899
|
* Registers an automation agent using **agent node id** (`nodeId`), sent to the server as `agentId`.
|
|
856
900
|
*
|
|
901
|
+
* Runs `POST /api/nodes/validate` with **`nodeId`** / **`mainNodeId`** from {@link AddAgentInput} before registering.
|
|
902
|
+
*
|
|
857
903
|
* If {@link initAudio} was called and **`enableP2a`** is **`"on"`**, this call mints a per-agent
|
|
858
904
|
* OpenAI Realtime client secret and forwards it as `realtimeWebrtc`.
|
|
859
905
|
*/
|
|
860
906
|
async addAgent(input) {
|
|
861
907
|
const sid = this.getSessionId();
|
|
862
|
-
const effectiveMainNodeId = this.derivedNodeId;
|
|
863
908
|
const validation = await this.validateNodeIdentity({
|
|
864
909
|
nodeId: input.nodeId,
|
|
865
|
-
mainNodeId:
|
|
910
|
+
mainNodeId: input.mainNodeId
|
|
866
911
|
});
|
|
867
912
|
console.info(
|
|
868
913
|
[
|
|
@@ -870,7 +915,7 @@ var RemotePlayWorld = class {
|
|
|
870
915
|
` status : validated`,
|
|
871
916
|
` nodeId : ${input.nodeId}`,
|
|
872
917
|
` nodeKind : ${validation.nodeKind ?? "unknown"}`,
|
|
873
|
-
` mainNode : ${
|
|
918
|
+
` mainNode : ${input.mainNodeId ?? "n/a"}`
|
|
874
919
|
].join("\n")
|
|
875
920
|
);
|
|
876
921
|
const url = `${this.apiBase}/api/agent-play/players?sid=${encodeURIComponent(sid)}`;
|
|
@@ -900,8 +945,8 @@ var RemotePlayWorld = class {
|
|
|
900
945
|
name: input.name,
|
|
901
946
|
type: input.type,
|
|
902
947
|
agent: input.agent,
|
|
903
|
-
mainNodeId:
|
|
904
|
-
|
|
948
|
+
mainNodeId: input.mainNodeId,
|
|
949
|
+
passwHash: this.passwHash,
|
|
905
950
|
agentId: input.nodeId,
|
|
906
951
|
connectionId,
|
|
907
952
|
leaseTtlSeconds,
|
|
@@ -1363,15 +1408,22 @@ var RemotePlayWorld = class {
|
|
|
1363
1408
|
|
|
1364
1409
|
// src/index.ts
|
|
1365
1410
|
import {
|
|
1411
|
+
createNodeCredentialMaterial,
|
|
1366
1412
|
loadAgentPlayCredentialsFileFromPath,
|
|
1367
1413
|
loadAgentPlayCredentialsFileFromPathSync as loadAgentPlayCredentialsFileFromPathSync2,
|
|
1368
1414
|
loadRootKey as loadRootKey2,
|
|
1369
|
-
|
|
1415
|
+
nodeCredentialFromHumanPhrase as nodeCredentialFromHumanPhrase2,
|
|
1416
|
+
nodeCredentialFromPasswHash,
|
|
1417
|
+
nodeCredentialsMaterialFromHumanPassphrase,
|
|
1370
1418
|
parseAgentPlayCredentialsJson,
|
|
1371
|
-
resolveAgentPlayCredentialsPath as resolveAgentPlayCredentialsPath2
|
|
1419
|
+
resolveAgentPlayCredentialsPath as resolveAgentPlayCredentialsPath2,
|
|
1420
|
+
verifyStoredNodeCredential
|
|
1372
1421
|
} from "@agent-play/node-tools";
|
|
1373
1422
|
export {
|
|
1423
|
+
CONTINUOUS_RENDER_OFFSET,
|
|
1424
|
+
DEFAULT_AGENT_SPAWN_MIN_DISTANCE,
|
|
1374
1425
|
MINIMUM_PLAY_WORLD_BOUNDS,
|
|
1426
|
+
OCCUPANCY_POINT_MULTIPLIER,
|
|
1375
1427
|
PLAYER_ADDED_EVENT,
|
|
1376
1428
|
PLAYER_CHAIN_GENESIS_STABLE_KEY,
|
|
1377
1429
|
PLAYER_CHAIN_HEADER_STABLE_KEY,
|
|
@@ -1381,28 +1433,46 @@ export {
|
|
|
1381
1433
|
SESSION_INVALID_EVENT,
|
|
1382
1434
|
SESSION_SSE_ERROR_EVENT,
|
|
1383
1435
|
SESSION_SSE_OPEN_EVENT,
|
|
1436
|
+
SPATIAL_ZONE_INDEX_AGENTS,
|
|
1437
|
+
SPATIAL_ZONE_INDEX_SPACES,
|
|
1384
1438
|
WORLD_AGENT_SIGNAL_EVENT,
|
|
1385
1439
|
WORLD_INTERACTION_EVENT,
|
|
1386
1440
|
WORLD_JOURNEY_EVENT,
|
|
1387
1441
|
agentPlayDebug,
|
|
1442
|
+
boundingWorldRectForOccupancyPoints,
|
|
1388
1443
|
boundsContain,
|
|
1444
|
+
buildRankedOccupancyPoints,
|
|
1445
|
+
buildRankedOccupancyPointsForSpatialZone,
|
|
1389
1446
|
clampWorldPosition,
|
|
1390
1447
|
configureAgentPlayDebug,
|
|
1448
|
+
createNodeCredentialMaterial,
|
|
1391
1449
|
expandBoundsToMinimumPlayArea,
|
|
1392
1450
|
intercomResultRecordFromLangChainInvokeOutput,
|
|
1393
1451
|
isAgentPlayDebugEnabled,
|
|
1452
|
+
isAgentSpawnOccupancyPointAvailable,
|
|
1453
|
+
isSpaceAnchorOccupancyPointAvailable,
|
|
1394
1454
|
langchainRegistration,
|
|
1455
|
+
listAllowedOccupancyPoints,
|
|
1456
|
+
listOccupancyPointsForSpatialZone,
|
|
1395
1457
|
loadAgentPlayCredentialsFileFromPath,
|
|
1396
1458
|
loadAgentPlayCredentialsFileFromPathSync2 as loadAgentPlayCredentialsFileFromPathSync,
|
|
1397
1459
|
loadRootKey2 as loadRootKey,
|
|
1398
1460
|
mergeSnapshotWithPlayerChainNode,
|
|
1399
|
-
|
|
1461
|
+
nodeCredentialFromHumanPhrase2 as nodeCredentialFromHumanPhrase,
|
|
1462
|
+
nodeCredentialFromPasswHash,
|
|
1463
|
+
nodeCredentialsMaterialFromHumanPassphrase,
|
|
1464
|
+
occupancyKeyForPosition,
|
|
1465
|
+
occupancyPointsGroupedBySpatialZone,
|
|
1400
1466
|
parseAgentPlayCredentialsJson,
|
|
1401
1467
|
parsePlayerChainFanoutNotify,
|
|
1402
1468
|
parsePlayerChainFanoutNotifyFromSsePayload,
|
|
1403
1469
|
parsePlayerChainNodeRpcBody,
|
|
1470
|
+
pointCellInSpatialZone,
|
|
1404
1471
|
resetAgentPlayDebug,
|
|
1405
1472
|
resolveAgentPlayCredentialsPath2 as resolveAgentPlayCredentialsPath,
|
|
1406
|
-
sortNodeRefsForSerializedFetch
|
|
1473
|
+
sortNodeRefsForSerializedFetch,
|
|
1474
|
+
spatialZoneBounds,
|
|
1475
|
+
spatialZoneCenter,
|
|
1476
|
+
verifyStoredNodeCredential
|
|
1407
1477
|
};
|
|
1408
1478
|
//# sourceMappingURL=index.js.map
|