@crowdedkingdoms/crowdyjs 11.0.0 → 12.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (81) hide show
  1. package/MIGRATION.md +118 -0
  2. package/README.md +208 -0
  3. package/dist/crowdy-agent/browser-dispatcher.d.ts +41 -0
  4. package/dist/crowdy-agent/browser-dispatcher.d.ts.map +1 -0
  5. package/dist/crowdy-agent/browser-dispatcher.js +264 -0
  6. package/dist/crowdy-agent/controller.d.ts +144 -0
  7. package/dist/crowdy-agent/controller.d.ts.map +1 -0
  8. package/dist/crowdy-agent/controller.js +1239 -0
  9. package/dist/crowdy-agent/errors.d.ts +37 -0
  10. package/dist/crowdy-agent/errors.d.ts.map +1 -0
  11. package/dist/crowdy-agent/errors.js +107 -0
  12. package/dist/crowdy-agent/graphql-transport.d.ts +154 -0
  13. package/dist/crowdy-agent/graphql-transport.d.ts.map +1 -0
  14. package/dist/crowdy-agent/graphql-transport.js +854 -0
  15. package/dist/crowdy-agent/index.d.ts +16 -0
  16. package/dist/crowdy-agent/index.d.ts.map +1 -0
  17. package/dist/crowdy-agent/index.js +15 -0
  18. package/dist/crowdy-agent/registry.d.ts +29 -0
  19. package/dist/crowdy-agent/registry.d.ts.map +1 -0
  20. package/dist/crowdy-agent/registry.js +281 -0
  21. package/dist/crowdy-agent/schema.d.ts +72 -0
  22. package/dist/crowdy-agent/schema.d.ts.map +1 -0
  23. package/dist/crowdy-agent/schema.js +467 -0
  24. package/dist/crowdy-agent/studio-tools.d.ts +15 -0
  25. package/dist/crowdy-agent/studio-tools.d.ts.map +1 -0
  26. package/dist/crowdy-agent/studio-tools.js +280 -0
  27. package/dist/crowdy-agent/tool-descriptors.d.ts +4 -0
  28. package/dist/crowdy-agent/tool-descriptors.d.ts.map +1 -0
  29. package/dist/crowdy-agent/tool-descriptors.js +1049 -0
  30. package/dist/crowdy-agent/transport.d.ts +152 -0
  31. package/dist/crowdy-agent/transport.d.ts.map +1 -0
  32. package/dist/crowdy-agent/transport.js +27 -0
  33. package/dist/crowdy-agent/types.d.ts +328 -0
  34. package/dist/crowdy-agent/types.d.ts.map +1 -0
  35. package/dist/crowdy-agent/types.js +37 -0
  36. package/dist/crowdy-client.d.ts +3 -0
  37. package/dist/crowdy-client.d.ts.map +1 -1
  38. package/dist/crowdy-client.js +6 -0
  39. package/dist/crowdy-studio/agent-dom-shell.d.ts +40 -0
  40. package/dist/crowdy-studio/agent-dom-shell.d.ts.map +1 -0
  41. package/dist/crowdy-studio/agent-dom-shell.js +354 -0
  42. package/dist/crowdy-studio/controller.d.ts +74 -4
  43. package/dist/crowdy-studio/controller.d.ts.map +1 -1
  44. package/dist/crowdy-studio/controller.js +450 -17
  45. package/dist/crowdy-studio/dom-shell.d.ts +4 -1
  46. package/dist/crowdy-studio/dom-shell.d.ts.map +1 -1
  47. package/dist/crowdy-studio/dom-shell.js +6 -1
  48. package/dist/crowdy-studio/index.d.ts +6 -3
  49. package/dist/crowdy-studio/index.d.ts.map +1 -1
  50. package/dist/crowdy-studio/index.js +3 -0
  51. package/dist/crowdy-studio/models.d.ts +67 -0
  52. package/dist/crowdy-studio/models.d.ts.map +1 -1
  53. package/dist/crowdy-studio/mount.d.ts +22 -1
  54. package/dist/crowdy-studio/mount.d.ts.map +1 -1
  55. package/dist/crowdy-studio/mount.js +163 -2
  56. package/dist/crowdy-studio/styles.d.ts +1 -1
  57. package/dist/crowdy-studio/styles.d.ts.map +1 -1
  58. package/dist/crowdy-studio/styles.js +5 -3
  59. package/dist/generated/graphql.d.ts +3753 -1
  60. package/dist/generated/graphql.d.ts.map +1 -1
  61. package/dist/generated/graphql.js +296 -0
  62. package/dist/index.d.ts +1 -1
  63. package/dist/index.js +1 -1
  64. package/dist/kit/npcs.d.ts.map +1 -1
  65. package/dist/kit/social.d.ts.map +1 -1
  66. package/dist/player-host/index.d.ts +5 -0
  67. package/dist/player-host/index.d.ts.map +1 -0
  68. package/dist/player-host/index.js +3 -0
  69. package/dist/player-host/lease-manager.d.ts +66 -0
  70. package/dist/player-host/lease-manager.d.ts.map +1 -0
  71. package/dist/player-host/lease-manager.js +428 -0
  72. package/dist/player-host/schemas.d.ts +9 -0
  73. package/dist/player-host/schemas.d.ts.map +1 -0
  74. package/dist/player-host/schemas.js +347 -0
  75. package/dist/player-host/tools.d.ts +13 -0
  76. package/dist/player-host/tools.d.ts.map +1 -0
  77. package/dist/player-host/tools.js +79 -0
  78. package/dist/player-host/types.d.ts +203 -0
  79. package/dist/player-host/types.d.ts.map +1 -0
  80. package/dist/player-host/types.js +1 -0
  81. package/package.json +12 -2
package/dist/index.d.ts CHANGED
@@ -45,7 +45,7 @@
45
45
  * or internal tooling, never an untrusted browser.
46
46
  */
47
47
  /** The published package version. Mirrors `package.json`. */
48
- export declare const VERSION = "11.0.0";
48
+ export declare const VERSION = "12.0.0";
49
49
  export { LbCookieStore } from './lb-cookie-store.js';
50
50
  export { CrowdyClient, createCrowdyClient, type CrowdyClientConfig, } from './crowdy-client.js';
51
51
  export { BrowserLocalStorageTokenStore, SessionStore, type SessionListener, type TokenStore, } from './session.js';
package/dist/index.js CHANGED
@@ -45,7 +45,7 @@
45
45
  * or internal tooling, never an untrusted browser.
46
46
  */
47
47
  /** The published package version. Mirrors `package.json`. */
48
- export const VERSION = '11.0.0';
48
+ export const VERSION = '12.0.0';
49
49
  export { LbCookieStore } from './lb-cookie-store.js';
50
50
  export { CrowdyClient, createCrowdyClient, } from './crowdy-client.js';
51
51
  export { BrowserLocalStorageTokenStore, SessionStore, } from './session.js';
@@ -1 +1 @@
1
- {"version":3,"file":"npcs.d.ts","sourceRoot":"","sources":["../../src/kit/npcs.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"npcs.d.ts","sourceRoot":"","sources":["../../src/kit/npcs.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"social.d.ts","sourceRoot":"","sources":["../../src/kit/social.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"social.d.ts","sourceRoot":"","sources":["../../src/kit/social.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAC1D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAC1D,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,yBAAyB,CAAC;AAGvD,qCAAqC;AACrC,MAAM,WAAW,gBAAgB;IAC/B;;;;OAIG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,oEAAoE;IACpE,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,oEAAoE;IACpE,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,+DAA+D;AAC/D,MAAM,WAAW,mBAAmB;IAClC,wDAAwD;IACxD,MAAM,EAAE,MAAM,CAAC;IACf,wEAAwE;IACxE,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;CACd;AAED,mDAAmD;AACnD,MAAM,WAAW,cAAc;IAC7B,SAAS,EAAE,MAAM,CAAC;IAClB,kEAAkE;IAClE,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;CACrB;AAED;;;;;;;;;;;;;;GAcG;AACH,qBAAa,SAAS;IAMlB,OAAO,CAAC,QAAQ,CAAC,KAAK;IACtB,OAAO,CAAC,QAAQ,CAAC,KAAK;IACtB,OAAO,CAAC,QAAQ,CAAC,QAAQ;IACzB,OAAO,CAAC,QAAQ,CAAC,GAAG;IACpB,OAAO,CAAC,QAAQ,CAAC,QAAQ;IAT3B,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;IACnC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAS;IACrC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAS;gBAGlB,KAAK,EAAE,OAAO,CAAC,QAAQ,CAAC,CAAC,OAAO,CAAC,EACjC,KAAK,EAAE,QAAQ,GAAG,SAAS,EAC3B,QAAQ,EAAE,WAAW,GAAG,SAAS,EACjC,GAAG,EAAE,MAAM,GAAG,SAAS,EACvB,QAAQ,EAAE,WAAW,EACtC,OAAO,GAAE,gBAAqB;IAOhC,OAAO,CAAC,YAAY;IASpB,OAAO,CAAC,eAAe;IASvB,OAAO,CAAC,UAAU;IASlB,uDAAuD;YACzC,UAAU;IAuBxB,mDAAmD;YACrC,QAAQ;IAetB,sEAAsE;IACtE,QAAQ,CAAC,KAAK;QACZ,2EAA2E;uBACtD,MAAM,KAAG,OAAO,CAAC,mBAAmB,CAAC;QAI1D,4BAA4B;qBACT,MAAM,KAAG,OAAO,CAAC,mBAAmB,GAAG,SAAS,CAAC;QAIpE;;;WAGG;wBACmB,mBAAmB,UAAU,OAAO,CAAC,QAAQ,CAAC,CAAC,OAAO,CAAC;;;;;;;;0BA8K+2k2B,CAAC;;;;;;;;QAtK77k2B,+DAA+D;sBAC3C,mBAAmB;;;;;;;;0BAqKo9n2B,CAAC;;;;;;;;QA7J5/n2B,8CAA8C;uBACzB,mBAAmB;QAOxC,wBAAwB;yBACD,mBAAmB;;;;;;;;0BAoJ8ju2B,CAAC;;;;;;;;MAjJzmu2B;IAEF,yEAAyE;IACzE,QAAQ,CAAC,KAAK;QACZ,+EAA+E;uBAEvE,MAAM,YACH;YAAE,gBAAgB,CAAC,EAAE,MAAM,CAAC;YAAC,WAAW,CAAC,EAAE,MAAM,CAAA;SAAE,KAC3D,OAAO,CAAC,mBAAmB,CAAC;QAQ/B,4BAA4B;qBACT,MAAM,KAAG,OAAO,CAAC,mBAAmB,GAAG,SAAS,CAAC;QAIpE,0DAA0D;wBACpC,mBAAmB;;;;;;;;0BA2H+ju2B,CAAC;;;;;;;;QAvHzmu2B,4DAA4D;uBACvC,mBAAmB;;;;;;;;;;QAIxC,4DAA4D;4BAEnD,mBAAmB,SACnB;YAAE,QAAQ,EAAE,MAAM,CAAC;YAAC,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;YAAC,IAAI,CAAC,EAAE,MAAM,CAAA;SAAE;;;;;;;;;;QAUpE;;;WAGG;yBAEM,mBAAmB,UAClB,OAAO,CAAC,QAAQ,CAAC,CAAC,OAAO,CAAC,WACzB,MAAM,EAAE;;;;;;;;0BA8Fg8r2B,CAAC;;;;;;;;QArFp9r2B;;;;;WAKG;gCAEM,mBAAmB,UAClB,OAAO,CAAC,QAAQ,CAAC,CAAC,OAAO,CAAC,YACzB;YAAE,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;YAAC,WAAW,CAAC,EAAE,MAAM,CAAA;SAAE;;;;;;;;;MAY9D;IAEF,8DAA8D;IAC9D,QAAQ,CAAC,IAAI;QACX,4DAA4D;qBACzC,MAAM;;;;;;;;;;;;;QAOzB,wBAAwB;0BACA,OAAO,CAAC,QAAQ,CAAC,CAAC,OAAO,CAAC;;;;;;;;0BAmDy06pB,CAAC;;;;;;;;QA/C536pB;;;;WAIG;0BAEU,OAAO,CAAC,QAAQ,CAAC,CAAC,OAAO,CAAC,QAC/B,MAAM,KACX,OAAO,CAAC,OAAO,CAAC;QAQnB;;;WAGG;+BAEU,OAAO,CAAC,QAAQ,CAAC,CAAC,OAAO,CAAC,YAC3B,CAAC,OAAO,EAAE,cAAc,KAAK,IAAI,KAC1C,CAAC,MAAM,IAAI,CAAC;MAsBf;CACH"}
@@ -0,0 +1,5 @@
1
+ export { AgentControlLeaseManager, type AgentControlDispatchV1, type AgentControlLeaseManagerOptionsV1, type AgentControlLeaseSnapshotV1, type AgentObservationDispatchV1, } from './lease-manager.js';
2
+ export { GAME_COMMAND_RESULT_SCHEMA_V1, GAME_COMMAND_SCHEMAS_V1, GAME_COMMAND_SCHEMA_V1, GAME_OBSERVATION_SCHEMA_V1, OBSERVE_REQUEST_SCHEMA_V1, PLAYER_HOST_CAPABILITIES_SCHEMA_V1, } from './schemas.js';
3
+ export { createPlayerHostAgentTools, type PlayerHostAgentToolsV1, } from './tools.js';
4
+ export type { GameChatSendCommandV1, GameCombatAttackCommandV1, GameCommandResultV1, GameCommandV1, GameCraftCommandV1, GameInteractCommandV1, GameInventoryConsumeCommandV1, GameInventorySelectCommandV1, GameInventoryTransferCommandV1, GameLookCommandV1, GameMountCommandV1, GameMoveCommandV1, GameObservationActorV1, GameObservationInventoryV1, GameObservationV1, GameStopCommandV1, GameTravelTeleportCommandV1, ObserveRequestV1, PlayerHostAdapterV1, PlayerHostCapabilitiesV1, PlayerHostCommandCapabilityV1, PlayerHostCommandKind, PlayerHostLeaseScope, PlayerHostLookV1, PlayerHostVector3V1, ValidatedGateV1, } from './types.js';
5
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/player-host/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,wBAAwB,EACxB,KAAK,sBAAsB,EAC3B,KAAK,iCAAiC,EACtC,KAAK,2BAA2B,EAChC,KAAK,0BAA0B,GAChC,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EACL,6BAA6B,EAC7B,uBAAuB,EACvB,sBAAsB,EACtB,0BAA0B,EAC1B,yBAAyB,EACzB,kCAAkC,GACnC,MAAM,cAAc,CAAC;AACtB,OAAO,EACL,0BAA0B,EAC1B,KAAK,sBAAsB,GAC5B,MAAM,YAAY,CAAC;AACpB,YAAY,EACV,qBAAqB,EACrB,yBAAyB,EACzB,mBAAmB,EACnB,aAAa,EACb,kBAAkB,EAClB,qBAAqB,EACrB,6BAA6B,EAC7B,4BAA4B,EAC5B,8BAA8B,EAC9B,iBAAiB,EACjB,kBAAkB,EAClB,iBAAiB,EACjB,sBAAsB,EACtB,0BAA0B,EAC1B,iBAAiB,EACjB,iBAAiB,EACjB,2BAA2B,EAC3B,gBAAgB,EAChB,mBAAmB,EACnB,wBAAwB,EACxB,6BAA6B,EAC7B,qBAAqB,EACrB,oBAAoB,EACpB,gBAAgB,EAChB,mBAAmB,EACnB,eAAe,GAChB,MAAM,YAAY,CAAC"}
@@ -0,0 +1,3 @@
1
+ export { AgentControlLeaseManager, } from './lease-manager.js';
2
+ export { GAME_COMMAND_RESULT_SCHEMA_V1, GAME_COMMAND_SCHEMAS_V1, GAME_COMMAND_SCHEMA_V1, GAME_OBSERVATION_SCHEMA_V1, OBSERVE_REQUEST_SCHEMA_V1, PLAYER_HOST_CAPABILITIES_SCHEMA_V1, } from './schemas.js';
3
+ export { createPlayerHostAgentTools, } from './tools.js';
@@ -0,0 +1,66 @@
1
+ import type { CrowdyAgentLeaseV1, CrowdyAgentPreemptionReason } from '../crowdy-agent/types.js';
2
+ import type { GameCommandResultV1, GameCommandV1, GameObservationV1, ObserveRequestV1, PlayerHostAdapterV1, PlayerHostCapabilitiesV1 } from './types.js';
3
+ export interface AgentControlDispatchV1 {
4
+ readonly toolCallId: string;
5
+ readonly clientEpoch: string;
6
+ readonly leaseId?: string;
7
+ readonly approvalGrant?: string;
8
+ readonly command: GameCommandV1;
9
+ }
10
+ export interface AgentObservationDispatchV1 {
11
+ readonly clientEpoch: string;
12
+ readonly leaseId?: string;
13
+ }
14
+ export interface AgentControlLeaseSnapshotV1 {
15
+ readonly connected: boolean;
16
+ readonly clientEpoch: string | null;
17
+ readonly lease: CrowdyAgentLeaseV1 | null;
18
+ readonly capabilities: PlayerHostCapabilitiesV1 | null;
19
+ readonly lastPreemption?: CrowdyAgentPreemptionReason;
20
+ }
21
+ export interface AgentControlLeaseManagerOptionsV1 {
22
+ readonly now?: () => number;
23
+ readonly contextVersion?: () => string;
24
+ readonly maxLeaseSeconds?: number;
25
+ readonly maxRememberedCalls?: number;
26
+ readonly onChange?: (snapshot: AgentControlLeaseSnapshotV1) => void;
27
+ }
28
+ /**
29
+ * Browser-local Play authority gate. Human takeover calls `preempt` and clears
30
+ * intent synchronously before any server acknowledgement or async cleanup.
31
+ */
32
+ export declare class AgentControlLeaseManager {
33
+ private readonly adapter;
34
+ private readonly options;
35
+ private clientEpoch;
36
+ private connected;
37
+ private lease;
38
+ private capabilitiesValue;
39
+ private readonly observations;
40
+ private readonly calls;
41
+ private readonly rateWindows;
42
+ private expiryTimer;
43
+ private lastPreemption?;
44
+ private readonly now;
45
+ constructor(adapter: PlayerHostAdapterV1, options?: AgentControlLeaseManagerOptionsV1);
46
+ snapshot(): AgentControlLeaseSnapshotV1;
47
+ attach(clientEpoch: string): void;
48
+ disconnect(): void;
49
+ refreshCapabilities(): Promise<PlayerHostCapabilitiesV1>;
50
+ grantLease(lease: CrowdyAgentLeaseV1): void;
51
+ revoke(reason?: CrowdyAgentPreemptionReason): void;
52
+ /** Human input, Escape, Stop, death, and context changes call this directly. */
53
+ preempt(reason: CrowdyAgentPreemptionReason): void;
54
+ observe(request: ObserveRequestV1, dispatch?: AgentObservationDispatchV1): Promise<GameObservationV1>;
55
+ private validateObservationLease;
56
+ dispatch(input: AgentControlDispatchV1): Promise<GameCommandResultV1>;
57
+ clearClosedSession(): void;
58
+ private execute;
59
+ private validateDispatch;
60
+ private validateObservationContext;
61
+ private consumeRate;
62
+ private requireCapabilities;
63
+ private clearExpiryTimer;
64
+ private emit;
65
+ }
66
+ //# sourceMappingURL=lease-manager.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lease-manager.d.ts","sourceRoot":"","sources":["../../src/player-host/lease-manager.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,428 @@
1
+ import { CrowdyAgentError, toAgentError } from '../crowdy-agent/errors.js';
2
+ import { canonicalJson, sha256Digest, validateJsonSchemaValue, } from '../crowdy-agent/schema.js';
3
+ import { GAME_COMMAND_RESULT_SCHEMA_V1, GAME_COMMAND_SCHEMA_V1, GAME_OBSERVATION_SCHEMA_V1, OBSERVE_REQUEST_SCHEMA_V1, PLAYER_HOST_CAPABILITIES_SCHEMA_V1, } from './schemas.js';
4
+ const TOOL_BY_COMMAND = Object.freeze({
5
+ MOVE: 'game.control.move',
6
+ LOOK: 'game.control.look',
7
+ STOP: 'game.control.stop',
8
+ INVENTORY_SELECT: 'game.inventory.select',
9
+ INVENTORY_CONSUME: 'game.inventory.consume',
10
+ INVENTORY_TRANSFER: 'game.inventory.transfer',
11
+ INTERACT: 'game.interact',
12
+ CRAFT: 'game.craft',
13
+ MOUNT: 'game.mount',
14
+ COMBAT_ATTACK: 'game.combat.attack',
15
+ CHAT_SEND: 'game.chat.send',
16
+ TRAVEL_TELEPORT: 'game.travel.teleport',
17
+ });
18
+ /**
19
+ * Browser-local Play authority gate. Human takeover calls `preempt` and clears
20
+ * intent synchronously before any server acknowledgement or async cleanup.
21
+ */
22
+ export class AgentControlLeaseManager {
23
+ constructor(adapter, options = {}) {
24
+ this.adapter = adapter;
25
+ this.options = options;
26
+ this.clientEpoch = null;
27
+ this.connected = false;
28
+ this.lease = null;
29
+ this.capabilitiesValue = null;
30
+ this.observations = new Map();
31
+ this.calls = new Map();
32
+ this.rateWindows = new Map();
33
+ this.expiryTimer = null;
34
+ if (adapter.contractVersion !== 'crowdy.player-host/1') {
35
+ throw new CrowdyAgentError('AGENT_HOST_UNAVAILABLE', 'Unsupported PlayerHostAdapter contract version');
36
+ }
37
+ this.now = options.now ?? Date.now;
38
+ }
39
+ snapshot() {
40
+ return {
41
+ connected: this.connected,
42
+ clientEpoch: this.clientEpoch,
43
+ lease: this.lease,
44
+ capabilities: this.capabilitiesValue,
45
+ ...(this.lastPreemption
46
+ ? { lastPreemption: this.lastPreemption }
47
+ : {}),
48
+ };
49
+ }
50
+ attach(clientEpoch) {
51
+ assertDecimal(clientEpoch, 'clientEpoch');
52
+ if (this.clientEpoch && this.clientEpoch !== clientEpoch) {
53
+ this.preempt('CLIENT_REATTACHED');
54
+ }
55
+ this.clientEpoch = clientEpoch;
56
+ this.connected = true;
57
+ this.emit();
58
+ }
59
+ disconnect() {
60
+ this.connected = false;
61
+ this.preempt('DISCONNECTED');
62
+ }
63
+ async refreshCapabilities() {
64
+ const next = await this.adapter.capabilities();
65
+ validateJsonSchemaValue(PLAYER_HOST_CAPABILITIES_SCHEMA_V1, next, {
66
+ direction: 'OUTPUT',
67
+ });
68
+ if (new Set(next.commands.map((command) => command.kind)).size !==
69
+ next.commands.length ||
70
+ next.commands.some((command) => TOOL_BY_COMMAND[command.kind] !== command.toolName)) {
71
+ throw new CrowdyAgentError('AGENT_HOST_CAPABILITY_CHANGED', 'Host command capabilities contain duplicate or confused tool mappings');
72
+ }
73
+ const previous = this.capabilitiesValue;
74
+ this.capabilitiesValue = next;
75
+ if (previous &&
76
+ this.lease &&
77
+ (previous.revision !== next.revision ||
78
+ previous.controlledEntityId !== next.controlledEntityId)) {
79
+ this.preempt(previous.controlledEntityId !== next.controlledEntityId
80
+ ? 'CONTROL_TARGET_CHANGED'
81
+ : 'CONTEXT_CHANGED');
82
+ }
83
+ this.emit();
84
+ return next;
85
+ }
86
+ grantLease(lease) {
87
+ const capabilities = this.requireCapabilities();
88
+ if (!this.connected || !this.clientEpoch) {
89
+ throw new CrowdyAgentError('AGENT_DISCONNECTED', 'Cannot grant Play control while the browser is disconnected');
90
+ }
91
+ if (lease.kind !== 'PLAY' ||
92
+ lease.status !== 'ACTIVE' ||
93
+ lease.clientEpoch !== this.clientEpoch) {
94
+ throw new CrowdyAgentError('AGENT_CLIENT_EPOCH_STALE', 'Play lease is not active for the attached client epoch');
95
+ }
96
+ if (lease.hostCapabilityRevision !== capabilities.revision ||
97
+ lease.controlledEntityId !== capabilities.controlledEntityId) {
98
+ throw new CrowdyAgentError('AGENT_HOST_CAPABILITY_CHANGED', 'Play lease does not match the current host capability and target');
99
+ }
100
+ if (this.options.contextVersion &&
101
+ lease.contextVersion !== this.options.contextVersion()) {
102
+ throw new CrowdyAgentError('AGENT_CONTEXT_STALE', 'Play lease belongs to a stale game context');
103
+ }
104
+ const now = this.now();
105
+ const expiry = Date.parse(lease.expiresAt);
106
+ const maxMs = (this.options.maxLeaseSeconds ?? 600) * 1000;
107
+ if (!Number.isFinite(expiry) || expiry <= now || expiry - now > maxMs) {
108
+ throw new CrowdyAgentError('AGENT_LEASE_EXPIRED', 'Play lease expiry is invalid or exceeds the host maximum');
109
+ }
110
+ for (const scope of lease.scopes)
111
+ assertLeaseScope(scope);
112
+ if (new Set(lease.scopes).size !== lease.scopes.length) {
113
+ throw new CrowdyAgentError('AGENT_LEASE_SCOPE_MISSING', 'Play lease scopes must be unique');
114
+ }
115
+ this.clearExpiryTimer();
116
+ this.lease = lease;
117
+ this.expiryTimer = setTimeout(() => {
118
+ this.expiryTimer = null;
119
+ if (this.lease?.leaseId === lease.leaseId)
120
+ this.preempt('LEASE_EXPIRED');
121
+ }, expiry - now);
122
+ this.emit();
123
+ }
124
+ revoke(reason = 'HUMAN_STOP') {
125
+ this.preempt(reason);
126
+ }
127
+ /** Human input, Escape, Stop, death, and context changes call this directly. */
128
+ preempt(reason) {
129
+ // Intent is cleared first and synchronously. Do not move below async/state work.
130
+ try {
131
+ this.adapter.clearAgentIntent(reason);
132
+ }
133
+ finally {
134
+ // A host cleanup bug cannot leave the SDK gate or lease active.
135
+ this.clearExpiryTimer();
136
+ this.lease = null;
137
+ this.observations.clear();
138
+ this.rateWindows.clear();
139
+ this.lastPreemption = reason;
140
+ this.emit();
141
+ }
142
+ }
143
+ async observe(request, dispatch) {
144
+ if (!this.connected) {
145
+ throw new CrowdyAgentError('AGENT_DISCONNECTED', 'Browser host is disconnected');
146
+ }
147
+ validateJsonSchemaValue(OBSERVE_REQUEST_SCHEMA_V1, request, {
148
+ direction: 'INPUT',
149
+ });
150
+ const capabilities = this.capabilitiesValue ?? (await this.refreshCapabilities());
151
+ if (dispatch) {
152
+ if (!this.clientEpoch || dispatch.clientEpoch !== this.clientEpoch) {
153
+ throw new CrowdyAgentError('AGENT_CLIENT_EPOCH_STALE', 'Game observation belongs to a stale client epoch');
154
+ }
155
+ if (dispatch.leaseId) {
156
+ this.validateObservationLease(dispatch, capabilities);
157
+ }
158
+ }
159
+ if (request.maxNearbyActors > capabilities.observation.maxNearbyActors ||
160
+ request.maxNearbyVoxels > capabilities.observation.maxNearbyVoxels) {
161
+ throw new CrowdyAgentError('AGENT_TOOL_INPUT_INVALID', 'Observation request exceeds host-advertised bounds');
162
+ }
163
+ const observation = await this.adapter.observe(request);
164
+ validateJsonSchemaValue(GAME_OBSERVATION_SCHEMA_V1, observation, {
165
+ direction: 'OUTPUT',
166
+ });
167
+ if (observation.nearbyActors.length > request.maxNearbyActors ||
168
+ observation.nearbyVoxels.length > request.maxNearbyVoxels) {
169
+ throw new CrowdyAgentError('AGENT_TOOL_OUTPUT_INVALID', 'Game observation exceeded the requested deterministic bounds');
170
+ }
171
+ this.validateObservationContext(observation, capabilities);
172
+ this.observations.set(observation.observationId, observation);
173
+ while (this.observations.size > 32) {
174
+ const oldest = this.observations.keys().next().value;
175
+ if (!oldest)
176
+ break;
177
+ this.observations.delete(oldest);
178
+ }
179
+ return observation;
180
+ }
181
+ validateObservationLease(dispatch, capabilities) {
182
+ const lease = this.lease;
183
+ if (!lease ||
184
+ lease.status !== 'ACTIVE' ||
185
+ dispatch.leaseId !== lease.leaseId) {
186
+ throw new CrowdyAgentError('AGENT_LEASE_REQUIRED', 'Play observations require the current visible lease');
187
+ }
188
+ if (Date.parse(lease.expiresAt) <= this.now()) {
189
+ this.preempt('LEASE_EXPIRED');
190
+ throw new CrowdyAgentError('AGENT_LEASE_EXPIRED', 'Play lease expired');
191
+ }
192
+ if (!lease.scopes.includes('observe')) {
193
+ throw new CrowdyAgentError('AGENT_LEASE_SCOPE_MISSING', 'Game observation requires observe scope', { requiredScope: 'observe' });
194
+ }
195
+ if (lease.hostCapabilityRevision !== capabilities.revision ||
196
+ lease.controlledEntityId !== capabilities.controlledEntityId) {
197
+ this.preempt('CONTROL_TARGET_CHANGED');
198
+ throw new CrowdyAgentError('AGENT_CONTROL_TARGET_CHANGED', 'Observation lease target or capability changed');
199
+ }
200
+ if (this.options.contextVersion &&
201
+ lease.contextVersion !== this.options.contextVersion()) {
202
+ this.preempt('CONTEXT_CHANGED');
203
+ throw new CrowdyAgentError('AGENT_CONTEXT_CHANGED', 'Observation lease context changed');
204
+ }
205
+ }
206
+ dispatch(input) {
207
+ if (typeof input.toolCallId !== 'string' ||
208
+ input.toolCallId.length < 1 ||
209
+ input.toolCallId.length > 128 ||
210
+ typeof input.clientEpoch !== 'string' ||
211
+ input.clientEpoch.length < 1 ||
212
+ input.clientEpoch.length > 40 ||
213
+ (input.leaseId !== undefined &&
214
+ (typeof input.leaseId !== 'string' || input.leaseId.length < 1)) ||
215
+ (input.leaseId?.length ?? 0) > 128 ||
216
+ (input.approvalGrant !== undefined &&
217
+ (typeof input.approvalGrant !== 'string' ||
218
+ input.approvalGrant.length < 1)) ||
219
+ (input.approvalGrant?.length ?? 0) > 512) {
220
+ return Promise.reject(new CrowdyAgentError('AGENT_TOOL_INPUT_INVALID', 'Game dispatch envelope is outside protocol bounds'));
221
+ }
222
+ validateJsonSchemaValue(GAME_COMMAND_SCHEMA_V1, input.command, {
223
+ direction: 'INPUT',
224
+ });
225
+ const fingerprint = sha256Digest(canonicalJson({
226
+ clientEpoch: input.clientEpoch,
227
+ ...(input.leaseId ? { leaseId: input.leaseId } : {}),
228
+ ...(input.approvalGrant
229
+ ? { approvalGrant: input.approvalGrant }
230
+ : {}),
231
+ command: input.command,
232
+ }));
233
+ const previous = this.calls.get(input.toolCallId);
234
+ if (previous) {
235
+ if (previous.fingerprint !== fingerprint) {
236
+ return Promise.reject(new CrowdyAgentError('AGENT_IDEMPOTENCY_CONFLICT', `Game tool call ${input.toolCallId} changed after first dispatch`));
237
+ }
238
+ return previous.promise;
239
+ }
240
+ if (this.calls.size >= (this.options.maxRememberedCalls ?? 2048)) {
241
+ return Promise.reject(new CrowdyAgentError('AGENT_RATE_LIMITED', 'Game execute-once result cache is full'));
242
+ }
243
+ const promise = this.execute(input);
244
+ this.calls.set(input.toolCallId, { fingerprint, promise });
245
+ return promise;
246
+ }
247
+ clearClosedSession() {
248
+ this.calls.clear();
249
+ }
250
+ async execute(input) {
251
+ if (input.command.kind === 'STOP') {
252
+ this.preempt('HUMAN_STOP');
253
+ return {
254
+ contractVersion: 'crowdy.game-command-result/1',
255
+ status: 'SUCCEEDED',
256
+ commandKind: 'STOP',
257
+ };
258
+ }
259
+ const gate = this.validateDispatch(input);
260
+ try {
261
+ const result = await this.adapter.dispatch(input.command, gate);
262
+ validateJsonSchemaValue(GAME_COMMAND_RESULT_SCHEMA_V1, result, {
263
+ direction: 'OUTPUT',
264
+ });
265
+ if (result.commandKind !== input.command.kind) {
266
+ throw new CrowdyAgentError('AGENT_TOOL_OUTPUT_INVALID', 'Player host returned a result for a different command kind');
267
+ }
268
+ return result;
269
+ }
270
+ catch (error) {
271
+ // Validation and policy failures happen before this try. Once the adapter
272
+ // starts, an exception is ambiguous and must never trigger a blind retry.
273
+ return {
274
+ contractVersion: 'crowdy.game-command-result/1',
275
+ status: 'OUTCOME_UNKNOWN',
276
+ commandKind: input.command.kind,
277
+ observationId: input.command.observationId,
278
+ error: toAgentError(error, 'AGENT_TOOL_OUTCOME_UNKNOWN'),
279
+ };
280
+ }
281
+ }
282
+ validateDispatch(input) {
283
+ if (input.command.kind === 'STOP') {
284
+ throw new CrowdyAgentError('AGENT_TOOL_INPUT_INVALID', 'STOP bypasses the leased dispatch path');
285
+ }
286
+ const command = input.command;
287
+ if (!this.connected || !this.clientEpoch) {
288
+ throw new CrowdyAgentError('AGENT_DISCONNECTED', 'Browser host is disconnected');
289
+ }
290
+ if (input.clientEpoch !== this.clientEpoch) {
291
+ throw new CrowdyAgentError('AGENT_CLIENT_EPOCH_STALE', 'Game command belongs to a stale client epoch');
292
+ }
293
+ const capabilities = this.requireCapabilities();
294
+ const advertised = capabilities.commands.find((candidate) => candidate.kind === command.kind);
295
+ if (!advertised) {
296
+ throw new CrowdyAgentError('AGENT_HOST_UNAVAILABLE', `Host does not advertise ${command.kind}`);
297
+ }
298
+ const lease = this.lease;
299
+ const now = this.now();
300
+ if (!lease ||
301
+ lease.status !== 'ACTIVE' ||
302
+ input.leaseId !== lease.leaseId) {
303
+ throw new CrowdyAgentError('AGENT_LEASE_REQUIRED', `${command.kind} requires the current visible Play lease`);
304
+ }
305
+ if (lease.clientEpoch !== this.clientEpoch) {
306
+ this.preempt('CLIENT_REATTACHED');
307
+ throw new CrowdyAgentError('AGENT_CLIENT_EPOCH_STALE', 'Play lease belongs to a stale client epoch');
308
+ }
309
+ if (Date.parse(lease.expiresAt) <= now) {
310
+ this.preempt('LEASE_EXPIRED');
311
+ throw new CrowdyAgentError('AGENT_LEASE_EXPIRED', 'Play lease expired');
312
+ }
313
+ if (lease.hostCapabilityRevision !== capabilities.revision ||
314
+ lease.controlledEntityId !== capabilities.controlledEntityId) {
315
+ this.preempt('CONTROL_TARGET_CHANGED');
316
+ throw new CrowdyAgentError('AGENT_CONTROL_TARGET_CHANGED', 'Controlled entity or host capability changed');
317
+ }
318
+ if (this.options.contextVersion &&
319
+ lease.contextVersion !== this.options.contextVersion()) {
320
+ this.preempt('CONTEXT_CHANGED');
321
+ throw new CrowdyAgentError('AGENT_CONTEXT_CHANGED', 'Play lease game context changed');
322
+ }
323
+ if (advertised.requiredScope &&
324
+ !lease.scopes.includes(advertised.requiredScope)) {
325
+ throw new CrowdyAgentError('AGENT_LEASE_SCOPE_MISSING', `${command.kind} requires ${advertised.requiredScope}`, { requiredScope: advertised.requiredScope });
326
+ }
327
+ if (advertised.approval !== 'NONE' && !input.approvalGrant) {
328
+ throw new CrowdyAgentError('AGENT_APPROVAL_REQUIRED', `${command.kind} requires exact approval`);
329
+ }
330
+ const observation = this.observations.get(command.observationId);
331
+ if (!observation) {
332
+ throw new CrowdyAgentError('AGENT_OBSERVATION_STALE', 'Command observation is missing or was invalidated');
333
+ }
334
+ this.validateObservationContext(observation, capabilities);
335
+ if (command.capabilityRevision !== observation.capabilityRevision ||
336
+ command.controlledEntityId !== observation.controlledEntityId) {
337
+ throw new CrowdyAgentError('AGENT_CONTROL_TARGET_CHANGED', 'Command target does not match its observation');
338
+ }
339
+ if (!observation.player.alive) {
340
+ this.preempt('DEATH');
341
+ throw new CrowdyAgentError('AGENT_PREEMPTED', 'Player is dead');
342
+ }
343
+ if (observation.inputState.modalOpen ||
344
+ observation.inputState.textInputFocused) {
345
+ throw new CrowdyAgentError('AGENT_CONTEXT_CHANGED', 'Game modal or text input blocks agent control');
346
+ }
347
+ if (observation.inputState.humanInputActive) {
348
+ this.preempt('HUMAN_INPUT');
349
+ throw new CrowdyAgentError('AGENT_PREEMPTED', 'Human input took control');
350
+ }
351
+ this.consumeRate(command.kind, advertised.rateLimitPerSecond, now);
352
+ return {
353
+ contractVersion: 'crowdy.validated-gate/1',
354
+ clientEpoch: this.clientEpoch,
355
+ leaseId: lease.leaseId,
356
+ scopes: lease.scopes.map(asLeaseScope),
357
+ contextVersion: lease.contextVersion,
358
+ observationId: observation.observationId,
359
+ validatedAt: new Date(now).toISOString(),
360
+ };
361
+ }
362
+ validateObservationContext(observation, capabilities) {
363
+ const now = this.now();
364
+ const observedAt = Date.parse(observation.observedAt);
365
+ const expiresAt = Date.parse(observation.expiresAt);
366
+ if (!Number.isFinite(observedAt) ||
367
+ !Number.isFinite(expiresAt) ||
368
+ observedAt > now + 1000 ||
369
+ expiresAt <= now ||
370
+ now - observedAt > capabilities.observation.maxAgeMs) {
371
+ throw new CrowdyAgentError('AGENT_OBSERVATION_STALE', 'Game observation is stale or has invalid freshness bounds');
372
+ }
373
+ if (observation.capabilityRevision !== capabilities.revision ||
374
+ observation.controlledEntityId !== capabilities.controlledEntityId) {
375
+ throw new CrowdyAgentError('AGENT_CONTROL_TARGET_CHANGED', 'Observation does not match the current host target');
376
+ }
377
+ }
378
+ consumeRate(kind, limit, now) {
379
+ const window = (this.rateWindows.get(kind) ?? []).filter((timestamp) => now - timestamp < 1000);
380
+ if (window.length >= limit) {
381
+ throw new CrowdyAgentError('AGENT_RATE_LIMITED', `${kind} exceeded the host rate limit`, { retryable: true });
382
+ }
383
+ window.push(now);
384
+ this.rateWindows.set(kind, window);
385
+ }
386
+ requireCapabilities() {
387
+ if (!this.capabilitiesValue) {
388
+ throw new CrowdyAgentError('AGENT_HOST_UNAVAILABLE', 'Host capabilities must be refreshed before granting control');
389
+ }
390
+ return this.capabilitiesValue;
391
+ }
392
+ clearExpiryTimer() {
393
+ if (this.expiryTimer)
394
+ clearTimeout(this.expiryTimer);
395
+ this.expiryTimer = null;
396
+ }
397
+ emit() {
398
+ this.options.onChange?.(this.snapshot());
399
+ }
400
+ }
401
+ function assertDecimal(value, field) {
402
+ if (typeof value !== 'string' ||
403
+ value.length < 1 ||
404
+ value.length > 40 ||
405
+ !/^(0|[1-9][0-9]*)$/u.test(value)) {
406
+ throw new CrowdyAgentError('AGENT_TOOL_INPUT_INVALID', `${field} must be a decimal string`, { field });
407
+ }
408
+ }
409
+ function assertLeaseScope(value) {
410
+ if (![
411
+ 'observe',
412
+ 'locomotion',
413
+ 'interact',
414
+ 'craft',
415
+ 'combat',
416
+ 'communicate',
417
+ 'travel',
418
+ 'grid',
419
+ 'trust_consent',
420
+ 'commerce',
421
+ ].includes(value)) {
422
+ throw new CrowdyAgentError('AGENT_LEASE_SCOPE_MISSING', `Unknown Play lease scope ${value}`);
423
+ }
424
+ }
425
+ function asLeaseScope(value) {
426
+ assertLeaseScope(value);
427
+ return value;
428
+ }
@@ -0,0 +1,9 @@
1
+ import { type JsonSchemaObject, type JsonSchemaUnion } from '../crowdy-agent/schema.js';
2
+ import type { PlayerHostCommandKind } from './types.js';
3
+ export declare const PLAYER_HOST_CAPABILITIES_SCHEMA_V1: Readonly<JsonSchemaObject>;
4
+ export declare const OBSERVE_REQUEST_SCHEMA_V1: Readonly<JsonSchemaObject>;
5
+ export declare const GAME_OBSERVATION_SCHEMA_V1: Readonly<JsonSchemaObject>;
6
+ export declare const GAME_COMMAND_SCHEMAS_V1: Readonly<Record<PlayerHostCommandKind, JsonSchemaObject>>;
7
+ export declare const GAME_COMMAND_SCHEMA_V1: JsonSchemaUnion;
8
+ export declare const GAME_COMMAND_RESULT_SCHEMA_V1: Readonly<JsonSchemaObject>;
9
+ //# sourceMappingURL=schemas.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schemas.d.ts","sourceRoot":"","sources":["../../src/player-host/schemas.ts"],"names":[],"mappings":"AAAA,OAAO,EAKL,KAAK,gBAAgB,EAErB,KAAK,eAAe,EACrB,MAAM,2BAA2B,CAAC;AAEnC,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,YAAY,CAAC;AAoGxD,eAAO,MAAM,kCAAkC,4BAsC9C,CAAC;AAEF,eAAO,MAAM,yBAAyB,4BAMrC,CAAC;AAgBF,eAAO,MAAM,0BAA0B,4BAwFtC,CAAC;AA6FF,eAAO,MAAM,uBAAuB,EAAE,QAAQ,CAC5C,MAAM,CAAC,qBAAqB,EAAE,gBAAgB,CAAC,CAc/C,CAAC;AAEH,eAAO,MAAM,sBAAsB,EAAE,eAEnC,CAAC;AAiBH,eAAO,MAAM,6BAA6B,4BAqBzC,CAAC"}