@band-ai/band-sdk-core 2.0.0 → 2.1.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.
- package/README.md +45 -0
- package/band_sdk_core.js +80 -0
- package/band_sdk_core_bg.wasm +0 -0
- package/index.d.ts +136 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -148,6 +148,51 @@ native `Error` with the same `.issues`/`.traceContext` contract as
|
|
|
148
148
|
`type` are independent issues, both reported when both strings are
|
|
149
149
|
invalid.
|
|
150
150
|
|
|
151
|
+
### One-shot delivery lifecycle
|
|
152
|
+
|
|
153
|
+
`evaluateDeliveryEvent`, `evaluateNextMessage`, `evaluateDrainCandidate`, and
|
|
154
|
+
`evaluateAdapterResult` are the stateless one-shot delivery lifecycle
|
|
155
|
+
decisions — design decisions live as rustdoc in
|
|
156
|
+
`crates/core/src/runtime/delivery.rs`. Each returns a plain tagged object;
|
|
157
|
+
there is no cross-invocation state, so there is no class here to construct.
|
|
158
|
+
Decision fields stay snake_case (message-wire vocabulary: `room_id`,
|
|
159
|
+
`sender_id`, `sender_type`, …), unlike this module's own camelCase
|
|
160
|
+
function/argument names, so the same shape returns identically from both
|
|
161
|
+
bindings.
|
|
162
|
+
|
|
163
|
+
`evaluateDeliveryEvent(eventType, roomId, payload, agentId, traceContext?)`
|
|
164
|
+
routes one inbound event: `"ignored"` for an unrecognized or out-of-scope
|
|
165
|
+
`eventType`; `"cleanup"` for `room_removed`/`room_deleted`; `"skip_self"` or
|
|
166
|
+
`"invocation"` for `message_created`, depending on whether the sender is
|
|
167
|
+
this agent (`sender_type === "Agent"` and `sender_id === agentId`).
|
|
168
|
+
`message_created` delegates to `validateEventPayload` for payload-shape
|
|
169
|
+
validation, so a malformed `payload` throws the same `Error`, and
|
|
170
|
+
additionally rejects an empty `payload.id` — a message with no identity
|
|
171
|
+
cannot be claimed or acknowledged. `room_removed`/`room_deleted` need no
|
|
172
|
+
payload shape and read `id` straight off the raw payload.
|
|
173
|
+
|
|
174
|
+
`roomId` resolves from the caller-supplied `roomId` first, else the payload's
|
|
175
|
+
own `chat_room_id` (message events) or `id` (room events). An empty string
|
|
176
|
+
counts as absent at both steps. Unresolvable throws an `Error` with one issue
|
|
177
|
+
on path `room_id`: code `missing` when the fallback field is absent or empty,
|
|
178
|
+
`wrong_type` when it is present but not a string.
|
|
179
|
+
|
|
180
|
+
`evaluateNextMessage(triggeringMessageId, nextMessageId)` compares the
|
|
181
|
+
triggering message against the platform's authoritative "next open message"
|
|
182
|
+
for a room (already fetched by the caller): `"no_pending"`,
|
|
183
|
+
`"already_processed"`, or `"ready_to_claim"`.
|
|
184
|
+
|
|
185
|
+
`evaluateDrainCandidate(candidate, seenIds, agentId)` classifies one
|
|
186
|
+
already-fetched drain candidate — `candidate` is `{id, sender_id,
|
|
187
|
+
sender_type}`, or `null`/`undefined` when the fetch returned nothing:
|
|
188
|
+
`"no_candidate"`, `"self_echo"` (checked before the snapshot, so an echo
|
|
189
|
+
never halts a drain), `"out_of_snapshot"` (stop), or `"drain"` (continue).
|
|
190
|
+
The caller's own bounded or unbounded loop owns the cap; this function
|
|
191
|
+
classifies one candidate per call.
|
|
192
|
+
|
|
193
|
+
`evaluateAdapterResult(roomId, messageId, succeeded)` maps an adapter
|
|
194
|
+
outcome to `"processed"` or `"failed"`.
|
|
195
|
+
|
|
151
196
|
The public declaration is
|
|
152
197
|
[`index.d.ts`](https://github.com/band-ai/band-sdk-core/blob/main/crates/wasm/index.d.ts).
|
|
153
198
|
|
package/band_sdk_core.js
CHANGED
|
@@ -1206,6 +1206,82 @@ function classifyUpgrade(status) {
|
|
|
1206
1206
|
}
|
|
1207
1207
|
exports.classifyUpgrade = classifyUpgrade;
|
|
1208
1208
|
|
|
1209
|
+
/**
|
|
1210
|
+
* Adapter outcome -> ack decision. Throws a plain `Error` if `roomId`/
|
|
1211
|
+
* `messageId` is not a string.
|
|
1212
|
+
* @param {any} roomId
|
|
1213
|
+
* @param {any} messageId
|
|
1214
|
+
* @param {boolean} succeeded
|
|
1215
|
+
* @returns {any}
|
|
1216
|
+
*/
|
|
1217
|
+
function evaluateAdapterResult(roomId, messageId, succeeded) {
|
|
1218
|
+
const ret = wasm.evaluateAdapterResult(roomId, messageId, succeeded);
|
|
1219
|
+
if (ret[2]) {
|
|
1220
|
+
throw takeFromExternrefTable0(ret[1]);
|
|
1221
|
+
}
|
|
1222
|
+
return takeFromExternrefTable0(ret[0]);
|
|
1223
|
+
}
|
|
1224
|
+
exports.evaluateAdapterResult = evaluateAdapterResult;
|
|
1225
|
+
|
|
1226
|
+
/**
|
|
1227
|
+
* Evaluate the routing decision for one inbound platform event.
|
|
1228
|
+
*
|
|
1229
|
+
* On failure throws a native `Error` with `.issues` (an array of
|
|
1230
|
+
* `{path, code, message}` objects) and `.traceContext`. A non-string
|
|
1231
|
+
* `eventType`/`roomId`/`agentId`/`traceContext`, or a `payload` that
|
|
1232
|
+
* cannot be converted, throws a plain `Error` without `.issues`.
|
|
1233
|
+
* @param {any} eventType
|
|
1234
|
+
* @param {any} roomId
|
|
1235
|
+
* @param {any} payload
|
|
1236
|
+
* @param {any} agentId
|
|
1237
|
+
* @param {any} traceContext
|
|
1238
|
+
* @returns {any}
|
|
1239
|
+
*/
|
|
1240
|
+
function evaluateDeliveryEvent(eventType, roomId, payload, agentId, traceContext) {
|
|
1241
|
+
const ret = wasm.evaluateDeliveryEvent(eventType, roomId, payload, agentId, traceContext);
|
|
1242
|
+
if (ret[2]) {
|
|
1243
|
+
throw takeFromExternrefTable0(ret[1]);
|
|
1244
|
+
}
|
|
1245
|
+
return takeFromExternrefTable0(ret[0]);
|
|
1246
|
+
}
|
|
1247
|
+
exports.evaluateDeliveryEvent = evaluateDeliveryEvent;
|
|
1248
|
+
|
|
1249
|
+
/**
|
|
1250
|
+
* One step of the drain loop. `candidate` is `{id, sender_id,
|
|
1251
|
+
* sender_type}` or `null`/`undefined` when the host's fetch returned no
|
|
1252
|
+
* candidate; a malformed object throws a plain `Error`.
|
|
1253
|
+
* @param {any} candidate
|
|
1254
|
+
* @param {any} seenIds
|
|
1255
|
+
* @param {any} agentId
|
|
1256
|
+
* @returns {any}
|
|
1257
|
+
*/
|
|
1258
|
+
function evaluateDrainCandidate(candidate, seenIds, agentId) {
|
|
1259
|
+
const ret = wasm.evaluateDrainCandidate(candidate, seenIds, agentId);
|
|
1260
|
+
if (ret[2]) {
|
|
1261
|
+
throw takeFromExternrefTable0(ret[1]);
|
|
1262
|
+
}
|
|
1263
|
+
return takeFromExternrefTable0(ret[0]);
|
|
1264
|
+
}
|
|
1265
|
+
exports.evaluateDrainCandidate = evaluateDrainCandidate;
|
|
1266
|
+
|
|
1267
|
+
/**
|
|
1268
|
+
* Compares the triggering message against the platform's authoritative
|
|
1269
|
+
* "next open message" for a room. Throws a plain `Error` if
|
|
1270
|
+
* `triggeringMessageId`/`nextMessageId` is not a string (or `null`/
|
|
1271
|
+
* `undefined` for `nextMessageId`).
|
|
1272
|
+
* @param {any} triggeringMessageId
|
|
1273
|
+
* @param {any} nextMessageId
|
|
1274
|
+
* @returns {any}
|
|
1275
|
+
*/
|
|
1276
|
+
function evaluateNextMessage(triggeringMessageId, nextMessageId) {
|
|
1277
|
+
const ret = wasm.evaluateNextMessage(triggeringMessageId, nextMessageId);
|
|
1278
|
+
if (ret[2]) {
|
|
1279
|
+
throw takeFromExternrefTable0(ret[1]);
|
|
1280
|
+
}
|
|
1281
|
+
return takeFromExternrefTable0(ret[0]);
|
|
1282
|
+
}
|
|
1283
|
+
exports.evaluateNextMessage = evaluateNextMessage;
|
|
1284
|
+
|
|
1209
1285
|
/**
|
|
1210
1286
|
* This platform's Phoenix Channels topic for a room's `room_participants`
|
|
1211
1287
|
* channel.
|
|
@@ -1386,6 +1462,10 @@ function __wbg_get_imports() {
|
|
|
1386
1462
|
const ret = arg0[arg1 >>> 0];
|
|
1387
1463
|
return ret;
|
|
1388
1464
|
},
|
|
1465
|
+
__wbg_get_with_ref_key_6412cf3094599694: function(arg0, arg1) {
|
|
1466
|
+
const ret = arg0[arg1];
|
|
1467
|
+
return ret;
|
|
1468
|
+
},
|
|
1389
1469
|
__wbg_instanceof_ArrayBuffer_993d02d2d254cad1: function(arg0) {
|
|
1390
1470
|
let result;
|
|
1391
1471
|
try {
|
package/band_sdk_core_bg.wasm
CHANGED
|
Binary file
|
package/index.d.ts
CHANGED
|
@@ -364,3 +364,139 @@ export class RoomRoster {
|
|
|
364
364
|
reconcile(currentRoomIds: string[]): RoomReconciliation;
|
|
365
365
|
clear(): string[];
|
|
366
366
|
}
|
|
367
|
+
|
|
368
|
+
// The one-shot delivery lifecycle decisions: evaluateDeliveryEvent,
|
|
369
|
+
// evaluateNextMessage, evaluateDrainCandidate, evaluateAdapterResult.
|
|
370
|
+
// Each returns a plain tagged object -- these functions carry no
|
|
371
|
+
// cross-invocation state, so there is no class here to construct. Decision
|
|
372
|
+
// fields stay snake_case (message-wire vocabulary: `room_id`, `sender_id`,
|
|
373
|
+
// `sender_type`, ...), unlike this module's own camelCase function/argument
|
|
374
|
+
// names, so the same shape is returned identically from both bindings.
|
|
375
|
+
|
|
376
|
+
export interface EventIgnored {
|
|
377
|
+
decision: "ignored";
|
|
378
|
+
event_type: string;
|
|
379
|
+
}
|
|
380
|
+
export interface EventCleanup {
|
|
381
|
+
decision: "cleanup";
|
|
382
|
+
room_id: string;
|
|
383
|
+
}
|
|
384
|
+
export interface EventSkipSelf {
|
|
385
|
+
decision: "skip_self";
|
|
386
|
+
room_id: string;
|
|
387
|
+
message_id: string;
|
|
388
|
+
}
|
|
389
|
+
export interface EventInvocation {
|
|
390
|
+
decision: "invocation";
|
|
391
|
+
room_id: string;
|
|
392
|
+
message_id: string;
|
|
393
|
+
sender_id: string;
|
|
394
|
+
sender_type: string;
|
|
395
|
+
}
|
|
396
|
+
export type EventDecision = EventIgnored | EventCleanup | EventSkipSelf | EventInvocation;
|
|
397
|
+
|
|
398
|
+
/**
|
|
399
|
+
* Evaluate the routing decision for one inbound platform event.
|
|
400
|
+
*
|
|
401
|
+
* `message_created` delegates to {@link validateEventPayload}'s own
|
|
402
|
+
* validation; a rejection there throws the same native `Error` with
|
|
403
|
+
* `.issues`/`.traceContext`, as does an empty `payload.id`.
|
|
404
|
+
* `room_removed`/`room_deleted` need no payload shape and read `id` straight
|
|
405
|
+
* off the raw payload. Both event kinds throw that same `Error` shape when
|
|
406
|
+
* `roomId` resolves from neither the envelope nor the payload — an empty
|
|
407
|
+
* string counting as absent — with issue code `missing` when the fallback
|
|
408
|
+
* field is absent or empty and `wrong_type` when it is present but not a
|
|
409
|
+
* string. Throws a plain `Error` without `.issues` if
|
|
410
|
+
* `eventType`/`roomId`/`agentId`/`traceContext` is not a string (or not
|
|
411
|
+
* `null`/`undefined` for `roomId`/`traceContext`), or if `payload` cannot be
|
|
412
|
+
* converted.
|
|
413
|
+
*/
|
|
414
|
+
export function evaluateDeliveryEvent(
|
|
415
|
+
eventType: string,
|
|
416
|
+
roomId: string | null | undefined,
|
|
417
|
+
payload: unknown,
|
|
418
|
+
agentId: string,
|
|
419
|
+
traceContext?: string | null,
|
|
420
|
+
): EventDecision;
|
|
421
|
+
|
|
422
|
+
export interface NextMessageNoPending {
|
|
423
|
+
decision: "no_pending";
|
|
424
|
+
}
|
|
425
|
+
export interface NextMessageAlreadyProcessed {
|
|
426
|
+
decision: "already_processed";
|
|
427
|
+
next_open_id: string;
|
|
428
|
+
}
|
|
429
|
+
export interface NextMessageReadyToClaim {
|
|
430
|
+
decision: "ready_to_claim";
|
|
431
|
+
}
|
|
432
|
+
export type NextMessageDecision =
|
|
433
|
+
| NextMessageNoPending
|
|
434
|
+
| NextMessageAlreadyProcessed
|
|
435
|
+
| NextMessageReadyToClaim;
|
|
436
|
+
|
|
437
|
+
/**
|
|
438
|
+
* Compares the triggering message against the platform's authoritative
|
|
439
|
+
* "next open message" for a room. Throws a plain `Error` if
|
|
440
|
+
* `triggeringMessageId` is not a string, or `nextMessageId` is not a
|
|
441
|
+
* string, `null`, or `undefined`.
|
|
442
|
+
*/
|
|
443
|
+
export function evaluateNextMessage(
|
|
444
|
+
triggeringMessageId: string,
|
|
445
|
+
nextMessageId: string | null | undefined,
|
|
446
|
+
): NextMessageDecision;
|
|
447
|
+
|
|
448
|
+
/** One already-fetched drain candidate, matching `evaluateDeliveryEvent`'s own field names. */
|
|
449
|
+
export interface DrainCandidate {
|
|
450
|
+
id: string;
|
|
451
|
+
sender_id: string;
|
|
452
|
+
sender_type: string;
|
|
453
|
+
}
|
|
454
|
+
export interface DrainNoCandidate {
|
|
455
|
+
decision: "no_candidate";
|
|
456
|
+
}
|
|
457
|
+
export interface DrainOutOfSnapshot {
|
|
458
|
+
decision: "out_of_snapshot";
|
|
459
|
+
message_id: string;
|
|
460
|
+
}
|
|
461
|
+
export interface DrainSelfEcho {
|
|
462
|
+
decision: "self_echo";
|
|
463
|
+
message_id: string;
|
|
464
|
+
}
|
|
465
|
+
export interface DrainMessage {
|
|
466
|
+
decision: "drain";
|
|
467
|
+
message_id: string;
|
|
468
|
+
}
|
|
469
|
+
export type DrainStep = DrainNoCandidate | DrainOutOfSnapshot | DrainSelfEcho | DrainMessage;
|
|
470
|
+
|
|
471
|
+
/**
|
|
472
|
+
* One step of the drain loop. `candidate` is `null`/`undefined` when the
|
|
473
|
+
* host's fetch returned no candidate. Throws a plain `Error` if
|
|
474
|
+
* `candidate` is present but malformed, or if `agentId` is not a string.
|
|
475
|
+
*/
|
|
476
|
+
export function evaluateDrainCandidate(
|
|
477
|
+
candidate: DrainCandidate | null | undefined,
|
|
478
|
+
seenIds: string[],
|
|
479
|
+
agentId: string,
|
|
480
|
+
): DrainStep;
|
|
481
|
+
|
|
482
|
+
export interface AckProcessed {
|
|
483
|
+
decision: "processed";
|
|
484
|
+
room_id: string;
|
|
485
|
+
message_id: string;
|
|
486
|
+
}
|
|
487
|
+
export interface AckFailed {
|
|
488
|
+
decision: "failed";
|
|
489
|
+
room_id: string;
|
|
490
|
+
message_id: string;
|
|
491
|
+
}
|
|
492
|
+
export type AckDecision = AckProcessed | AckFailed;
|
|
493
|
+
|
|
494
|
+
/**
|
|
495
|
+
* Adapter outcome -> ack decision. Throws a plain `Error` if `roomId`/
|
|
496
|
+
* `messageId` is not a string.
|
|
497
|
+
*/
|
|
498
|
+
export function evaluateAdapterResult(
|
|
499
|
+
roomId: string,
|
|
500
|
+
messageId: string,
|
|
501
|
+
succeeded: boolean,
|
|
502
|
+
): AckDecision;
|