agentbnb 8.2.1 → 8.2.2
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-7Q2XUXSA.js → chunk-4IPJJRTP.js} +1 -1
- package/dist/{chunk-EZVOG7QS.js → chunk-CKOOVZOI.js} +15 -18
- package/dist/chunk-CQFBNTGT.js +145 -0
- package/dist/{chunk-WKWJWKX7.js → chunk-DYQOFGGI.js} +155 -445
- package/dist/{chunk-NP55V7RQ.js → chunk-EG6RS4JC.js} +70 -46
- package/dist/{chunk-KBQNTUTN.js → chunk-LKLKYXLV.js} +1 -1
- package/dist/{chunk-STJLWMXH.js → chunk-MCED4GDW.js} +467 -98
- package/dist/{chunk-GWMMYVLL.js → chunk-MWOXW7JQ.js} +7 -7
- package/dist/{chunk-GJETGML6.js → chunk-QCGIG7WW.js} +4 -6
- package/dist/{chunk-UYCD3JBZ.js → chunk-QHZGOG3O.js} +148 -46
- package/dist/{chunk-JLNHMNES.js → chunk-RYISHSHB.js} +286 -1
- package/dist/{chunk-SRBVKO2V.js → chunk-S3V6R3EN.js} +66 -39
- package/dist/{chunk-RBXTWWUH.js → chunk-WNXXLCV5.js} +1 -1
- package/dist/{chunk-LOUEJI6X.js → chunk-XBGVQMQJ.js} +71 -47
- package/dist/{chunk-DEWY7OQK.js → chunk-Z2GEFFDO.js} +1 -1
- package/dist/cli/index.js +25 -28
- package/dist/{client-66TFS7RS.js → client-XOLP5IUZ.js} +1 -1
- package/dist/{conduct-A6COHLHY.js → conduct-AZFLNUX3.js} +9 -10
- package/dist/{conduct-IUVAXUAV.js → conduct-VPUYTNEA.js} +9 -10
- package/dist/{conductor-mode-L2MB44BW.js → conductor-mode-PLTB6MS3.js} +6 -7
- package/dist/{conductor-mode-D5TFQW5L.js → conductor-mode-WKB42PYM.js} +6 -3
- package/dist/{execute-WOS457HW.js → execute-NNDCXTN4.js} +3 -2
- package/dist/{execute-5AWLARB5.js → execute-RIRHTIBU.js} +5 -4
- package/dist/index.d.ts +5069 -0
- package/dist/index.js +208 -610
- package/dist/{publish-capability-JJCBBMSX.js → publish-capability-QDR2QIZ2.js} +2 -2
- package/dist/{request-6YQLA7K3.js → request-NX7GSPIG.js} +30 -40
- package/dist/{serve-skill-X7TZSILV.js → serve-skill-E6EJQYAK.js} +9 -8
- package/dist/{server-5TSP4DBX.js → server-VBCT32FC.js} +10 -14
- package/dist/{service-coordinator-WTUSMPY6.js → service-coordinator-KMSA6BST.js} +77 -32
- package/dist/skills/agentbnb/bootstrap.js +113 -69
- package/package.json +1 -1
- package/dist/chunk-BZOJ7HBT.js +0 -170
- package/dist/chunk-KF3TZHA5.js +0 -91
|
@@ -1,14 +1,20 @@
|
|
|
1
|
+
import {
|
|
2
|
+
requestCapability,
|
|
3
|
+
requestCapabilityBatch,
|
|
4
|
+
requestViaRelay
|
|
5
|
+
} from "./chunk-CKOOVZOI.js";
|
|
1
6
|
import {
|
|
2
7
|
findPeer
|
|
3
8
|
} from "./chunk-HLUEOLSZ.js";
|
|
4
9
|
import {
|
|
10
|
+
fetchRemoteCards,
|
|
5
11
|
getBalance,
|
|
6
|
-
getFeedbackForProvider,
|
|
7
12
|
holdEscrow,
|
|
8
13
|
releaseEscrow,
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
14
|
+
resolveTargetCapability,
|
|
15
|
+
searchCards,
|
|
16
|
+
settleEscrow
|
|
17
|
+
} from "./chunk-MCED4GDW.js";
|
|
12
18
|
import {
|
|
13
19
|
AgentBnBError
|
|
14
20
|
} from "./chunk-WVY2W7AA.js";
|
|
@@ -256,317 +262,11 @@ function decompose(task, _availableCapabilities) {
|
|
|
256
262
|
return [];
|
|
257
263
|
}
|
|
258
264
|
|
|
259
|
-
// src/
|
|
260
|
-
import { randomUUID as
|
|
261
|
-
import { Agent } from "undici";
|
|
262
|
-
var gatewayAgent = new Agent({
|
|
263
|
-
keepAliveTimeout: 3e4,
|
|
264
|
-
keepAliveMaxTimeout: 6e4,
|
|
265
|
-
connections: 10,
|
|
266
|
-
pipelining: 1
|
|
267
|
-
});
|
|
268
|
-
async function requestCapability(opts) {
|
|
269
|
-
const { gatewayUrl, token, cardId, params = {}, timeoutMs = 3e5, escrowReceipt, identity } = opts;
|
|
270
|
-
const id = randomUUID2();
|
|
271
|
-
const payload = {
|
|
272
|
-
jsonrpc: "2.0",
|
|
273
|
-
id,
|
|
274
|
-
method: "capability.execute",
|
|
275
|
-
params: {
|
|
276
|
-
card_id: cardId,
|
|
277
|
-
...params,
|
|
278
|
-
...escrowReceipt ? { escrow_receipt: escrowReceipt } : {}
|
|
279
|
-
}
|
|
280
|
-
};
|
|
281
|
-
const headers = { "Content-Type": "application/json" };
|
|
282
|
-
if (identity) {
|
|
283
|
-
const signature = signEscrowReceipt(payload, identity.privateKey);
|
|
284
|
-
headers["X-Agent-Id"] = identity.agentId;
|
|
285
|
-
headers["X-Agent-Public-Key"] = identity.publicKey;
|
|
286
|
-
headers["X-Agent-Signature"] = signature;
|
|
287
|
-
} else if (token) {
|
|
288
|
-
headers["Authorization"] = `Bearer ${token}`;
|
|
289
|
-
}
|
|
290
|
-
const controller = new AbortController();
|
|
291
|
-
const timer = setTimeout(() => controller.abort(), timeoutMs);
|
|
292
|
-
let response;
|
|
293
|
-
try {
|
|
294
|
-
response = await fetch(`${gatewayUrl}/rpc`, {
|
|
295
|
-
method: "POST",
|
|
296
|
-
headers,
|
|
297
|
-
body: JSON.stringify(payload),
|
|
298
|
-
signal: controller.signal,
|
|
299
|
-
// undici dispatcher for connection pooling (Node.js 20+)
|
|
300
|
-
dispatcher: gatewayAgent
|
|
301
|
-
});
|
|
302
|
-
} catch (err) {
|
|
303
|
-
clearTimeout(timer);
|
|
304
|
-
const isTimeout = err instanceof Error && err.name === "AbortError";
|
|
305
|
-
throw new AgentBnBError(
|
|
306
|
-
isTimeout ? "Request timed out" : `Network error: ${String(err)}`,
|
|
307
|
-
isTimeout ? "TIMEOUT" : "NETWORK_ERROR"
|
|
308
|
-
);
|
|
309
|
-
} finally {
|
|
310
|
-
clearTimeout(timer);
|
|
311
|
-
}
|
|
312
|
-
const body = await response.json();
|
|
313
|
-
if (body.error) {
|
|
314
|
-
throw new AgentBnBError(body.error.message, `RPC_ERROR_${body.error.code}`);
|
|
315
|
-
}
|
|
316
|
-
return body.result;
|
|
317
|
-
}
|
|
318
|
-
async function requestCapabilityBatch(gatewayUrl, token, items, opts = {}) {
|
|
319
|
-
if (items.length === 0) return /* @__PURE__ */ new Map();
|
|
320
|
-
if (items.length === 1) {
|
|
321
|
-
const item = items[0];
|
|
322
|
-
const result = await requestCapability({
|
|
323
|
-
gatewayUrl,
|
|
324
|
-
token,
|
|
325
|
-
cardId: item.cardId,
|
|
326
|
-
params: item.params,
|
|
327
|
-
escrowReceipt: item.escrowReceipt,
|
|
328
|
-
timeoutMs: opts.timeoutMs,
|
|
329
|
-
identity: opts.identity
|
|
330
|
-
});
|
|
331
|
-
return /* @__PURE__ */ new Map([[item.id, result]]);
|
|
332
|
-
}
|
|
333
|
-
const { timeoutMs = 3e5, identity } = opts;
|
|
334
|
-
const batchPayload = items.map((item) => ({
|
|
335
|
-
jsonrpc: "2.0",
|
|
336
|
-
id: item.id,
|
|
337
|
-
method: "capability.execute",
|
|
338
|
-
params: {
|
|
339
|
-
card_id: item.cardId,
|
|
340
|
-
...item.params,
|
|
341
|
-
...item.escrowReceipt ? { escrow_receipt: item.escrowReceipt } : {}
|
|
342
|
-
}
|
|
343
|
-
}));
|
|
344
|
-
const headers = { "Content-Type": "application/json" };
|
|
345
|
-
if (identity) {
|
|
346
|
-
const signature = signEscrowReceipt(batchPayload, identity.privateKey);
|
|
347
|
-
headers["X-Agent-Id"] = identity.agentId;
|
|
348
|
-
headers["X-Agent-Public-Key"] = identity.publicKey;
|
|
349
|
-
headers["X-Agent-Signature"] = signature;
|
|
350
|
-
} else if (token) {
|
|
351
|
-
headers["Authorization"] = `Bearer ${token}`;
|
|
352
|
-
}
|
|
353
|
-
const controller = new AbortController();
|
|
354
|
-
const timer = setTimeout(() => controller.abort(), timeoutMs);
|
|
355
|
-
let response;
|
|
356
|
-
try {
|
|
357
|
-
response = await fetch(`${gatewayUrl}/rpc`, {
|
|
358
|
-
method: "POST",
|
|
359
|
-
headers,
|
|
360
|
-
body: JSON.stringify(batchPayload),
|
|
361
|
-
signal: controller.signal,
|
|
362
|
-
dispatcher: gatewayAgent
|
|
363
|
-
});
|
|
364
|
-
} catch (err) {
|
|
365
|
-
clearTimeout(timer);
|
|
366
|
-
const isTimeout = err instanceof Error && err.name === "AbortError";
|
|
367
|
-
throw new AgentBnBError(
|
|
368
|
-
isTimeout ? "Batch request timed out" : `Network error: ${String(err)}`,
|
|
369
|
-
isTimeout ? "TIMEOUT" : "NETWORK_ERROR"
|
|
370
|
-
);
|
|
371
|
-
} finally {
|
|
372
|
-
clearTimeout(timer);
|
|
373
|
-
}
|
|
374
|
-
const body = await response.json();
|
|
375
|
-
const results = /* @__PURE__ */ new Map();
|
|
376
|
-
for (const resp of body) {
|
|
377
|
-
if (resp.error) {
|
|
378
|
-
results.set(resp.id, new AgentBnBError(resp.error.message, `RPC_ERROR_${resp.error.code}`));
|
|
379
|
-
} else {
|
|
380
|
-
results.set(resp.id, resp.result);
|
|
381
|
-
}
|
|
382
|
-
}
|
|
383
|
-
return results;
|
|
384
|
-
}
|
|
385
|
-
async function requestViaRelay(relay, opts) {
|
|
386
|
-
try {
|
|
387
|
-
return await relay.request({
|
|
388
|
-
targetOwner: opts.targetOwner,
|
|
389
|
-
cardId: opts.cardId,
|
|
390
|
-
skillId: opts.skillId,
|
|
391
|
-
params: opts.params ?? {},
|
|
392
|
-
requester: opts.requester,
|
|
393
|
-
escrowReceipt: opts.escrowReceipt,
|
|
394
|
-
timeoutMs: opts.timeoutMs
|
|
395
|
-
});
|
|
396
|
-
} catch (err) {
|
|
397
|
-
const message = err instanceof Error ? err.message : String(err);
|
|
398
|
-
if (message.includes("timeout")) {
|
|
399
|
-
throw new AgentBnBError(message, "TIMEOUT");
|
|
400
|
-
}
|
|
401
|
-
if (message.includes("offline")) {
|
|
402
|
-
throw new AgentBnBError(message, "AGENT_OFFLINE");
|
|
403
|
-
}
|
|
404
|
-
throw new AgentBnBError(message, "RELAY_ERROR");
|
|
405
|
-
}
|
|
406
|
-
}
|
|
407
|
-
|
|
408
|
-
// src/feedback/reputation.ts
|
|
409
|
-
var QUALITY_SCORES = {
|
|
410
|
-
excellent: 1,
|
|
411
|
-
good: 0.8,
|
|
412
|
-
acceptable: 0.6,
|
|
413
|
-
poor: 0.3,
|
|
414
|
-
failed: 0
|
|
415
|
-
};
|
|
416
|
-
var COST_VALUE_SCORES = {
|
|
417
|
-
great: 1,
|
|
418
|
-
fair: 0.6,
|
|
419
|
-
overpriced: 0.2
|
|
420
|
-
};
|
|
421
|
-
var DECAY_DAYS = 30;
|
|
422
|
-
var WEIGHTS = {
|
|
423
|
-
rating: 0.4,
|
|
424
|
-
quality: 0.3,
|
|
425
|
-
would_reuse: 0.2,
|
|
426
|
-
cost_value: 0.1
|
|
427
|
-
};
|
|
428
|
-
function computeReputation(feedbacks) {
|
|
429
|
-
if (feedbacks.length === 0) return 0.5;
|
|
430
|
-
const now = Date.now();
|
|
431
|
-
let weightedSum = 0;
|
|
432
|
-
let totalWeight = 0;
|
|
433
|
-
for (const fb of feedbacks) {
|
|
434
|
-
const feedbackDate = new Date(fb.timestamp).getTime();
|
|
435
|
-
const ageDays = Math.max(0, (now - feedbackDate) / (1e3 * 60 * 60 * 24));
|
|
436
|
-
const recencyWeight = Math.exp(-ageDays / DECAY_DAYS);
|
|
437
|
-
const ratingScore = (fb.rating - 1) / 4;
|
|
438
|
-
const qualityScore = QUALITY_SCORES[fb.result_quality];
|
|
439
|
-
const reuseScore = fb.would_reuse ? 1 : 0;
|
|
440
|
-
const costScore = COST_VALUE_SCORES[fb.cost_value_ratio];
|
|
441
|
-
const componentScore = WEIGHTS.rating * ratingScore + WEIGHTS.quality * qualityScore + WEIGHTS.would_reuse * reuseScore + WEIGHTS.cost_value * costScore;
|
|
442
|
-
weightedSum += recencyWeight * componentScore;
|
|
443
|
-
totalWeight += recencyWeight;
|
|
444
|
-
}
|
|
445
|
-
if (totalWeight === 0) return 0.5;
|
|
446
|
-
const raw = weightedSum / totalWeight;
|
|
447
|
-
return Math.max(0, Math.min(1, raw));
|
|
448
|
-
}
|
|
449
|
-
function getReputationScore(db, agentId) {
|
|
450
|
-
const feedbacks = getFeedbackForProvider(db, agentId);
|
|
451
|
-
return computeReputation(feedbacks);
|
|
452
|
-
}
|
|
453
|
-
|
|
454
|
-
// src/registry/matcher.ts
|
|
455
|
-
var CACHE_MAX_ENTRIES = 100;
|
|
456
|
-
var CACHE_TTL_MS = 3e4;
|
|
457
|
-
var dbCaches = /* @__PURE__ */ new WeakMap();
|
|
458
|
-
function getDbCache(db) {
|
|
459
|
-
let cache = dbCaches.get(db);
|
|
460
|
-
if (!cache) {
|
|
461
|
-
cache = /* @__PURE__ */ new Map();
|
|
462
|
-
dbCaches.set(db, cache);
|
|
463
|
-
}
|
|
464
|
-
return cache;
|
|
465
|
-
}
|
|
466
|
-
function cacheKey(query, filters) {
|
|
467
|
-
return `${query}|${filters.level ?? ""}|${filters.online ?? ""}|${(filters.apis_used ?? []).join(",")}|${filters.min_reputation ?? ""}`;
|
|
468
|
-
}
|
|
469
|
-
function evictCache(cache) {
|
|
470
|
-
const now = Date.now();
|
|
471
|
-
for (const [key, entry] of cache) {
|
|
472
|
-
if (entry.expiresAt <= now) cache.delete(key);
|
|
473
|
-
}
|
|
474
|
-
while (cache.size > CACHE_MAX_ENTRIES) {
|
|
475
|
-
const firstKey = cache.keys().next().value;
|
|
476
|
-
cache.delete(firstKey);
|
|
477
|
-
}
|
|
478
|
-
}
|
|
479
|
-
function searchCards(db, query, filters = {}) {
|
|
480
|
-
const cache = getDbCache(db);
|
|
481
|
-
const key = cacheKey(query, filters);
|
|
482
|
-
const cached = cache.get(key);
|
|
483
|
-
if (cached && cached.expiresAt > Date.now()) {
|
|
484
|
-
return cached.results;
|
|
485
|
-
}
|
|
486
|
-
const words = query.trim().split(/\s+/).map((w) => w.replace(/["*^{}():]/g, "")).filter((w) => w.length > 0);
|
|
487
|
-
if (words.length === 0) return [];
|
|
488
|
-
const ftsQuery = words.map((w) => `"${w}"`).join(" OR ");
|
|
489
|
-
const conditions = [];
|
|
490
|
-
const params = [ftsQuery];
|
|
491
|
-
if (filters.level !== void 0) {
|
|
492
|
-
conditions.push(`json_extract(cc.data, '$.level') = ?`);
|
|
493
|
-
params.push(filters.level);
|
|
494
|
-
}
|
|
495
|
-
if (filters.online !== void 0) {
|
|
496
|
-
conditions.push(`json_extract(cc.data, '$.availability.online') = ?`);
|
|
497
|
-
params.push(filters.online ? 1 : 0);
|
|
498
|
-
}
|
|
499
|
-
const whereClause = conditions.length > 0 ? `AND ${conditions.join(" AND ")}` : "";
|
|
500
|
-
const sql = `
|
|
501
|
-
SELECT cc.data
|
|
502
|
-
FROM capability_cards cc
|
|
503
|
-
JOIN cards_fts ON cc.rowid = cards_fts.rowid
|
|
504
|
-
WHERE cards_fts MATCH ?
|
|
505
|
-
${whereClause}
|
|
506
|
-
ORDER BY bm25(cards_fts)
|
|
507
|
-
LIMIT 50
|
|
508
|
-
`;
|
|
509
|
-
const stmt = db.prepare(sql);
|
|
510
|
-
const rows = stmt.all(...params);
|
|
511
|
-
const results = rows.map((row) => JSON.parse(row.data));
|
|
512
|
-
let filtered = results;
|
|
513
|
-
if (filters.apis_used && filters.apis_used.length > 0) {
|
|
514
|
-
const requiredApis = filters.apis_used;
|
|
515
|
-
filtered = filtered.filter((card) => {
|
|
516
|
-
const cardApis = card.metadata?.apis_used ?? [];
|
|
517
|
-
return requiredApis.every((api) => cardApis.includes(api));
|
|
518
|
-
});
|
|
519
|
-
}
|
|
520
|
-
if (filters.min_reputation !== void 0 && filters.min_reputation > 0) {
|
|
521
|
-
filtered = applyReputationFilter(db, filtered, filters.min_reputation);
|
|
522
|
-
}
|
|
523
|
-
evictCache(cache);
|
|
524
|
-
cache.set(key, { results: filtered, expiresAt: Date.now() + CACHE_TTL_MS });
|
|
525
|
-
return filtered;
|
|
526
|
-
}
|
|
527
|
-
function filterCards(db, filters) {
|
|
528
|
-
const conditions = [];
|
|
529
|
-
const params = [];
|
|
530
|
-
if (filters.level !== void 0) {
|
|
531
|
-
conditions.push(`json_extract(data, '$.level') = ?`);
|
|
532
|
-
params.push(filters.level);
|
|
533
|
-
}
|
|
534
|
-
if (filters.online !== void 0) {
|
|
535
|
-
conditions.push(`json_extract(data, '$.availability.online') = ?`);
|
|
536
|
-
params.push(filters.online ? 1 : 0);
|
|
537
|
-
}
|
|
538
|
-
const whereClause = conditions.length > 0 ? `WHERE ${conditions.join(" AND ")}` : "";
|
|
539
|
-
const sql = `SELECT data FROM capability_cards ${whereClause}`;
|
|
540
|
-
const stmt = db.prepare(sql);
|
|
541
|
-
const rows = stmt.all(...params);
|
|
542
|
-
let cards = rows.map((row) => JSON.parse(row.data));
|
|
543
|
-
if (filters.min_reputation !== void 0 && filters.min_reputation > 0) {
|
|
544
|
-
cards = applyReputationFilter(db, cards, filters.min_reputation);
|
|
545
|
-
}
|
|
546
|
-
return cards;
|
|
547
|
-
}
|
|
548
|
-
function applyReputationFilter(db, cards, minReputation) {
|
|
549
|
-
const owners = [...new Set(cards.map((c) => c.owner))];
|
|
550
|
-
const reputationMap = /* @__PURE__ */ new Map();
|
|
551
|
-
for (const owner of owners) {
|
|
552
|
-
reputationMap.set(owner, getReputationScore(db, owner));
|
|
553
|
-
}
|
|
554
|
-
return cards.filter((card) => {
|
|
555
|
-
const score = reputationMap.get(card.owner) ?? 0.5;
|
|
556
|
-
return score >= minReputation;
|
|
557
|
-
});
|
|
558
|
-
}
|
|
559
|
-
function buildReputationMap(db, owners) {
|
|
560
|
-
const unique = [...new Set(owners)];
|
|
561
|
-
const map = /* @__PURE__ */ new Map();
|
|
562
|
-
for (const owner of unique) {
|
|
563
|
-
map.set(owner, getReputationScore(db, owner));
|
|
564
|
-
}
|
|
565
|
-
return map;
|
|
566
|
-
}
|
|
265
|
+
// src/autonomy/auto-request.ts
|
|
266
|
+
import { randomUUID as randomUUID4 } from "crypto";
|
|
567
267
|
|
|
568
268
|
// src/autonomy/tiers.ts
|
|
569
|
-
import { randomUUID as
|
|
269
|
+
import { randomUUID as randomUUID2 } from "crypto";
|
|
570
270
|
var DEFAULT_AUTONOMY_CONFIG = {
|
|
571
271
|
tier1_max_credits: 0,
|
|
572
272
|
tier2_max_credits: 0
|
|
@@ -587,7 +287,7 @@ function insertAuditEvent(db, event) {
|
|
|
587
287
|
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
588
288
|
`);
|
|
589
289
|
stmt.run(
|
|
590
|
-
|
|
290
|
+
randomUUID2(),
|
|
591
291
|
cardId,
|
|
592
292
|
"autonomy-audit",
|
|
593
293
|
"self",
|
|
@@ -602,9 +302,9 @@ function insertAuditEvent(db, event) {
|
|
|
602
302
|
}
|
|
603
303
|
|
|
604
304
|
// src/autonomy/pending-requests.ts
|
|
605
|
-
import { randomUUID as
|
|
305
|
+
import { randomUUID as randomUUID3 } from "crypto";
|
|
606
306
|
function createPendingRequest(db, opts) {
|
|
607
|
-
const id =
|
|
307
|
+
const id = randomUUID3();
|
|
608
308
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
609
309
|
const paramsJson = opts.params !== void 0 ? JSON.stringify(opts.params) : null;
|
|
610
310
|
db.prepare(`
|
|
@@ -642,89 +342,6 @@ function resolvePendingRequest(db, id, resolution) {
|
|
|
642
342
|
}
|
|
643
343
|
}
|
|
644
344
|
|
|
645
|
-
// src/cli/remote-registry.ts
|
|
646
|
-
var RegistryTimeoutError = class extends AgentBnBError {
|
|
647
|
-
constructor(url) {
|
|
648
|
-
super(
|
|
649
|
-
`Registry at ${url} did not respond within 5s. Showing local results only.`,
|
|
650
|
-
"REGISTRY_TIMEOUT"
|
|
651
|
-
);
|
|
652
|
-
this.name = "RegistryTimeoutError";
|
|
653
|
-
}
|
|
654
|
-
};
|
|
655
|
-
var RegistryConnectionError = class extends AgentBnBError {
|
|
656
|
-
constructor(url) {
|
|
657
|
-
super(
|
|
658
|
-
`Cannot reach ${url}. Is the registry running? Showing local results only.`,
|
|
659
|
-
"REGISTRY_CONNECTION"
|
|
660
|
-
);
|
|
661
|
-
this.name = "RegistryConnectionError";
|
|
662
|
-
}
|
|
663
|
-
};
|
|
664
|
-
var RegistryAuthError = class extends AgentBnBError {
|
|
665
|
-
constructor(url) {
|
|
666
|
-
super(
|
|
667
|
-
`Authentication failed for ${url}. Run \`agentbnb config set token <your-token>\`.`,
|
|
668
|
-
"REGISTRY_AUTH"
|
|
669
|
-
);
|
|
670
|
-
this.name = "RegistryAuthError";
|
|
671
|
-
}
|
|
672
|
-
};
|
|
673
|
-
async function fetchRemoteCards(registryUrl, params, timeoutMs = 5e3) {
|
|
674
|
-
let cardsUrl;
|
|
675
|
-
try {
|
|
676
|
-
cardsUrl = new URL("/cards", registryUrl);
|
|
677
|
-
} catch {
|
|
678
|
-
throw new AgentBnBError(`Invalid registry URL: ${registryUrl}`, "INVALID_REGISTRY_URL");
|
|
679
|
-
}
|
|
680
|
-
const searchParams = new URLSearchParams();
|
|
681
|
-
if (params.q !== void 0) searchParams.set("q", params.q);
|
|
682
|
-
if (params.level !== void 0) searchParams.set("level", String(params.level));
|
|
683
|
-
if (params.online !== void 0) searchParams.set("online", String(params.online));
|
|
684
|
-
if (params.tag !== void 0) searchParams.set("tag", params.tag);
|
|
685
|
-
searchParams.set("limit", "100");
|
|
686
|
-
cardsUrl.search = searchParams.toString();
|
|
687
|
-
const controller = new AbortController();
|
|
688
|
-
const timer = setTimeout(() => controller.abort(), timeoutMs);
|
|
689
|
-
let response;
|
|
690
|
-
try {
|
|
691
|
-
response = await fetch(cardsUrl.toString(), { signal: controller.signal });
|
|
692
|
-
} catch (err) {
|
|
693
|
-
clearTimeout(timer);
|
|
694
|
-
const isTimeout = err instanceof Error && err.name === "AbortError";
|
|
695
|
-
if (isTimeout) {
|
|
696
|
-
throw new RegistryTimeoutError(registryUrl);
|
|
697
|
-
}
|
|
698
|
-
throw new RegistryConnectionError(registryUrl);
|
|
699
|
-
} finally {
|
|
700
|
-
clearTimeout(timer);
|
|
701
|
-
}
|
|
702
|
-
if (response.status === 401 || response.status === 403) {
|
|
703
|
-
throw new RegistryAuthError(registryUrl);
|
|
704
|
-
}
|
|
705
|
-
if (!response.ok) {
|
|
706
|
-
throw new RegistryConnectionError(registryUrl);
|
|
707
|
-
}
|
|
708
|
-
const body = await response.json();
|
|
709
|
-
return body.items;
|
|
710
|
-
}
|
|
711
|
-
function mergeResults(localCards, remoteCards, hasQuery) {
|
|
712
|
-
const taggedLocal = localCards.map((c) => ({ ...c, source: "local" }));
|
|
713
|
-
const taggedRemote = remoteCards.map((c) => ({ ...c, source: "remote" }));
|
|
714
|
-
const localIds = new Set(localCards.map((c) => c.id));
|
|
715
|
-
const dedupedRemote = taggedRemote.filter((c) => !localIds.has(c.id));
|
|
716
|
-
if (!hasQuery) {
|
|
717
|
-
return [...taggedLocal, ...dedupedRemote];
|
|
718
|
-
}
|
|
719
|
-
const result = [];
|
|
720
|
-
const maxLen = Math.max(taggedLocal.length, dedupedRemote.length);
|
|
721
|
-
for (let i = 0; i < maxLen; i++) {
|
|
722
|
-
if (i < taggedLocal.length) result.push(taggedLocal[i]);
|
|
723
|
-
if (i < dedupedRemote.length) result.push(dedupedRemote[i]);
|
|
724
|
-
}
|
|
725
|
-
return result;
|
|
726
|
-
}
|
|
727
|
-
|
|
728
345
|
// src/autonomy/auto-request.ts
|
|
729
346
|
function minMaxNormalize(values) {
|
|
730
347
|
if (values.length === 0) return [];
|
|
@@ -848,88 +465,189 @@ var AutoRequestor = class {
|
|
|
848
465
|
}
|
|
849
466
|
}
|
|
850
467
|
const scored = scorePeers(candidates, this.owner);
|
|
468
|
+
const resolverOptions = {
|
|
469
|
+
registryDb: this.registryDb,
|
|
470
|
+
registryUrl: this.registryUrl,
|
|
471
|
+
onlineOnly: true
|
|
472
|
+
};
|
|
473
|
+
let resolvedTarget = null;
|
|
851
474
|
if (scored.length === 0) {
|
|
475
|
+
resolvedTarget = await resolveTargetCapability(need.query, resolverOptions);
|
|
476
|
+
if (!resolvedTarget || resolvedTarget.owner === this.owner || resolvedTarget.credits_per_call > need.maxCostCredits) {
|
|
477
|
+
this.logFailure("auto_request_failed", "system", "none", 3, 0, "none", "No eligible peer found");
|
|
478
|
+
return { status: "no_peer", reason: "No eligible peer found" };
|
|
479
|
+
}
|
|
480
|
+
} else {
|
|
481
|
+
const top = scored[0];
|
|
482
|
+
const targetKey = top.skillId ?? top.card.id;
|
|
483
|
+
resolvedTarget = await resolveTargetCapability(targetKey, resolverOptions) ?? await resolveTargetCapability(need.query, resolverOptions);
|
|
484
|
+
if (!resolvedTarget || resolvedTarget.owner === this.owner) {
|
|
485
|
+
this.logFailure("auto_request_failed", top.card.id, top.skillId ?? "none", 3, top.cost, top.card.owner, "No eligible peer found");
|
|
486
|
+
return { status: "no_peer", reason: "No eligible peer found" };
|
|
487
|
+
}
|
|
488
|
+
}
|
|
489
|
+
if (!resolvedTarget) {
|
|
852
490
|
this.logFailure("auto_request_failed", "system", "none", 3, 0, "none", "No eligible peer found");
|
|
853
491
|
return { status: "no_peer", reason: "No eligible peer found" };
|
|
854
492
|
}
|
|
855
|
-
const
|
|
856
|
-
const
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
const tier = getAutonomyTier(top.cost, this.autonomyConfig);
|
|
493
|
+
const selectedCardId = resolvedTarget.cardId;
|
|
494
|
+
const selectedSkillId = resolvedTarget.skillId;
|
|
495
|
+
const selectedPeer = resolvedTarget.owner;
|
|
496
|
+
const selectedCost = resolvedTarget.credits_per_call;
|
|
497
|
+
const selectedViaRelay = resolvedTarget.via_relay;
|
|
498
|
+
const tier = getAutonomyTier(selectedCost, this.autonomyConfig);
|
|
862
499
|
if (tier === 3) {
|
|
863
500
|
createPendingRequest(this.registryDb, {
|
|
864
501
|
skill_query: need.query,
|
|
865
502
|
max_cost_credits: need.maxCostCredits,
|
|
866
|
-
credits:
|
|
867
|
-
selected_peer:
|
|
868
|
-
selected_card_id:
|
|
869
|
-
selected_skill_id:
|
|
503
|
+
credits: selectedCost,
|
|
504
|
+
selected_peer: selectedPeer,
|
|
505
|
+
selected_card_id: selectedCardId,
|
|
506
|
+
selected_skill_id: selectedSkillId,
|
|
870
507
|
params: need.params
|
|
871
508
|
});
|
|
872
509
|
insertAuditEvent(this.registryDb, {
|
|
873
510
|
type: "auto_request_pending",
|
|
874
|
-
card_id:
|
|
875
|
-
skill_id:
|
|
511
|
+
card_id: selectedCardId,
|
|
512
|
+
skill_id: selectedSkillId ?? selectedCardId,
|
|
876
513
|
tier_invoked: 3,
|
|
877
|
-
credits:
|
|
878
|
-
peer:
|
|
514
|
+
credits: selectedCost,
|
|
515
|
+
peer: selectedPeer
|
|
879
516
|
});
|
|
880
517
|
return {
|
|
881
518
|
status: "tier_blocked",
|
|
882
519
|
reason: "Tier 3: owner approval required",
|
|
883
|
-
peer:
|
|
520
|
+
peer: selectedPeer
|
|
884
521
|
};
|
|
885
522
|
}
|
|
886
|
-
if (!this.budgetManager.canSpend(
|
|
887
|
-
this.logFailure(
|
|
523
|
+
if (!this.budgetManager.canSpend(selectedCost)) {
|
|
524
|
+
this.logFailure(
|
|
525
|
+
"auto_request_failed",
|
|
526
|
+
selectedCardId,
|
|
527
|
+
selectedSkillId ?? "none",
|
|
528
|
+
tier,
|
|
529
|
+
selectedCost,
|
|
530
|
+
selectedPeer,
|
|
531
|
+
"Budget reserve would be breached"
|
|
532
|
+
);
|
|
888
533
|
return { status: "budget_blocked", reason: "Insufficient credits \u2014 reserve floor would be breached" };
|
|
889
534
|
}
|
|
890
|
-
const escrowId = holdEscrow(this.creditDb, this.owner,
|
|
535
|
+
const escrowId = holdEscrow(this.creditDb, this.owner, selectedCost, selectedCardId);
|
|
891
536
|
try {
|
|
892
|
-
const
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
537
|
+
const requestParams = selectedSkillId ? { skill_id: selectedSkillId, ...need.params, requester: this.owner } : { ...need.params, requester: this.owner };
|
|
538
|
+
let execResult;
|
|
539
|
+
if (selectedViaRelay) {
|
|
540
|
+
if (!this.registryUrl) {
|
|
541
|
+
this.logFailure(
|
|
542
|
+
"auto_request_failed",
|
|
543
|
+
selectedCardId,
|
|
544
|
+
selectedSkillId ?? "none",
|
|
545
|
+
tier,
|
|
546
|
+
selectedCost,
|
|
547
|
+
selectedPeer,
|
|
548
|
+
"Relay target found but registryUrl is not configured"
|
|
549
|
+
);
|
|
550
|
+
releaseEscrow(this.creditDb, escrowId);
|
|
551
|
+
return { status: "no_peer", reason: "Relay target found but registryUrl is not configured" };
|
|
552
|
+
}
|
|
553
|
+
const relayRequesterOwner = `${this.owner}:req:${randomUUID4()}`;
|
|
554
|
+
const { RelayClient } = await import("./websocket-client-4Z5P54RU.js");
|
|
555
|
+
const relayClient = new RelayClient({
|
|
556
|
+
registryUrl: this.registryUrl,
|
|
557
|
+
owner: relayRequesterOwner,
|
|
558
|
+
token: "auto-request-token",
|
|
559
|
+
card: {
|
|
560
|
+
spec_version: "1.0",
|
|
561
|
+
id: randomUUID4(),
|
|
562
|
+
owner: relayRequesterOwner,
|
|
563
|
+
name: relayRequesterOwner,
|
|
564
|
+
description: "Auto-request requester",
|
|
565
|
+
level: 1,
|
|
566
|
+
inputs: [],
|
|
567
|
+
outputs: [],
|
|
568
|
+
pricing: { credits_per_call: 1 },
|
|
569
|
+
availability: { online: false }
|
|
570
|
+
},
|
|
571
|
+
onRequest: async () => ({ error: { code: -32601, message: "Auto-request relay requester does not serve capabilities" } }),
|
|
572
|
+
silent: true
|
|
573
|
+
});
|
|
574
|
+
try {
|
|
575
|
+
await relayClient.connect();
|
|
576
|
+
execResult = await requestViaRelay(relayClient, {
|
|
577
|
+
targetOwner: selectedPeer,
|
|
578
|
+
cardId: selectedCardId,
|
|
579
|
+
skillId: selectedSkillId,
|
|
580
|
+
params: requestParams,
|
|
581
|
+
requester: this.owner
|
|
582
|
+
});
|
|
583
|
+
} finally {
|
|
584
|
+
relayClient.disconnect();
|
|
585
|
+
}
|
|
586
|
+
} else {
|
|
587
|
+
const peerConfig = findPeer(selectedPeer);
|
|
588
|
+
if (!peerConfig) {
|
|
589
|
+
this.logFailure(
|
|
590
|
+
"auto_request_failed",
|
|
591
|
+
selectedCardId,
|
|
592
|
+
selectedSkillId ?? "none",
|
|
593
|
+
tier,
|
|
594
|
+
selectedCost,
|
|
595
|
+
selectedPeer,
|
|
596
|
+
"No gateway config for peer"
|
|
597
|
+
);
|
|
598
|
+
releaseEscrow(this.creditDb, escrowId);
|
|
599
|
+
return { status: "no_peer", reason: "No gateway config for peer" };
|
|
600
|
+
}
|
|
601
|
+
execResult = await requestCapability({
|
|
602
|
+
gatewayUrl: peerConfig.url,
|
|
603
|
+
token: peerConfig.token,
|
|
604
|
+
cardId: selectedCardId,
|
|
605
|
+
params: requestParams
|
|
606
|
+
});
|
|
607
|
+
}
|
|
608
|
+
settleEscrow(this.creditDb, escrowId, selectedPeer);
|
|
899
609
|
if (tier === 2) {
|
|
900
610
|
insertAuditEvent(this.registryDb, {
|
|
901
611
|
type: "auto_request_notify",
|
|
902
|
-
card_id:
|
|
903
|
-
skill_id:
|
|
612
|
+
card_id: selectedCardId,
|
|
613
|
+
skill_id: selectedSkillId ?? selectedCardId,
|
|
904
614
|
tier_invoked: 2,
|
|
905
|
-
credits:
|
|
906
|
-
peer:
|
|
615
|
+
credits: selectedCost,
|
|
616
|
+
peer: selectedPeer
|
|
907
617
|
});
|
|
908
618
|
} else {
|
|
909
619
|
insertAuditEvent(this.registryDb, {
|
|
910
620
|
type: "auto_request",
|
|
911
|
-
card_id:
|
|
912
|
-
skill_id:
|
|
621
|
+
card_id: selectedCardId,
|
|
622
|
+
skill_id: selectedSkillId ?? selectedCardId,
|
|
913
623
|
tier_invoked: 1,
|
|
914
|
-
credits:
|
|
915
|
-
peer:
|
|
624
|
+
credits: selectedCost,
|
|
625
|
+
peer: selectedPeer
|
|
916
626
|
});
|
|
917
627
|
}
|
|
918
628
|
return {
|
|
919
629
|
status: "success",
|
|
920
630
|
result: execResult,
|
|
921
631
|
escrowId,
|
|
922
|
-
peer:
|
|
923
|
-
creditsSpent:
|
|
632
|
+
peer: selectedPeer,
|
|
633
|
+
creditsSpent: selectedCost
|
|
924
634
|
};
|
|
925
635
|
} catch (err) {
|
|
926
636
|
releaseEscrow(this.creditDb, escrowId);
|
|
927
637
|
const reason = err instanceof Error ? err.message : String(err);
|
|
928
|
-
this.logFailure(
|
|
638
|
+
this.logFailure(
|
|
639
|
+
"auto_request_failed",
|
|
640
|
+
selectedCardId,
|
|
641
|
+
selectedSkillId ?? "none",
|
|
642
|
+
tier,
|
|
643
|
+
selectedCost,
|
|
644
|
+
selectedPeer,
|
|
645
|
+
`Execution failed: ${reason}`
|
|
646
|
+
);
|
|
929
647
|
return {
|
|
930
648
|
status: "failed",
|
|
931
649
|
reason: `Execution failed: ${reason}`,
|
|
932
|
-
peer:
|
|
650
|
+
peer: selectedPeer
|
|
933
651
|
};
|
|
934
652
|
}
|
|
935
653
|
}
|
|
@@ -1437,19 +1155,11 @@ export {
|
|
|
1437
1155
|
interpolateObject,
|
|
1438
1156
|
validateAndNormalizeSubtasks,
|
|
1439
1157
|
decompose,
|
|
1440
|
-
computeReputation,
|
|
1441
|
-
searchCards,
|
|
1442
|
-
filterCards,
|
|
1443
|
-
buildReputationMap,
|
|
1444
|
-
requestCapability,
|
|
1445
|
-
requestViaRelay,
|
|
1446
1158
|
DEFAULT_AUTONOMY_CONFIG,
|
|
1447
1159
|
getAutonomyTier,
|
|
1448
1160
|
insertAuditEvent,
|
|
1449
1161
|
listPendingRequests,
|
|
1450
1162
|
resolvePendingRequest,
|
|
1451
|
-
fetchRemoteCards,
|
|
1452
|
-
mergeResults,
|
|
1453
1163
|
AutoRequestor,
|
|
1454
1164
|
matchSubTasks,
|
|
1455
1165
|
ORCHESTRATION_FEE,
|