@band-ai/band-sdk-core 2.0.0 → 2.2.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 +51 -0
- package/band_sdk_core.js +100 -0
- package/band_sdk_core_bg.wasm +0 -0
- package/index.d.ts +145 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -148,6 +148,57 @@ 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
|
+
|
|
196
|
+
`isSelfEcho(senderId, senderType, agentId)` is the one definition of
|
|
197
|
+
"self echo" (`senderType === "Agent" && senderId === agentId`) that
|
|
198
|
+
`evaluateDeliveryEvent` and `evaluateDrainCandidate` use internally,
|
|
199
|
+
exposed for a host's own call sites that classify a sender without going
|
|
200
|
+
through either function.
|
|
201
|
+
|
|
151
202
|
The public declaration is
|
|
152
203
|
[`index.d.ts`](https://github.com/band-ai/band-sdk-core/blob/main/crates/wasm/index.d.ts).
|
|
153
204
|
|
package/band_sdk_core.js
CHANGED
|
@@ -1206,6 +1206,102 @@ 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
|
+
|
|
1285
|
+
/**
|
|
1286
|
+
* The one definition of "self echo" (`senderType === "Agent" &&
|
|
1287
|
+
* senderId === agentId`), shared by `evaluateDeliveryEvent` and
|
|
1288
|
+
* `evaluateDrainCandidate` internally and exposed here for a host's own
|
|
1289
|
+
* call sites that don't go through either. Throws a plain `Error` if
|
|
1290
|
+
* `senderId`/`senderType`/`agentId` is not a string.
|
|
1291
|
+
* @param {any} senderId
|
|
1292
|
+
* @param {any} senderType
|
|
1293
|
+
* @param {any} agentId
|
|
1294
|
+
* @returns {boolean}
|
|
1295
|
+
*/
|
|
1296
|
+
function isSelfEcho(senderId, senderType, agentId) {
|
|
1297
|
+
const ret = wasm.isSelfEcho(senderId, senderType, agentId);
|
|
1298
|
+
if (ret[2]) {
|
|
1299
|
+
throw takeFromExternrefTable0(ret[1]);
|
|
1300
|
+
}
|
|
1301
|
+
return ret[0] !== 0;
|
|
1302
|
+
}
|
|
1303
|
+
exports.isSelfEcho = isSelfEcho;
|
|
1304
|
+
|
|
1209
1305
|
/**
|
|
1210
1306
|
* This platform's Phoenix Channels topic for a room's `room_participants`
|
|
1211
1307
|
* channel.
|
|
@@ -1386,6 +1482,10 @@ function __wbg_get_imports() {
|
|
|
1386
1482
|
const ret = arg0[arg1 >>> 0];
|
|
1387
1483
|
return ret;
|
|
1388
1484
|
},
|
|
1485
|
+
__wbg_get_with_ref_key_6412cf3094599694: function(arg0, arg1) {
|
|
1486
|
+
const ret = arg0[arg1];
|
|
1487
|
+
return ret;
|
|
1488
|
+
},
|
|
1389
1489
|
__wbg_instanceof_ArrayBuffer_993d02d2d254cad1: function(arg0) {
|
|
1390
1490
|
let result;
|
|
1391
1491
|
try {
|
package/band_sdk_core_bg.wasm
CHANGED
|
Binary file
|
package/index.d.ts
CHANGED
|
@@ -364,3 +364,148 @@ 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;
|
|
503
|
+
|
|
504
|
+
/**
|
|
505
|
+
* The one definition of "self echo" (`senderType === "Agent" &&
|
|
506
|
+
* senderId === agentId`), shared by {@link evaluateDeliveryEvent} and
|
|
507
|
+
* {@link evaluateDrainCandidate} internally and exposed here for a host's
|
|
508
|
+
* own call sites that don't go through either. Throws a plain `Error` if
|
|
509
|
+
* `senderId`/`senderType`/`agentId` is not a string.
|
|
510
|
+
*/
|
|
511
|
+
export function isSelfEcho(senderId: string, senderType: string, agentId: string): boolean;
|