castle-web-sdk 0.4.33 → 0.4.34

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.
@@ -102,17 +102,57 @@ export interface CompleteCharacterBeatInput {
102
102
  eventOccurrenceId: string;
103
103
  outcomeId: string;
104
104
  }
105
+ export interface EvaluateCharacterInformationInput {
106
+ operationId: string;
107
+ maxDeliveries?: number;
108
+ }
109
+ export interface CharacterInformationEvaluationResult {
110
+ generation: number;
111
+ evaluatedAt: string;
112
+ snapshotCandidateCount: number;
113
+ deliveries: Array<{
114
+ ruleId: string;
115
+ rootId: string;
116
+ recipientCharacterId: string;
117
+ status: "delivered" | "already_known";
118
+ }>;
119
+ cancelled: Array<{
120
+ ruleId: string;
121
+ rootId: string;
122
+ }>;
123
+ blocked: Array<{
124
+ ruleId: string;
125
+ rootId: string;
126
+ recipientCharacterId: string;
127
+ code: "testimony_backlog_full" | "information_limit" | "storage_capacity";
128
+ }>;
129
+ remainingCount: number;
130
+ }
131
+ export type CharacterInformationEvaluationOperation = Omit<CharacterOperation, "result"> & {
132
+ result: CharacterInformationEvaluationResult | null;
133
+ };
134
+ export interface SendCharacterInput {
135
+ operationId: string;
136
+ characterId: string;
137
+ input: string;
138
+ audience: {
139
+ listenerCharacterIds: string[];
140
+ };
141
+ }
105
142
  /**
106
143
  * Narrative commands do not run a model. They record creator-validated events,
107
144
  * knowledge delivery and beat completion inside this immutable playthrough.
108
145
  */
109
146
  export interface ServerPlaythroughCharacters {
147
+ /** Queues a funded turn whose admitted listeners are fixed at enqueue time. */
148
+ send(input: SendCharacterInput): Promise<CharacterOperation>;
110
149
  recordEvent(input: RecordCharacterEventInput): Promise<CharacterOperation>;
111
150
  setGameState(input: SetCharacterGameStateInput): Promise<CharacterOperation>;
112
151
  shareClaim(input: ShareCharacterClaimInput): Promise<CharacterOperation>;
113
152
  inspect(): Promise<Json>;
114
153
  deliverKnowledge(input: DeliverCharacterKnowledgeInput): Promise<CharacterOperation>;
115
154
  completeBeat(input: CompleteCharacterBeatInput): Promise<CharacterOperation>;
155
+ evaluateInformation(input: EvaluateCharacterInformationInput): Promise<CharacterInformationEvaluationOperation>;
116
156
  status(operationId: string): Promise<CharacterOperation>;
117
157
  history(options?: ServerCharacterHistoryOptions): Promise<CharacterHistory>;
118
158
  }
@@ -84,6 +84,17 @@ export function createServerStorage(platformHandle) {
84
84
  }
85
85
  function createPlaythrough(call, subject, generation) {
86
86
  const characters = Object.freeze({
87
+ async send(input) {
88
+ const characterId = assertNarrativeId(input?.characterId, "characterId");
89
+ return call("characterSendWithAudience", {
90
+ subject,
91
+ generation,
92
+ operationId: assertOperationId(input?.operationId),
93
+ characterId,
94
+ input: assertCharacterInput(input?.input),
95
+ audience: assertCharacterAudience(input?.audience, characterId),
96
+ });
97
+ },
87
98
  async recordEvent(input) {
88
99
  return call("characterRecordEvent", {
89
100
  subject,
@@ -139,6 +150,15 @@ function createPlaythrough(call, subject, generation) {
139
150
  outcomeId: assertNarrativeId(input?.outcomeId, "outcomeId"),
140
151
  });
141
152
  },
153
+ async evaluateInformation(input) {
154
+ const maxDeliveries = assertInformationMaxDeliveries(input?.maxDeliveries);
155
+ return call("characterEvaluateInformation", {
156
+ subject,
157
+ generation,
158
+ operationId: assertOperationId(input?.operationId),
159
+ ...(maxDeliveries === undefined ? {} : { maxDeliveries }),
160
+ });
161
+ },
142
162
  async status(operationId) {
143
163
  return call("characterStatus", {
144
164
  subject,
@@ -351,6 +371,33 @@ function assertNarrativeIds(value, field) {
351
371
  }
352
372
  return value.map((item) => assertNarrativeId(item, field));
353
373
  }
374
+ function assertCharacterInput(value) {
375
+ if (typeof value !== "string" ||
376
+ value.length === 0 ||
377
+ value.length > 2000 ||
378
+ value.includes("\0") ||
379
+ hasUnpairedSurrogate(value)) {
380
+ throw characterArgumentError("input must be valid non-empty text of at most 2000 characters.");
381
+ }
382
+ return value;
383
+ }
384
+ function assertCharacterAudience(value, targetCharacterId) {
385
+ if (!value || typeof value !== "object" || Array.isArray(value)) {
386
+ throw characterArgumentError("audience must contain listenerCharacterIds.");
387
+ }
388
+ const audience = value;
389
+ if (Object.keys(audience).some((key) => key !== "listenerCharacterIds") ||
390
+ !Array.isArray(audience.listenerCharacterIds) ||
391
+ audience.listenerCharacterIds.length > 3) {
392
+ throw characterArgumentError("audience must contain at most three listener character ids.");
393
+ }
394
+ const listenerCharacterIds = audience.listenerCharacterIds.map((id) => assertNarrativeId(id, "audience.listenerCharacterIds"));
395
+ if (new Set(listenerCharacterIds).size !== listenerCharacterIds.length ||
396
+ listenerCharacterIds.includes(targetCharacterId)) {
397
+ throw characterArgumentError("audience listeners must be unique and must not include the target character.");
398
+ }
399
+ return { listenerCharacterIds };
400
+ }
354
401
  function assertKnowledgeSource(value) {
355
402
  if (!value || typeof value !== "object" || Array.isArray(value)) {
356
403
  throw storageError("CAULDRON_CHARACTER_INVALID_ARGUMENT", "source must name creator_event or a character.", "session.storage.playthrough.characters.deliverKnowledge");
@@ -402,6 +449,14 @@ function assertStateRevision(value) {
402
449
  }
403
450
  return value;
404
451
  }
452
+ function assertInformationMaxDeliveries(value) {
453
+ if (value === undefined)
454
+ return undefined;
455
+ if (!Number.isSafeInteger(value) || value < 1 || value > 32) {
456
+ throw characterArgumentError("maxDeliveries must be an integer from 1 through 32.");
457
+ }
458
+ return value;
459
+ }
405
460
  function assertStateChanges(value, hasObjectChanges = false) {
406
461
  if (!Array.isArray(value) || value.length > 32 || (!hasObjectChanges && value.length < 1)) {
407
462
  throw characterArgumentError(hasObjectChanges
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "castle-web-sdk",
3
- "version": "0.4.33",
3
+ "version": "0.4.34",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "git+https://github.com/castle-xyz/castle-experimental-web.git"