agent-relay 8.4.0 → 8.5.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/dist/index.cjs +237 -33
- package/package.json +6 -6
package/dist/index.cjs
CHANGED
|
@@ -250,8 +250,11 @@ __export(index_exports, {
|
|
|
250
250
|
normalizeChannelMember: () => normalizeChannelMember,
|
|
251
251
|
normalizeChannelName: () => normalizeChannelName,
|
|
252
252
|
normalizeChannelReadStatus: () => normalizeChannelReadStatus,
|
|
253
|
+
normalizeDeliveryTransition: () => normalizeDeliveryTransition,
|
|
253
254
|
normalizeGroupDirectConversation: () => normalizeGroupDirectConversation,
|
|
254
255
|
normalizeInbox: () => normalizeInbox,
|
|
256
|
+
normalizeInboxItem: () => normalizeInboxItem,
|
|
257
|
+
normalizeInboxItemState: () => normalizeInboxItemState,
|
|
255
258
|
normalizeMessage: () => normalizeMessage,
|
|
256
259
|
normalizeMessagingEvent: () => normalizeMessagingEvent,
|
|
257
260
|
normalizeReaction: () => normalizeReaction,
|
|
@@ -33215,6 +33218,74 @@ function normalizeChannelReadStatus(input) {
|
|
|
33215
33218
|
...lastReadAt ? { lastReadAt } : {}
|
|
33216
33219
|
};
|
|
33217
33220
|
}
|
|
33221
|
+
var INBOX_STATE_BY_DELIVERY_STATUS = {
|
|
33222
|
+
accepted: "queued",
|
|
33223
|
+
delivered: "delivered",
|
|
33224
|
+
deferred: "deferred",
|
|
33225
|
+
failed: "failed"
|
|
33226
|
+
};
|
|
33227
|
+
function normalizeInboxItemState(value) {
|
|
33228
|
+
return (value !== void 0 ? INBOX_STATE_BY_DELIVERY_STATUS[value] : void 0) ?? "queued";
|
|
33229
|
+
}
|
|
33230
|
+
function normalizeDeliveryMetadata(record3) {
|
|
33231
|
+
const metadata = {};
|
|
33232
|
+
const mode = readString(record3, "mode");
|
|
33233
|
+
const reason = readNullableString(record3, "reason");
|
|
33234
|
+
const priority = readString(record3, "priority");
|
|
33235
|
+
const retryable = readBoolean(record3, "retryable");
|
|
33236
|
+
const error101 = readNullableString(record3, "error");
|
|
33237
|
+
const deadline = readNullableString(record3, "deadline");
|
|
33238
|
+
if (mode)
|
|
33239
|
+
metadata.mode = mode;
|
|
33240
|
+
if (reason)
|
|
33241
|
+
metadata.reason = reason;
|
|
33242
|
+
if (priority)
|
|
33243
|
+
metadata.priority = priority;
|
|
33244
|
+
if (retryable !== void 0)
|
|
33245
|
+
metadata.retryable = retryable;
|
|
33246
|
+
if (error101)
|
|
33247
|
+
metadata.error = error101;
|
|
33248
|
+
if (deadline)
|
|
33249
|
+
metadata.deadline = deadline;
|
|
33250
|
+
return Object.keys(metadata).length > 0 ? metadata : void 0;
|
|
33251
|
+
}
|
|
33252
|
+
function normalizeInboxItem(input, context = {}) {
|
|
33253
|
+
const record3 = isRecord(input) ? input : {};
|
|
33254
|
+
const messageId = readString(record3, "messageId", "message_id");
|
|
33255
|
+
const channelId = readString(record3, "channelId", "channel_id");
|
|
33256
|
+
const agentId = readString(record3, "agentId", "agent_id");
|
|
33257
|
+
const availableAt = readNullableString(record3, "availableAt", "available_at");
|
|
33258
|
+
const messageRecord = readRecord(record3, "message");
|
|
33259
|
+
const metadata = normalizeDeliveryMetadata(record3);
|
|
33260
|
+
return {
|
|
33261
|
+
id: readString(record3, "id", "deliveryId", "delivery_id") ?? "",
|
|
33262
|
+
recipient: {
|
|
33263
|
+
name: context.recipientName ?? agentId ?? "",
|
|
33264
|
+
...agentId ? { id: agentId } : {}
|
|
33265
|
+
},
|
|
33266
|
+
state: normalizeInboxItemState(readString(record3, "status")),
|
|
33267
|
+
// The relaycast ledger does not expose attempt counts.
|
|
33268
|
+
attempts: 0,
|
|
33269
|
+
...availableAt ? { availableAt } : {},
|
|
33270
|
+
message: normalizeMessage(messageRecord ?? {
|
|
33271
|
+
...messageId ? { id: messageId } : {},
|
|
33272
|
+
...channelId ? { channel_id: channelId } : {}
|
|
33273
|
+
}),
|
|
33274
|
+
...metadata ? { metadata } : {}
|
|
33275
|
+
};
|
|
33276
|
+
}
|
|
33277
|
+
function normalizeDeliveryTransition(action, input) {
|
|
33278
|
+
const record3 = isRecord(input) ? input : {};
|
|
33279
|
+
const availableAt = readNullableString(record3, "availableAt", "available_at");
|
|
33280
|
+
return {
|
|
33281
|
+
supported: true,
|
|
33282
|
+
action,
|
|
33283
|
+
deliveryId: readString(record3, "id", "deliveryId", "delivery_id") ?? "",
|
|
33284
|
+
messageId: readString(record3, "messageId", "message_id") ?? "",
|
|
33285
|
+
state: normalizeInboxItemState(readString(record3, "status")),
|
|
33286
|
+
...action === "defer" && availableAt ? { deferUntil: availableAt } : {}
|
|
33287
|
+
};
|
|
33288
|
+
}
|
|
33218
33289
|
function normalizeSearchResult(input) {
|
|
33219
33290
|
const record3 = isRecord(input) ? input : {};
|
|
33220
33291
|
const createdAt = readString(record3, "createdAt", "created_at");
|
|
@@ -33532,13 +33603,7 @@ function createRelaycastClient(options) {
|
|
|
33532
33603
|
}));
|
|
33533
33604
|
}
|
|
33534
33605
|
var RelaycastMessagingClient = class {
|
|
33535
|
-
capabilities
|
|
33536
|
-
serverDeliveryState: false,
|
|
33537
|
-
durableDelivery: false,
|
|
33538
|
-
durableAck: false,
|
|
33539
|
-
durableFail: false,
|
|
33540
|
-
durableDefer: false
|
|
33541
|
-
};
|
|
33606
|
+
capabilities;
|
|
33542
33607
|
relaycast;
|
|
33543
33608
|
agentClient;
|
|
33544
33609
|
eventHandlers = /* @__PURE__ */ new Map();
|
|
@@ -33546,6 +33611,14 @@ var RelaycastMessagingClient = class {
|
|
|
33546
33611
|
constructor(options) {
|
|
33547
33612
|
this.relaycast = createRelaycastClient(options);
|
|
33548
33613
|
this.agentClient = options.agentClient ?? (options.agentToken ? this.relaycast.as?.(options.agentToken, options.agentClientOptions) : void 0);
|
|
33614
|
+
const durable = this.deliverySurface() !== void 0;
|
|
33615
|
+
this.capabilities = {
|
|
33616
|
+
serverDeliveryState: durable,
|
|
33617
|
+
durableDelivery: durable,
|
|
33618
|
+
durableAck: durable,
|
|
33619
|
+
durableFail: durable,
|
|
33620
|
+
durableDefer: durable
|
|
33621
|
+
};
|
|
33549
33622
|
}
|
|
33550
33623
|
agents = {
|
|
33551
33624
|
list: async (options) => {
|
|
@@ -33681,12 +33754,55 @@ var RelaycastMessagingClient = class {
|
|
|
33681
33754
|
};
|
|
33682
33755
|
inbox = {
|
|
33683
33756
|
get: async (options) => normalizeInbox(await this.requireAgentClient("inbox.get").inbox(definedOptions({ limit: options?.limit }))),
|
|
33684
|
-
|
|
33685
|
-
|
|
33686
|
-
|
|
33687
|
-
|
|
33688
|
-
|
|
33689
|
-
|
|
33757
|
+
/**
|
|
33758
|
+
* List durable deliveries queued for the authenticated agent. The
|
|
33759
|
+
* relaycast ledger replays non-terminal items (accepted + deferred) in
|
|
33760
|
+
* FIFO order with the message payload embedded. The underlying API has no
|
|
33761
|
+
* cursor, so `nextCursor` is never set and `before`/`after` are ignored.
|
|
33762
|
+
*/
|
|
33763
|
+
list: async (input) => {
|
|
33764
|
+
const surface = this.deliverySurface();
|
|
33765
|
+
if (!surface)
|
|
33766
|
+
return { items: [] };
|
|
33767
|
+
const deliveries = await surface.deliveries(definedOptions({ limit: input?.limit }));
|
|
33768
|
+
return {
|
|
33769
|
+
items: deliveries.map((delivery) => normalizeInboxItem(delivery, definedOptions({ recipientName: input?.agentName })))
|
|
33770
|
+
};
|
|
33771
|
+
},
|
|
33772
|
+
/**
|
|
33773
|
+
* Stream durable deliveries: seed from the non-terminal queue, then push
|
|
33774
|
+
* items announced by `delivery.accepted` WebSocket events, deduplicated by
|
|
33775
|
+
* delivery id. Falls back to an empty stream without an agent client.
|
|
33776
|
+
*/
|
|
33777
|
+
subscribe: (input) => {
|
|
33778
|
+
const surface = this.deliverySurface();
|
|
33779
|
+
if (!surface)
|
|
33780
|
+
return this.emptyInboxSubscription();
|
|
33781
|
+
return this.createInboxSubscription(surface, input);
|
|
33782
|
+
},
|
|
33783
|
+
ack: async (input) => {
|
|
33784
|
+
const surface = this.deliverySurface();
|
|
33785
|
+
if (!surface)
|
|
33786
|
+
return this.unsupportedInboxDelivery("ack", input.inboxItemId);
|
|
33787
|
+
return normalizeDeliveryTransition("ack", await surface.ackDelivery(input.inboxItemId));
|
|
33788
|
+
},
|
|
33789
|
+
fail: async (input) => {
|
|
33790
|
+
const surface = this.deliverySurface();
|
|
33791
|
+
if (!surface)
|
|
33792
|
+
return this.unsupportedInboxDelivery("fail", input.inboxItemId, input.error);
|
|
33793
|
+
return normalizeDeliveryTransition("fail", await surface.failDelivery(input.inboxItemId, definedOptions({ error: input.error, retryable: input.retry })));
|
|
33794
|
+
},
|
|
33795
|
+
defer: async (input) => {
|
|
33796
|
+
const surface = this.deliverySurface();
|
|
33797
|
+
if (!surface) {
|
|
33798
|
+
return this.unsupportedInboxDelivery("defer", input.inboxItemId, input.reason, input.availableAt);
|
|
33799
|
+
}
|
|
33800
|
+
return normalizeDeliveryTransition("defer", await surface.deferDelivery(input.inboxItemId, {
|
|
33801
|
+
availableAt: input.availableAt,
|
|
33802
|
+
...input.reason === void 0 ? {} : { reason: input.reason }
|
|
33803
|
+
}));
|
|
33804
|
+
},
|
|
33805
|
+
markRead: async (input) => this.unsupportedInboxDelivery("ack", input.inboxItemId, "The Relaycast delivery ledger has no read state; use inbox.ack to mark a delivery handled.")
|
|
33690
33806
|
};
|
|
33691
33807
|
events = {
|
|
33692
33808
|
connect: () => {
|
|
@@ -33722,26 +33838,34 @@ var RelaycastMessagingClient = class {
|
|
|
33722
33838
|
},
|
|
33723
33839
|
on: (event, handler) => this.addEventListener(event, handler)
|
|
33724
33840
|
};
|
|
33841
|
+
/**
|
|
33842
|
+
* Durable delivery transitions keyed by the relaycast delivery id (the
|
|
33843
|
+
* `InboxItem.id` returned by `inbox.list`/`inbox.subscribe`). Transitions
|
|
33844
|
+
* are idempotent on the server.
|
|
33845
|
+
*/
|
|
33725
33846
|
deliveries = {
|
|
33726
|
-
ack: async (
|
|
33727
|
-
|
|
33728
|
-
|
|
33729
|
-
|
|
33730
|
-
|
|
33731
|
-
}
|
|
33732
|
-
fail: async (
|
|
33733
|
-
|
|
33734
|
-
|
|
33735
|
-
|
|
33736
|
-
|
|
33737
|
-
}
|
|
33738
|
-
defer: async (
|
|
33739
|
-
|
|
33740
|
-
|
|
33741
|
-
|
|
33742
|
-
|
|
33743
|
-
|
|
33744
|
-
|
|
33847
|
+
ack: async (deliveryId) => {
|
|
33848
|
+
const surface = this.deliverySurface();
|
|
33849
|
+
if (!surface)
|
|
33850
|
+
return this.unsupportedInboxDelivery("ack", deliveryId);
|
|
33851
|
+
return normalizeDeliveryTransition("ack", await surface.ackDelivery(deliveryId));
|
|
33852
|
+
},
|
|
33853
|
+
fail: async (deliveryId, reason) => {
|
|
33854
|
+
const surface = this.deliverySurface();
|
|
33855
|
+
if (!surface)
|
|
33856
|
+
return this.unsupportedInboxDelivery("fail", deliveryId, reason);
|
|
33857
|
+
return normalizeDeliveryTransition("fail", await surface.failDelivery(deliveryId, definedOptions({ error: reason })));
|
|
33858
|
+
},
|
|
33859
|
+
defer: async (deliveryId, deferUntil) => {
|
|
33860
|
+
const surface = this.deliverySurface();
|
|
33861
|
+
if (!surface)
|
|
33862
|
+
return this.unsupportedInboxDelivery("defer", deliveryId, void 0, deferUntil);
|
|
33863
|
+
return normalizeDeliveryTransition("defer", await surface.deferDelivery(deliveryId, {
|
|
33864
|
+
// The relaycast defer transition requires an explicit availability
|
|
33865
|
+
// time; default to a short retry window when none is given.
|
|
33866
|
+
availableAt: deferUntil ?? new Date(Date.now() + 3e4).toISOString()
|
|
33867
|
+
}));
|
|
33868
|
+
}
|
|
33745
33869
|
};
|
|
33746
33870
|
integrations = {
|
|
33747
33871
|
webhooks: {
|
|
@@ -33838,6 +33962,83 @@ var RelaycastMessagingClient = class {
|
|
|
33838
33962
|
}
|
|
33839
33963
|
return this.relaycast.dmMessages;
|
|
33840
33964
|
}
|
|
33965
|
+
/**
|
|
33966
|
+
* The durable delivery API of the agent client, when present. Requires an
|
|
33967
|
+
* agent-scoped client built from `@relaycast/sdk` 2.5+ (or a compatible
|
|
33968
|
+
* injected `agentClient`).
|
|
33969
|
+
*/
|
|
33970
|
+
deliverySurface() {
|
|
33971
|
+
const agent = this.agentClient;
|
|
33972
|
+
if (!agent || typeof agent.deliveries !== "function" || typeof agent.ackDelivery !== "function" || typeof agent.failDelivery !== "function" || typeof agent.deferDelivery !== "function") {
|
|
33973
|
+
return void 0;
|
|
33974
|
+
}
|
|
33975
|
+
return agent;
|
|
33976
|
+
}
|
|
33977
|
+
async *createInboxSubscription(agent, input) {
|
|
33978
|
+
const signal = input?.signal;
|
|
33979
|
+
if (signal?.aborted)
|
|
33980
|
+
return;
|
|
33981
|
+
const recipient = definedOptions({ recipientName: input?.agentName });
|
|
33982
|
+
const seen = /* @__PURE__ */ new Set();
|
|
33983
|
+
const queue = [];
|
|
33984
|
+
let stopped = false;
|
|
33985
|
+
let notify;
|
|
33986
|
+
const wake = () => {
|
|
33987
|
+
const resolve2 = notify;
|
|
33988
|
+
notify = void 0;
|
|
33989
|
+
resolve2?.();
|
|
33990
|
+
};
|
|
33991
|
+
const push = (item) => {
|
|
33992
|
+
if (!item.id || seen.has(item.id))
|
|
33993
|
+
return;
|
|
33994
|
+
seen.add(item.id);
|
|
33995
|
+
queue.push(item);
|
|
33996
|
+
wake();
|
|
33997
|
+
};
|
|
33998
|
+
const stop = () => {
|
|
33999
|
+
stopped = true;
|
|
34000
|
+
wake();
|
|
34001
|
+
};
|
|
34002
|
+
const inFlight = /* @__PURE__ */ new Set();
|
|
34003
|
+
agent.connect();
|
|
34004
|
+
const unsubscribe = agent.on.any((event) => {
|
|
34005
|
+
const record3 = asRecord(event);
|
|
34006
|
+
if (record3.type !== "delivery.accepted")
|
|
34007
|
+
return;
|
|
34008
|
+
const deliveryId = readStr(record3, "deliveryId", "delivery_id");
|
|
34009
|
+
if (!deliveryId || seen.has(deliveryId) || inFlight.has(deliveryId))
|
|
34010
|
+
return;
|
|
34011
|
+
inFlight.add(deliveryId);
|
|
34012
|
+
void agent.deliveries().then((deliveries) => {
|
|
34013
|
+
const match = deliveries.find((raw) => readStr(asRecord(raw), "id") === deliveryId);
|
|
34014
|
+
if (match)
|
|
34015
|
+
push(normalizeInboxItem(match, recipient));
|
|
34016
|
+
}).catch(() => {
|
|
34017
|
+
}).finally(() => {
|
|
34018
|
+
inFlight.delete(deliveryId);
|
|
34019
|
+
});
|
|
34020
|
+
});
|
|
34021
|
+
signal?.addEventListener("abort", stop, { once: true });
|
|
34022
|
+
try {
|
|
34023
|
+
for (const raw of await agent.deliveries()) {
|
|
34024
|
+
push(normalizeInboxItem(raw, recipient));
|
|
34025
|
+
}
|
|
34026
|
+
while (!stopped) {
|
|
34027
|
+
const next = queue.shift();
|
|
34028
|
+
if (next) {
|
|
34029
|
+
yield next;
|
|
34030
|
+
continue;
|
|
34031
|
+
}
|
|
34032
|
+
await new Promise((resolve2) => {
|
|
34033
|
+
notify = resolve2;
|
|
34034
|
+
});
|
|
34035
|
+
}
|
|
34036
|
+
} finally {
|
|
34037
|
+
stopped = true;
|
|
34038
|
+
unsubscribe();
|
|
34039
|
+
signal?.removeEventListener("abort", stop);
|
|
34040
|
+
}
|
|
34041
|
+
}
|
|
33841
34042
|
async *emptyInboxSubscription() {
|
|
33842
34043
|
return;
|
|
33843
34044
|
}
|
|
@@ -33847,7 +34048,7 @@ var RelaycastMessagingClient = class {
|
|
|
33847
34048
|
action,
|
|
33848
34049
|
messageId,
|
|
33849
34050
|
...reason ? { reason } : {
|
|
33850
|
-
reason: "
|
|
34051
|
+
reason: "Durable delivery transitions require an agent-scoped client with the Relaycast delivery API."
|
|
33851
34052
|
},
|
|
33852
34053
|
...deferUntil ? { deferUntil } : {}
|
|
33853
34054
|
};
|
|
@@ -36388,8 +36589,11 @@ function generateRequestId(prefix = "") {
|
|
|
36388
36589
|
normalizeChannelMember,
|
|
36389
36590
|
normalizeChannelName,
|
|
36390
36591
|
normalizeChannelReadStatus,
|
|
36592
|
+
normalizeDeliveryTransition,
|
|
36391
36593
|
normalizeGroupDirectConversation,
|
|
36392
36594
|
normalizeInbox,
|
|
36595
|
+
normalizeInboxItem,
|
|
36596
|
+
normalizeInboxItemState,
|
|
36393
36597
|
normalizeMessage,
|
|
36394
36598
|
normalizeMessagingEvent,
|
|
36395
36599
|
normalizeReaction,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "agent-relay",
|
|
3
|
-
"version": "8.
|
|
3
|
+
"version": "8.5.0",
|
|
4
4
|
"description": "Real-time agent-to-agent communication system",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.cjs",
|
|
@@ -43,11 +43,11 @@
|
|
|
43
43
|
"pack:validate": "npm pack --dry-run"
|
|
44
44
|
},
|
|
45
45
|
"dependencies": {
|
|
46
|
-
"@agent-relay/cloud": "8.
|
|
47
|
-
"@agent-relay/config": "8.
|
|
48
|
-
"@agent-relay/harness-driver": "8.
|
|
49
|
-
"@agent-relay/sdk": "8.
|
|
50
|
-
"@agent-relay/utils": "8.
|
|
46
|
+
"@agent-relay/cloud": "8.5.0",
|
|
47
|
+
"@agent-relay/config": "8.5.0",
|
|
48
|
+
"@agent-relay/harness-driver": "8.5.0",
|
|
49
|
+
"@agent-relay/sdk": "8.5.0",
|
|
50
|
+
"@agent-relay/utils": "8.5.0",
|
|
51
51
|
"@modelcontextprotocol/sdk": "^1.0.0",
|
|
52
52
|
"@relaycast/sdk": "^3.1.1",
|
|
53
53
|
"@relayflows/cli": "^1.0.1",
|