@agent-play/sdk 3.3.5 → 3.3.8

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.d.ts CHANGED
@@ -1,5 +1,5 @@
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-da9E-kSP.js';
2
- export { e as AgentPlayWorldLayout, f as AgentPlayWorldLayoutZone, g as AgentPlayWorldMap, h as AgentPlayWorldMapAgentOccupant, i as AgentPlayWorldMapBounds, j as AgentPlayWorldMapMcpOccupant, k as AssistToolFieldType, l as AssistToolParameterSpec, m as AssistToolSpec, C as CONTINUOUS_RENDER_OFFSET, n as CarWashCar, o as CarWashCarSchema, p as ComputeTalkAgentPowerUpsEarnedInput, D as DEFAULT_AGENT_SPAWN_MIN_DISTANCE, q as DEFAULT_PLAYER_WALLET_BALANCE_USD, r as DestinationJourneyStep, s as JourneyStep, M as MINIMUM_PLAY_WORLD_BOUNDS, t as MINIMUM_STREET_LAYOUT_BOUNDS, O as OCCUPANCY_POINT_MULTIPLIER, u as OccupancyGridPoint, v as OccupantGroup, w as OriginJourneyStep, x as P2aEnableFlag, y as PLAYER_CHAIN_GENESIS_STABLE_KEY, z as PLAYER_CHAIN_HEADER_STABLE_KEY, B as PlatformAgentInformation, E as PlayAgentInformation, F as PlayerChainFanoutNotify, G as PlayerChainGenesisNode, H as PlayerChainHeaderNode, I as PlayerChainNotifyNodeRef, K as PlayerChainOccupantPresentNode, N as PlayerChainOccupantRemovedNode, Q as PlayerWallet, S as PlayerWalletSchema, T as PositionedStep, U as PurchaseRecord, V as PurchaseRecordSchema, X as RealtimeWebrtcClientSecret, Y as RegisteredAgentSummary, Z as RemotePlayWorldOpenAiAudioOptions, _ as SPACE_STRUCTURE_ANCHOR_MIN_DISTANCE, $ as SPATIAL_ZONE_INDEX_AGENTS, a0 as SPATIAL_ZONE_INDEX_SPACES, a1 as STREET_NAME_POOL, a2 as SaleState, a3 as SaleStateSchema, a4 as ShopItem, a5 as ShopItemSchema, a6 as SpaceContentItem, a7 as Street, a8 as StreetPoolEntry, a9 as StructureJourneyStep, aa as SupermarketItem, ab as SupermarketItemSchema, ac as TALK_AGENT_PU_BILLED_SECONDS_PER_UNIT, ad as TALK_AGENT_PU_MAX_PER_LEG, ae as TALK_PRICE_PER_60S_USD, af as TALK_PRICE_PER_SECOND_USD, ag as TALK_TICK_SECONDS, ah as WALLET_BUNDLE_OFFERS, ai as WalletBundleId, aj as WalletBundleOffer, ak as WorldBounds, al as WorldJourneyUpdate, am as WorldLayout, an as WorldLayoutBoundsField, ao as YieldEventInfo, ap as Zone, aq as ZoneEventInfo, ar as applyBoundsFieldUpdateToLayout, as as availableCellsForZone, at as boundingWorldRectForOccupancyPoints, au as boundsContain, av as buildRankedOccupancyPoints, aw as buildRankedOccupancyPointsForSpatialZone, ax as buildRankedOccupancyPointsForZone, ay as buildRankedOccupancyPointsInRect, az as cellsForZone, aA as centerOfZone, aB as clampWorldPosition, aC as computeTalkAgentPowerUpsEarned, aD as costForSeconds, aE as createInitialAgentRewardWallet, aF as createInitialPlayerWallet, aG as createVerticalStripSeedLayout, aH as desaturateColor, aI as enumerateIntegerCellsInRect, aJ as expandBoundsToMinimumPlayArea, aK as getStreetPoolEntryById, aL as getWalletBundleById, aM as isAgentSpawnOccupancyPointAvailable, aN as isAgentSpawnOccupancyPointAvailableInRect, aO as isAgentSpawnOccupancyPointAvailableInZone, aP as isItemAvailableForPurchase, aQ as isSpaceAnchorOccupancyPointAvailable, aR as isSpaceAnchorOccupancyPointAvailableInRect, aS as isSpaceAnchorOccupancyPointAvailableInZone, aT as listAllowedOccupancyPoints, aU as listOccupancyPointsForSpatialZone, aV as listOccupancyPointsForZone, aW as listOccupancyPointsInRect, aX as mergeSnapshotWithPlayerChainNode, aY as migrateWorldLayoutBounds, aZ as nextStreetFromPool, a_ as occupancyKeyForPosition, a$ as occupancyPointsGroupedBySpatialZone, b0 as occupancyPointsGroupedByZones, b1 as parsePlayerChainFanoutNotify, b2 as parsePlayerChainFanoutNotifyFromSsePayload, b3 as parsePlayerChainNodeRpcBody, b4 as pickZoneForGroup, b5 as pointCellInRect, b6 as pointCellInSpatialZone, b7 as pointCellInZone, b8 as primaryZoneForGroup, b9 as sortNodeRefsForSerializedFetch, ba as spatialZoneBounds, bb as spatialZoneCenter, bc as streetFromPoolEntry, bd as zonesForGroup } from './browser-da9E-kSP.js';
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-Djc4apJO.js';
2
+ export { e as AgentPlayWorldLayout, f as AgentPlayWorldLayoutZone, g as AgentPlayWorldMap, h as AgentPlayWorldMapAgentOccupant, i as AgentPlayWorldMapBounds, j as AgentPlayWorldMapMcpOccupant, k as AssistToolFieldType, l as AssistToolParameterSpec, m as AssistToolSpec, C as CONTINUOUS_RENDER_OFFSET, n as CarWashCar, o as CarWashCarSchema, p as ComputeTalkAgentPowerUpsEarnedInput, D as DEFAULT_AGENT_SPAWN_MIN_DISTANCE, q as DEFAULT_PLAYER_WALLET_BALANCE_USD, r as DestinationJourneyStep, s as JourneyStep, M as MINIMUM_PLAY_WORLD_BOUNDS, t as MINIMUM_STREET_LAYOUT_BOUNDS, O as OCCUPANCY_POINT_MULTIPLIER, u as OccupancyGridPoint, v as OccupantGroup, w as OriginJourneyStep, x as P2aEnableFlag, y as PLAYER_CHAIN_GENESIS_STABLE_KEY, z as PLAYER_CHAIN_HEADER_STABLE_KEY, B as PlatformAgentInformation, E as PlayAgentInformation, F as PlayerChainFanoutNotify, G as PlayerChainGenesisNode, H as PlayerChainHeaderNode, I as PlayerChainNotifyNodeRef, K as PlayerChainOccupantPresentNode, N as PlayerChainOccupantRemovedNode, Q as PlayerWallet, S as PlayerWalletSchema, T as PositionedStep, U as PurchaseRecord, V as PurchaseRecordSchema, X as RealtimeWebrtcClientSecret, Y as RegisteredAgentSummary, Z as RemotePlayWorldOpenAiAudioOptions, _ as SPACE_STRUCTURE_ANCHOR_MIN_DISTANCE, $ as SPATIAL_ZONE_INDEX_AGENTS, a0 as SPATIAL_ZONE_INDEX_SPACES, a1 as STREET_NAME_POOL, a2 as SaleState, a3 as SaleStateSchema, a4 as ShopItem, a5 as ShopItemSchema, a6 as SpaceContentItem, a7 as Street, a8 as StreetPoolEntry, a9 as StructureJourneyStep, aa as SupermarketItem, ab as SupermarketItemSchema, ac as TALK_AGENT_PU_BILLED_SECONDS_PER_UNIT, ad as TALK_AGENT_PU_MAX_PER_LEG, ae as TALK_PRICE_PER_60S_USD, af as TALK_PRICE_PER_SECOND_USD, ag as TALK_TICK_SECONDS, ah as WALLET_BUNDLE_OFFERS, ai as WalletBundleId, aj as WalletBundleOffer, ak as WorldBounds, al as WorldJourneyUpdate, am as WorldLayout, an as WorldLayoutBoundsField, ao as YieldEventInfo, ap as Zone, aq as ZoneEventInfo, ar as applyBoundsFieldUpdateToLayout, as as availableCellsForZone, at as boundingWorldRectForOccupancyPoints, au as boundsContain, av as buildRankedOccupancyPoints, aw as buildRankedOccupancyPointsForSpatialZone, ax as buildRankedOccupancyPointsForZone, ay as buildRankedOccupancyPointsInRect, az as cellsForZone, aA as centerOfZone, aB as clampWorldPosition, aC as computeTalkAgentPowerUpsEarned, aD as costForSeconds, aE as createInitialAgentRewardWallet, aF as createInitialPlayerWallet, aG as createVerticalStripSeedLayout, aH as desaturateColor, aI as enumerateIntegerCellsInRect, aJ as expandBoundsToMinimumPlayArea, aK as getStreetPoolEntryById, aL as getWalletBundleById, aM as isAgentSpawnOccupancyPointAvailable, aN as isAgentSpawnOccupancyPointAvailableInRect, aO as isAgentSpawnOccupancyPointAvailableInZone, aP as isItemAvailableForPurchase, aQ as isSpaceAnchorOccupancyPointAvailable, aR as isSpaceAnchorOccupancyPointAvailableInRect, aS as isSpaceAnchorOccupancyPointAvailableInZone, aT as listAllowedOccupancyPoints, aU as listOccupancyPointsForSpatialZone, aV as listOccupancyPointsForZone, aW as listOccupancyPointsInRect, aX as mergeSnapshotWithPlayerChainNode, aY as migrateWorldLayoutBounds, aZ as nextStreetFromPool, a_ as occupancyKeyForPosition, a$ as occupancyPointsGroupedBySpatialZone, b0 as occupancyPointsGroupedByZones, b1 as parsePlayerChainFanoutNotify, b2 as parsePlayerChainFanoutNotifyFromSsePayload, b3 as parsePlayerChainNodeRpcBody, b4 as pickZoneForGroup, b5 as pointCellInRect, b6 as pointCellInSpatialZone, b7 as pointCellInZone, b8 as primaryZoneForGroup, b9 as sortNodeRefsForSerializedFetch, ba as spatialZoneBounds, bb as spatialZoneCenter, bc as streetFromPoolEntry, bd as zonesForGroup } from './browser-Djc4apJO.js';
3
3
  import { WorldIntercomEventPayload, IntercomResponsePayload } from '@agent-play/intercom';
4
4
  export { AgentPlayAgentNodeEntry, AgentPlayCredentialsFile, NodeCredentialMaterial, createNodeCredentialMaterial, loadAgentPlayCredentialsFileFromPath, loadAgentPlayCredentialsFileFromPathSync, loadRootKey, nodeCredentialFromHumanPhrase, nodeCredentialFromPasswHash, nodeCredentialsMaterialFromHumanPassphrase, parseAgentPlayCredentialsJson, resolveAgentPlayCredentialsPath, verifyStoredNodeCredential } from '@agent-play/node-tools';
5
5
  import 'zod';
@@ -36,6 +36,8 @@ declare const WORLD_INTERACTION_EVENT = "world:interaction";
36
36
  declare const WORLD_AGENT_SIGNAL_EVENT = "world:agent_signal";
37
37
  /** Full journey + path update for a player. */
38
38
  declare const WORLD_JOURNEY_EVENT = "world:journey";
39
+ /** Ephemeral human positions (not persisted on the world snapshot). */
40
+ declare const WORLD_GEOGRAPHY_EVENT = "world:geography";
39
41
  /**
40
42
  * Payload for {@link WORLD_AGENT_SIGNAL_EVENT}.
41
43
  *
@@ -124,7 +126,12 @@ type RemotePlayWorldLogging = "off" | "on";
124
126
  type RemotePlayWorldOptions = {
125
127
  baseUrl?: string;
126
128
  /**
127
- * `rootKey` from `.root` and **`passw`** human phrase from **`credentials.json`** (see **`loadAgentPlayCredentialsFileFromPathSync`** in **@agent-play/node-tools**).
129
+ * Main node bootstrap credentials: `rootKey` from `.root` and **`passw`** human phrase for the
130
+ * main node (session connect, snapshot, SSE). Alias: **`nodeCredentials`**.
131
+ */
132
+ mainNodeCredentials?: RemotePlayWorldNodeCredentials;
133
+ /**
134
+ * @deprecated Alias for {@link RemotePlayWorldOptions.mainNodeCredentials}.
128
135
  */
129
136
  nodeCredentials?: RemotePlayWorldNodeCredentials;
130
137
  /** Called for session lifecycle events (`session:connected`, `session:closed`; see `world-events`). */
@@ -180,16 +187,17 @@ type SubscribeIntercomCommandsOptions = ({
180
187
  declare class RemotePlayWorld {
181
188
  private readonly apiBase;
182
189
  private readonly rootKey;
183
- /** Node id derived from hashed passphrase material + root (main or agent node id). */
184
- private readonly derivedNodeId;
185
- /** Hex SHA-256 of the normalized human phrase; sent as `x-node-passw` and as `passwHash`. */
186
- private readonly passwHash;
190
+ /** Main node id derived from main passphrase material (session bootstrap). */
191
+ private readonly mainDerivedNodeId;
192
+ /** Main node passwHash (session bootstrap, snapshot, SSE). */
193
+ private readonly mainPasswHash;
187
194
  private readonly onSessionEvent;
188
195
  private readonly transportLog;
189
196
  private sid;
190
197
  private configuredMainNodeId;
191
198
  private closed;
192
199
  private readonly closeListeners;
200
+ private readonly playerAgentCredentials;
193
201
  private readonly playerConnectionInfo;
194
202
  private audioInitOptions;
195
203
  constructor(options?: RemotePlayWorldOptions);
@@ -198,8 +206,15 @@ declare class RemotePlayWorld {
198
206
  private emitSessionEvent;
199
207
  onClose(handler: () => void): () => void;
200
208
  hold(): RemotePlayWorldHold;
201
- private authHeaders;
209
+ private credentialFromHumanPhrase;
210
+ private resolveAgentCredential;
211
+ private mainAuthHeaders;
212
+ private agentAuthHeaders;
213
+ private agentAuthHeadersForPlayer;
202
214
  private jsonHeaders;
215
+ private mainJsonHeaders;
216
+ private agentJsonHeaders;
217
+ private agentJsonHeadersForPlayer;
203
218
  private mergeAuthFetch;
204
219
  private validateNodeIdentity;
205
220
  /**
@@ -271,4 +286,4 @@ declare class RemotePlayWorld {
271
286
  */
272
287
  declare function intercomResultRecordFromLangChainInvokeOutput(output: unknown): Record<string, unknown>;
273
288
 
274
- export { AddAgentInput, AddPlayerInput, AgentPlaySnapshot, type IntercomToolExecutor, Journey, LangChainAgentRegistration, PLAYER_ADDED_EVENT, PlayerChainNodeResponse, RecordInteractionInput, RegisteredPlayer, RemotePlayWorld, type RemotePlayWorldConnectOptions, type RemotePlayWorldHold, RemotePlayWorldInitAudioOptions, type RemotePlayWorldLogging, type RemotePlayWorldNodeCredentials, type RemotePlayWorldOptions, type RemotePlayWorldSessionEvent, SESSION_CLOSED_EVENT, SESSION_CONNECTED_EVENT, SESSION_INVALID_EVENT, SESSION_SSE_ERROR_EVENT, SESSION_SSE_OPEN_EVENT, type SubscribeIntercomCommandsOptions, WORLD_AGENT_SIGNAL_EVENT, WORLD_INTERACTION_EVENT, WORLD_JOURNEY_EVENT, type WorldAgentSignalPayload, type WorldInteractionPayload, WorldInteractionRole, agentPlayDebug, configureAgentPlayDebug, intercomResultRecordFromLangChainInvokeOutput, isAgentPlayDebugEnabled, langchainRegistration, resetAgentPlayDebug };
289
+ export { AddAgentInput, AddPlayerInput, AgentPlaySnapshot, type IntercomToolExecutor, Journey, LangChainAgentRegistration, PLAYER_ADDED_EVENT, PlayerChainNodeResponse, RecordInteractionInput, RegisteredPlayer, RemotePlayWorld, type RemotePlayWorldConnectOptions, type RemotePlayWorldHold, RemotePlayWorldInitAudioOptions, type RemotePlayWorldLogging, type RemotePlayWorldNodeCredentials, type RemotePlayWorldOptions, type RemotePlayWorldSessionEvent, SESSION_CLOSED_EVENT, SESSION_CONNECTED_EVENT, SESSION_INVALID_EVENT, SESSION_SSE_ERROR_EVENT, SESSION_SSE_OPEN_EVENT, type SubscribeIntercomCommandsOptions, WORLD_AGENT_SIGNAL_EVENT, WORLD_GEOGRAPHY_EVENT, WORLD_INTERACTION_EVENT, WORLD_JOURNEY_EVENT, type WorldAgentSignalPayload, type WorldInteractionPayload, WorldInteractionRole, agentPlayDebug, configureAgentPlayDebug, intercomResultRecordFromLangChainInvokeOutput, isAgentPlayDebugEnabled, langchainRegistration, resetAgentPlayDebug };
package/dist/index.js CHANGED
@@ -79,7 +79,7 @@ import {
79
79
  spatialZoneCenter,
80
80
  streetFromPoolEntry,
81
81
  zonesForGroup
82
- } from "./chunk-BCDEUIYP.js";
82
+ } from "./chunk-SLAPRNMF.js";
83
83
 
84
84
  // src/world-events.ts
85
85
  var SESSION_CONNECTED_EVENT = "session:connected";
@@ -91,6 +91,7 @@ var PLAYER_ADDED_EVENT = "world:player_added";
91
91
  var WORLD_INTERACTION_EVENT = "world:interaction";
92
92
  var WORLD_AGENT_SIGNAL_EVENT = "world:agent_signal";
93
93
  var WORLD_JOURNEY_EVENT = "world:journey";
94
+ var WORLD_GEOGRAPHY_EVENT = "world:geography";
94
95
 
95
96
  // src/lib/agent-play-debug.ts
96
97
  var configuredDebug;
@@ -136,7 +137,8 @@ function formatMissingAgentToolsError() {
136
137
  return [
137
138
  "langchainRegistration: expected a LangChain agent with a tools array.",
138
139
  "",
139
- " Pass the object returned from createAgent({ tools: [...] }) (or equivalent) so tool names are available for the play world.",
140
+ " Pass the object returned from createAgent({ tools: [...] }) (or equivalent) so tool names are available for assist/chat UI.",
141
+ " Tool names no longer spawn map structures; author spaces separately with an owner (see world map v3 docs).",
140
142
  ' The tools array must include named tools; see the separate message if "chat_tool" or assist_* tools are missing.'
141
143
  ].join("\n");
142
144
  }
@@ -394,7 +396,7 @@ var PLAYER_CONNECTION_HEARTBEAT_MAX_ATTEMPTS = 10;
394
396
  var PLAYER_CONNECTION_HEARTBEAT_RETRY_DELAY_MS = 1e4;
395
397
  function formatMissingCredentialsError() {
396
398
  return [
397
- "RemotePlayWorld: provide nodeCredentials: { rootKey, passw },",
399
+ "RemotePlayWorld: provide mainNodeCredentials: { rootKey, passw },",
398
400
  "or run agent-play create-main-node so ~/.agent-play/credentials.json exists."
399
401
  ].join(" ");
400
402
  }
@@ -605,16 +607,17 @@ function normalizeIntercomSubscribePlayerIds(options) {
605
607
  var RemotePlayWorld = class {
606
608
  apiBase;
607
609
  rootKey;
608
- /** Node id derived from hashed passphrase material + root (main or agent node id). */
609
- derivedNodeId;
610
- /** Hex SHA-256 of the normalized human phrase; sent as `x-node-passw` and as `passwHash`. */
611
- passwHash;
610
+ /** Main node id derived from main passphrase material (session bootstrap). */
611
+ mainDerivedNodeId;
612
+ /** Main node passwHash (session bootstrap, snapshot, SSE). */
613
+ mainPasswHash;
612
614
  onSessionEvent;
613
615
  transportLog;
614
616
  sid = null;
615
617
  configuredMainNodeId = null;
616
618
  closed = false;
617
619
  closeListeners = /* @__PURE__ */ new Set();
620
+ playerAgentCredentials = /* @__PURE__ */ new Map();
618
621
  playerConnectionInfo = /* @__PURE__ */ new Map();
619
622
  audioInitOptions = null;
620
623
  constructor(options = {}) {
@@ -628,15 +631,15 @@ var RemotePlayWorld = class {
628
631
  this.apiBase = normalizeBaseUrl(resolvedBaseUrl);
629
632
  this.onSessionEvent = options.onSessionEvent;
630
633
  this.transportLog = options.logging === "on";
631
- const nc = options.nodeCredentials ?? (creds === null ? void 0 : { rootKey: loadRootKey(), passw: creds.passw });
634
+ const nc = options.mainNodeCredentials ?? options.nodeCredentials ?? (creds === null ? void 0 : { rootKey: loadRootKey(), passw: creds.passw });
632
635
  if (nc !== void 0 && typeof nc.rootKey === "string" && nc.rootKey.trim().length > 0 && typeof nc.passw === "string" && nc.passw.length > 0) {
633
636
  this.rootKey = nc.rootKey.trim().toLowerCase();
634
637
  const credential = nodeCredentialFromHumanPhrase({
635
638
  phrase: nc.passw,
636
639
  rootKey: this.rootKey
637
640
  });
638
- this.passwHash = credential.passwHash;
639
- this.derivedNodeId = credential.nodeId;
641
+ this.mainPasswHash = credential.passwHash;
642
+ this.mainDerivedNodeId = credential.nodeId;
640
643
  return;
641
644
  }
642
645
  throw new Error(formatMissingCredentialsError());
@@ -676,21 +679,58 @@ var RemotePlayWorld = class {
676
679
  }
677
680
  };
678
681
  }
679
- authHeaders() {
682
+ credentialFromHumanPhrase(phrase) {
683
+ const credential = nodeCredentialFromHumanPhrase({
684
+ phrase,
685
+ rootKey: this.rootKey
686
+ });
687
+ return { nodeId: credential.nodeId, passwHash: credential.passwHash };
688
+ }
689
+ resolveAgentCredential(input) {
690
+ const phrase = input.agentPassphrase !== void 0 && input.agentPassphrase.length > 0 ? input.agentPassphrase : void 0;
691
+ if (phrase === void 0) {
692
+ return { nodeId: input.nodeId.trim(), passwHash: this.mainPasswHash };
693
+ }
694
+ const derived = this.credentialFromHumanPhrase(phrase);
695
+ return { nodeId: input.nodeId.trim(), passwHash: derived.passwHash };
696
+ }
697
+ mainAuthHeaders() {
680
698
  return {
681
- "x-node-id": this.derivedNodeId,
682
- "x-node-passw": this.passwHash
699
+ "x-node-id": this.mainDerivedNodeId,
700
+ "x-node-passw": this.mainPasswHash
683
701
  };
684
702
  }
685
- jsonHeaders() {
703
+ agentAuthHeaders(credential) {
704
+ return {
705
+ "x-node-id": credential.nodeId,
706
+ "x-node-passw": credential.passwHash
707
+ };
708
+ }
709
+ agentAuthHeadersForPlayer(playerId) {
710
+ const stored = this.playerAgentCredentials.get(playerId);
711
+ if (stored === void 0) {
712
+ return this.mainAuthHeaders();
713
+ }
714
+ return this.agentAuthHeaders(stored);
715
+ }
716
+ jsonHeaders(auth) {
686
717
  return {
687
718
  "content-type": "application/json",
688
- ...this.authHeaders()
719
+ ...auth
689
720
  };
690
721
  }
722
+ mainJsonHeaders() {
723
+ return this.jsonHeaders(this.mainAuthHeaders());
724
+ }
725
+ agentJsonHeaders(credential) {
726
+ return this.jsonHeaders(this.agentAuthHeaders(credential));
727
+ }
728
+ agentJsonHeadersForPlayer(playerId) {
729
+ return this.jsonHeaders(this.agentAuthHeadersForPlayer(playerId));
730
+ }
691
731
  mergeAuthFetch(input, init) {
692
732
  const headers = new Headers(init?.headers);
693
- const auth = this.authHeaders();
733
+ const auth = this.mainAuthHeaders();
694
734
  for (const [k, v] of Object.entries(auth)) {
695
735
  headers.set(k, v);
696
736
  }
@@ -706,7 +746,7 @@ var RemotePlayWorld = class {
706
746
  }
707
747
  const res = await fetch(`${this.apiBase}/api/nodes/validate`, {
708
748
  method: "POST",
709
- headers: this.jsonHeaders(),
749
+ headers: this.agentJsonHeaders(options.auth),
710
750
  body: JSON.stringify(body)
711
751
  });
712
752
  let json;
@@ -716,13 +756,13 @@ var RemotePlayWorld = class {
716
756
  throw new Error(`node validation failed: ${String(res.status)} invalid JSON`);
717
757
  }
718
758
  if (!isRecord(json) || json.ok !== true) {
719
- const reason = isRecord(json) && typeof json.reason === "string" ? json.reason : `HTTP ${String(res.status)}`;
759
+ const reason = isRecord(json) && typeof json.reason === "string" ? json.reason : isRecord(json) && typeof json.error === "string" ? json.error : `HTTP ${String(res.status)}`;
720
760
  throw new Error(`node validation failed: ${reason}`);
721
761
  }
722
762
  const nodeKind = isRecord(json) && typeof json.nodeKind === "string" ? json.nodeKind : void 0;
723
763
  agentPlayDebug("remote-play-world", "node identity validated", {
724
764
  nodeKind,
725
- derivedNodeIdPrefix: `${this.derivedNodeId.slice(0, 8)}\u2026`
765
+ nodeIdPrefix: `${options.auth.nodeId.slice(0, 8)}\u2026`
726
766
  });
727
767
  return nodeKind !== void 0 ? { nodeKind } : {};
728
768
  }
@@ -733,10 +773,24 @@ var RemotePlayWorld = class {
733
773
  async connect(options) {
734
774
  const mainNodeIdOpt = options?.mainNodeId?.trim();
735
775
  if (mainNodeIdOpt !== void 0 && mainNodeIdOpt.length > 0) {
776
+ if (mainNodeIdOpt !== this.mainDerivedNodeId) {
777
+ throw new Error(
778
+ [
779
+ "connect: mainNodeId does not match the node id derived from mainNodeCredentials.passw.",
780
+ ` mainNodeId (option): ${mainNodeIdOpt}`,
781
+ ` derived node id: ${this.mainDerivedNodeId}`,
782
+ "Ensure AGENT_PLAY_MAIN_NODE_ID_* and AGENT_PLAY_MAIN_NODE_ID_*_PASSW are paired from the same create-main-node output."
783
+ ].join("\n")
784
+ );
785
+ }
736
786
  this.configuredMainNodeId = mainNodeIdOpt;
737
787
  const validation = await this.validateNodeIdentity({
738
- nodeId: mainNodeIdOpt,
739
- mainNodeId: void 0
788
+ nodeId: this.mainDerivedNodeId,
789
+ mainNodeId: void 0,
790
+ auth: {
791
+ nodeId: this.mainDerivedNodeId,
792
+ passwHash: this.mainPasswHash
793
+ }
740
794
  });
741
795
  console.info(
742
796
  `[agent-play] Node identity validated (${validation.nodeKind ?? "unknown"}).`
@@ -745,7 +799,7 @@ var RemotePlayWorld = class {
745
799
  this.configuredMainNodeId = null;
746
800
  }
747
801
  const res = await fetch(`${this.apiBase}/api/agent-play/session`, {
748
- headers: this.authHeaders()
802
+ headers: this.mainAuthHeaders()
749
803
  });
750
804
  if (!res.ok) {
751
805
  throw new Error(`session failed: ${res.status}`);
@@ -814,7 +868,7 @@ var RemotePlayWorld = class {
814
868
  async getWorldSnapshot() {
815
869
  const res = await fetch(`${this.apiBase}/api/agent-play/sdk/rpc`, {
816
870
  method: "POST",
817
- headers: this.jsonHeaders(),
871
+ headers: this.mainJsonHeaders(),
818
872
  body: JSON.stringify({ op: "getWorldSnapshot", payload: {} })
819
873
  });
820
874
  const text = await res.text();
@@ -842,7 +896,7 @@ var RemotePlayWorld = class {
842
896
  }
843
897
  const res = await fetch(`${this.apiBase}/api/agent-play/sdk/rpc`, {
844
898
  method: "POST",
845
- headers: this.jsonHeaders(),
899
+ headers: this.mainJsonHeaders(),
846
900
  body: JSON.stringify({
847
901
  op: "getPlayerChainNode",
848
902
  payload: { stableKey: trimmed }
@@ -962,9 +1016,15 @@ var RemotePlayWorld = class {
962
1016
  */
963
1017
  async addAgent(input) {
964
1018
  const sid = this.getSessionId();
1019
+ const agentCredentialInput = { nodeId: input.nodeId };
1020
+ if (input.agentPassphrase !== void 0 && input.agentPassphrase.length > 0) {
1021
+ agentCredentialInput.agentPassphrase = input.agentPassphrase;
1022
+ }
1023
+ const agentCredential = this.resolveAgentCredential(agentCredentialInput);
965
1024
  const validation = await this.validateNodeIdentity({
966
1025
  nodeId: input.nodeId,
967
- mainNodeId: input.mainNodeId
1026
+ mainNodeId: input.mainNodeId,
1027
+ auth: agentCredential
968
1028
  });
969
1029
  console.info(
970
1030
  [
@@ -1001,7 +1061,7 @@ var RemotePlayWorld = class {
1001
1061
  type: input.type,
1002
1062
  agent: input.agent,
1003
1063
  mainNodeId: input.mainNodeId,
1004
- passwHash: this.passwHash,
1064
+ passwHash: agentCredential.passwHash,
1005
1065
  agentId: input.nodeId,
1006
1066
  connectionId,
1007
1067
  leaseTtlSeconds,
@@ -1016,7 +1076,7 @@ var RemotePlayWorld = class {
1016
1076
  const requestBody = JSON.stringify(requestPayload);
1017
1077
  const res = await fetch(url, {
1018
1078
  method: "POST",
1019
- headers: this.jsonHeaders(),
1079
+ headers: this.agentJsonHeaders(agentCredential),
1020
1080
  body: requestBody
1021
1081
  });
1022
1082
  const bodyText = await res.text();
@@ -1040,6 +1100,7 @@ var RemotePlayWorld = class {
1040
1100
  const registeredAgent = parseRegisteredAgentSummary(body.registeredAgent);
1041
1101
  const bodyConnectionId = typeof body.connectionId === "string" && body.connectionId.length > 0 ? body.connectionId : connectionId;
1042
1102
  const bodyLeaseTtlSeconds = typeof body.leaseTtlSeconds === "number" && Number.isFinite(body.leaseTtlSeconds) ? body.leaseTtlSeconds : leaseTtlSeconds;
1103
+ this.playerAgentCredentials.set(playerId, agentCredential);
1043
1104
  const existingConnection = this.playerConnectionInfo.get(playerId);
1044
1105
  if (existingConnection !== void 0) {
1045
1106
  clearInterval(existingConnection.timer);
@@ -1115,14 +1176,18 @@ var RemotePlayWorld = class {
1115
1176
  return this.addAgent(payload);
1116
1177
  }
1117
1178
  async recordInteraction(input) {
1118
- await this.rpc("recordInteraction", {
1119
- playerId: input.playerId,
1120
- role: input.role,
1121
- text: input.text
1122
- });
1179
+ await this.rpc(
1180
+ "recordInteraction",
1181
+ {
1182
+ playerId: input.playerId,
1183
+ role: input.role,
1184
+ text: input.text
1185
+ },
1186
+ input.playerId
1187
+ );
1123
1188
  }
1124
1189
  async recordJourney(playerId, journey) {
1125
- await this.rpc("recordJourney", { playerId, journey });
1190
+ await this.rpc("recordJourney", { playerId, journey }, playerId);
1126
1191
  }
1127
1192
  async sendIntercomResponse(payload) {
1128
1193
  const sid = this.getSessionId();
@@ -1140,7 +1205,7 @@ var RemotePlayWorld = class {
1140
1205
  });
1141
1206
  const res = await fetch(url, {
1142
1207
  method: "POST",
1143
- headers: this.jsonHeaders(),
1208
+ headers: this.agentJsonHeadersForPlayer(payload.fromPlayerId),
1144
1209
  body: JSON.stringify({ op: INTERCOM_RESPONSE_OP, payload })
1145
1210
  });
1146
1211
  const okText = await res.text();
@@ -1356,7 +1421,7 @@ var RemotePlayWorld = class {
1356
1421
  }
1357
1422
  const res = await fetch(url, {
1358
1423
  method: "POST",
1359
- headers: this.jsonHeaders(),
1424
+ headers: this.mainJsonHeaders(),
1360
1425
  body: JSON.stringify(body)
1361
1426
  });
1362
1427
  const text = await res.text();
@@ -1374,12 +1439,12 @@ var RemotePlayWorld = class {
1374
1439
  }
1375
1440
  return json.id;
1376
1441
  }
1377
- async rpc(op, payload) {
1442
+ async rpc(op, payload, playerId) {
1378
1443
  const sid = this.getSessionId();
1379
1444
  const url = `${this.apiBase}/api/agent-play/sdk/rpc?sid=${encodeURIComponent(sid)}`;
1380
1445
  const res = await fetch(url, {
1381
1446
  method: "POST",
1382
- headers: this.jsonHeaders(),
1447
+ headers: this.agentJsonHeadersForPlayer(playerId),
1383
1448
  body: JSON.stringify({ op, payload })
1384
1449
  });
1385
1450
  if (!res.ok) {
@@ -1401,7 +1466,7 @@ var RemotePlayWorld = class {
1401
1466
  try {
1402
1467
  const res = await fetch(url, {
1403
1468
  method: "POST",
1404
- headers: this.jsonHeaders(),
1469
+ headers: this.agentJsonHeadersForPlayer(input.playerId),
1405
1470
  body: bodyJson
1406
1471
  });
1407
1472
  const text = await res.text();
@@ -1455,7 +1520,7 @@ var RemotePlayWorld = class {
1455
1520
  const url = `${this.apiBase}/api/agent-play/players/disconnect?sid=${encodeURIComponent(sid)}`;
1456
1521
  await fetch(url, {
1457
1522
  method: "POST",
1458
- headers: this.jsonHeaders(),
1523
+ headers: this.agentJsonHeadersForPlayer(input.playerId),
1459
1524
  body: JSON.stringify({
1460
1525
  playerId: input.playerId,
1461
1526
  connectionId: input.connectionId
@@ -1510,6 +1575,7 @@ export {
1510
1575
  TALK_TICK_SECONDS,
1511
1576
  WALLET_BUNDLE_OFFERS,
1512
1577
  WORLD_AGENT_SIGNAL_EVENT,
1578
+ WORLD_GEOGRAPHY_EVENT,
1513
1579
  WORLD_INTERACTION_EVENT,
1514
1580
  WORLD_JOURNEY_EVENT,
1515
1581
  agentPlayDebug,