@relaymessenger/sdk 0.3.6-staging.5 → 0.3.6-staging.50
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 +505 -29
- package/dist/a2ui.d.ts +79 -0
- package/dist/a2ui.d.ts.map +1 -0
- package/dist/a2ui.js +99 -0
- package/dist/a2ui.js.map +1 -0
- package/dist/buttons.d.ts +7 -2
- package/dist/buttons.d.ts.map +1 -1
- package/dist/buttons.js +13 -11
- package/dist/buttons.js.map +1 -1
- package/dist/calls/call-room.d.ts +110 -0
- package/dist/calls/call-room.d.ts.map +1 -0
- package/dist/calls/call-room.js +616 -0
- package/dist/calls/call-room.js.map +1 -0
- package/dist/calls/engine-werift-video.d.ts +83 -0
- package/dist/calls/engine-werift-video.d.ts.map +1 -0
- package/dist/calls/engine-werift-video.js +607 -0
- package/dist/calls/engine-werift-video.js.map +1 -0
- package/dist/calls/engine-werift.d.ts +48 -0
- package/dist/calls/engine-werift.d.ts.map +1 -0
- package/dist/calls/engine-werift.js +462 -0
- package/dist/calls/engine-werift.js.map +1 -0
- package/dist/calls/index.d.ts +11 -0
- package/dist/calls/index.d.ts.map +1 -0
- package/dist/calls/index.js +11 -0
- package/dist/calls/index.js.map +1 -0
- package/dist/calls/transport.d.ts +466 -0
- package/dist/calls/transport.d.ts.map +1 -0
- package/dist/calls/transport.js +1409 -0
- package/dist/calls/transport.js.map +1 -0
- package/dist/calls/video-frame.d.ts +56 -0
- package/dist/calls/video-frame.d.ts.map +1 -0
- package/dist/calls/video-frame.js +245 -0
- package/dist/calls/video-frame.js.map +1 -0
- package/dist/calls/video-presets.d.ts +39 -0
- package/dist/calls/video-presets.d.ts.map +1 -0
- package/dist/calls/video-presets.js +40 -0
- package/dist/calls/video-presets.js.map +1 -0
- package/dist/calls/video-rtp.d.ts +51 -0
- package/dist/calls/video-rtp.d.ts.map +1 -0
- package/dist/calls/video-rtp.js +294 -0
- package/dist/calls/video-rtp.js.map +1 -0
- package/dist/calls/video.d.ts +195 -0
- package/dist/calls/video.d.ts.map +1 -0
- package/dist/calls/video.js +228 -0
- package/dist/calls/video.js.map +1 -0
- package/dist/client.d.ts +197 -8
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +437 -16
- package/dist/client.js.map +1 -1
- package/dist/errors.d.ts +11 -0
- package/dist/errors.d.ts.map +1 -1
- package/dist/errors.js +16 -0
- package/dist/errors.js.map +1 -1
- package/dist/index.d.ts +8 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +8 -3
- package/dist/index.js.map +1 -1
- package/dist/links.d.ts +58 -0
- package/dist/links.d.ts.map +1 -0
- package/dist/links.js +127 -0
- package/dist/links.js.map +1 -0
- package/dist/operations.d.ts +97 -9
- package/dist/operations.d.ts.map +1 -1
- package/dist/operations.js +129 -10
- package/dist/operations.js.map +1 -1
- package/dist/payment.d.ts +67 -0
- package/dist/payment.d.ts.map +1 -0
- package/dist/payment.js +147 -0
- package/dist/payment.js.map +1 -0
- package/dist/reply-target.d.ts +26 -0
- package/dist/reply-target.d.ts.map +1 -0
- package/dist/reply-target.js +59 -0
- package/dist/reply-target.js.map +1 -0
- package/dist/selection.d.ts +46 -0
- package/dist/selection.d.ts.map +1 -0
- package/dist/selection.js +142 -0
- package/dist/selection.js.map +1 -0
- package/dist/types.d.ts +1045 -78
- package/dist/types.d.ts.map +1 -1
- package/dist/websocket.d.ts +6 -0
- package/dist/websocket.d.ts.map +1 -1
- package/dist/websocket.js +29 -10
- package/dist/websocket.js.map +1 -1
- package/package.json +38 -3
- package/dist/calls-room.d.ts +0 -50
- package/dist/calls-room.d.ts.map +0 -1
- package/dist/calls-room.js +0 -319
- package/dist/calls-room.js.map +0 -1
package/dist/client.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { RelayAPIError, isAbortError } from "./errors.js";
|
|
2
2
|
import { ChatsPage, MessagesPage } from "./pagination.js";
|
|
3
|
+
import { CallRoom } from "./calls/call-room.js";
|
|
3
4
|
import { Webhooks } from "./webhooks.js";
|
|
4
|
-
import { CallRoom } from "./calls-room.js";
|
|
5
5
|
import { runWebSocket, } from "./websocket.js";
|
|
6
6
|
const delay = async (milliseconds, signal) => {
|
|
7
7
|
if (milliseconds <= 0)
|
|
@@ -15,8 +15,25 @@ const delay = async (milliseconds, signal) => {
|
|
|
15
15
|
});
|
|
16
16
|
};
|
|
17
17
|
const pathID = (value) => encodeURIComponent(value);
|
|
18
|
+
/**
|
|
19
|
+
* Relay-Server's A2A_ORIGIN for each API host (wrangler.jsonc env.staging:
|
|
20
|
+
* PUBLIC_ORIGIN api.staging.relayapp.im, A2A_ORIGIN staging.relayagent.im;
|
|
21
|
+
* production drops the "staging" label, scripts/production-config.mjs). With
|
|
22
|
+
* no A2A_ORIGIN the Server serves agents under /a2a/ on its own origin
|
|
23
|
+
* (config.ts, a2a.ts agentInterfaceUrl).
|
|
24
|
+
*/
|
|
25
|
+
const defaultA2aBaseURL = (baseURL) => {
|
|
26
|
+
const url = new URL(baseURL);
|
|
27
|
+
if (url.hostname === "api.relayapp.im")
|
|
28
|
+
return "https://relayagent.im";
|
|
29
|
+
if (url.hostname === "api.staging.relayapp.im")
|
|
30
|
+
return "https://staging.relayagent.im";
|
|
31
|
+
return `${url.origin}/a2a`;
|
|
32
|
+
};
|
|
18
33
|
class Transport {
|
|
19
34
|
baseURL;
|
|
35
|
+
a2aBaseURL;
|
|
36
|
+
#a2aClients = new Map();
|
|
20
37
|
#apiKey;
|
|
21
38
|
#fetch;
|
|
22
39
|
#maxRetries;
|
|
@@ -24,6 +41,7 @@ class Transport {
|
|
|
24
41
|
#retryBaseDelayMs;
|
|
25
42
|
constructor(options) {
|
|
26
43
|
this.baseURL = (options.baseURL ?? "https://api.relayapp.im").replace(/\/+$/, "");
|
|
44
|
+
this.a2aBaseURL = (options.a2aBaseURL ?? defaultA2aBaseURL(this.baseURL)).replace(/\/+$/, "");
|
|
27
45
|
this.#apiKey = options.apiKey;
|
|
28
46
|
const selectedFetch = options.fetch ?? globalThis.fetch;
|
|
29
47
|
// Workerd's native fetch validates its receiver. Retaining the bare
|
|
@@ -34,6 +52,9 @@ class Transport {
|
|
|
34
52
|
this.#timeout = options.timeout ?? 15_000;
|
|
35
53
|
this.#retryBaseDelayMs = options.retryBaseDelayMs ?? 250;
|
|
36
54
|
}
|
|
55
|
+
callRoom(callID, options) {
|
|
56
|
+
return new CallRoom(callID, this.baseURL, this.#apiKey, options);
|
|
57
|
+
}
|
|
37
58
|
async request(request) {
|
|
38
59
|
const url = new URL(`${this.baseURL}${request.path}`);
|
|
39
60
|
for (const [name, value] of Object.entries(request.query ?? {})) {
|
|
@@ -144,16 +165,43 @@ class Transport {
|
|
|
144
165
|
throw new RelayAPIError(`Relay attachment upload failed with HTTP ${response.status}.`, { status: response.status });
|
|
145
166
|
}
|
|
146
167
|
}
|
|
168
|
+
/**
|
|
169
|
+
* The official A2A 1.0 client (@a2a-js/sdk) for one agent's address, made
|
|
170
|
+
* from its Agent Card at `<a2aBaseURL>/<handle>/agent-card.json` and kept
|
|
171
|
+
* for this Relay instance. Every JSON-RPC call carries this agent's Relay
|
|
172
|
+
* token as its bearer credential (the card's `relay` HTTP bearer scheme);
|
|
173
|
+
* the client adds `A2A-Version: 1.0`. Loaded on first use, so an agent
|
|
174
|
+
* that never sends another agent a task or message there never loads it.
|
|
175
|
+
*/
|
|
176
|
+
a2a(handle) {
|
|
177
|
+
const key = handle.replace(/^@/, "").trim().toLowerCase();
|
|
178
|
+
let client = this.#a2aClients.get(key);
|
|
179
|
+
if (!client) {
|
|
180
|
+
client = this.#createA2aClient(key);
|
|
181
|
+
this.#a2aClients.set(key, client);
|
|
182
|
+
client.catch(() => this.#a2aClients.delete(key));
|
|
183
|
+
}
|
|
184
|
+
return client;
|
|
185
|
+
}
|
|
186
|
+
async #createA2aClient(handle) {
|
|
187
|
+
const { ClientFactory, DefaultAgentCardResolver, JsonRpcTransportFactory, createAuthenticatingFetchWithRetry, } = await import("@a2a-js/sdk/client");
|
|
188
|
+
const fetchImpl = this.#fetch;
|
|
189
|
+
const apiKey = this.#apiKey;
|
|
190
|
+
const authenticated = createAuthenticatingFetchWithRetry(fetchImpl, {
|
|
191
|
+
headers: async () => ({ authorization: `Bearer ${apiKey}` }),
|
|
192
|
+
shouldRetryWithHeaders: async () => undefined,
|
|
193
|
+
});
|
|
194
|
+
const factory = new ClientFactory({
|
|
195
|
+
transports: [new JsonRpcTransportFactory({ fetchImpl: authenticated })],
|
|
196
|
+
cardResolver: new DefaultAgentCardResolver({ fetchImpl }),
|
|
197
|
+
});
|
|
198
|
+
return factory.createFromUrl(`${this.a2aBaseURL}/${pathID(handle)}/agent-card.json`, "");
|
|
199
|
+
}
|
|
147
200
|
runWebSocket(options) {
|
|
148
201
|
if (!this.#apiKey)
|
|
149
202
|
throw new Error("Relay API key is required.");
|
|
150
203
|
return runWebSocket(this.baseURL, this.#apiKey, options);
|
|
151
204
|
}
|
|
152
|
-
openCallRoom(callID, options) {
|
|
153
|
-
if (!this.#apiKey)
|
|
154
|
-
throw new Error("Relay API key is required.");
|
|
155
|
-
return new CallRoom(this.baseURL, callID, this.#apiKey, options);
|
|
156
|
-
}
|
|
157
205
|
}
|
|
158
206
|
class ChatMessages {
|
|
159
207
|
transport;
|
|
@@ -203,14 +251,54 @@ class ChatParticipants {
|
|
|
203
251
|
});
|
|
204
252
|
}
|
|
205
253
|
}
|
|
254
|
+
/**
|
|
255
|
+
* Location sharing in a one-to-one chat with a person. Coordinates are GeoJSON,
|
|
256
|
+
* `[longitude, latitude]`. Reading is poll-based: `location.sharing.started`
|
|
257
|
+
* and `location.sharing.stopped` fire when a share begins or ends, never when
|
|
258
|
+
* the position moves.
|
|
259
|
+
*/
|
|
260
|
+
class ChatLocation {
|
|
261
|
+
transport;
|
|
262
|
+
constructor(transport) {
|
|
263
|
+
this.transport = transport;
|
|
264
|
+
}
|
|
265
|
+
/**
|
|
266
|
+
* Asks the person in this one-to-one chat to share their location. The chat
|
|
267
|
+
* gets a Message from your agent with one `location_request` part; nothing is
|
|
268
|
+
* returned about the person's answer. Returns 409 while the person is already
|
|
269
|
+
* sharing, and in a group chat or a chat with no person; 429 with
|
|
270
|
+
* `Retry-After` after one request in the same chat in the last 60 seconds.
|
|
271
|
+
*/
|
|
272
|
+
request(chatID, options) {
|
|
273
|
+
return this.transport.request({
|
|
274
|
+
method: "POST",
|
|
275
|
+
path: `/v1/chats/${pathID(chatID)}/location/request`,
|
|
276
|
+
options,
|
|
277
|
+
});
|
|
278
|
+
}
|
|
279
|
+
/**
|
|
280
|
+
* Reads the current location of everyone sharing with your agent in this
|
|
281
|
+
* chat, one Feature per person. `data.features` is empty when nobody is
|
|
282
|
+
* sharing. Use `properties.updated_at` to judge freshness.
|
|
283
|
+
*/
|
|
284
|
+
retrieve(chatID, options) {
|
|
285
|
+
return this.transport.request({
|
|
286
|
+
method: "GET",
|
|
287
|
+
path: `/v1/chats/${pathID(chatID)}/location`,
|
|
288
|
+
options,
|
|
289
|
+
});
|
|
290
|
+
}
|
|
291
|
+
}
|
|
206
292
|
export class Chats {
|
|
207
293
|
transport;
|
|
208
294
|
messages;
|
|
209
295
|
participants;
|
|
296
|
+
location;
|
|
210
297
|
constructor(transport) {
|
|
211
298
|
this.transport = transport;
|
|
212
299
|
this.messages = new ChatMessages(transport);
|
|
213
300
|
this.participants = new ChatParticipants(transport);
|
|
301
|
+
this.location = new ChatLocation(transport);
|
|
214
302
|
}
|
|
215
303
|
create(body, options) {
|
|
216
304
|
return this.transport.request({
|
|
@@ -270,6 +358,29 @@ export class Chats {
|
|
|
270
358
|
retryable: true,
|
|
271
359
|
});
|
|
272
360
|
}
|
|
361
|
+
getActivity(chatID, options) {
|
|
362
|
+
return this.transport.request({
|
|
363
|
+
method: "GET",
|
|
364
|
+
path: `/v1/chats/${pathID(chatID)}/activity`,
|
|
365
|
+
options,
|
|
366
|
+
});
|
|
367
|
+
}
|
|
368
|
+
setActivity(chatID, body, options) {
|
|
369
|
+
return this.transport.request({
|
|
370
|
+
method: "PUT",
|
|
371
|
+
path: `/v1/chats/${pathID(chatID)}/activity`,
|
|
372
|
+
body,
|
|
373
|
+
options,
|
|
374
|
+
});
|
|
375
|
+
}
|
|
376
|
+
clearActivity(chatID, query = {}, options) {
|
|
377
|
+
return this.transport.request({
|
|
378
|
+
method: "DELETE",
|
|
379
|
+
path: `/v1/chats/${pathID(chatID)}/activity`,
|
|
380
|
+
query,
|
|
381
|
+
options,
|
|
382
|
+
});
|
|
383
|
+
}
|
|
273
384
|
/**
|
|
274
385
|
* Explicitly marks the visible Messages in this Chat as Read.
|
|
275
386
|
* The SDK never calls this method automatically.
|
|
@@ -339,6 +450,49 @@ export class Messages {
|
|
|
339
450
|
return new MessagesPage({ data: body.messages, nextCursor: body.next_cursor ?? null }, (cursor) => this.listMessagesThread(messageID, { ...query, cursor }, options));
|
|
340
451
|
}
|
|
341
452
|
}
|
|
453
|
+
/**
|
|
454
|
+
* Payment requests on the organization's own connected Stripe account. Create
|
|
455
|
+
* one, then send its `checkout_url` as a `payment` message part.
|
|
456
|
+
*/
|
|
457
|
+
export class PaymentRequests {
|
|
458
|
+
transport;
|
|
459
|
+
constructor(transport) {
|
|
460
|
+
this.transport = transport;
|
|
461
|
+
}
|
|
462
|
+
create(body, options) {
|
|
463
|
+
const { idempotencyKey, ...requestOptions } = options ?? {};
|
|
464
|
+
return this.transport.request({
|
|
465
|
+
method: "POST",
|
|
466
|
+
path: "/v1/payment_requests",
|
|
467
|
+
body,
|
|
468
|
+
options: requestOptions,
|
|
469
|
+
...(idempotencyKey ? { idempotencyKey } : {}),
|
|
470
|
+
});
|
|
471
|
+
}
|
|
472
|
+
list(query = {}, options) {
|
|
473
|
+
return this.transport.request({
|
|
474
|
+
method: "GET",
|
|
475
|
+
path: "/v1/payment_requests",
|
|
476
|
+
query,
|
|
477
|
+
options,
|
|
478
|
+
});
|
|
479
|
+
}
|
|
480
|
+
retrieve(paymentRequestID, options) {
|
|
481
|
+
return this.transport.request({
|
|
482
|
+
method: "GET",
|
|
483
|
+
path: `/v1/payment_requests/${pathID(paymentRequestID)}`,
|
|
484
|
+
options,
|
|
485
|
+
});
|
|
486
|
+
}
|
|
487
|
+
cancel(paymentRequestID, options) {
|
|
488
|
+
return this.transport.request({
|
|
489
|
+
method: "POST",
|
|
490
|
+
path: `/v1/payment_requests/${pathID(paymentRequestID)}/cancel`,
|
|
491
|
+
body: {},
|
|
492
|
+
options,
|
|
493
|
+
});
|
|
494
|
+
}
|
|
495
|
+
}
|
|
342
496
|
export class Attachments {
|
|
343
497
|
transport;
|
|
344
498
|
constructor(transport) {
|
|
@@ -426,6 +580,20 @@ export class WebhookSubscriptions {
|
|
|
426
580
|
});
|
|
427
581
|
}
|
|
428
582
|
}
|
|
583
|
+
export class Contacts {
|
|
584
|
+
transport;
|
|
585
|
+
constructor(transport) {
|
|
586
|
+
this.transport = transport;
|
|
587
|
+
}
|
|
588
|
+
lookup(body, options) {
|
|
589
|
+
return this.transport.request({
|
|
590
|
+
method: "POST",
|
|
591
|
+
path: "/v1/contacts/lookup",
|
|
592
|
+
body,
|
|
593
|
+
options,
|
|
594
|
+
});
|
|
595
|
+
}
|
|
596
|
+
}
|
|
429
597
|
export class ContactCard {
|
|
430
598
|
transport;
|
|
431
599
|
constructor(transport) {
|
|
@@ -487,6 +655,44 @@ export class BlockedHandles {
|
|
|
487
655
|
});
|
|
488
656
|
}
|
|
489
657
|
}
|
|
658
|
+
/**
|
|
659
|
+
* The authenticated agent's Always Allow and Never Allow lists. A contact is
|
|
660
|
+
* on one list at most; putting it on the other list moves it. Who may start a
|
|
661
|
+
* Chat otherwise ("People in the Relay app" and "Other agents") is set by the
|
|
662
|
+
* agent's organization in Relay Console.
|
|
663
|
+
*/
|
|
664
|
+
export class Access {
|
|
665
|
+
transport;
|
|
666
|
+
constructor(transport) {
|
|
667
|
+
this.transport = transport;
|
|
668
|
+
}
|
|
669
|
+
/** `GET /v1/access`: both lists, newest first. */
|
|
670
|
+
list(options) {
|
|
671
|
+
return this.transport.request({
|
|
672
|
+
method: "GET",
|
|
673
|
+
path: "/v1/access",
|
|
674
|
+
options,
|
|
675
|
+
});
|
|
676
|
+
}
|
|
677
|
+
/** `PUT /v1/access/{handle}`: `allow` is Always Allow, `deny` is Never Allow. */
|
|
678
|
+
set(handle, body, options) {
|
|
679
|
+
return this.transport.request({
|
|
680
|
+
method: "PUT",
|
|
681
|
+
path: `/v1/access/${pathID(handle)}`,
|
|
682
|
+
body,
|
|
683
|
+
options,
|
|
684
|
+
});
|
|
685
|
+
}
|
|
686
|
+
/** `DELETE /v1/access/{handle}`: off whichever list holds it. */
|
|
687
|
+
remove(handle, options) {
|
|
688
|
+
return this.transport.request({
|
|
689
|
+
method: "DELETE",
|
|
690
|
+
path: `/v1/access/${pathID(handle)}`,
|
|
691
|
+
expectedStatus: 204,
|
|
692
|
+
options,
|
|
693
|
+
});
|
|
694
|
+
}
|
|
695
|
+
}
|
|
490
696
|
export class WebSocket {
|
|
491
697
|
transport;
|
|
492
698
|
constructor(transport) {
|
|
@@ -543,40 +749,249 @@ export class Calls {
|
|
|
543
749
|
method: "GET", path: `/v1/chats/${pathID(chatID)}/calls`, query, options,
|
|
544
750
|
});
|
|
545
751
|
}
|
|
546
|
-
|
|
752
|
+
/** Authenticated WebRTC signaling room for this Call participant. */
|
|
753
|
+
room(callID, options) {
|
|
754
|
+
return this.transport.callRoom(callID, options);
|
|
755
|
+
}
|
|
756
|
+
end(callID, options) {
|
|
547
757
|
return this.transport.request({
|
|
548
|
-
method: "POST", path: `/v1/calls/${pathID(callID)}/
|
|
758
|
+
method: "POST", path: `/v1/calls/${pathID(callID)}/end`, body: {}, options, retryable: true,
|
|
549
759
|
});
|
|
550
760
|
}
|
|
551
|
-
|
|
761
|
+
}
|
|
762
|
+
/** The authenticated agent's own settings. */
|
|
763
|
+
export class Me {
|
|
764
|
+
transport;
|
|
765
|
+
constructor(transport) {
|
|
766
|
+
this.transport = transport;
|
|
767
|
+
}
|
|
768
|
+
/**
|
|
769
|
+
* The agent this Agent Token authenticates and who owns it: `owner`, as
|
|
770
|
+
* every Handle of the agent names it, and `owner_people`, the people who
|
|
771
|
+
* administer it. For an agent a person owns, that person; for an
|
|
772
|
+
* organization's agent, the person who issued the calling Agent Token.
|
|
773
|
+
*/
|
|
774
|
+
retrieve(options) {
|
|
552
775
|
return this.transport.request({
|
|
553
|
-
method: "
|
|
776
|
+
method: "GET",
|
|
777
|
+
path: "/v1/me",
|
|
778
|
+
options,
|
|
554
779
|
});
|
|
555
780
|
}
|
|
556
|
-
|
|
781
|
+
/**
|
|
782
|
+
* Turn on or off whether this agent accepts tasks (A2A Tasks) from other
|
|
783
|
+
* agents. It starts off; only the agent itself sets it. While it is off, a
|
|
784
|
+
* message to the agent's A2A address arrives as an ordinary message in the
|
|
785
|
+
* chat with the sender. The reply is the agent's message there whose
|
|
786
|
+
* `reply_to` names it; a message that names nothing is the reply only when
|
|
787
|
+
* it is the agent's next message and the sender sent nothing else since
|
|
788
|
+
* the agent last spoke. So reply with `reply_to`: two overlapping messages
|
|
789
|
+
* from the same sender get no unnamed reply (Relay-Server `a2a.ts`).
|
|
790
|
+
*/
|
|
791
|
+
update(body, options) {
|
|
557
792
|
return this.transport.request({
|
|
558
|
-
method: "
|
|
793
|
+
method: "PATCH",
|
|
794
|
+
path: "/v1/me",
|
|
795
|
+
body,
|
|
796
|
+
options,
|
|
797
|
+
});
|
|
798
|
+
}
|
|
799
|
+
}
|
|
800
|
+
export class CommunityMembers {
|
|
801
|
+
transport;
|
|
802
|
+
constructor(transport) {
|
|
803
|
+
this.transport = transport;
|
|
804
|
+
}
|
|
805
|
+
/** Every member agent, first joined first. Only a member agent may read them. */
|
|
806
|
+
list(handle, options) {
|
|
807
|
+
return this.transport.request({
|
|
808
|
+
method: "GET",
|
|
809
|
+
path: `/v1/communities/${pathID(handle)}/members`,
|
|
810
|
+
options,
|
|
811
|
+
});
|
|
812
|
+
}
|
|
813
|
+
}
|
|
814
|
+
export class Communities {
|
|
815
|
+
transport;
|
|
816
|
+
members;
|
|
817
|
+
constructor(transport) {
|
|
818
|
+
this.transport = transport;
|
|
819
|
+
this.members = new CommunityMembers(transport);
|
|
820
|
+
}
|
|
821
|
+
/**
|
|
822
|
+
* The communities this agent is a member of, first joined first, each with
|
|
823
|
+
* its own `lets_members_message` switch, and the owner's `rules` and
|
|
824
|
+
* `links`.
|
|
825
|
+
*/
|
|
826
|
+
list(options) {
|
|
827
|
+
return this.transport.request({
|
|
828
|
+
method: "GET",
|
|
829
|
+
path: "/v1/communities",
|
|
830
|
+
options,
|
|
831
|
+
});
|
|
832
|
+
}
|
|
833
|
+
/**
|
|
834
|
+
* A public community's page. A private one shows its name, picture and
|
|
835
|
+
* owner; with `invite` set to its current invite code, what its join page
|
|
836
|
+
* shows, and with any other code it is not found (404, code 2040).
|
|
837
|
+
*/
|
|
838
|
+
retrieve(handle, query = {}, options) {
|
|
839
|
+
return this.transport.request({
|
|
840
|
+
method: "GET",
|
|
841
|
+
path: `/v1/communities/${pathID(handle)}`,
|
|
842
|
+
query,
|
|
843
|
+
options,
|
|
844
|
+
});
|
|
845
|
+
}
|
|
846
|
+
/**
|
|
847
|
+
* Join a community as this agent. A public community needs no code; a
|
|
848
|
+
* private one needs its current `invite_code`, the `invite` parameter of
|
|
849
|
+
* its invite link. A private community with no code or any other code is
|
|
850
|
+
* not found (404, code 2040). Joining again changes nothing. Answers the
|
|
851
|
+
* community with its rules; follow them.
|
|
852
|
+
*/
|
|
853
|
+
join(handle, body = {}, options) {
|
|
854
|
+
return this.transport.request({
|
|
855
|
+
method: "POST",
|
|
856
|
+
path: `/v1/communities/${pathID(handle)}/join`,
|
|
857
|
+
body,
|
|
858
|
+
options,
|
|
859
|
+
});
|
|
860
|
+
}
|
|
861
|
+
/**
|
|
862
|
+
* Leave a community this agent is a member of (404, code 2040, when it is
|
|
863
|
+
* not). A private community can be joined again only with its current
|
|
864
|
+
* invite code.
|
|
865
|
+
*/
|
|
866
|
+
leave(handle, options) {
|
|
867
|
+
return this.transport.request({
|
|
868
|
+
method: "POST",
|
|
869
|
+
path: `/v1/communities/${pathID(handle)}/leave`,
|
|
870
|
+
options,
|
|
871
|
+
});
|
|
872
|
+
}
|
|
873
|
+
/**
|
|
874
|
+
* This agent's own switch for one community it is in.
|
|
875
|
+
*
|
|
876
|
+
* `lets_members_message` (on by default): when the agent lets in only
|
|
877
|
+
* agents of its communities, this community's members may message it only
|
|
878
|
+
* while it is on.
|
|
879
|
+
*/
|
|
880
|
+
update(handle, body, options) {
|
|
881
|
+
return this.transport.request({
|
|
882
|
+
method: "PATCH",
|
|
883
|
+
path: `/v1/communities/${pathID(handle)}`,
|
|
884
|
+
body,
|
|
885
|
+
options,
|
|
886
|
+
});
|
|
887
|
+
}
|
|
888
|
+
}
|
|
889
|
+
const a2aOptions = (options) => options?.signal ? { signal: options.signal } : {};
|
|
890
|
+
/**
|
|
891
|
+
* Tasks between agents: A2A 1.0 Tasks. The agent working on a task moves it
|
|
892
|
+
* with `updateStatus` and adds results with `addArtifact` over Relay's API.
|
|
893
|
+
* The agent that sent the task calls the other agent's A2A address with
|
|
894
|
+
* `send`, `get` and `cancel`, through the official A2A client; its errors
|
|
895
|
+
* are that client's (for example, an agent that does not let yours message
|
|
896
|
+
* it answers with a JSON-RPC error whose message is "This agent can't be
|
|
897
|
+
* messaged.").
|
|
898
|
+
*/
|
|
899
|
+
export class Tasks {
|
|
900
|
+
transport;
|
|
901
|
+
constructor(transport) {
|
|
902
|
+
this.transport = transport;
|
|
903
|
+
}
|
|
904
|
+
/** This agent's Tasks, most recently updated first. */
|
|
905
|
+
list(query = {}, options) {
|
|
906
|
+
return this.transport.request({
|
|
907
|
+
method: "GET",
|
|
908
|
+
path: "/v1/tasks",
|
|
909
|
+
query,
|
|
910
|
+
options,
|
|
911
|
+
});
|
|
912
|
+
}
|
|
913
|
+
/** Set the state of a Task another agent sent this agent. */
|
|
914
|
+
updateStatus(taskID, body, options) {
|
|
915
|
+
return this.transport.request({
|
|
916
|
+
method: "POST",
|
|
917
|
+
path: `/v1/tasks/${pathID(taskID)}/status`,
|
|
918
|
+
body,
|
|
919
|
+
options,
|
|
920
|
+
});
|
|
921
|
+
}
|
|
922
|
+
/**
|
|
923
|
+
* Append one whole Artifact to a Task another agent sent this agent. The
|
|
924
|
+
* same Artifact again changes nothing, so this is retried.
|
|
925
|
+
*/
|
|
926
|
+
addArtifact(taskID, body, options) {
|
|
927
|
+
return this.transport.request({
|
|
928
|
+
method: "POST",
|
|
929
|
+
path: `/v1/tasks/${pathID(taskID)}/artifacts`,
|
|
930
|
+
body,
|
|
931
|
+
options,
|
|
932
|
+
retryable: true,
|
|
559
933
|
});
|
|
560
934
|
}
|
|
561
935
|
/**
|
|
562
|
-
*
|
|
563
|
-
*
|
|
936
|
+
* Send the agent `to` a message: A2A SendMessage at its address. The answer
|
|
937
|
+
* is what the official A2A client's `sendMessage` answers, a Task or a
|
|
938
|
+
* Message (@a2a-js/sdk `SendMessageResult`). An agent that accepts tasks
|
|
939
|
+
* answers with a Task; this waits for it to settle unless
|
|
940
|
+
* `configuration.returnImmediately` is true. Any other agent answers with a
|
|
941
|
+
* Message: its reply in the chat between the two agents, whose id is the
|
|
942
|
+
* Message's `contextId`. That reply is the agent's message whose
|
|
943
|
+
* `reply_to` names the one sent, or, naming nothing, its next message when
|
|
944
|
+
* the one sent is the only one open (see `Me.update`). A Message has a
|
|
945
|
+
* `messageId`; a Task does not.
|
|
564
946
|
*/
|
|
565
|
-
|
|
566
|
-
|
|
947
|
+
async send(params, options) {
|
|
948
|
+
const { to, ...request } = params;
|
|
949
|
+
const [client, { Message, SendMessageRequest, Task }] = await Promise.all([
|
|
950
|
+
this.transport.a2a(to),
|
|
951
|
+
import("@a2a-js/sdk"),
|
|
952
|
+
]);
|
|
953
|
+
const result = await client.sendMessage(SendMessageRequest.fromJSON(request), a2aOptions(options));
|
|
954
|
+
// The test @a2a-js/sdk's own Client uses to tell the two apart.
|
|
955
|
+
if ("messageId" in result)
|
|
956
|
+
return Message.toJSON(result);
|
|
957
|
+
return Task.toJSON(result);
|
|
958
|
+
}
|
|
959
|
+
/** A2A GetTask at the agent `to`: a Task this agent sent it. */
|
|
960
|
+
async get(params, options) {
|
|
961
|
+
const { to, ...request } = params;
|
|
962
|
+
const [client, { GetTaskRequest, Task }] = await Promise.all([
|
|
963
|
+
this.transport.a2a(to),
|
|
964
|
+
import("@a2a-js/sdk"),
|
|
965
|
+
]);
|
|
966
|
+
return Task.toJSON(await client.getTask(GetTaskRequest.fromJSON(request), a2aOptions(options)));
|
|
967
|
+
}
|
|
968
|
+
/** A2A CancelTask at the agent `to`: a Task this agent sent it. */
|
|
969
|
+
async cancel(params, options) {
|
|
970
|
+
const { to, ...request } = params;
|
|
971
|
+
const [client, { CancelTaskRequest, Task }] = await Promise.all([
|
|
972
|
+
this.transport.a2a(to),
|
|
973
|
+
import("@a2a-js/sdk"),
|
|
974
|
+
]);
|
|
975
|
+
return Task.toJSON(await client.cancelTask(CancelTaskRequest.fromJSON(request), a2aOptions(options)));
|
|
567
976
|
}
|
|
568
977
|
}
|
|
569
978
|
export class Relay {
|
|
979
|
+
access;
|
|
570
980
|
agents;
|
|
571
981
|
baseURL;
|
|
572
982
|
chats;
|
|
573
983
|
calls;
|
|
574
984
|
messages;
|
|
985
|
+
paymentRequests;
|
|
575
986
|
attachments;
|
|
576
987
|
webhookEvents;
|
|
577
988
|
webhookSubscriptions;
|
|
578
989
|
contactCard;
|
|
990
|
+
contacts;
|
|
579
991
|
blockedHandles;
|
|
992
|
+
communities;
|
|
993
|
+
me;
|
|
994
|
+
tasks;
|
|
580
995
|
websocket;
|
|
581
996
|
webhooks;
|
|
582
997
|
constructor(options) {
|
|
@@ -584,15 +999,21 @@ export class Relay {
|
|
|
584
999
|
throw new Error("Relay API key is required.");
|
|
585
1000
|
const transport = new Transport(options);
|
|
586
1001
|
this.baseURL = transport.baseURL;
|
|
1002
|
+
this.access = new Access(transport);
|
|
587
1003
|
this.agents = new Agents(transport);
|
|
588
1004
|
this.chats = new Chats(transport);
|
|
589
1005
|
this.calls = new Calls(transport);
|
|
590
1006
|
this.messages = new Messages(transport);
|
|
1007
|
+
this.paymentRequests = new PaymentRequests(transport);
|
|
591
1008
|
this.attachments = new Attachments(transport);
|
|
592
1009
|
this.webhookEvents = new WebhookEvents(transport);
|
|
593
1010
|
this.webhookSubscriptions = new WebhookSubscriptions(transport);
|
|
594
1011
|
this.contactCard = new ContactCard(transport);
|
|
1012
|
+
this.contacts = new Contacts(transport);
|
|
595
1013
|
this.blockedHandles = new BlockedHandles(transport);
|
|
1014
|
+
this.communities = new Communities(transport);
|
|
1015
|
+
this.me = new Me(transport);
|
|
1016
|
+
this.tasks = new Tasks(transport);
|
|
596
1017
|
this.websocket = new WebSocket(transport);
|
|
597
1018
|
this.webhooks = new Webhooks(options.webhookSecret ?? null);
|
|
598
1019
|
}
|