agentbnb 8.2.3 → 8.3.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.
Files changed (62) hide show
  1. package/dist/{card-EX2EYGCZ.js → card-BN643ZOY.js} +6 -2
  2. package/dist/card-T2XJZA5A.js +92 -0
  3. package/dist/{chunk-3LWBH7P3.js → chunk-4NFJ3VYZ.js} +20 -1
  4. package/dist/chunk-5AIYALBX.js +857 -0
  5. package/dist/chunk-6QMDJVMS.js +238 -0
  6. package/dist/{chunk-LKLKYXLV.js → chunk-74LZDEDT.js} +6 -4
  7. package/dist/{chunk-GKVTD4EZ.js → chunk-77KGEDH4.js} +1 -1
  8. package/dist/{chunk-QCGIG7WW.js → chunk-7IQE34QK.js} +14 -7
  9. package/dist/{chunk-QHZGOG3O.js → chunk-D242QZCR.js} +168 -41
  10. package/dist/chunk-EE3V3DXK.js +60 -0
  11. package/dist/{chunk-RYISHSHB.js → chunk-F3KIEVJ2.js} +207 -265
  12. package/dist/{chunk-XBGVQMQJ.js → chunk-FELGHDCA.js} +16 -39
  13. package/dist/{chunk-EJKW57ZV.js → chunk-GIEJVKZZ.js} +1 -1
  14. package/dist/{chunk-WVY2W7AA.js → chunk-I7KWA7OB.js} +20 -0
  15. package/dist/{chunk-4IPJJRTP.js → chunk-IGQNP3ZO.js} +5 -2
  16. package/dist/chunk-NQANA6WH.js +797 -0
  17. package/dist/{chunk-Z4MCGKTL.js → chunk-NX27AFPA.js} +15 -2
  18. package/dist/{chunk-Z2GEFFDO.js → chunk-O4Q7BRG6.js} +2 -2
  19. package/dist/{chunk-SSK653A6.js → chunk-PQIP7EXY.js} +6 -0
  20. package/dist/{chunk-EG6RS4JC.js → chunk-QFPXZITP.js} +20 -65
  21. package/dist/chunk-R4F4XII4.js +264 -0
  22. package/dist/{chunk-DYQOFGGI.js → chunk-RVBW2QXU.js} +178 -49
  23. package/dist/{chunk-CQFBNTGT.js → chunk-S7DZHKCG.js} +25 -12
  24. package/dist/chunk-U6LP4KWN.js +238 -0
  25. package/dist/{chunk-MWOXW7JQ.js → chunk-VJ7XBEY6.js} +24 -16
  26. package/dist/chunk-WTHMHNKC.js +129 -0
  27. package/dist/{chunk-OCSU2S6W.js → chunk-WX3GZVFG.js} +2 -1
  28. package/dist/{chunk-CKOOVZOI.js → chunk-YKMBFQC2.js} +37 -5
  29. package/dist/{chunk-S3V6R3EN.js → chunk-ZU2TP7CN.js} +70 -27
  30. package/dist/cli/index.js +203 -237
  31. package/dist/client-OKJJ3UP2.js +19 -0
  32. package/dist/client-UQBGCIPA.js +20 -0
  33. package/dist/conduct-4JDMWBQD.js +22 -0
  34. package/dist/{conduct-AZFLNUX3.js → conduct-VYYBCPHA.js} +14 -13
  35. package/dist/{conductor-mode-WKB42PYM.js → conductor-mode-OPGQJFLA.js} +12 -8
  36. package/dist/{conductor-mode-PLTB6MS3.js → conductor-mode-SBDCRIX6.js} +16 -11
  37. package/dist/execute-FZLQGIXB.js +14 -0
  38. package/dist/execute-TEZPQ5WP.js +15 -0
  39. package/dist/index.d.ts +172 -11
  40. package/dist/index.js +1529 -433
  41. package/dist/{process-guard-GH5LRNWO.js → process-guard-TNSUNHSR.js} +1 -1
  42. package/dist/{publish-capability-QDR2QIZ2.js → publish-capability-HVYILTPR.js} +4 -3
  43. package/dist/{reliability-metrics-QG7WC5QK.js → reliability-metrics-G7LPUYJD.js} +3 -1
  44. package/dist/reliability-metrics-RRUKJ4ME.js +20 -0
  45. package/dist/{request-OERS5BE7.js → request-KJNKR27T.js} +76 -71
  46. package/dist/{serve-skill-E6EJQYAK.js → serve-skill-GC6NIQ5T.js} +10 -11
  47. package/dist/{server-46VEG2W7.js → server-YV3XPTX5.js} +11 -10
  48. package/dist/{service-coordinator-KMSA6BST.js → service-coordinator-RY5AKUZS.js} +420 -171
  49. package/dist/{skill-config-FETXPNVP.js → skill-config-5O2VR546.js} +1 -1
  50. package/dist/skills/agentbnb/bootstrap.js +528 -253
  51. package/dist/websocket-client-3U27WJUU.js +7 -0
  52. package/dist/{websocket-client-4Z5P54RU.js → websocket-client-SNDF3B6N.js} +1 -1
  53. package/package.json +1 -1
  54. package/dist/chunk-MCED4GDW.js +0 -1572
  55. package/dist/chunk-NWIQJ2CL.js +0 -108
  56. package/dist/chunk-TUCEDQGM.js +0 -44
  57. package/dist/chunk-WNXXLCV5.js +0 -32
  58. package/dist/client-XOLP5IUZ.js +0 -12
  59. package/dist/conduct-VPUYTNEA.js +0 -21
  60. package/dist/execute-NNDCXTN4.js +0 -13
  61. package/dist/execute-RIRHTIBU.js +0 -16
  62. package/dist/websocket-client-QOVARTRN.js +0 -7
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  RelayMessageSchema
3
- } from "./chunk-SSK653A6.js";
3
+ } from "./chunk-PQIP7EXY.js";
4
4
 
5
5
  // src/relay/websocket-client.ts
6
6
  import WebSocket from "ws";
@@ -125,10 +125,23 @@ var RelayClient = class {
125
125
  });
126
126
  });
127
127
  }
128
+ /**
129
+ * Send a relay_started message to acknowledge that provider has started work.
130
+ *
131
+ * @param requestId - The relay request ID being processed.
132
+ * @param message - Optional status message.
133
+ */
134
+ sendStarted(requestId, message) {
135
+ this.send({
136
+ type: "relay_started",
137
+ id: requestId,
138
+ ...message ? { message } : {}
139
+ });
140
+ }
128
141
  /**
129
142
  * Send a relay_progress message to the relay server for a given request.
130
143
  * Used by the onRequest handler to forward SkillExecutor progress updates
131
- * to the requesting agent so it can reset its timeout window.
144
+ * to the requesting agent while work is in-flight.
132
145
  *
133
146
  * @param requestId - The relay request ID to associate progress with.
134
147
  * @param info - Progress details (step, total, message).
@@ -1,9 +1,9 @@
1
1
  import {
2
2
  searchCards
3
- } from "./chunk-RYISHSHB.js";
3
+ } from "./chunk-F3KIEVJ2.js";
4
4
  import {
5
5
  AgentBnBError
6
- } from "./chunk-WVY2W7AA.js";
6
+ } from "./chunk-I7KWA7OB.js";
7
7
 
8
8
  // src/registry/pricing.ts
9
9
  function getPricingStats(db, query) {
@@ -79,6 +79,11 @@ var RelayProgressMessageSchema = z.object({
79
79
  message: z.string().optional()
80
80
  // optional status message
81
81
  });
82
+ var RelayStartedMessageSchema = z.object({
83
+ type: z.literal("relay_started"),
84
+ id: z.string().uuid(),
85
+ message: z.string().optional()
86
+ });
82
87
  var HeartbeatMessageSchema = z.object({
83
88
  type: z.literal("heartbeat"),
84
89
  owner: z.string().min(1),
@@ -155,6 +160,7 @@ var RelayMessageSchema = z.discriminatedUnion("type", [
155
160
  ResponseMessageSchema,
156
161
  ErrorMessageSchema,
157
162
  RelayProgressMessageSchema,
163
+ RelayStartedMessageSchema,
158
164
  HeartbeatMessageSchema,
159
165
  EscrowHoldMessageSchema,
160
166
  EscrowHoldConfirmedMessageSchema,
@@ -1,50 +1,24 @@
1
1
  import {
2
- NETWORK_FEE_RATE,
3
- confirmEscrowDebit,
4
2
  getBalance,
5
- getCard,
6
3
  holdEscrow,
7
- insertRequestLog,
8
- recordEarning,
9
4
  releaseEscrow,
10
5
  resolveTargetCapability,
11
- settleEscrow,
12
- updateReputation
13
- } from "./chunk-MCED4GDW.js";
14
- import {
15
- verifyEscrowReceipt
16
- } from "./chunk-EJKW57ZV.js";
6
+ settleEscrow
7
+ } from "./chunk-NQANA6WH.js";
17
8
  import {
18
9
  loadConfig
19
10
  } from "./chunk-IVOYM3WG.js";
11
+ import {
12
+ getCard,
13
+ insertRequestLog,
14
+ updateReputation
15
+ } from "./chunk-ZU2TP7CN.js";
20
16
  import {
21
17
  AgentBnBError
22
- } from "./chunk-WVY2W7AA.js";
18
+ } from "./chunk-I7KWA7OB.js";
23
19
 
24
20
  // src/gateway/execute.ts
25
21
  import { randomUUID } from "crypto";
26
-
27
- // src/credit/settlement.ts
28
- function settleProviderEarning(providerDb, providerOwner, receipt) {
29
- const feeAmount = Math.floor(receipt.amount * NETWORK_FEE_RATE);
30
- const providerAmount = receipt.amount - feeAmount;
31
- recordEarning(
32
- providerDb,
33
- providerOwner,
34
- providerAmount,
35
- receipt.card_id,
36
- receipt.nonce
37
- );
38
- return { settled: true };
39
- }
40
- function settleRequesterEscrow(requesterDb, escrowId) {
41
- confirmEscrowDebit(requesterDb, escrowId);
42
- }
43
- function releaseRequesterEscrow(requesterDb, escrowId) {
44
- releaseEscrow(requesterDb, escrowId);
45
- }
46
-
47
- // src/gateway/execute.ts
48
22
  async function notifyTelegramSkillExecuted(opts) {
49
23
  const cfg = loadConfig();
50
24
  if (!cfg?.telegram_notifications) return;
@@ -123,23 +97,17 @@ async function executeCapabilityRequest(opts) {
123
97
  cardName = card.name;
124
98
  }
125
99
  let escrowId = null;
126
- let isRemoteEscrow = false;
127
100
  if (relayAuthorized) {
128
101
  } else if (receipt) {
129
- const { signature, ...receiptData2 } = receipt;
130
- const publicKeyBuf = Buffer.from(receipt.requester_public_key, "hex");
131
- const valid = verifyEscrowReceipt(receiptData2, signature, publicKeyBuf);
132
- if (!valid) {
133
- return { success: false, error: { code: -32603, message: "Invalid escrow receipt signature" } };
134
- }
135
- if (receipt.amount < creditsNeeded) {
136
- return { success: false, error: { code: -32603, message: "Insufficient escrow amount" } };
137
- }
138
- const receiptAge = Date.now() - new Date(receipt.timestamp).getTime();
139
- if (receiptAge > 5 * 60 * 1e3) {
140
- return { success: false, error: { code: -32603, message: "Escrow receipt expired" } };
102
+ if (creditsNeeded > 0) {
103
+ return {
104
+ success: false,
105
+ error: {
106
+ code: -32603,
107
+ message: "Direct HTTP paid remote settlement is disabled. Route paid requests through relay."
108
+ }
109
+ };
141
110
  }
142
- isRemoteEscrow = true;
143
111
  } else {
144
112
  try {
145
113
  const balance = getBalance(creditDb, requester);
@@ -153,9 +121,8 @@ async function executeCapabilityRequest(opts) {
153
121
  }
154
122
  }
155
123
  const startMs = Date.now();
156
- const receiptData = isRemoteEscrow ? { receipt_released: true } : void 0;
157
124
  const handleFailure = (status, latencyMs, message, failureReason = "bad_execution") => {
158
- if (!isRemoteEscrow && escrowId) releaseEscrow(creditDb, escrowId);
125
+ if (escrowId) releaseEscrow(creditDb, escrowId);
159
126
  if (failureReason === "bad_execution" || failureReason === "auth_error") {
160
127
  updateReputation(registryDb, cardId, false, latencyMs);
161
128
  }
@@ -174,15 +141,10 @@ async function executeCapabilityRequest(opts) {
174
141
  });
175
142
  } catch {
176
143
  }
177
- return {
178
- success: false,
179
- error: { code: -32603, message, ...receiptData ? { data: receiptData } : {} }
180
- };
144
+ return { success: false, error: { code: -32603, message } };
181
145
  };
182
146
  const handleSuccess = (result, latencyMs) => {
183
- if (isRemoteEscrow && receipt) {
184
- settleProviderEarning(creditDb, card.owner, receipt);
185
- } else if (escrowId) {
147
+ if (escrowId) {
186
148
  settleEscrow(creditDb, escrowId, card.owner);
187
149
  }
188
150
  updateReputation(registryDb, cardId, true, latencyMs);
@@ -210,12 +172,7 @@ async function executeCapabilityRequest(opts) {
210
172
  latencyMs
211
173
  }).catch(() => {
212
174
  });
213
- const successResult = isRemoteEscrow ? {
214
- ...typeof result === "object" && result !== null ? result : { data: result },
215
- receipt_settled: true,
216
- receipt_nonce: receipt.nonce
217
- } : result;
218
- return { success: true, result: successResult };
175
+ return { success: true, result };
219
176
  };
220
177
  if (skillExecutor) {
221
178
  let targetSkillId = resolvedSkillId ?? skillId;
@@ -447,8 +404,6 @@ async function executeCapabilityBatch(options) {
447
404
  }
448
405
 
449
406
  export {
450
- settleRequesterEscrow,
451
- releaseRequesterEscrow,
452
407
  executeCapabilityRequest,
453
408
  executeCapabilityBatch
454
409
  };
@@ -0,0 +1,264 @@
1
+ import {
2
+ AgentBnBError
3
+ } from "./chunk-I7KWA7OB.js";
4
+
5
+ // src/gateway/client.ts
6
+ import { randomUUID } from "crypto";
7
+ import { Agent } from "undici";
8
+
9
+ // src/credit/signing.ts
10
+ import { generateKeyPairSync, sign, verify, createPublicKey, createPrivateKey } from "crypto";
11
+ import { writeFileSync, readFileSync, existsSync, chmodSync } from "fs";
12
+ import { join } from "path";
13
+ function generateKeyPair() {
14
+ const { publicKey, privateKey } = generateKeyPairSync("ed25519", {
15
+ publicKeyEncoding: { type: "spki", format: "der" },
16
+ privateKeyEncoding: { type: "pkcs8", format: "der" }
17
+ });
18
+ return {
19
+ publicKey: Buffer.from(publicKey),
20
+ privateKey: Buffer.from(privateKey)
21
+ };
22
+ }
23
+ function saveKeyPair(configDir, keys) {
24
+ const privatePath = join(configDir, "private.key");
25
+ const publicPath = join(configDir, "public.key");
26
+ writeFileSync(privatePath, keys.privateKey);
27
+ chmodSync(privatePath, 384);
28
+ writeFileSync(publicPath, keys.publicKey);
29
+ }
30
+ function loadKeyPair(configDir) {
31
+ const privatePath = join(configDir, "private.key");
32
+ const publicPath = join(configDir, "public.key");
33
+ if (!existsSync(privatePath) || !existsSync(publicPath)) {
34
+ throw new AgentBnBError("Keypair not found. Run `agentbnb init` to generate one.", "KEYPAIR_NOT_FOUND");
35
+ }
36
+ return {
37
+ publicKey: readFileSync(publicPath),
38
+ privateKey: readFileSync(privatePath)
39
+ };
40
+ }
41
+ function canonicalJson(data) {
42
+ return JSON.stringify(sortForCanonicalJson(data));
43
+ }
44
+ function sortForCanonicalJson(value) {
45
+ if (Array.isArray(value)) {
46
+ return value.map((item) => sortForCanonicalJson(item));
47
+ }
48
+ if (value !== null && typeof value === "object") {
49
+ const proto = Object.getPrototypeOf(value);
50
+ if (proto === Object.prototype || proto === null) {
51
+ const input = value;
52
+ const output = {};
53
+ const sortedKeys = Object.keys(input).sort();
54
+ for (const key of sortedKeys) {
55
+ output[key] = sortForCanonicalJson(input[key]);
56
+ }
57
+ return output;
58
+ }
59
+ }
60
+ return value;
61
+ }
62
+ function signEscrowReceipt(data, privateKey) {
63
+ const message = Buffer.from(canonicalJson(data), "utf-8");
64
+ const keyObject = createPrivateKey({ key: privateKey, format: "der", type: "pkcs8" });
65
+ const signature = sign(null, message, keyObject);
66
+ return signature.toString("base64url");
67
+ }
68
+ function verifyEscrowReceipt(data, signature, publicKey) {
69
+ try {
70
+ const message = Buffer.from(canonicalJson(data), "utf-8");
71
+ const keyObject = createPublicKey({ key: publicKey, format: "der", type: "spki" });
72
+ const sigBuffer = Buffer.from(signature, "base64url");
73
+ return verify(null, message, keyObject, sigBuffer);
74
+ } catch {
75
+ return false;
76
+ }
77
+ }
78
+
79
+ // src/gateway/client.ts
80
+ var REQUEST_TIMEOUT_FALLBACK_MS = 3e5;
81
+ var REQUEST_TIMEOUT_GRACE_MS = 3e4;
82
+ var REQUEST_TIMEOUT_EXPECTED_MULTIPLIER = 1.5;
83
+ var gatewayAgent = new Agent({
84
+ keepAliveTimeout: 3e4,
85
+ keepAliveMaxTimeout: 6e4,
86
+ connections: 10,
87
+ pipelining: 1
88
+ });
89
+ function deriveRequestTimeoutMs(hint) {
90
+ const expectedDurationMs = hint?.expected_duration_ms;
91
+ if (typeof expectedDurationMs === "number" && expectedDurationMs > 0) {
92
+ return Math.ceil(expectedDurationMs * REQUEST_TIMEOUT_EXPECTED_MULTIPLIER) + REQUEST_TIMEOUT_GRACE_MS;
93
+ }
94
+ const hardTimeoutMs = hint?.hard_timeout_ms;
95
+ if (typeof hardTimeoutMs === "number" && hardTimeoutMs > 0) {
96
+ return Math.ceil(hardTimeoutMs) + REQUEST_TIMEOUT_GRACE_MS;
97
+ }
98
+ return REQUEST_TIMEOUT_FALLBACK_MS;
99
+ }
100
+ function buildGatewayAuthHeaders(payload, token, identity) {
101
+ const headers = { "Content-Type": "application/json" };
102
+ if (identity) {
103
+ const signature = signEscrowReceipt(payload, identity.privateKey);
104
+ headers["X-Agent-Id"] = identity.agentId;
105
+ headers["X-Agent-Public-Key"] = identity.publicKey;
106
+ headers["X-Agent-Signature"] = signature;
107
+ }
108
+ if (token) {
109
+ headers["Authorization"] = `Bearer ${token}`;
110
+ }
111
+ return headers;
112
+ }
113
+ async function requestCapability(opts) {
114
+ const {
115
+ gatewayUrl,
116
+ token,
117
+ cardId,
118
+ params = {},
119
+ timeoutMs: timeoutOverrideMs,
120
+ timeoutHint,
121
+ escrowReceipt,
122
+ identity
123
+ } = opts;
124
+ const timeoutMs = timeoutOverrideMs ?? deriveRequestTimeoutMs(timeoutHint);
125
+ const id = randomUUID();
126
+ const payload = {
127
+ jsonrpc: "2.0",
128
+ id,
129
+ method: "capability.execute",
130
+ params: {
131
+ card_id: cardId,
132
+ ...params,
133
+ ...escrowReceipt ? { escrow_receipt: escrowReceipt } : {}
134
+ }
135
+ };
136
+ const headers = buildGatewayAuthHeaders(payload, token, identity);
137
+ const controller = new AbortController();
138
+ const timer = setTimeout(() => controller.abort(), timeoutMs);
139
+ let response;
140
+ try {
141
+ response = await fetch(`${gatewayUrl}/rpc`, {
142
+ method: "POST",
143
+ headers,
144
+ body: JSON.stringify(payload),
145
+ signal: controller.signal,
146
+ // undici dispatcher for connection pooling (Node.js 20+)
147
+ dispatcher: gatewayAgent
148
+ });
149
+ } catch (err) {
150
+ clearTimeout(timer);
151
+ const isTimeout = err instanceof Error && err.name === "AbortError";
152
+ throw new AgentBnBError(
153
+ isTimeout ? "Request timed out" : `Network error: ${String(err)}`,
154
+ isTimeout ? "TIMEOUT" : "NETWORK_ERROR"
155
+ );
156
+ } finally {
157
+ clearTimeout(timer);
158
+ }
159
+ const body = await response.json();
160
+ if (body.error) {
161
+ throw new AgentBnBError(body.error.message, `RPC_ERROR_${body.error.code}`);
162
+ }
163
+ return body.result;
164
+ }
165
+ async function requestCapabilityBatch(gatewayUrl, token, items, opts = {}) {
166
+ if (items.length === 0) return /* @__PURE__ */ new Map();
167
+ if (items.length === 1) {
168
+ const item = items[0];
169
+ const result = await requestCapability({
170
+ gatewayUrl,
171
+ token,
172
+ cardId: item.cardId,
173
+ params: item.params,
174
+ escrowReceipt: item.escrowReceipt,
175
+ timeoutMs: opts.timeoutMs,
176
+ timeoutHint: opts.timeoutHint,
177
+ identity: opts.identity
178
+ });
179
+ return /* @__PURE__ */ new Map([[item.id, result]]);
180
+ }
181
+ const { timeoutMs: timeoutOverrideMs, timeoutHint, identity } = opts;
182
+ const timeoutMs = timeoutOverrideMs ?? deriveRequestTimeoutMs(timeoutHint);
183
+ const batchPayload = items.map((item) => ({
184
+ jsonrpc: "2.0",
185
+ id: item.id,
186
+ method: "capability.execute",
187
+ params: {
188
+ card_id: item.cardId,
189
+ ...item.params,
190
+ ...item.escrowReceipt ? { escrow_receipt: item.escrowReceipt } : {}
191
+ }
192
+ }));
193
+ const headers = buildGatewayAuthHeaders(batchPayload, token, identity);
194
+ const controller = new AbortController();
195
+ const timer = setTimeout(() => controller.abort(), timeoutMs);
196
+ let response;
197
+ try {
198
+ response = await fetch(`${gatewayUrl}/rpc`, {
199
+ method: "POST",
200
+ headers,
201
+ body: JSON.stringify(batchPayload),
202
+ signal: controller.signal,
203
+ dispatcher: gatewayAgent
204
+ });
205
+ } catch (err) {
206
+ clearTimeout(timer);
207
+ const isTimeout = err instanceof Error && err.name === "AbortError";
208
+ throw new AgentBnBError(
209
+ isTimeout ? "Batch request timed out" : `Network error: ${String(err)}`,
210
+ isTimeout ? "TIMEOUT" : "NETWORK_ERROR"
211
+ );
212
+ } finally {
213
+ clearTimeout(timer);
214
+ }
215
+ const body = await response.json();
216
+ const results = /* @__PURE__ */ new Map();
217
+ for (const resp of body) {
218
+ if (resp.error) {
219
+ results.set(resp.id, new AgentBnBError(resp.error.message, `RPC_ERROR_${resp.error.code}`));
220
+ } else {
221
+ results.set(resp.id, resp.result);
222
+ }
223
+ }
224
+ return results;
225
+ }
226
+ async function requestViaRelay(relay, opts) {
227
+ const timeoutMs = opts.timeoutMs ?? deriveRequestTimeoutMs(opts.timeoutHint);
228
+ try {
229
+ return await relay.request({
230
+ targetOwner: opts.targetOwner,
231
+ targetAgentId: opts.targetAgentId,
232
+ cardId: opts.cardId,
233
+ skillId: opts.skillId,
234
+ params: opts.params ?? {},
235
+ requester: opts.requester,
236
+ escrowReceipt: opts.escrowReceipt,
237
+ timeoutMs
238
+ });
239
+ } catch (err) {
240
+ const message = err instanceof Error ? err.message : String(err);
241
+ if (message.includes("timeout")) {
242
+ throw new AgentBnBError(message, "TIMEOUT");
243
+ }
244
+ if (message.includes("offline")) {
245
+ throw new AgentBnBError(message, "AGENT_OFFLINE");
246
+ }
247
+ throw new AgentBnBError(message, "RELAY_ERROR");
248
+ }
249
+ }
250
+
251
+ export {
252
+ generateKeyPair,
253
+ saveKeyPair,
254
+ loadKeyPair,
255
+ signEscrowReceipt,
256
+ verifyEscrowReceipt,
257
+ REQUEST_TIMEOUT_FALLBACK_MS,
258
+ REQUEST_TIMEOUT_GRACE_MS,
259
+ REQUEST_TIMEOUT_EXPECTED_MULTIPLIER,
260
+ deriveRequestTimeoutMs,
261
+ requestCapability,
262
+ requestCapabilityBatch,
263
+ requestViaRelay
264
+ };