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.
Files changed (34) hide show
  1. package/dist/{chunk-7Q2XUXSA.js → chunk-4IPJJRTP.js} +1 -1
  2. package/dist/{chunk-EZVOG7QS.js → chunk-CKOOVZOI.js} +15 -18
  3. package/dist/chunk-CQFBNTGT.js +145 -0
  4. package/dist/{chunk-WKWJWKX7.js → chunk-DYQOFGGI.js} +155 -445
  5. package/dist/{chunk-NP55V7RQ.js → chunk-EG6RS4JC.js} +70 -46
  6. package/dist/{chunk-KBQNTUTN.js → chunk-LKLKYXLV.js} +1 -1
  7. package/dist/{chunk-STJLWMXH.js → chunk-MCED4GDW.js} +467 -98
  8. package/dist/{chunk-GWMMYVLL.js → chunk-MWOXW7JQ.js} +7 -7
  9. package/dist/{chunk-GJETGML6.js → chunk-QCGIG7WW.js} +4 -6
  10. package/dist/{chunk-UYCD3JBZ.js → chunk-QHZGOG3O.js} +148 -46
  11. package/dist/{chunk-JLNHMNES.js → chunk-RYISHSHB.js} +286 -1
  12. package/dist/{chunk-SRBVKO2V.js → chunk-S3V6R3EN.js} +66 -39
  13. package/dist/{chunk-RBXTWWUH.js → chunk-WNXXLCV5.js} +1 -1
  14. package/dist/{chunk-LOUEJI6X.js → chunk-XBGVQMQJ.js} +71 -47
  15. package/dist/{chunk-DEWY7OQK.js → chunk-Z2GEFFDO.js} +1 -1
  16. package/dist/cli/index.js +25 -28
  17. package/dist/{client-66TFS7RS.js → client-XOLP5IUZ.js} +1 -1
  18. package/dist/{conduct-A6COHLHY.js → conduct-AZFLNUX3.js} +9 -10
  19. package/dist/{conduct-IUVAXUAV.js → conduct-VPUYTNEA.js} +9 -10
  20. package/dist/{conductor-mode-L2MB44BW.js → conductor-mode-PLTB6MS3.js} +6 -7
  21. package/dist/{conductor-mode-D5TFQW5L.js → conductor-mode-WKB42PYM.js} +6 -3
  22. package/dist/{execute-WOS457HW.js → execute-NNDCXTN4.js} +3 -2
  23. package/dist/{execute-5AWLARB5.js → execute-RIRHTIBU.js} +5 -4
  24. package/dist/index.d.ts +5069 -0
  25. package/dist/index.js +208 -610
  26. package/dist/{publish-capability-JJCBBMSX.js → publish-capability-QDR2QIZ2.js} +2 -2
  27. package/dist/{request-6YQLA7K3.js → request-NX7GSPIG.js} +30 -40
  28. package/dist/{serve-skill-X7TZSILV.js → serve-skill-E6EJQYAK.js} +9 -8
  29. package/dist/{server-5TSP4DBX.js → server-VBCT32FC.js} +10 -14
  30. package/dist/{service-coordinator-WTUSMPY6.js → service-coordinator-KMSA6BST.js} +77 -32
  31. package/dist/skills/agentbnb/bootstrap.js +113 -69
  32. package/package.json +1 -1
  33. package/dist/chunk-BZOJ7HBT.js +0 -170
  34. 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
- settleEscrow,
10
- signEscrowReceipt
11
- } from "./chunk-STJLWMXH.js";
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/gateway/client.ts
260
- import { randomUUID as randomUUID2 } from "crypto";
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 randomUUID3 } from "crypto";
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
- randomUUID3(),
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 randomUUID4 } from "crypto";
305
+ import { randomUUID as randomUUID3 } from "crypto";
606
306
  function createPendingRequest(db, opts) {
607
- const id = randomUUID4();
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 top = scored[0];
856
- const peerConfig = findPeer(top.card.owner);
857
- if (!peerConfig) {
858
- this.logFailure("auto_request_failed", top.card.id, top.skillId ?? "none", 3, top.cost, top.card.owner, "No gateway config for peer");
859
- return { status: "no_peer", reason: "No gateway config for peer" };
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: top.cost,
867
- selected_peer: top.card.owner,
868
- selected_card_id: top.card.id,
869
- selected_skill_id: top.skillId,
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: top.card.id,
875
- skill_id: top.skillId ?? top.card.id,
511
+ card_id: selectedCardId,
512
+ skill_id: selectedSkillId ?? selectedCardId,
876
513
  tier_invoked: 3,
877
- credits: top.cost,
878
- peer: top.card.owner
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: top.card.owner
520
+ peer: selectedPeer
884
521
  };
885
522
  }
886
- if (!this.budgetManager.canSpend(top.cost)) {
887
- this.logFailure("auto_request_failed", top.card.id, top.skillId ?? "none", tier, top.cost, top.card.owner, "Budget reserve would be breached");
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, top.cost, top.card.id);
535
+ const escrowId = holdEscrow(this.creditDb, this.owner, selectedCost, selectedCardId);
891
536
  try {
892
- const execResult = await requestCapability({
893
- gatewayUrl: peerConfig.url,
894
- token: peerConfig.token,
895
- cardId: top.card.id,
896
- params: top.skillId ? { skill_id: top.skillId, ...need.params, requester: this.owner } : { ...need.params, requester: this.owner }
897
- });
898
- settleEscrow(this.creditDb, escrowId, top.card.owner);
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: top.card.id,
903
- skill_id: top.skillId ?? top.card.id,
612
+ card_id: selectedCardId,
613
+ skill_id: selectedSkillId ?? selectedCardId,
904
614
  tier_invoked: 2,
905
- credits: top.cost,
906
- peer: top.card.owner
615
+ credits: selectedCost,
616
+ peer: selectedPeer
907
617
  });
908
618
  } else {
909
619
  insertAuditEvent(this.registryDb, {
910
620
  type: "auto_request",
911
- card_id: top.card.id,
912
- skill_id: top.skillId ?? top.card.id,
621
+ card_id: selectedCardId,
622
+ skill_id: selectedSkillId ?? selectedCardId,
913
623
  tier_invoked: 1,
914
- credits: top.cost,
915
- peer: top.card.owner
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: top.card.owner,
923
- creditsSpent: top.cost
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("auto_request_failed", top.card.id, top.skillId ?? "none", tier, top.cost, top.card.owner, `Execution failed: ${reason}`);
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: top.card.owner
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,