agentbnb 8.2.0 → 8.2.1
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/{chunk-TBJ3FZKZ.js → chunk-7Q2XUXSA.js} +1 -1
- package/dist/{chunk-LJM7FHPM.js → chunk-BZOJ7HBT.js} +33 -1
- package/dist/{chunk-FTZTEHYG.js → chunk-DEWY7OQK.js} +135 -8
- package/dist/{chunk-CUONY5TO.js → chunk-EJKW57ZV.js} +19 -1
- package/dist/chunk-EZVOG7QS.js +161 -0
- package/dist/{chunk-E2OKP5CY.js → chunk-GJETGML6.js} +181 -83
- package/dist/{chunk-YHY7OG6S.js → chunk-GWMMYVLL.js} +4 -4
- package/dist/{chunk-D6RKW2XG.js → chunk-JLNHMNES.js} +16 -3
- package/dist/{chunk-5AAFG2V2.js → chunk-KBQNTUTN.js} +239 -24
- package/dist/{chunk-C537SFHV.js → chunk-LOUEJI6X.js} +4 -4
- package/dist/{chunk-ALX4WS3A.js → chunk-NP55V7RQ.js} +1 -1
- package/dist/{chunk-X32NE6V4.js → chunk-RBXTWWUH.js} +1 -1
- package/dist/{chunk-O2OYBAVR.js → chunk-SRBVKO2V.js} +9 -0
- package/dist/{chunk-7EF3HYVZ.js → chunk-STJLWMXH.js} +48 -4
- package/dist/{chunk-5GME4KJZ.js → chunk-UYCD3JBZ.js} +3 -3
- package/dist/{chunk-P4LOYSLA.js → chunk-WKWJWKX7.js} +286 -81
- package/dist/cli/index.js +35 -57
- package/dist/{client-HKV3QWZ3.js → client-66TFS7RS.js} +4 -2
- package/dist/{conduct-W6XF6DJW.js → conduct-A6COHLHY.js} +8 -8
- package/dist/{conduct-YB64OHI6.js → conduct-IUVAXUAV.js} +8 -8
- package/dist/{conductor-mode-TFCVCQHU.js → conductor-mode-D5TFQW5L.js} +2 -2
- package/dist/{conductor-mode-AKREGDIU.js → conductor-mode-L2MB44BW.js} +7 -7
- package/dist/{execute-AYQWORVH.js → execute-5AWLARB5.js} +5 -5
- package/dist/{execute-EPE6MZLT.js → execute-WOS457HW.js} +2 -2
- package/dist/index.js +438 -92
- package/dist/{publish-capability-AH2HDW54.js → publish-capability-JJCBBMSX.js} +2 -2
- package/dist/{request-HCCXSKAY.js → request-6YQLA7K3.js} +13 -8
- package/dist/{serve-skill-SZAQT5T5.js → serve-skill-X7TZSILV.js} +5 -5
- package/dist/{server-LMY2A3GT.js → server-5TSP4DBX.js} +10 -12
- package/dist/{service-coordinator-WGH6B2VT.js → service-coordinator-WTUSMPY6.js} +69 -46
- package/dist/skills/agentbnb/bootstrap.js +459 -189
- package/package.json +13 -17
- package/skills/agentbnb/bootstrap.test.ts +8 -6
- package/skills/agentbnb/bootstrap.ts +21 -13
- package/skills/agentbnb/install.sh +0 -0
- package/dist/chunk-64AK4FJM.js +0 -84
- package/dist/chunk-OH7BP5NP.js +0 -96
- package/dist/index.d.ts +0 -5069
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
getFeedbackForProvider
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-SRBVKO2V.js";
|
|
4
4
|
|
|
5
5
|
// src/feedback/reputation.ts
|
|
6
6
|
var QUALITY_SCORES = {
|
|
@@ -49,7 +49,37 @@ function getReputationScore(db, agentId) {
|
|
|
49
49
|
}
|
|
50
50
|
|
|
51
51
|
// src/registry/matcher.ts
|
|
52
|
+
var CACHE_MAX_ENTRIES = 100;
|
|
53
|
+
var CACHE_TTL_MS = 3e4;
|
|
54
|
+
var dbCaches = /* @__PURE__ */ new WeakMap();
|
|
55
|
+
function getDbCache(db) {
|
|
56
|
+
let cache = dbCaches.get(db);
|
|
57
|
+
if (!cache) {
|
|
58
|
+
cache = /* @__PURE__ */ new Map();
|
|
59
|
+
dbCaches.set(db, cache);
|
|
60
|
+
}
|
|
61
|
+
return cache;
|
|
62
|
+
}
|
|
63
|
+
function cacheKey(query, filters) {
|
|
64
|
+
return `${query}|${filters.level ?? ""}|${filters.online ?? ""}|${(filters.apis_used ?? []).join(",")}|${filters.min_reputation ?? ""}`;
|
|
65
|
+
}
|
|
66
|
+
function evictCache(cache) {
|
|
67
|
+
const now = Date.now();
|
|
68
|
+
for (const [key, entry] of cache) {
|
|
69
|
+
if (entry.expiresAt <= now) cache.delete(key);
|
|
70
|
+
}
|
|
71
|
+
while (cache.size > CACHE_MAX_ENTRIES) {
|
|
72
|
+
const firstKey = cache.keys().next().value;
|
|
73
|
+
cache.delete(firstKey);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
52
76
|
function searchCards(db, query, filters = {}) {
|
|
77
|
+
const cache = getDbCache(db);
|
|
78
|
+
const key = cacheKey(query, filters);
|
|
79
|
+
const cached = cache.get(key);
|
|
80
|
+
if (cached && cached.expiresAt > Date.now()) {
|
|
81
|
+
return cached.results;
|
|
82
|
+
}
|
|
53
83
|
const words = query.trim().split(/\s+/).map((w) => w.replace(/["*^{}():]/g, "")).filter((w) => w.length > 0);
|
|
54
84
|
if (words.length === 0) return [];
|
|
55
85
|
const ftsQuery = words.map((w) => `"${w}"`).join(" OR ");
|
|
@@ -87,6 +117,8 @@ function searchCards(db, query, filters = {}) {
|
|
|
87
117
|
if (filters.min_reputation !== void 0 && filters.min_reputation > 0) {
|
|
88
118
|
filtered = applyReputationFilter(db, filtered, filters.min_reputation);
|
|
89
119
|
}
|
|
120
|
+
evictCache(cache);
|
|
121
|
+
cache.set(key, { results: filtered, expiresAt: Date.now() + CACHE_TTL_MS });
|
|
90
122
|
return filtered;
|
|
91
123
|
}
|
|
92
124
|
function filterCards(db, filters) {
|
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
import {
|
|
2
2
|
searchCards
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-BZOJ7HBT.js";
|
|
4
|
+
import {
|
|
5
|
+
AgentBnBError
|
|
6
|
+
} from "./chunk-WVY2W7AA.js";
|
|
4
7
|
|
|
5
8
|
// src/registry/pricing.ts
|
|
6
9
|
function getPricingStats(db, query) {
|
|
@@ -105,14 +108,137 @@ async function stopAnnouncement() {
|
|
|
105
108
|
}
|
|
106
109
|
const instance = bonjourInstance;
|
|
107
110
|
bonjourInstance = null;
|
|
108
|
-
await new Promise((
|
|
111
|
+
await new Promise((resolve2) => {
|
|
109
112
|
instance.unpublishAll(() => {
|
|
110
113
|
instance.destroy();
|
|
111
|
-
|
|
114
|
+
resolve2();
|
|
112
115
|
});
|
|
113
116
|
});
|
|
114
117
|
}
|
|
115
118
|
|
|
119
|
+
// src/runtime/resolve-self-cli.ts
|
|
120
|
+
import { execFileSync } from "child_process";
|
|
121
|
+
import { existsSync, realpathSync } from "fs";
|
|
122
|
+
import { createRequire } from "module";
|
|
123
|
+
import { homedir } from "os";
|
|
124
|
+
import { basename, isAbsolute, join, resolve } from "path";
|
|
125
|
+
function resolveSelfCli() {
|
|
126
|
+
const require2 = createRequire(import.meta.url);
|
|
127
|
+
return resolveSelfCliWithDeps({
|
|
128
|
+
argv1: process.argv[1],
|
|
129
|
+
cwd: process.cwd(),
|
|
130
|
+
platform: process.platform,
|
|
131
|
+
homeDir: homedir(),
|
|
132
|
+
envPath: process.env["PATH"],
|
|
133
|
+
exists: existsSync,
|
|
134
|
+
realpath: realpathSync,
|
|
135
|
+
runWhich: (pathEnv) => execFileSync("which", ["agentbnb"], {
|
|
136
|
+
encoding: "utf8",
|
|
137
|
+
env: { ...process.env, PATH: pathEnv }
|
|
138
|
+
}).trim(),
|
|
139
|
+
requireResolve: (id) => require2.resolve(id)
|
|
140
|
+
});
|
|
141
|
+
}
|
|
142
|
+
function resolveSelfCliWithDeps(deps) {
|
|
143
|
+
const tried = [];
|
|
144
|
+
const tryCandidate = (rawPath, label, requireCliShape = false) => {
|
|
145
|
+
if (!rawPath || rawPath.trim().length === 0) {
|
|
146
|
+
tried.push(`${label}: <empty>`);
|
|
147
|
+
return null;
|
|
148
|
+
}
|
|
149
|
+
const maybeAbsolute = isAbsolute(rawPath) ? rawPath : resolve(deps.cwd, rawPath);
|
|
150
|
+
tried.push(`${label}: ${maybeAbsolute}`);
|
|
151
|
+
if (!deps.exists(maybeAbsolute)) return null;
|
|
152
|
+
const resolvedPath = safeRealpath(deps.realpath, maybeAbsolute);
|
|
153
|
+
if (requireCliShape && !looksLikeAgentbnbCli(resolvedPath)) return null;
|
|
154
|
+
return resolvedPath;
|
|
155
|
+
};
|
|
156
|
+
const argvPath = tryCandidate(deps.argv1, "process.argv[1]", true);
|
|
157
|
+
if (argvPath) return argvPath;
|
|
158
|
+
const fullPathEnv = buildFullPathEnv(deps.envPath, deps.homeDir);
|
|
159
|
+
tried.push(`which agentbnb PATH=${fullPathEnv}`);
|
|
160
|
+
try {
|
|
161
|
+
const whichPath = tryCandidate(deps.runWhich(fullPathEnv), "which agentbnb");
|
|
162
|
+
if (whichPath) return whichPath;
|
|
163
|
+
} catch (err) {
|
|
164
|
+
tried.push(`which agentbnb failed: ${extractErrorMessage(err)}`);
|
|
165
|
+
}
|
|
166
|
+
const npmGlobalCandidates = ["/usr/local/bin/agentbnb", "/opt/homebrew/bin/agentbnb"];
|
|
167
|
+
for (const candidate of npmGlobalCandidates) {
|
|
168
|
+
const resolvedPath = tryCandidate(candidate, "npm-global");
|
|
169
|
+
if (resolvedPath) return resolvedPath;
|
|
170
|
+
}
|
|
171
|
+
const pnpmCandidates = getPnpmGlobalCandidates(deps.platform, deps.homeDir);
|
|
172
|
+
for (const candidate of pnpmCandidates) {
|
|
173
|
+
const resolvedPath = tryCandidate(candidate, "pnpm-global");
|
|
174
|
+
if (resolvedPath) return resolvedPath;
|
|
175
|
+
}
|
|
176
|
+
try {
|
|
177
|
+
const requireResolved = deps.requireResolve("agentbnb/dist/cli/index.js");
|
|
178
|
+
const resolvedPath = tryCandidate(requireResolved, "require.resolve(agentbnb/dist/cli/index.js)");
|
|
179
|
+
if (resolvedPath) return resolvedPath;
|
|
180
|
+
} catch (err) {
|
|
181
|
+
tried.push(`require.resolve(agentbnb/dist/cli/index.js) failed: ${extractErrorMessage(err)}`);
|
|
182
|
+
}
|
|
183
|
+
throw new AgentBnBError(
|
|
184
|
+
`Unable to resolve absolute path to agentbnb CLI.
|
|
185
|
+
Paths tried:
|
|
186
|
+
${tried.map((item) => `- ${item}`).join("\n")}`,
|
|
187
|
+
"CLI_ENTRY_NOT_FOUND"
|
|
188
|
+
);
|
|
189
|
+
}
|
|
190
|
+
function buildFullPathEnv(pathEnv, homeDir) {
|
|
191
|
+
const values = /* @__PURE__ */ new Set();
|
|
192
|
+
for (const item of (pathEnv ?? "").split(":")) {
|
|
193
|
+
if (item.trim()) values.add(item.trim());
|
|
194
|
+
}
|
|
195
|
+
for (const extra of [
|
|
196
|
+
"/usr/local/bin",
|
|
197
|
+
"/opt/homebrew/bin",
|
|
198
|
+
"/usr/bin",
|
|
199
|
+
"/bin",
|
|
200
|
+
"/usr/sbin",
|
|
201
|
+
"/sbin",
|
|
202
|
+
join(homeDir, ".local", "bin"),
|
|
203
|
+
join(homeDir, "Library", "pnpm"),
|
|
204
|
+
join(homeDir, ".local", "share", "pnpm")
|
|
205
|
+
]) {
|
|
206
|
+
values.add(extra);
|
|
207
|
+
}
|
|
208
|
+
return [...values].join(":");
|
|
209
|
+
}
|
|
210
|
+
function safeRealpath(realpath, path) {
|
|
211
|
+
try {
|
|
212
|
+
return realpath(path);
|
|
213
|
+
} catch {
|
|
214
|
+
return path;
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
function getPnpmGlobalCandidates(platform, homeDir) {
|
|
218
|
+
const candidates = /* @__PURE__ */ new Set();
|
|
219
|
+
if (platform === "darwin") {
|
|
220
|
+
candidates.add(join(homeDir, "Library", "pnpm", "agentbnb"));
|
|
221
|
+
}
|
|
222
|
+
if (platform === "linux") {
|
|
223
|
+
candidates.add(join(homeDir, ".local", "share", "pnpm", "agentbnb"));
|
|
224
|
+
}
|
|
225
|
+
candidates.add(join(homeDir, "Library", "pnpm", "agentbnb"));
|
|
226
|
+
candidates.add(join(homeDir, ".local", "share", "pnpm", "agentbnb"));
|
|
227
|
+
return [...candidates];
|
|
228
|
+
}
|
|
229
|
+
function looksLikeAgentbnbCli(path) {
|
|
230
|
+
const normalized = path.replace(/\\/g, "/").toLowerCase();
|
|
231
|
+
const fileName = basename(normalized);
|
|
232
|
+
if (fileName === "agentbnb" || fileName === "agentbnb.cmd" || fileName === "agentbnb.exe") {
|
|
233
|
+
return true;
|
|
234
|
+
}
|
|
235
|
+
return normalized.includes("/agentbnb/dist/cli/index.") || normalized.endsWith("/dist/cli/index.js") || normalized.endsWith("/dist/cli/index.mjs") || normalized.endsWith("/dist/cli/index.cjs");
|
|
236
|
+
}
|
|
237
|
+
function extractErrorMessage(err) {
|
|
238
|
+
if (err instanceof Error && err.message) return err.message;
|
|
239
|
+
return String(err);
|
|
240
|
+
}
|
|
241
|
+
|
|
116
242
|
// src/cli/onboarding.ts
|
|
117
243
|
import { randomUUID } from "crypto";
|
|
118
244
|
import { createConnection } from "net";
|
|
@@ -234,20 +360,20 @@ function detectApiKeys(knownKeys) {
|
|
|
234
360
|
return knownKeys.filter((key) => key in process.env);
|
|
235
361
|
}
|
|
236
362
|
async function isPortOpen(port, host = "127.0.0.1", timeoutMs = 300) {
|
|
237
|
-
return new Promise((
|
|
363
|
+
return new Promise((resolve2) => {
|
|
238
364
|
const socket = createConnection({ port, host });
|
|
239
365
|
const timer = setTimeout(() => {
|
|
240
366
|
socket.destroy();
|
|
241
|
-
|
|
367
|
+
resolve2(false);
|
|
242
368
|
}, timeoutMs);
|
|
243
369
|
socket.on("connect", () => {
|
|
244
370
|
clearTimeout(timer);
|
|
245
371
|
socket.destroy();
|
|
246
|
-
|
|
372
|
+
resolve2(true);
|
|
247
373
|
});
|
|
248
374
|
socket.on("error", () => {
|
|
249
375
|
clearTimeout(timer);
|
|
250
|
-
|
|
376
|
+
resolve2(false);
|
|
251
377
|
});
|
|
252
378
|
});
|
|
253
379
|
}
|
|
@@ -290,5 +416,6 @@ export {
|
|
|
290
416
|
KNOWN_API_KEYS,
|
|
291
417
|
detectApiKeys,
|
|
292
418
|
detectOpenPorts,
|
|
293
|
-
buildDraftCard
|
|
419
|
+
buildDraftCard,
|
|
420
|
+
resolveSelfCli
|
|
294
421
|
};
|
|
@@ -35,7 +35,25 @@ function loadKeyPair(configDir) {
|
|
|
35
35
|
};
|
|
36
36
|
}
|
|
37
37
|
function canonicalJson(data) {
|
|
38
|
-
return JSON.stringify(
|
|
38
|
+
return JSON.stringify(sortForCanonicalJson(data));
|
|
39
|
+
}
|
|
40
|
+
function sortForCanonicalJson(value) {
|
|
41
|
+
if (Array.isArray(value)) {
|
|
42
|
+
return value.map((item) => sortForCanonicalJson(item));
|
|
43
|
+
}
|
|
44
|
+
if (value !== null && typeof value === "object") {
|
|
45
|
+
const proto = Object.getPrototypeOf(value);
|
|
46
|
+
if (proto === Object.prototype || proto === null) {
|
|
47
|
+
const input = value;
|
|
48
|
+
const output = {};
|
|
49
|
+
const sortedKeys = Object.keys(input).sort();
|
|
50
|
+
for (const key of sortedKeys) {
|
|
51
|
+
output[key] = sortForCanonicalJson(input[key]);
|
|
52
|
+
}
|
|
53
|
+
return output;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
return value;
|
|
39
57
|
}
|
|
40
58
|
function signEscrowReceipt(data, privateKey) {
|
|
41
59
|
const message = Buffer.from(canonicalJson(data), "utf-8");
|
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
import {
|
|
2
|
+
signEscrowReceipt
|
|
3
|
+
} from "./chunk-EJKW57ZV.js";
|
|
4
|
+
import {
|
|
5
|
+
AgentBnBError
|
|
6
|
+
} from "./chunk-WVY2W7AA.js";
|
|
7
|
+
|
|
8
|
+
// src/gateway/client.ts
|
|
9
|
+
import { randomUUID } from "crypto";
|
|
10
|
+
import { Agent } from "undici";
|
|
11
|
+
var gatewayAgent = new Agent({
|
|
12
|
+
keepAliveTimeout: 3e4,
|
|
13
|
+
keepAliveMaxTimeout: 6e4,
|
|
14
|
+
connections: 10,
|
|
15
|
+
pipelining: 1
|
|
16
|
+
});
|
|
17
|
+
async function requestCapability(opts) {
|
|
18
|
+
const { gatewayUrl, token, cardId, params = {}, timeoutMs = 3e5, escrowReceipt, identity } = opts;
|
|
19
|
+
const id = randomUUID();
|
|
20
|
+
const payload = {
|
|
21
|
+
jsonrpc: "2.0",
|
|
22
|
+
id,
|
|
23
|
+
method: "capability.execute",
|
|
24
|
+
params: {
|
|
25
|
+
card_id: cardId,
|
|
26
|
+
...params,
|
|
27
|
+
...escrowReceipt ? { escrow_receipt: escrowReceipt } : {}
|
|
28
|
+
}
|
|
29
|
+
};
|
|
30
|
+
const headers = { "Content-Type": "application/json" };
|
|
31
|
+
if (identity) {
|
|
32
|
+
const signature = signEscrowReceipt(payload, identity.privateKey);
|
|
33
|
+
headers["X-Agent-Id"] = identity.agentId;
|
|
34
|
+
headers["X-Agent-Public-Key"] = identity.publicKey;
|
|
35
|
+
headers["X-Agent-Signature"] = signature;
|
|
36
|
+
} else if (token) {
|
|
37
|
+
headers["Authorization"] = `Bearer ${token}`;
|
|
38
|
+
}
|
|
39
|
+
const controller = new AbortController();
|
|
40
|
+
const timer = setTimeout(() => controller.abort(), timeoutMs);
|
|
41
|
+
let response;
|
|
42
|
+
try {
|
|
43
|
+
response = await fetch(`${gatewayUrl}/rpc`, {
|
|
44
|
+
method: "POST",
|
|
45
|
+
headers,
|
|
46
|
+
body: JSON.stringify(payload),
|
|
47
|
+
signal: controller.signal,
|
|
48
|
+
// undici dispatcher for connection pooling (Node.js 20+)
|
|
49
|
+
dispatcher: gatewayAgent
|
|
50
|
+
});
|
|
51
|
+
} catch (err) {
|
|
52
|
+
clearTimeout(timer);
|
|
53
|
+
const isTimeout = err instanceof Error && err.name === "AbortError";
|
|
54
|
+
throw new AgentBnBError(
|
|
55
|
+
isTimeout ? "Request timed out" : `Network error: ${String(err)}`,
|
|
56
|
+
isTimeout ? "TIMEOUT" : "NETWORK_ERROR"
|
|
57
|
+
);
|
|
58
|
+
} finally {
|
|
59
|
+
clearTimeout(timer);
|
|
60
|
+
}
|
|
61
|
+
const body = await response.json();
|
|
62
|
+
if (body.error) {
|
|
63
|
+
throw new AgentBnBError(body.error.message, `RPC_ERROR_${body.error.code}`);
|
|
64
|
+
}
|
|
65
|
+
return body.result;
|
|
66
|
+
}
|
|
67
|
+
async function requestCapabilityBatch(gatewayUrl, token, items, opts = {}) {
|
|
68
|
+
if (items.length === 0) return /* @__PURE__ */ new Map();
|
|
69
|
+
if (items.length === 1) {
|
|
70
|
+
const item = items[0];
|
|
71
|
+
const result = await requestCapability({
|
|
72
|
+
gatewayUrl,
|
|
73
|
+
token,
|
|
74
|
+
cardId: item.cardId,
|
|
75
|
+
params: item.params,
|
|
76
|
+
escrowReceipt: item.escrowReceipt,
|
|
77
|
+
timeoutMs: opts.timeoutMs,
|
|
78
|
+
identity: opts.identity
|
|
79
|
+
});
|
|
80
|
+
return /* @__PURE__ */ new Map([[item.id, result]]);
|
|
81
|
+
}
|
|
82
|
+
const { timeoutMs = 3e5, identity } = opts;
|
|
83
|
+
const batchPayload = items.map((item) => ({
|
|
84
|
+
jsonrpc: "2.0",
|
|
85
|
+
id: item.id,
|
|
86
|
+
method: "capability.execute",
|
|
87
|
+
params: {
|
|
88
|
+
card_id: item.cardId,
|
|
89
|
+
...item.params,
|
|
90
|
+
...item.escrowReceipt ? { escrow_receipt: item.escrowReceipt } : {}
|
|
91
|
+
}
|
|
92
|
+
}));
|
|
93
|
+
const headers = { "Content-Type": "application/json" };
|
|
94
|
+
if (identity) {
|
|
95
|
+
const signature = signEscrowReceipt(batchPayload, identity.privateKey);
|
|
96
|
+
headers["X-Agent-Id"] = identity.agentId;
|
|
97
|
+
headers["X-Agent-Public-Key"] = identity.publicKey;
|
|
98
|
+
headers["X-Agent-Signature"] = signature;
|
|
99
|
+
} else if (token) {
|
|
100
|
+
headers["Authorization"] = `Bearer ${token}`;
|
|
101
|
+
}
|
|
102
|
+
const controller = new AbortController();
|
|
103
|
+
const timer = setTimeout(() => controller.abort(), timeoutMs);
|
|
104
|
+
let response;
|
|
105
|
+
try {
|
|
106
|
+
response = await fetch(`${gatewayUrl}/rpc`, {
|
|
107
|
+
method: "POST",
|
|
108
|
+
headers,
|
|
109
|
+
body: JSON.stringify(batchPayload),
|
|
110
|
+
signal: controller.signal,
|
|
111
|
+
dispatcher: gatewayAgent
|
|
112
|
+
});
|
|
113
|
+
} catch (err) {
|
|
114
|
+
clearTimeout(timer);
|
|
115
|
+
const isTimeout = err instanceof Error && err.name === "AbortError";
|
|
116
|
+
throw new AgentBnBError(
|
|
117
|
+
isTimeout ? "Batch request timed out" : `Network error: ${String(err)}`,
|
|
118
|
+
isTimeout ? "TIMEOUT" : "NETWORK_ERROR"
|
|
119
|
+
);
|
|
120
|
+
} finally {
|
|
121
|
+
clearTimeout(timer);
|
|
122
|
+
}
|
|
123
|
+
const body = await response.json();
|
|
124
|
+
const results = /* @__PURE__ */ new Map();
|
|
125
|
+
for (const resp of body) {
|
|
126
|
+
if (resp.error) {
|
|
127
|
+
results.set(resp.id, new AgentBnBError(resp.error.message, `RPC_ERROR_${resp.error.code}`));
|
|
128
|
+
} else {
|
|
129
|
+
results.set(resp.id, resp.result);
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
return results;
|
|
133
|
+
}
|
|
134
|
+
async function requestViaRelay(relay, opts) {
|
|
135
|
+
try {
|
|
136
|
+
return await relay.request({
|
|
137
|
+
targetOwner: opts.targetOwner,
|
|
138
|
+
cardId: opts.cardId,
|
|
139
|
+
skillId: opts.skillId,
|
|
140
|
+
params: opts.params ?? {},
|
|
141
|
+
requester: opts.requester,
|
|
142
|
+
escrowReceipt: opts.escrowReceipt,
|
|
143
|
+
timeoutMs: opts.timeoutMs
|
|
144
|
+
});
|
|
145
|
+
} catch (err) {
|
|
146
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
147
|
+
if (message.includes("timeout")) {
|
|
148
|
+
throw new AgentBnBError(message, "TIMEOUT");
|
|
149
|
+
}
|
|
150
|
+
if (message.includes("offline")) {
|
|
151
|
+
throw new AgentBnBError(message, "AGENT_OFFLINE");
|
|
152
|
+
}
|
|
153
|
+
throw new AgentBnBError(message, "RELAY_ERROR");
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
export {
|
|
158
|
+
requestCapability,
|
|
159
|
+
requestCapabilityBatch,
|
|
160
|
+
requestViaRelay
|
|
161
|
+
};
|