agentbnb 8.2.2 → 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 +211 -278
  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-NX7GSPIG.js → request-KJNKR27T.js} +96 -43
  46. package/dist/{serve-skill-E6EJQYAK.js → serve-skill-GC6NIQ5T.js} +10 -11
  47. package/dist/{server-VBCT32FC.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 +550 -231
  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 +18 -12
  54. package/skills/agentbnb/install.sh +0 -0
  55. package/dist/chunk-MCED4GDW.js +0 -1572
  56. package/dist/chunk-NWIQJ2CL.js +0 -108
  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
package/dist/cli/index.js CHANGED
@@ -7,50 +7,44 @@ import {
7
7
  discoverLocalAgents,
8
8
  getPricingStats,
9
9
  resolveSelfCli
10
- } from "../chunk-Z2GEFFDO.js";
10
+ } from "../chunk-O4Q7BRG6.js";
11
11
  import {
12
12
  createLedger,
13
13
  ensureIdentity,
14
14
  loadOrRepairIdentity
15
- } from "../chunk-LKLKYXLV.js";
16
- import {
17
- releaseRequesterEscrow,
18
- settleRequesterEscrow
19
- } from "../chunk-WNXXLCV5.js";
15
+ } from "../chunk-74LZDEDT.js";
20
16
  import {
21
17
  AutoRequestor,
22
18
  BudgetManager,
23
- DEFAULT_BUDGET_CONFIG
24
- } from "../chunk-QHZGOG3O.js";
19
+ DEFAULT_BUDGET_CONFIG,
20
+ requestViaTemporaryRelay
21
+ } from "../chunk-D242QZCR.js";
25
22
  import {
26
23
  DEFAULT_AUTONOMY_CONFIG
27
- } from "../chunk-GKVTD4EZ.js";
28
- import "../chunk-CQFBNTGT.js";
24
+ } from "../chunk-77KGEDH4.js";
25
+ import "../chunk-S7DZHKCG.js";
29
26
  import {
30
27
  bootstrapAgent,
31
- createAgentRecord,
32
28
  fetchRemoteCards,
33
29
  filterCards,
34
30
  getBalance,
35
31
  getTransactions,
36
- holdEscrow,
37
- lookupAgent,
38
- lookupAgentByOwner,
39
32
  mergeResults,
40
33
  migrateOwner,
41
34
  openCreditDb,
42
35
  searchCards
43
- } from "../chunk-RYISHSHB.js";
44
- import "../chunk-NWIQJ2CL.js";
36
+ } from "../chunk-F3KIEVJ2.js";
37
+ import "../chunk-NX27AFPA.js";
38
+ import "../chunk-PQIP7EXY.js";
45
39
  import {
46
40
  requestCapability
47
- } from "../chunk-CKOOVZOI.js";
41
+ } from "../chunk-YKMBFQC2.js";
48
42
  import {
49
43
  generateKeyPair,
50
44
  loadKeyPair,
51
- saveKeyPair,
52
- signEscrowReceipt
53
- } from "../chunk-EJKW57ZV.js";
45
+ saveKeyPair
46
+ } from "../chunk-GIEJVKZZ.js";
47
+ import "../chunk-U6LP4KWN.js";
54
48
  import {
55
49
  findPeer,
56
50
  loadPeers,
@@ -64,64 +58,37 @@ import {
64
58
  } from "../chunk-75OC6E4F.js";
65
59
  import {
66
60
  parseSoulMd
67
- } from "../chunk-4IPJJRTP.js";
61
+ } from "../chunk-IGQNP3ZO.js";
68
62
  import {
63
+ attachCanonicalAgentId,
69
64
  deleteCard,
70
65
  getCard,
71
66
  insertCard,
72
67
  listCards,
73
68
  openDatabase
74
- } from "../chunk-S3V6R3EN.js";
69
+ } from "../chunk-5AIYALBX.js";
70
+ import {
71
+ createAgentRecord,
72
+ lookupAgent,
73
+ lookupAgentByOwner,
74
+ updateAgentRecord
75
+ } from "../chunk-WTHMHNKC.js";
75
76
  import {
76
77
  AgentBnBError,
77
78
  AnyCardSchema,
78
79
  CapabilityCardV2Schema
79
- } from "../chunk-WVY2W7AA.js";
80
+ } from "../chunk-I7KWA7OB.js";
80
81
 
81
82
  // src/cli/index.ts
82
83
  import { Command } from "commander";
83
84
  import { readFileSync as readFileSync4 } from "fs";
84
- import { randomUUID as randomUUID4 } from "crypto";
85
+ import { randomUUID as randomUUID3 } from "crypto";
85
86
  import { join as join4 } from "path";
86
87
  import { networkInterfaces as networkInterfaces2 } from "os";
87
88
  import { createInterface as createInterface3 } from "readline";
88
89
 
89
- // src/credit/escrow-receipt.ts
90
- import { z } from "zod";
91
- import { randomUUID } from "crypto";
92
- var EscrowReceiptSchema = z.object({
93
- requester_owner: z.string().min(1),
94
- requester_agent_id: z.string().optional(),
95
- requester_public_key: z.string().min(1),
96
- amount: z.number().positive(),
97
- card_id: z.string().min(1),
98
- skill_id: z.string().optional(),
99
- timestamp: z.string(),
100
- nonce: z.string().uuid(),
101
- signature: z.string().min(1)
102
- });
103
- function createSignedEscrowReceipt(db, privateKey, publicKey, opts) {
104
- const escrowId = holdEscrow(db, opts.owner, opts.amount, opts.cardId);
105
- const receiptData = {
106
- requester_owner: opts.owner,
107
- ...opts.agent_id ? { requester_agent_id: opts.agent_id } : {},
108
- requester_public_key: publicKey.toString("hex"),
109
- amount: opts.amount,
110
- card_id: opts.cardId,
111
- ...opts.skillId ? { skill_id: opts.skillId } : {},
112
- timestamp: (/* @__PURE__ */ new Date()).toISOString(),
113
- nonce: randomUUID()
114
- };
115
- const signature = signEscrowReceipt(receiptData, privateKey);
116
- const receipt = {
117
- ...receiptData,
118
- signature
119
- };
120
- return { escrowId, receipt };
121
- }
122
-
123
90
  // src/openclaw/soul-sync.ts
124
- import { randomUUID as randomUUID2 } from "crypto";
91
+ import { randomUUID } from "crypto";
125
92
  var SKILL_META_GLOBAL_RE = /(?:^|\s)-\s*(capability_types|requires(?:_capabilities)?|visibility)\s*:\s*([^-][^]*?)(?=\s+-\s+(?:capability_types|requires(?:_capabilities)?|visibility)\s*:|$)/gi;
126
93
  function extractSkillMeta(raw) {
127
94
  let capability_types;
@@ -156,7 +123,7 @@ function parseSoulMdV2(content) {
156
123
  const parsed = parseSoulMd(content);
157
124
  const skills = parsed.capabilities.map((cap) => {
158
125
  const sanitizedId = cap.name.toLowerCase().replace(/\s+/g, "-").replace(/[^a-z0-9-]/g, "");
159
- const id = sanitizedId.length > 0 ? sanitizedId : randomUUID2();
126
+ const id = sanitizedId.length > 0 ? sanitizedId : randomUUID();
160
127
  const { description: cleanDesc, capability_types, requires_capabilities, visibility } = extractSkillMeta(cap.description);
161
128
  const finalDescription = (cleanDesc || cap.name).slice(0, 500);
162
129
  const skill = {
@@ -210,7 +177,7 @@ function publishFromSoulV2(db, soulContent, owner, sharedSkills) {
210
177
  (c) => c.spec_version === "2.0"
211
178
  );
212
179
  const now = (/* @__PURE__ */ new Date()).toISOString();
213
- const cardId = existingV2?.id ?? randomUUID2();
180
+ const cardId = existingV2?.id ?? randomUUID();
214
181
  const card = {
215
182
  spec_version: "2.0",
216
183
  id: cardId,
@@ -221,17 +188,18 @@ function publishFromSoulV2(db, soulContent, owner, sharedSkills) {
221
188
  created_at: existingV2?.created_at ?? now,
222
189
  updated_at: now
223
190
  };
224
- CapabilityCardV2Schema.parse(card);
191
+ const storedCard = attachCanonicalAgentId(db, card);
192
+ CapabilityCardV2Schema.parse(storedCard);
225
193
  if (existingV2) {
226
194
  db.prepare(
227
195
  "UPDATE capability_cards SET data = ?, updated_at = ? WHERE id = ?"
228
- ).run(JSON.stringify(card), now, cardId);
196
+ ).run(JSON.stringify(storedCard), now, cardId);
229
197
  } else {
230
198
  db.prepare(
231
199
  "INSERT INTO capability_cards (id, owner, data, created_at, updated_at) VALUES (?, ?, ?, ?, ?)"
232
- ).run(cardId, owner, JSON.stringify(card), now, now);
200
+ ).run(cardId, storedCard.owner, JSON.stringify(storedCard), now, now);
233
201
  }
234
- return card;
202
+ return storedCard;
235
203
  }
236
204
 
237
205
  // src/openclaw/heartbeat-writer.ts
@@ -326,7 +294,7 @@ import { join as join2 } from "path";
326
294
  import { networkInterfaces } from "os";
327
295
 
328
296
  // src/onboarding/index.ts
329
- import { randomUUID as randomUUID3 } from "crypto";
297
+ import { randomUUID as randomUUID2 } from "crypto";
330
298
  import { existsSync as existsSync2, readFileSync as readFileSync2 } from "fs";
331
299
  import { join } from "path";
332
300
 
@@ -489,7 +457,7 @@ function capabilitiesToV2Card(capabilities, owner, agentName) {
489
457
  }));
490
458
  const card = {
491
459
  spec_version: "2.0",
492
- id: randomUUID3(),
460
+ id: randomUUID2(),
493
461
  owner,
494
462
  agent_name: agentName ?? owner,
495
463
  skills,
@@ -532,6 +500,28 @@ function loadIdentityAuth(owner) {
532
500
  privateKey: keys.privateKey
533
501
  };
534
502
  }
503
+ function syncAgentRecord(db, identity, owner, displayName) {
504
+ const existingAgent = lookupAgent(db, identity.agent_id) ?? lookupAgentByOwner(db, owner);
505
+ if (!existingAgent) {
506
+ createAgentRecord(db, {
507
+ agent_id: identity.agent_id,
508
+ display_name: displayName,
509
+ public_key: identity.public_key,
510
+ legacy_owner: owner
511
+ });
512
+ return;
513
+ }
514
+ const updates = {};
515
+ if (existingAgent.display_name !== displayName) {
516
+ updates.display_name = displayName;
517
+ }
518
+ if (existingAgent.legacy_owner !== owner) {
519
+ updates.legacy_owner = owner;
520
+ }
521
+ if (Object.keys(updates).length > 0) {
522
+ updateAgentRecord(db, existingAgent.agent_id, updates);
523
+ }
524
+ }
535
525
  async function performInit(opts) {
536
526
  const configDir = getConfigDir();
537
527
  const dbPath = join2(configDir, "registry.db");
@@ -557,24 +547,25 @@ async function performInit(opts) {
557
547
  const identity = identityMaterial.identity;
558
548
  const keypairStatus = identityMaterial.status === "generated" ? "generated" : "existing";
559
549
  const creditDb = openCreditDb(creditDbPath);
550
+ const registryDb = openDatabase(dbPath);
551
+ syncAgentRecord(creditDb, identity, owner, config.display_name ?? owner);
552
+ syncAgentRecord(registryDb, identity, owner, config.display_name ?? owner);
560
553
  if (existingConfig?.owner && existingConfig.owner !== owner) {
561
554
  migrateOwner(creditDb, existingConfig.owner, owner);
562
- const regDb = openDatabase(dbPath);
563
- try {
564
- const rows = regDb.prepare("SELECT id, owner, data FROM capability_cards WHERE owner != ?").all(owner);
565
- for (const row of rows) {
566
- try {
567
- const card = JSON.parse(row.data);
568
- card.owner = owner;
569
- regDb.prepare("UPDATE capability_cards SET owner = ?, data = ? WHERE id = ?").run(owner, JSON.stringify(card), row.id);
570
- } catch {
571
- }
572
- }
573
- if (!opts.json && rows.length > 0) {
574
- console.log(`Migrated ${rows.length} card(s) \u2192 ${owner}`);
555
+ const rows = registryDb.prepare("SELECT id, owner, data FROM capability_cards WHERE owner = ?").all(existingConfig.owner);
556
+ for (const row of rows) {
557
+ try {
558
+ const card = JSON.parse(row.data);
559
+ const updatedCard = attachCanonicalAgentId(registryDb, {
560
+ ...card,
561
+ owner
562
+ });
563
+ registryDb.prepare("UPDATE capability_cards SET owner = ?, data = ? WHERE id = ?").run(owner, JSON.stringify(updatedCard), row.id);
564
+ } catch {
575
565
  }
576
- } finally {
577
- regDb.close();
566
+ }
567
+ if (!opts.json && rows.length > 0) {
568
+ console.log(`Migrated ${rows.length} card(s) \u2192 ${owner}`);
578
569
  }
579
570
  const allOwners = creditDb.prepare("SELECT owner FROM credit_balances WHERE owner != ?").all(owner);
580
571
  for (const { owner: oldOwner } of allOwners) {
@@ -602,23 +593,12 @@ async function performInit(opts) {
602
593
  console.log(`Migrated local credits: ${existingConfig.owner} \u2192 ${owner}`);
603
594
  }
604
595
  }
605
- const existingAgent = lookupAgent(creditDb, identity.agent_id) ?? lookupAgentByOwner(creditDb, owner);
606
- if (!existingAgent) {
607
- try {
608
- createAgentRecord(creditDb, {
609
- agent_id: identity.agent_id,
610
- display_name: config.display_name ?? owner,
611
- public_key: identity.public_key,
612
- legacy_owner: owner
613
- });
614
- } catch {
615
- }
616
- }
617
596
  if (!config.agent_id || config.agent_id !== identity.agent_id) {
618
597
  config.agent_id = identity.agent_id;
619
598
  saveConfig(config);
620
599
  }
621
- bootstrapAgent(creditDb, owner, 100);
600
+ bootstrapAgent(creditDb, identity.agent_id, 100);
601
+ registryDb.close();
622
602
  creditDb.close();
623
603
  let registryBalance;
624
604
  if (config.registry) {
@@ -669,13 +649,20 @@ async function performInit(opts) {
669
649
  if (yesMode) {
670
650
  const db = openDatabase(dbPath);
671
651
  try {
652
+ const storedCard = attachCanonicalAgentId(db, card);
672
653
  db.prepare(
673
654
  `INSERT OR REPLACE INTO capability_cards (id, owner, data, created_at, updated_at)
674
655
  VALUES (?, ?, ?, ?, ?)`
675
- ).run(card.id, card.owner, JSON.stringify(card), card.created_at, card.updated_at);
676
- publishedCards.push({ id: card.id, name: card.agent_name });
656
+ ).run(
657
+ storedCard.id,
658
+ storedCard.owner,
659
+ JSON.stringify(storedCard),
660
+ storedCard.created_at,
661
+ storedCard.updated_at
662
+ );
663
+ publishedCards.push({ id: storedCard.id, name: storedCard.agent_name });
677
664
  if (!opts.json) {
678
- console.log(` Published v2.0 card: ${card.agent_name} (${card.skills.length} skills)`);
665
+ console.log(` Published v2.0 card: ${storedCard.agent_name} (${storedCard.skills.length} skills)`);
679
666
  }
680
667
  } finally {
681
668
  db.close();
@@ -686,12 +673,19 @@ Publish these ${card.skills.length} capabilities? [y/N] `);
686
673
  if (yes) {
687
674
  const db = openDatabase(dbPath);
688
675
  try {
676
+ const storedCard = attachCanonicalAgentId(db, card);
689
677
  db.prepare(
690
678
  `INSERT OR REPLACE INTO capability_cards (id, owner, data, created_at, updated_at)
691
679
  VALUES (?, ?, ?, ?, ?)`
692
- ).run(card.id, card.owner, JSON.stringify(card), card.created_at, card.updated_at);
693
- publishedCards.push({ id: card.id, name: card.agent_name });
694
- console.log(` Published v2.0 card: ${card.agent_name} (${card.skills.length} skills)`);
680
+ ).run(
681
+ storedCard.id,
682
+ storedCard.owner,
683
+ JSON.stringify(storedCard),
684
+ storedCard.created_at,
685
+ storedCard.updated_at
686
+ );
687
+ publishedCards.push({ id: storedCard.id, name: storedCard.agent_name });
688
+ console.log(` Published v2.0 card: ${storedCard.agent_name} (${storedCard.skills.length} skills)`);
695
689
  } finally {
696
690
  db.close();
697
691
  }
@@ -754,13 +748,20 @@ Publish these ${card.skills.length} capabilities? [y/N] `);
754
748
  const card = capabilitiesToV2Card(selected, owner);
755
749
  const db = openDatabase(dbPath);
756
750
  try {
751
+ const storedCard = attachCanonicalAgentId(db, card);
757
752
  db.prepare(
758
753
  `INSERT OR REPLACE INTO capability_cards (id, owner, data, created_at, updated_at)
759
754
  VALUES (?, ?, ?, ?, ?)`
760
- ).run(card.id, card.owner, JSON.stringify(card), card.created_at, card.updated_at);
761
- publishedCards.push({ id: card.id, name: card.agent_name });
755
+ ).run(
756
+ storedCard.id,
757
+ storedCard.owner,
758
+ JSON.stringify(storedCard),
759
+ storedCard.created_at,
760
+ storedCard.updated_at
761
+ );
762
+ publishedCards.push({ id: storedCard.id, name: storedCard.agent_name });
762
763
  console.log(`
763
- Published v2.0 card: ${card.agent_name} (${card.skills.length} skills)`);
764
+ Published v2.0 card: ${storedCard.agent_name} (${storedCard.skills.length} skills)`);
764
765
  } finally {
765
766
  db.close();
766
767
  }
@@ -918,8 +919,8 @@ Skills: ${skills.skillCount} skill(s) in ${skills.path}`);
918
919
  let daemonStatus = { running: false, reason: "skipped" };
919
920
  if (!skipServe) {
920
921
  try {
921
- const { ProcessGuard } = await import("../process-guard-GH5LRNWO.js");
922
- const { ServiceCoordinator } = await import("../service-coordinator-KMSA6BST.js");
922
+ const { ProcessGuard } = await import("../process-guard-TNSUNHSR.js");
923
+ const { ServiceCoordinator } = await import("../service-coordinator-RY5AKUZS.js");
923
924
  const guard = new ProcessGuard(join3(initResult.configDir, ".pid"));
924
925
  const coordinator = new ServiceCoordinator(initResult.config, guard);
925
926
  const result = await coordinator.ensureRunning({
@@ -981,7 +982,7 @@ Skills: ${skills.skillCount} skill(s) in ${skills.path}`);
981
982
  }
982
983
 
983
984
  // src/cli/index.ts
984
- var VERSION = "8.2.2";
985
+ var VERSION = true ? "8.3.0" : "0.0.0-dev";
985
986
  function loadIdentityAuth2(owner) {
986
987
  const configDir = getConfigDir();
987
988
  let keys;
@@ -998,6 +999,32 @@ function loadIdentityAuth2(owner) {
998
999
  privateKey: keys.privateKey
999
1000
  };
1000
1001
  }
1002
+ function parsePositiveNumber(value) {
1003
+ return typeof value === "number" && value > 0 ? value : void 0;
1004
+ }
1005
+ function buildTimeoutHintFromCard(card, skillId) {
1006
+ const cardHint = {
1007
+ expected_duration_ms: parsePositiveNumber(card["expected_duration_ms"]),
1008
+ hard_timeout_ms: parsePositiveNumber(card["hard_timeout_ms"])
1009
+ };
1010
+ const skills = card["skills"];
1011
+ if (!Array.isArray(skills)) {
1012
+ return cardHint.expected_duration_ms !== void 0 || cardHint.hard_timeout_ms !== void 0 ? cardHint : void 0;
1013
+ }
1014
+ const selected = skillId ? skills.find((candidate) => {
1015
+ if (!candidate || typeof candidate !== "object") return false;
1016
+ return candidate["id"] === skillId;
1017
+ }) : skills[0];
1018
+ if (!selected || typeof selected !== "object") {
1019
+ return cardHint.expected_duration_ms !== void 0 || cardHint.hard_timeout_ms !== void 0 ? cardHint : void 0;
1020
+ }
1021
+ const selectedRecord = selected;
1022
+ const hint = {
1023
+ expected_duration_ms: parsePositiveNumber(selectedRecord["expected_duration_ms"]) ?? cardHint.expected_duration_ms,
1024
+ hard_timeout_ms: parsePositiveNumber(selectedRecord["hard_timeout_ms"]) ?? cardHint.hard_timeout_ms
1025
+ };
1026
+ return hint.expected_duration_ms !== void 0 || hint.hard_timeout_ms !== void 0 ? hint : void 0;
1027
+ }
1001
1028
  function getLanIp2() {
1002
1029
  const nets = networkInterfaces2();
1003
1030
  for (const ifaces of Object.values(nets)) {
@@ -1105,15 +1132,22 @@ program.command("publish <card.json>").description("Publish a Capability Card to
1105
1132
  }
1106
1133
  }
1107
1134
  const db = openDatabase(config.db_path);
1135
+ let localCard = card;
1108
1136
  try {
1109
1137
  if (card.spec_version === "2.0") {
1110
1138
  const now = (/* @__PURE__ */ new Date()).toISOString();
1111
- const cardWithTimestamps = { ...card, created_at: card.created_at ?? now, updated_at: now };
1139
+ const cardWithTimestamps = attachCanonicalAgentId(db, {
1140
+ ...card,
1141
+ created_at: card.created_at ?? now,
1142
+ updated_at: now
1143
+ });
1112
1144
  db.prepare(
1113
1145
  "INSERT OR REPLACE INTO capability_cards (id, owner, data, created_at, updated_at) VALUES (?, ?, ?, ?, ?)"
1114
1146
  ).run(cardWithTimestamps.id, cardWithTimestamps.owner, JSON.stringify(cardWithTimestamps), cardWithTimestamps.created_at, cardWithTimestamps.updated_at);
1147
+ localCard = cardWithTimestamps;
1115
1148
  } else {
1116
1149
  insertCard(db, card);
1150
+ localCard = attachCanonicalAgentId(db, card);
1117
1151
  }
1118
1152
  } finally {
1119
1153
  db.close();
@@ -1125,7 +1159,7 @@ program.command("publish <card.json>").description("Publish a Capability Card to
1125
1159
  let remoteSuccess = false;
1126
1160
  if (registryUrl) {
1127
1161
  const url = `${registryUrl.replace(/\/$/, "")}/cards`;
1128
- const remoteCard = { ...card, gateway_url: config.gateway_url };
1162
+ const remoteCard = config.agent_id && localCard.owner === config.owner && localCard.agent_id !== config.agent_id ? { ...localCard, agent_id: config.agent_id, gateway_url: config.gateway_url } : { ...localCard, gateway_url: config.gateway_url };
1129
1163
  try {
1130
1164
  const response = await fetch(url, {
1131
1165
  method: "POST",
@@ -1161,8 +1195,8 @@ program.command("publish-skills").description("Publish capabilities from skills.
1161
1195
  console.error("Error: not initialized. Run `agentbnb init` first.");
1162
1196
  process.exit(1);
1163
1197
  }
1164
- const { parseSkillsFile } = await import("../skill-config-FETXPNVP.js");
1165
- const { skillConfigToSkill } = await import("../publish-capability-QDR2QIZ2.js");
1198
+ const { parseSkillsFile } = await import("../skill-config-5O2VR546.js");
1199
+ const { skillConfigToSkill } = await import("../publish-capability-HVYILTPR.js");
1166
1200
  const skillsPath = typeof opts.fromSkills === "string" ? opts.fromSkills : "./skills.yaml";
1167
1201
  let yamlContent;
1168
1202
  try {
@@ -1190,8 +1224,9 @@ program.command("publish-skills").description("Publish capabilities from skills.
1190
1224
  const now = (/* @__PURE__ */ new Date()).toISOString();
1191
1225
  const card = {
1192
1226
  spec_version: "2.0",
1193
- id: randomUUID4(),
1227
+ id: randomUUID3(),
1194
1228
  owner: config.owner,
1229
+ agent_id: config.agent_id,
1195
1230
  agent_name: config.owner,
1196
1231
  skills,
1197
1232
  availability: { online: true },
@@ -1200,9 +1235,10 @@ program.command("publish-skills").description("Publish capabilities from skills.
1200
1235
  };
1201
1236
  const db = openDatabase(config.db_path);
1202
1237
  try {
1238
+ const storedCard = attachCanonicalAgentId(db, card);
1203
1239
  db.prepare(
1204
1240
  "INSERT OR REPLACE INTO capability_cards (id, owner, data, created_at, updated_at) VALUES (?, ?, ?, ?, ?)"
1205
- ).run(card.id, card.owner, JSON.stringify(card), now, now);
1241
+ ).run(storedCard.id, storedCard.owner, JSON.stringify(storedCard), now, now);
1206
1242
  } finally {
1207
1243
  db.close();
1208
1244
  }
@@ -1399,7 +1435,7 @@ ${discovered.length} agent(s) found on local network`);
1399
1435
  console.log(`
1400
1436
  ${outputCards.length} result(s)`);
1401
1437
  });
1402
- program.command("request [card-id]").description("Request a capability from another agent \u2014 direct (card-id) or auto (--query)").option("--params <json>", "Input parameters as JSON string", "{}").option("--peer <name>", "Peer name to send request to (resolves URL+token from peer registry)").option("--skill <id>", "Skill ID within a v2.0 card").option("--cost <credits>", "Credits to commit (required for cross-machine peer requests)").option("--query <text>", "Search query for capability gap (triggers auto-request flow)").option("--max-cost <credits>", "Maximum credits to spend on auto-request (default: 50)").option("--no-receipt", "Skip signed escrow receipt (local-only mode)").option("--batch <file>", "Path to JSON file with batch request payload { requests, strategy, total_budget }").option("--json", "Output as JSON").action(async (cardId, opts) => {
1438
+ program.command("request [card-id]").description("Request a capability from another agent \u2014 direct (card-id) or auto (--query)").option("--params <json>", "Input parameters as JSON string", "{}").option("--peer <name>", "Peer name to send request to (resolves URL+token from peer registry)").option("--skill <id>", "Skill ID within a v2.0 card").option("--cost <credits>", "Credits to commit (required for cross-machine peer requests)").option("--query <text>", "Search query for capability gap (triggers auto-request flow)").option("--max-cost <credits>", "Maximum credits to spend on auto-request (default: 50)").option("--timeout <ms>", "Request timeout override in milliseconds").option("--no-receipt", "Skip signed escrow receipt (local-only mode)").option("--batch <file>", "Path to JSON file with batch request payload { requests, strategy, total_budget }").option("--json", "Output as JSON").action(async (cardId, opts) => {
1403
1439
  const config = loadConfig();
1404
1440
  if (!config) {
1405
1441
  console.error("Error: not initialized. Run `agentbnb init` first.");
@@ -1511,10 +1547,20 @@ Batch Results (${res.results.length} items):`);
1511
1547
  console.error("Error: --params must be valid JSON.");
1512
1548
  process.exit(1);
1513
1549
  }
1550
+ let timeoutOverrideMs;
1551
+ if (opts.timeout !== void 0) {
1552
+ timeoutOverrideMs = Number(opts.timeout);
1553
+ if (!Number.isFinite(timeoutOverrideMs) || timeoutOverrideMs <= 0) {
1554
+ console.error("Error: --timeout <ms> must be a positive number.");
1555
+ process.exit(1);
1556
+ }
1557
+ }
1514
1558
  let gatewayUrl;
1515
1559
  let token;
1516
1560
  let isRemoteRequest = false;
1517
1561
  let targetOwner;
1562
+ let targetAgentId;
1563
+ let timeoutHint;
1518
1564
  const identityAuth = loadIdentityAuth2(config.owner);
1519
1565
  if (opts.peer) {
1520
1566
  const peer = findPeer(opts.peer);
@@ -1537,6 +1583,7 @@ Batch Results (${res.results.length} items):`);
1537
1583
  if (localCard && localCard.owner === config.owner) {
1538
1584
  gatewayUrl = config.gateway_url;
1539
1585
  token = config.token;
1586
+ timeoutHint = buildTimeoutHintFromCard(localCard, opts.skill);
1540
1587
  } else {
1541
1588
  const registryUrl = config.registry;
1542
1589
  if (!registryUrl) {
@@ -1558,6 +1605,8 @@ Batch Results (${res.results.length} items):`);
1558
1605
  process.exit(1);
1559
1606
  }
1560
1607
  targetOwner = remoteCard.owner ?? remoteCard.agent_name;
1608
+ targetAgentId = typeof remoteCard.agent_id === "string" ? remoteCard.agent_id : void 0;
1609
+ timeoutHint = buildTimeoutHintFromCard(remoteCard, opts.skill);
1561
1610
  if (remoteCard.gateway_url && typeof remoteCard.gateway_url === "string") {
1562
1611
  gatewayUrl = remoteCard.gateway_url;
1563
1612
  } else if (targetOwner && config.registry) {
@@ -1578,110 +1627,6 @@ Batch Results (${res.results.length} items):`);
1578
1627
  }
1579
1628
  }
1580
1629
  }
1581
- const useReceipt = isRemoteRequest && opts.receipt !== false;
1582
- const isRelayOnly = isRemoteRequest && !gatewayUrl;
1583
- const useRegistryLedger = false;
1584
- if (useReceipt && !opts.cost && !isRelayOnly) {
1585
- console.error("Error: --cost <credits> is required for remote requests. Specify the credits to commit.");
1586
- process.exit(1);
1587
- }
1588
- let escrowId;
1589
- let escrowReceipt;
1590
- let requestLedger;
1591
- if (useReceipt) {
1592
- const amount = Number(opts.cost);
1593
- if (isNaN(amount) || amount <= 0) {
1594
- console.error("Error: --cost must be a positive number.");
1595
- process.exit(1);
1596
- }
1597
- if (useRegistryLedger) {
1598
- const reqIdentityAuth = loadIdentityAuth2(config.owner);
1599
- requestLedger = createLedger({
1600
- registryUrl: config.registry,
1601
- ownerPublicKey: reqIdentityAuth.publicKey,
1602
- privateKey: reqIdentityAuth.privateKey
1603
- });
1604
- try {
1605
- const { escrowId: heldId } = await requestLedger.hold(config.owner, amount, cardId);
1606
- escrowId = heldId;
1607
- if (!opts.json) {
1608
- console.log(`Escrow: ${amount} credits held via Registry (ID: ${escrowId.slice(0, 8)}...)`);
1609
- }
1610
- } catch (err) {
1611
- const msg = err instanceof Error ? err.message : String(err);
1612
- if (opts.json) {
1613
- console.log(JSON.stringify({ success: false, error: msg }, null, 2));
1614
- } else {
1615
- console.error(`Error creating escrow via Registry: ${msg}`);
1616
- }
1617
- process.exit(1);
1618
- }
1619
- } else if (gatewayUrl) {
1620
- const configDir = getConfigDir();
1621
- const creditDb = openCreditDb(join4(configDir, "credit.db"));
1622
- creditDb.pragma("busy_timeout = 5000");
1623
- try {
1624
- const keys = loadKeyPair(configDir);
1625
- const receiptResult = createSignedEscrowReceipt(creditDb, keys.privateKey, keys.publicKey, {
1626
- owner: config.owner,
1627
- amount,
1628
- cardId,
1629
- skillId: opts.skill
1630
- });
1631
- escrowId = receiptResult.escrowId;
1632
- escrowReceipt = receiptResult.receipt;
1633
- if (!opts.json) {
1634
- console.log(`Escrow: ${amount} credits held (ID: ${escrowId.slice(0, 8)}...)`);
1635
- }
1636
- } catch (err) {
1637
- creditDb.close();
1638
- const msg = err instanceof Error ? err.message : String(err);
1639
- if (opts.json) {
1640
- console.log(JSON.stringify({ success: false, error: msg }, null, 2));
1641
- } else {
1642
- console.error(`Error creating escrow receipt: ${msg}`);
1643
- }
1644
- process.exit(1);
1645
- }
1646
- creditDb.close();
1647
- }
1648
- }
1649
- const settleEscrow = async () => {
1650
- if (useReceipt && escrowId) {
1651
- if (requestLedger) {
1652
- await requestLedger.settle(escrowId, targetOwner ?? config.owner);
1653
- if (!opts.json) console.log(`Escrow settled: ${opts.cost} credits deducted.`);
1654
- } else if (escrowReceipt) {
1655
- const configDir = getConfigDir();
1656
- const creditDb = openCreditDb(join4(configDir, "credit.db"));
1657
- creditDb.pragma("busy_timeout = 5000");
1658
- try {
1659
- settleRequesterEscrow(creditDb, escrowId);
1660
- if (!opts.json) console.log(`Escrow settled: ${opts.cost} credits deducted.`);
1661
- } finally {
1662
- creditDb.close();
1663
- }
1664
- }
1665
- }
1666
- };
1667
- const releaseEscrow = async () => {
1668
- if (useReceipt && escrowId) {
1669
- if (requestLedger) {
1670
- await requestLedger.release(escrowId);
1671
- if (!opts.json) console.log("Escrow released: credits refunded.");
1672
- } else if (escrowReceipt) {
1673
- const configDir = getConfigDir();
1674
- const creditDb = openCreditDb(join4(configDir, "credit.db"));
1675
- creditDb.pragma("busy_timeout = 5000");
1676
- try {
1677
- releaseRequesterEscrow(creditDb, escrowId);
1678
- if (!opts.json) console.log("Escrow released: credits refunded.");
1679
- } finally {
1680
- creditDb.close();
1681
- }
1682
- }
1683
- }
1684
- };
1685
1630
  const printResult = (result) => {
1686
1631
  if (opts.json) {
1687
1632
  console.log(JSON.stringify({ success: true, result }, null, 2));
@@ -1690,70 +1635,58 @@ Batch Results (${res.results.length} items):`);
1690
1635
  console.log(typeof result === "string" ? result : JSON.stringify(result, null, 2));
1691
1636
  }
1692
1637
  };
1693
- const isNetworkError = (err) => {
1694
- const msg = err instanceof Error ? err.message : String(err);
1695
- return msg.includes("NETWORK_ERROR") || msg.includes("ECONNREFUSED") || msg.includes("fetch failed") || msg.includes("Network error");
1696
- };
1697
- const tryViaRelay = async () => {
1698
- const { RelayClient } = await import("../websocket-client-QOVARTRN.js");
1699
- const { requestViaRelay } = await import("../client-XOLP5IUZ.js");
1700
- const requesterId = `${config.owner}:req:${randomUUID4()}`;
1701
- const tempRelay = new RelayClient({
1702
- registryUrl: config.registry,
1703
- owner: requesterId,
1704
- token: config.token,
1705
- card: { id: randomUUID4(), owner: requesterId, name: requesterId, description: "Requester", level: 1, spec_version: "1.0", inputs: [], outputs: [], pricing: { credits_per_call: 1 }, availability: { online: false } },
1706
- onRequest: async () => ({ error: { code: -32601, message: "Not serving" } }),
1707
- silent: true
1708
- });
1709
- try {
1710
- await tempRelay.connect();
1711
- const result = await requestViaRelay(tempRelay, {
1638
+ try {
1639
+ let result;
1640
+ if (!isRemoteRequest) {
1641
+ result = await requestCapability({
1642
+ gatewayUrl,
1643
+ token,
1644
+ cardId,
1645
+ params: {
1646
+ ...params,
1647
+ ...opts.skill ? { skill_id: opts.skill } : {},
1648
+ requester: config.owner
1649
+ },
1650
+ timeoutMs: timeoutOverrideMs,
1651
+ timeoutHint,
1652
+ identity: identityAuth
1653
+ });
1654
+ } else if (isRemoteRequest && config.registry && targetOwner) {
1655
+ if (!opts.json) console.log("Requesting via relay...");
1656
+ result = await requestViaTemporaryRelay({
1657
+ registryUrl: config.registry,
1658
+ owner: config.owner,
1659
+ token: config.token,
1712
1660
  targetOwner,
1661
+ targetAgentId,
1713
1662
  cardId,
1714
1663
  skillId: opts.skill,
1715
- params: { ...params, ...opts.skill ? { skill_id: opts.skill } : {} },
1716
- requester: config.owner,
1717
- // actual owner for credit tracking on relay server
1718
- escrowReceipt
1664
+ params: {
1665
+ ...params,
1666
+ ...opts.skill ? { skill_id: opts.skill } : {},
1667
+ requester: config.owner
1668
+ },
1669
+ timeoutMs: timeoutOverrideMs
1670
+ });
1671
+ } else if (gatewayUrl) {
1672
+ result = await requestCapability({
1673
+ gatewayUrl,
1674
+ token,
1675
+ cardId,
1676
+ params: {
1677
+ ...params,
1678
+ ...opts.skill ? { skill_id: opts.skill } : {},
1679
+ requester: config.owner
1680
+ },
1681
+ timeoutMs: timeoutOverrideMs,
1682
+ timeoutHint,
1683
+ identity: identityAuth
1719
1684
  });
1720
- return result;
1721
- } finally {
1722
- tempRelay.disconnect();
1723
- }
1724
- };
1725
- try {
1726
- let result;
1727
- if (!gatewayUrl && isRemoteRequest && config.registry && targetOwner) {
1728
- if (!opts.json) console.log("No gateway URL, requesting via relay...");
1729
- result = await tryViaRelay();
1730
1685
  } else {
1731
- try {
1732
- result = await requestCapability({
1733
- gatewayUrl,
1734
- token,
1735
- cardId,
1736
- params: {
1737
- ...params,
1738
- ...opts.skill ? { skill_id: opts.skill } : {},
1739
- requester: config.owner
1740
- },
1741
- escrowReceipt,
1742
- identity: identityAuth
1743
- });
1744
- } catch (directErr) {
1745
- if (isNetworkError(directErr) && isRemoteRequest && config.registry && targetOwner) {
1746
- if (!opts.json) console.log("Direct connection failed, trying relay...");
1747
- result = await tryViaRelay();
1748
- } else {
1749
- throw directErr;
1750
- }
1751
- }
1686
+ throw new Error("Remote request requires a registry URL and target owner. Configure registry with: agentbnb config set registry <url>");
1752
1687
  }
1753
- await settleEscrow();
1754
1688
  printResult(result);
1755
1689
  } catch (err) {
1756
- await releaseEscrow();
1757
1690
  const msg = err instanceof Error ? err.message : String(err);
1758
1691
  if (opts.json) {
1759
1692
  console.log(JSON.stringify({ success: false, error: msg }, null, 2));
@@ -1825,8 +1758,8 @@ program.command("serve").description("Start the AgentBnB gateway server").option
1825
1758
  console.error("Error: not initialized. Run `agentbnb init` first.");
1826
1759
  process.exit(1);
1827
1760
  }
1828
- const { ProcessGuard } = await import("../process-guard-GH5LRNWO.js");
1829
- const { ServiceCoordinator } = await import("../service-coordinator-KMSA6BST.js");
1761
+ const { ProcessGuard } = await import("../process-guard-TNSUNHSR.js");
1762
+ const { ServiceCoordinator } = await import("../service-coordinator-RY5AKUZS.js");
1830
1763
  const port = opts.port ? parseInt(opts.port, 10) : config.gateway_port;
1831
1764
  const registryPort = parseInt(opts.registryPort, 10);
1832
1765
  if (!Number.isFinite(port) || !Number.isFinite(registryPort)) {
@@ -2200,7 +2133,7 @@ openclaw.command("rules").description("Print HEARTBEAT.md rules block (or inject
2200
2133
  }
2201
2134
  });
2202
2135
  program.command("conduct <task>").description("Orchestrate a complex task across the AgentBnB network").option("--plan-only", "Show execution plan without executing").option("--max-budget <credits>", "Maximum credits to spend", "100").option("--json", "Output as JSON").action(async (task, opts) => {
2203
- const { conductAction } = await import("../conduct-VPUYTNEA.js");
2136
+ const { conductAction } = await import("../conduct-4JDMWBQD.js");
2204
2137
  const result = await conductAction(task, opts);
2205
2138
  if (opts.json) {
2206
2139
  console.log(JSON.stringify(result, null, 2));
@@ -2312,7 +2245,7 @@ Feedback for skill: ${opts.skill} (${feedbacks.length} entries)
2312
2245
  });
2313
2246
  program.command("quickstart").alias("qs").description("One-command setup: init + skills.yaml + MCP registration + serve daemon").option("--owner <name>", "Agent owner name").option("--port <port>", "Gateway port", "7700").option("--no-serve", "Skip starting background daemon").option("--no-mcp", "Skip MCP registration with Claude Code").option("--json", "Output as JSON").action(runQuickstart);
2314
2247
  program.command("mcp-server").description("Start an MCP (Model Context Protocol) server for IDE integration").action(async () => {
2315
- const { startMcpServer } = await import("../server-VBCT32FC.js");
2248
+ const { startMcpServer } = await import("../server-YV3XPTX5.js");
2316
2249
  await startMcpServer();
2317
2250
  });
2318
2251
  await program.parseAsync(process.argv);