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
package/dist/index.js
CHANGED
|
@@ -1,3 +1,8 @@
|
|
|
1
|
+
import {
|
|
2
|
+
RelayClient,
|
|
3
|
+
RelayMessageSchema
|
|
4
|
+
} from "./chunk-3LWBH7P3.js";
|
|
5
|
+
|
|
1
6
|
// src/types/index.ts
|
|
2
7
|
import { z } from "zod";
|
|
3
8
|
var IOSchemaSchema = z.object({
|
|
@@ -351,7 +356,10 @@ var V2_FTS_TRIGGERS = `
|
|
|
351
356
|
new.id,
|
|
352
357
|
new.owner,
|
|
353
358
|
COALESCE(
|
|
354
|
-
(SELECT group_concat(
|
|
359
|
+
(SELECT group_concat(
|
|
360
|
+
COALESCE(json_extract(value, '$.id'), '') || ' ' || COALESCE(json_extract(value, '$.name'), ''),
|
|
361
|
+
' '
|
|
362
|
+
)
|
|
355
363
|
FROM json_each(json_extract(new.data, '$.skills'))),
|
|
356
364
|
json_extract(new.data, '$.name'),
|
|
357
365
|
''
|
|
@@ -391,7 +399,10 @@ var V2_FTS_TRIGGERS = `
|
|
|
391
399
|
old.id,
|
|
392
400
|
old.owner,
|
|
393
401
|
COALESCE(
|
|
394
|
-
(SELECT group_concat(
|
|
402
|
+
(SELECT group_concat(
|
|
403
|
+
COALESCE(json_extract(value, '$.id'), '') || ' ' || COALESCE(json_extract(value, '$.name'), ''),
|
|
404
|
+
' '
|
|
405
|
+
)
|
|
395
406
|
FROM json_each(json_extract(old.data, '$.skills'))),
|
|
396
407
|
json_extract(old.data, '$.name'),
|
|
397
408
|
''
|
|
@@ -427,7 +438,10 @@ var V2_FTS_TRIGGERS = `
|
|
|
427
438
|
new.id,
|
|
428
439
|
new.owner,
|
|
429
440
|
COALESCE(
|
|
430
|
-
(SELECT group_concat(
|
|
441
|
+
(SELECT group_concat(
|
|
442
|
+
COALESCE(json_extract(value, '$.id'), '') || ' ' || COALESCE(json_extract(value, '$.name'), ''),
|
|
443
|
+
' '
|
|
444
|
+
)
|
|
431
445
|
FROM json_each(json_extract(new.data, '$.skills'))),
|
|
432
446
|
json_extract(new.data, '$.name'),
|
|
433
447
|
''
|
|
@@ -467,7 +481,10 @@ var V2_FTS_TRIGGERS = `
|
|
|
467
481
|
old.id,
|
|
468
482
|
old.owner,
|
|
469
483
|
COALESCE(
|
|
470
|
-
(SELECT group_concat(
|
|
484
|
+
(SELECT group_concat(
|
|
485
|
+
COALESCE(json_extract(value, '$.id'), '') || ' ' || COALESCE(json_extract(value, '$.name'), ''),
|
|
486
|
+
' '
|
|
487
|
+
)
|
|
471
488
|
FROM json_each(json_extract(old.data, '$.skills'))),
|
|
472
489
|
json_extract(old.data, '$.name'),
|
|
473
490
|
''
|
|
@@ -554,6 +571,10 @@ function runMigrations(db) {
|
|
|
554
571
|
const version = db.pragma("user_version")[0]?.user_version ?? 0;
|
|
555
572
|
if (version < 2) {
|
|
556
573
|
migrateV1toV2(db);
|
|
574
|
+
return;
|
|
575
|
+
}
|
|
576
|
+
if (version < 3) {
|
|
577
|
+
migrateV2toV3(db);
|
|
557
578
|
}
|
|
558
579
|
}
|
|
559
580
|
function migrateV1toV2(db) {
|
|
@@ -595,44 +616,55 @@ function migrateV1toV2(db) {
|
|
|
595
616
|
);
|
|
596
617
|
}
|
|
597
618
|
db.exec(V2_FTS_TRIGGERS);
|
|
598
|
-
db
|
|
599
|
-
|
|
600
|
-
const ftsInsert = db.prepare(
|
|
601
|
-
"INSERT INTO cards_fts(rowid, id, owner, name, description, tags) VALUES (?, ?, ?, ?, ?, ?)"
|
|
602
|
-
);
|
|
603
|
-
for (const row of allRows) {
|
|
604
|
-
const data = JSON.parse(row.data);
|
|
605
|
-
const skills = data["skills"] ?? [];
|
|
606
|
-
let name;
|
|
607
|
-
let description;
|
|
608
|
-
let tags;
|
|
609
|
-
if (skills.length > 0) {
|
|
610
|
-
name = skills.map((s) => String(s["name"] ?? "")).join(" ");
|
|
611
|
-
description = skills.map((s) => String(s["description"] ?? "")).join(" ");
|
|
612
|
-
tags = [
|
|
613
|
-
// tags from metadata.tags[]
|
|
614
|
-
...skills.flatMap((s) => {
|
|
615
|
-
const meta = s["metadata"];
|
|
616
|
-
return meta?.["tags"] ?? [];
|
|
617
|
-
}),
|
|
618
|
-
// capability_type (singular)
|
|
619
|
-
...skills.map((s) => s["capability_type"]).filter((v) => typeof v === "string" && v.length > 0),
|
|
620
|
-
// capability_types[] (plural)
|
|
621
|
-
...skills.flatMap((s) => s["capability_types"] ?? [])
|
|
622
|
-
].join(" ");
|
|
623
|
-
} else {
|
|
624
|
-
name = String(data["name"] ?? "");
|
|
625
|
-
description = String(data["description"] ?? "");
|
|
626
|
-
const meta = data["metadata"];
|
|
627
|
-
const rawTags = meta?.["tags"] ?? [];
|
|
628
|
-
tags = rawTags.join(" ");
|
|
629
|
-
}
|
|
630
|
-
ftsInsert.run(row.rowid, row.id, row.owner, name, description, tags);
|
|
631
|
-
}
|
|
632
|
-
db.pragma("user_version = 2");
|
|
619
|
+
rebuildCardsFts(db);
|
|
620
|
+
db.pragma("user_version = 3");
|
|
633
621
|
});
|
|
634
622
|
migrate();
|
|
635
623
|
}
|
|
624
|
+
function migrateV2toV3(db) {
|
|
625
|
+
const migrate = db.transaction(() => {
|
|
626
|
+
db.exec(V2_FTS_TRIGGERS);
|
|
627
|
+
rebuildCardsFts(db);
|
|
628
|
+
db.pragma("user_version = 3");
|
|
629
|
+
});
|
|
630
|
+
migrate();
|
|
631
|
+
}
|
|
632
|
+
function rebuildCardsFts(db) {
|
|
633
|
+
db.exec(`INSERT INTO cards_fts(cards_fts) VALUES('delete-all')`);
|
|
634
|
+
const allRows = db.prepare("SELECT rowid, id, owner, data FROM capability_cards").all();
|
|
635
|
+
const ftsInsert = db.prepare(
|
|
636
|
+
"INSERT INTO cards_fts(rowid, id, owner, name, description, tags) VALUES (?, ?, ?, ?, ?, ?)"
|
|
637
|
+
);
|
|
638
|
+
for (const row of allRows) {
|
|
639
|
+
const data = JSON.parse(row.data);
|
|
640
|
+
const skills = data["skills"] ?? [];
|
|
641
|
+
let name;
|
|
642
|
+
let description;
|
|
643
|
+
let tags;
|
|
644
|
+
if (skills.length > 0) {
|
|
645
|
+
name = skills.map((s) => `${String(s["id"] ?? "")} ${String(s["name"] ?? "")}`.trim()).join(" ");
|
|
646
|
+
description = skills.map((s) => String(s["description"] ?? "")).join(" ");
|
|
647
|
+
tags = [
|
|
648
|
+
// tags from metadata.tags[]
|
|
649
|
+
...skills.flatMap((s) => {
|
|
650
|
+
const meta = s["metadata"];
|
|
651
|
+
return meta?.["tags"] ?? [];
|
|
652
|
+
}),
|
|
653
|
+
// capability_type (singular)
|
|
654
|
+
...skills.map((s) => s["capability_type"]).filter((v) => typeof v === "string" && v.length > 0),
|
|
655
|
+
// capability_types[] (plural)
|
|
656
|
+
...skills.flatMap((s) => s["capability_types"] ?? [])
|
|
657
|
+
].join(" ");
|
|
658
|
+
} else {
|
|
659
|
+
name = String(data["name"] ?? "");
|
|
660
|
+
description = String(data["description"] ?? "");
|
|
661
|
+
const meta = data["metadata"];
|
|
662
|
+
const rawTags = meta?.["tags"] ?? [];
|
|
663
|
+
tags = rawTags.join(" ");
|
|
664
|
+
}
|
|
665
|
+
ftsInsert.run(row.rowid, row.id, row.owner, name, description, tags);
|
|
666
|
+
}
|
|
667
|
+
}
|
|
636
668
|
function insertCard(db, card) {
|
|
637
669
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
638
670
|
const withTimestamps = { ...card, created_at: card.created_at ?? now, updated_at: now };
|
|
@@ -793,8 +825,12 @@ function searchCards(db, query, filters = {}) {
|
|
|
793
825
|
if (cached && cached.expiresAt > Date.now()) {
|
|
794
826
|
return cached.results;
|
|
795
827
|
}
|
|
828
|
+
const trimmedQuery = query.trim();
|
|
829
|
+
const exactSkillMatches = findCardsByExactSkillId(db, trimmedQuery, filters);
|
|
796
830
|
const words = query.trim().split(/\s+/).map((w) => w.replace(/["*^{}():]/g, "")).filter((w) => w.length > 0);
|
|
797
|
-
if (words.length === 0)
|
|
831
|
+
if (words.length === 0) {
|
|
832
|
+
return exactSkillMatches;
|
|
833
|
+
}
|
|
798
834
|
const ftsQuery = words.map((w) => `"${w}"`).join(" OR ");
|
|
799
835
|
const conditions = [];
|
|
800
836
|
const params = [ftsQuery];
|
|
@@ -819,7 +855,8 @@ function searchCards(db, query, filters = {}) {
|
|
|
819
855
|
const stmt = db.prepare(sql);
|
|
820
856
|
const rows = stmt.all(...params);
|
|
821
857
|
const results = rows.map((row) => JSON.parse(row.data));
|
|
822
|
-
|
|
858
|
+
const mergedResults = mergeByCardId(exactSkillMatches, results);
|
|
859
|
+
let filtered = mergedResults;
|
|
823
860
|
if (filters.apis_used && filters.apis_used.length > 0) {
|
|
824
861
|
const requiredApis = filters.apis_used;
|
|
825
862
|
filtered = filtered.filter((card) => {
|
|
@@ -834,6 +871,34 @@ function searchCards(db, query, filters = {}) {
|
|
|
834
871
|
cache.set(key, { results: filtered, expiresAt: Date.now() + CACHE_TTL_MS });
|
|
835
872
|
return filtered;
|
|
836
873
|
}
|
|
874
|
+
function mergeByCardId(primary, secondary) {
|
|
875
|
+
const seen = /* @__PURE__ */ new Set();
|
|
876
|
+
const merged = [];
|
|
877
|
+
for (const card of primary) {
|
|
878
|
+
if (seen.has(card.id)) continue;
|
|
879
|
+
seen.add(card.id);
|
|
880
|
+
merged.push(card);
|
|
881
|
+
}
|
|
882
|
+
for (const card of secondary) {
|
|
883
|
+
if (seen.has(card.id)) continue;
|
|
884
|
+
seen.add(card.id);
|
|
885
|
+
merged.push(card);
|
|
886
|
+
}
|
|
887
|
+
return merged;
|
|
888
|
+
}
|
|
889
|
+
function findCardsByExactSkillId(db, query, filters) {
|
|
890
|
+
if (query.length === 0) return [];
|
|
891
|
+
const rows = db.prepare("SELECT data FROM capability_cards").all();
|
|
892
|
+
const cards = rows.map((row) => JSON.parse(row.data));
|
|
893
|
+
return cards.filter((card) => {
|
|
894
|
+
if (filters.level !== void 0 && card.level !== filters.level) return false;
|
|
895
|
+
if (filters.online !== void 0 && card.availability?.online !== filters.online) return false;
|
|
896
|
+
const asRecord = card;
|
|
897
|
+
const skills = asRecord["skills"];
|
|
898
|
+
if (!Array.isArray(skills)) return false;
|
|
899
|
+
return skills.some((skill) => String(skill["id"] ?? "") === query);
|
|
900
|
+
});
|
|
901
|
+
}
|
|
837
902
|
function applyReputationFilter(db, cards, minReputation) {
|
|
838
903
|
const owners = [...new Set(cards.map((c) => c.owner))];
|
|
839
904
|
const reputationMap = /* @__PURE__ */ new Map();
|
|
@@ -1297,6 +1362,73 @@ function loadConfig() {
|
|
|
1297
1362
|
}
|
|
1298
1363
|
}
|
|
1299
1364
|
|
|
1365
|
+
// src/cli/remote-registry.ts
|
|
1366
|
+
var RegistryTimeoutError = class extends AgentBnBError {
|
|
1367
|
+
constructor(url) {
|
|
1368
|
+
super(
|
|
1369
|
+
`Registry at ${url} did not respond within 5s. Showing local results only.`,
|
|
1370
|
+
"REGISTRY_TIMEOUT"
|
|
1371
|
+
);
|
|
1372
|
+
this.name = "RegistryTimeoutError";
|
|
1373
|
+
}
|
|
1374
|
+
};
|
|
1375
|
+
var RegistryConnectionError = class extends AgentBnBError {
|
|
1376
|
+
constructor(url) {
|
|
1377
|
+
super(
|
|
1378
|
+
`Cannot reach ${url}. Is the registry running? Showing local results only.`,
|
|
1379
|
+
"REGISTRY_CONNECTION"
|
|
1380
|
+
);
|
|
1381
|
+
this.name = "RegistryConnectionError";
|
|
1382
|
+
}
|
|
1383
|
+
};
|
|
1384
|
+
var RegistryAuthError = class extends AgentBnBError {
|
|
1385
|
+
constructor(url) {
|
|
1386
|
+
super(
|
|
1387
|
+
`Authentication failed for ${url}. Run \`agentbnb config set token <your-token>\`.`,
|
|
1388
|
+
"REGISTRY_AUTH"
|
|
1389
|
+
);
|
|
1390
|
+
this.name = "RegistryAuthError";
|
|
1391
|
+
}
|
|
1392
|
+
};
|
|
1393
|
+
async function fetchRemoteCards(registryUrl, params, timeoutMs = 5e3) {
|
|
1394
|
+
let cardsUrl;
|
|
1395
|
+
try {
|
|
1396
|
+
cardsUrl = new URL("/cards", registryUrl);
|
|
1397
|
+
} catch {
|
|
1398
|
+
throw new AgentBnBError(`Invalid registry URL: ${registryUrl}`, "INVALID_REGISTRY_URL");
|
|
1399
|
+
}
|
|
1400
|
+
const searchParams = new URLSearchParams();
|
|
1401
|
+
if (params.q !== void 0) searchParams.set("q", params.q);
|
|
1402
|
+
if (params.level !== void 0) searchParams.set("level", String(params.level));
|
|
1403
|
+
if (params.online !== void 0) searchParams.set("online", String(params.online));
|
|
1404
|
+
if (params.tag !== void 0) searchParams.set("tag", params.tag);
|
|
1405
|
+
searchParams.set("limit", "100");
|
|
1406
|
+
cardsUrl.search = searchParams.toString();
|
|
1407
|
+
const controller = new AbortController();
|
|
1408
|
+
const timer = setTimeout(() => controller.abort(), timeoutMs);
|
|
1409
|
+
let response;
|
|
1410
|
+
try {
|
|
1411
|
+
response = await fetch(cardsUrl.toString(), { signal: controller.signal });
|
|
1412
|
+
} catch (err) {
|
|
1413
|
+
clearTimeout(timer);
|
|
1414
|
+
const isTimeout = err instanceof Error && err.name === "AbortError";
|
|
1415
|
+
if (isTimeout) {
|
|
1416
|
+
throw new RegistryTimeoutError(registryUrl);
|
|
1417
|
+
}
|
|
1418
|
+
throw new RegistryConnectionError(registryUrl);
|
|
1419
|
+
} finally {
|
|
1420
|
+
clearTimeout(timer);
|
|
1421
|
+
}
|
|
1422
|
+
if (response.status === 401 || response.status === 403) {
|
|
1423
|
+
throw new RegistryAuthError(registryUrl);
|
|
1424
|
+
}
|
|
1425
|
+
if (!response.ok) {
|
|
1426
|
+
throw new RegistryConnectionError(registryUrl);
|
|
1427
|
+
}
|
|
1428
|
+
const body = await response.json();
|
|
1429
|
+
return body.items;
|
|
1430
|
+
}
|
|
1431
|
+
|
|
1300
1432
|
// src/gateway/execute.ts
|
|
1301
1433
|
async function notifyTelegramSkillExecuted(opts) {
|
|
1302
1434
|
const cfg = loadConfig();
|
|
@@ -2945,6 +3077,9 @@ function decompose(task, _availableCapabilities) {
|
|
|
2945
3077
|
return [];
|
|
2946
3078
|
}
|
|
2947
3079
|
|
|
3080
|
+
// src/autonomy/auto-request.ts
|
|
3081
|
+
import { randomUUID as randomUUID11 } from "crypto";
|
|
3082
|
+
|
|
2948
3083
|
// src/gateway/client.ts
|
|
2949
3084
|
import { randomUUID as randomUUID8 } from "crypto";
|
|
2950
3085
|
import { Agent } from "undici";
|
|
@@ -2954,6 +3089,19 @@ var gatewayAgent = new Agent({
|
|
|
2954
3089
|
connections: 10,
|
|
2955
3090
|
pipelining: 1
|
|
2956
3091
|
});
|
|
3092
|
+
function buildGatewayAuthHeaders(payload, token, identity) {
|
|
3093
|
+
const headers = { "Content-Type": "application/json" };
|
|
3094
|
+
if (identity) {
|
|
3095
|
+
const signature = signEscrowReceipt(payload, identity.privateKey);
|
|
3096
|
+
headers["X-Agent-Id"] = identity.agentId;
|
|
3097
|
+
headers["X-Agent-Public-Key"] = identity.publicKey;
|
|
3098
|
+
headers["X-Agent-Signature"] = signature;
|
|
3099
|
+
}
|
|
3100
|
+
if (token) {
|
|
3101
|
+
headers["Authorization"] = `Bearer ${token}`;
|
|
3102
|
+
}
|
|
3103
|
+
return headers;
|
|
3104
|
+
}
|
|
2957
3105
|
async function requestCapability(opts) {
|
|
2958
3106
|
const { gatewayUrl, token, cardId, params = {}, timeoutMs = 3e5, escrowReceipt, identity } = opts;
|
|
2959
3107
|
const id = randomUUID8();
|
|
@@ -2967,15 +3115,7 @@ async function requestCapability(opts) {
|
|
|
2967
3115
|
...escrowReceipt ? { escrow_receipt: escrowReceipt } : {}
|
|
2968
3116
|
}
|
|
2969
3117
|
};
|
|
2970
|
-
const headers =
|
|
2971
|
-
if (identity) {
|
|
2972
|
-
const signature = signEscrowReceipt(payload, identity.privateKey);
|
|
2973
|
-
headers["X-Agent-Id"] = identity.agentId;
|
|
2974
|
-
headers["X-Agent-Public-Key"] = identity.publicKey;
|
|
2975
|
-
headers["X-Agent-Signature"] = signature;
|
|
2976
|
-
} else if (token) {
|
|
2977
|
-
headers["Authorization"] = `Bearer ${token}`;
|
|
2978
|
-
}
|
|
3118
|
+
const headers = buildGatewayAuthHeaders(payload, token, identity);
|
|
2979
3119
|
const controller = new AbortController();
|
|
2980
3120
|
const timer = setTimeout(() => controller.abort(), timeoutMs);
|
|
2981
3121
|
let response;
|
|
@@ -3030,15 +3170,7 @@ async function requestCapabilityBatch(gatewayUrl, token, items, opts = {}) {
|
|
|
3030
3170
|
...item.escrowReceipt ? { escrow_receipt: item.escrowReceipt } : {}
|
|
3031
3171
|
}
|
|
3032
3172
|
}));
|
|
3033
|
-
const headers =
|
|
3034
|
-
if (identity) {
|
|
3035
|
-
const signature = signEscrowReceipt(batchPayload, identity.privateKey);
|
|
3036
|
-
headers["X-Agent-Id"] = identity.agentId;
|
|
3037
|
-
headers["X-Agent-Public-Key"] = identity.publicKey;
|
|
3038
|
-
headers["X-Agent-Signature"] = signature;
|
|
3039
|
-
} else if (token) {
|
|
3040
|
-
headers["Authorization"] = `Bearer ${token}`;
|
|
3041
|
-
}
|
|
3173
|
+
const headers = buildGatewayAuthHeaders(batchPayload, token, identity);
|
|
3042
3174
|
const controller = new AbortController();
|
|
3043
3175
|
const timer = setTimeout(() => controller.abort(), timeoutMs);
|
|
3044
3176
|
let response;
|
|
@@ -3104,73 +3236,6 @@ import { randomUUID as randomUUID10 } from "crypto";
|
|
|
3104
3236
|
import { readFileSync as readFileSync3, writeFileSync as writeFileSync3, existsSync as existsSync3, mkdirSync as mkdirSync2 } from "fs";
|
|
3105
3237
|
import { join as join3 } from "path";
|
|
3106
3238
|
|
|
3107
|
-
// src/cli/remote-registry.ts
|
|
3108
|
-
var RegistryTimeoutError = class extends AgentBnBError {
|
|
3109
|
-
constructor(url) {
|
|
3110
|
-
super(
|
|
3111
|
-
`Registry at ${url} did not respond within 5s. Showing local results only.`,
|
|
3112
|
-
"REGISTRY_TIMEOUT"
|
|
3113
|
-
);
|
|
3114
|
-
this.name = "RegistryTimeoutError";
|
|
3115
|
-
}
|
|
3116
|
-
};
|
|
3117
|
-
var RegistryConnectionError = class extends AgentBnBError {
|
|
3118
|
-
constructor(url) {
|
|
3119
|
-
super(
|
|
3120
|
-
`Cannot reach ${url}. Is the registry running? Showing local results only.`,
|
|
3121
|
-
"REGISTRY_CONNECTION"
|
|
3122
|
-
);
|
|
3123
|
-
this.name = "RegistryConnectionError";
|
|
3124
|
-
}
|
|
3125
|
-
};
|
|
3126
|
-
var RegistryAuthError = class extends AgentBnBError {
|
|
3127
|
-
constructor(url) {
|
|
3128
|
-
super(
|
|
3129
|
-
`Authentication failed for ${url}. Run \`agentbnb config set token <your-token>\`.`,
|
|
3130
|
-
"REGISTRY_AUTH"
|
|
3131
|
-
);
|
|
3132
|
-
this.name = "RegistryAuthError";
|
|
3133
|
-
}
|
|
3134
|
-
};
|
|
3135
|
-
async function fetchRemoteCards(registryUrl, params, timeoutMs = 5e3) {
|
|
3136
|
-
let cardsUrl;
|
|
3137
|
-
try {
|
|
3138
|
-
cardsUrl = new URL("/cards", registryUrl);
|
|
3139
|
-
} catch {
|
|
3140
|
-
throw new AgentBnBError(`Invalid registry URL: ${registryUrl}`, "INVALID_REGISTRY_URL");
|
|
3141
|
-
}
|
|
3142
|
-
const searchParams = new URLSearchParams();
|
|
3143
|
-
if (params.q !== void 0) searchParams.set("q", params.q);
|
|
3144
|
-
if (params.level !== void 0) searchParams.set("level", String(params.level));
|
|
3145
|
-
if (params.online !== void 0) searchParams.set("online", String(params.online));
|
|
3146
|
-
if (params.tag !== void 0) searchParams.set("tag", params.tag);
|
|
3147
|
-
searchParams.set("limit", "100");
|
|
3148
|
-
cardsUrl.search = searchParams.toString();
|
|
3149
|
-
const controller = new AbortController();
|
|
3150
|
-
const timer = setTimeout(() => controller.abort(), timeoutMs);
|
|
3151
|
-
let response;
|
|
3152
|
-
try {
|
|
3153
|
-
response = await fetch(cardsUrl.toString(), { signal: controller.signal });
|
|
3154
|
-
} catch (err) {
|
|
3155
|
-
clearTimeout(timer);
|
|
3156
|
-
const isTimeout = err instanceof Error && err.name === "AbortError";
|
|
3157
|
-
if (isTimeout) {
|
|
3158
|
-
throw new RegistryTimeoutError(registryUrl);
|
|
3159
|
-
}
|
|
3160
|
-
throw new RegistryConnectionError(registryUrl);
|
|
3161
|
-
} finally {
|
|
3162
|
-
clearTimeout(timer);
|
|
3163
|
-
}
|
|
3164
|
-
if (response.status === 401 || response.status === 403) {
|
|
3165
|
-
throw new RegistryAuthError(registryUrl);
|
|
3166
|
-
}
|
|
3167
|
-
if (!response.ok) {
|
|
3168
|
-
throw new RegistryConnectionError(registryUrl);
|
|
3169
|
-
}
|
|
3170
|
-
const body = await response.json();
|
|
3171
|
-
return body.items;
|
|
3172
|
-
}
|
|
3173
|
-
|
|
3174
3239
|
// src/autonomy/auto-request.ts
|
|
3175
3240
|
function minMaxNormalize(values) {
|
|
3176
3241
|
if (values.length === 0) return [];
|
|
@@ -3731,7 +3796,7 @@ var BudgetManager = class {
|
|
|
3731
3796
|
};
|
|
3732
3797
|
|
|
3733
3798
|
// src/conductor/team-formation.ts
|
|
3734
|
-
import { randomUUID as
|
|
3799
|
+
import { randomUUID as randomUUID12 } from "crypto";
|
|
3735
3800
|
function selectByStrategy(matches, strategy) {
|
|
3736
3801
|
if (matches.length === 0) return void 0;
|
|
3737
3802
|
if (strategy === "balanced") {
|
|
@@ -3748,7 +3813,7 @@ function selectByStrategy(matches, strategy) {
|
|
|
3748
3813
|
}
|
|
3749
3814
|
async function formTeam(opts) {
|
|
3750
3815
|
const { subtasks, strategy, db, conductorOwner, registryUrl } = opts;
|
|
3751
|
-
const team_id =
|
|
3816
|
+
const team_id = randomUUID12();
|
|
3752
3817
|
if (subtasks.length === 0) {
|
|
3753
3818
|
return { team_id, strategy, matched: [], unrouted: [] };
|
|
3754
3819
|
}
|
|
@@ -3978,7 +4043,7 @@ var ConductorMode = class {
|
|
|
3978
4043
|
|
|
3979
4044
|
// src/credit/escrow-receipt.ts
|
|
3980
4045
|
import { z as z3 } from "zod";
|
|
3981
|
-
import { randomUUID as
|
|
4046
|
+
import { randomUUID as randomUUID13 } from "crypto";
|
|
3982
4047
|
var EscrowReceiptSchema = z3.object({
|
|
3983
4048
|
requester_owner: z3.string().min(1),
|
|
3984
4049
|
requester_agent_id: z3.string().optional(),
|
|
@@ -4000,7 +4065,7 @@ function createSignedEscrowReceipt(db, privateKey, publicKey, opts) {
|
|
|
4000
4065
|
card_id: opts.cardId,
|
|
4001
4066
|
...opts.skillId ? { skill_id: opts.skillId } : {},
|
|
4002
4067
|
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
4003
|
-
nonce:
|
|
4068
|
+
nonce: randomUUID13()
|
|
4004
4069
|
};
|
|
4005
4070
|
const signature = signEscrowReceipt(receiptData, privateKey);
|
|
4006
4071
|
const receipt = {
|
|
@@ -4262,7 +4327,12 @@ var AgentBnBConsumer = class {
|
|
|
4262
4327
|
cardId: opts.cardId,
|
|
4263
4328
|
params: opts.params,
|
|
4264
4329
|
timeoutMs: opts.timeoutMs,
|
|
4265
|
-
escrowReceipt: receipt
|
|
4330
|
+
escrowReceipt: receipt,
|
|
4331
|
+
identity: {
|
|
4332
|
+
agentId: identity.agent_id,
|
|
4333
|
+
publicKey: identity.public_key,
|
|
4334
|
+
privateKey: this.keys.privateKey
|
|
4335
|
+
}
|
|
4266
4336
|
});
|
|
4267
4337
|
settleRequesterEscrow(db, escrowId);
|
|
4268
4338
|
return result;
|
|
@@ -4438,7 +4508,7 @@ var AgentBnBProvider = class {
|
|
|
4438
4508
|
|
|
4439
4509
|
// src/identity/guarantor.ts
|
|
4440
4510
|
import { z as z5 } from "zod";
|
|
4441
|
-
import { randomUUID as
|
|
4511
|
+
import { randomUUID as randomUUID14 } from "crypto";
|
|
4442
4512
|
var MAX_AGENTS_PER_GUARANTOR = 10;
|
|
4443
4513
|
var GUARANTOR_CREDIT_POOL = 50;
|
|
4444
4514
|
var GuarantorRecordSchema = z5.object({
|
|
@@ -4477,7 +4547,7 @@ function registerGuarantor(db, githubLogin) {
|
|
|
4477
4547
|
);
|
|
4478
4548
|
}
|
|
4479
4549
|
const record = {
|
|
4480
|
-
id:
|
|
4550
|
+
id: randomUUID14(),
|
|
4481
4551
|
github_login: githubLogin,
|
|
4482
4552
|
agent_count: 0,
|
|
4483
4553
|
credit_pool: GUARANTOR_CREDIT_POOL,
|
|
@@ -4551,178 +4621,12 @@ function getAgentGuarantor(db, agentId) {
|
|
|
4551
4621
|
function initiateGithubAuth() {
|
|
4552
4622
|
return {
|
|
4553
4623
|
auth_url: "https://github.com/login/oauth/authorize?client_id=PLACEHOLDER&scope=read:user",
|
|
4554
|
-
state:
|
|
4624
|
+
state: randomUUID14()
|
|
4555
4625
|
};
|
|
4556
4626
|
}
|
|
4557
4627
|
|
|
4558
|
-
// src/relay/types.ts
|
|
4559
|
-
import { z as z6 } from "zod";
|
|
4560
|
-
var RegisterMessageSchema = z6.object({
|
|
4561
|
-
type: z6.literal("register"),
|
|
4562
|
-
owner: z6.string().min(1),
|
|
4563
|
-
/** V8: Cryptographic agent identity. When present, used as the canonical key. */
|
|
4564
|
-
agent_id: z6.string().optional(),
|
|
4565
|
-
/** V8 Phase 3: Server identifier for multi-agent delegation. */
|
|
4566
|
-
server_id: z6.string().optional(),
|
|
4567
|
-
token: z6.string().min(1),
|
|
4568
|
-
card: z6.record(z6.unknown()),
|
|
4569
|
-
// CapabilityCard (validated separately)
|
|
4570
|
-
cards: z6.array(z6.record(z6.unknown())).optional(),
|
|
4571
|
-
// Additional cards (e.g., conductor card)
|
|
4572
|
-
/** V8 Phase 3: Additional agents served by this server (multi-agent registration). */
|
|
4573
|
-
agents: z6.array(z6.object({
|
|
4574
|
-
agent_id: z6.string().min(1),
|
|
4575
|
-
display_name: z6.string().min(1),
|
|
4576
|
-
cards: z6.array(z6.record(z6.unknown())),
|
|
4577
|
-
delegation_token: z6.record(z6.unknown()).optional()
|
|
4578
|
-
})).optional()
|
|
4579
|
-
});
|
|
4580
|
-
var RegisteredMessageSchema = z6.object({
|
|
4581
|
-
type: z6.literal("registered"),
|
|
4582
|
-
agent_id: z6.string()
|
|
4583
|
-
});
|
|
4584
|
-
var RelayRequestMessageSchema = z6.object({
|
|
4585
|
-
type: z6.literal("relay_request"),
|
|
4586
|
-
id: z6.string().uuid(),
|
|
4587
|
-
target_owner: z6.string().min(1),
|
|
4588
|
-
/** V8: Target agent's cryptographic identity. Preferred over target_owner. */
|
|
4589
|
-
target_agent_id: z6.string().optional(),
|
|
4590
|
-
card_id: z6.string(),
|
|
4591
|
-
skill_id: z6.string().optional(),
|
|
4592
|
-
params: z6.record(z6.unknown()).default({}),
|
|
4593
|
-
requester: z6.string().optional(),
|
|
4594
|
-
escrow_receipt: z6.record(z6.unknown()).optional()
|
|
4595
|
-
});
|
|
4596
|
-
var IncomingRequestMessageSchema = z6.object({
|
|
4597
|
-
type: z6.literal("incoming_request"),
|
|
4598
|
-
id: z6.string().uuid(),
|
|
4599
|
-
from_owner: z6.string().min(1),
|
|
4600
|
-
card_id: z6.string(),
|
|
4601
|
-
skill_id: z6.string().optional(),
|
|
4602
|
-
params: z6.record(z6.unknown()).default({}),
|
|
4603
|
-
requester: z6.string().optional(),
|
|
4604
|
-
escrow_receipt: z6.record(z6.unknown()).optional()
|
|
4605
|
-
});
|
|
4606
|
-
var RelayResponseMessageSchema = z6.object({
|
|
4607
|
-
type: z6.literal("relay_response"),
|
|
4608
|
-
id: z6.string().uuid(),
|
|
4609
|
-
result: z6.unknown().optional(),
|
|
4610
|
-
error: z6.object({
|
|
4611
|
-
code: z6.number(),
|
|
4612
|
-
message: z6.string()
|
|
4613
|
-
}).optional()
|
|
4614
|
-
});
|
|
4615
|
-
var ResponseMessageSchema = z6.object({
|
|
4616
|
-
type: z6.literal("response"),
|
|
4617
|
-
id: z6.string().uuid(),
|
|
4618
|
-
result: z6.unknown().optional(),
|
|
4619
|
-
error: z6.object({
|
|
4620
|
-
code: z6.number(),
|
|
4621
|
-
message: z6.string()
|
|
4622
|
-
}).optional()
|
|
4623
|
-
});
|
|
4624
|
-
var ErrorMessageSchema = z6.object({
|
|
4625
|
-
type: z6.literal("error"),
|
|
4626
|
-
code: z6.string(),
|
|
4627
|
-
message: z6.string(),
|
|
4628
|
-
request_id: z6.string().optional()
|
|
4629
|
-
});
|
|
4630
|
-
var RelayProgressMessageSchema = z6.object({
|
|
4631
|
-
type: z6.literal("relay_progress"),
|
|
4632
|
-
id: z6.string().uuid(),
|
|
4633
|
-
// request ID this progress relates to
|
|
4634
|
-
progress: z6.number().min(0).max(100).optional(),
|
|
4635
|
-
// optional percentage
|
|
4636
|
-
message: z6.string().optional()
|
|
4637
|
-
// optional status message
|
|
4638
|
-
});
|
|
4639
|
-
var HeartbeatMessageSchema = z6.object({
|
|
4640
|
-
type: z6.literal("heartbeat"),
|
|
4641
|
-
owner: z6.string().min(1),
|
|
4642
|
-
capacity: z6.object({
|
|
4643
|
-
current_load: z6.number(),
|
|
4644
|
-
max_concurrent: z6.number(),
|
|
4645
|
-
queue_depth: z6.number()
|
|
4646
|
-
}),
|
|
4647
|
-
self_summary: z6.object({
|
|
4648
|
-
capabilities: z6.array(z6.string()),
|
|
4649
|
-
success_rate: z6.number(),
|
|
4650
|
-
credit_balance: z6.number(),
|
|
4651
|
-
total_completed: z6.number(),
|
|
4652
|
-
provider_number: z6.number(),
|
|
4653
|
-
reliability: z6.object({
|
|
4654
|
-
current_streak: z6.number(),
|
|
4655
|
-
repeat_hire_rate: z6.number(),
|
|
4656
|
-
avg_feedback: z6.number()
|
|
4657
|
-
})
|
|
4658
|
-
})
|
|
4659
|
-
});
|
|
4660
|
-
var EscrowHoldMessageSchema = z6.object({
|
|
4661
|
-
type: z6.literal("escrow_hold"),
|
|
4662
|
-
consumer_agent_id: z6.string().min(1),
|
|
4663
|
-
provider_agent_id: z6.string().min(1),
|
|
4664
|
-
skill_id: z6.string().min(1),
|
|
4665
|
-
amount: z6.number().positive(),
|
|
4666
|
-
request_id: z6.string().uuid(),
|
|
4667
|
-
signature: z6.string().optional(),
|
|
4668
|
-
public_key: z6.string().optional()
|
|
4669
|
-
});
|
|
4670
|
-
var EscrowHoldConfirmedMessageSchema = z6.object({
|
|
4671
|
-
type: z6.literal("escrow_hold_confirmed"),
|
|
4672
|
-
request_id: z6.string(),
|
|
4673
|
-
escrow_id: z6.string(),
|
|
4674
|
-
hold_amount: z6.number(),
|
|
4675
|
-
consumer_remaining: z6.number()
|
|
4676
|
-
});
|
|
4677
|
-
var EscrowSettleMessageSchema = z6.object({
|
|
4678
|
-
type: z6.literal("escrow_settle"),
|
|
4679
|
-
escrow_id: z6.string().min(1),
|
|
4680
|
-
request_id: z6.string().uuid(),
|
|
4681
|
-
success: z6.boolean(),
|
|
4682
|
-
failure_reason: z6.enum(["bad_execution", "overload", "timeout", "auth_error", "not_found"]).optional(),
|
|
4683
|
-
result_hash: z6.string().optional(),
|
|
4684
|
-
signature: z6.string().optional(),
|
|
4685
|
-
public_key: z6.string().optional(),
|
|
4686
|
-
consumer_agent_id: z6.string().optional()
|
|
4687
|
-
});
|
|
4688
|
-
var EscrowSettledMessageSchema = z6.object({
|
|
4689
|
-
type: z6.literal("escrow_settled"),
|
|
4690
|
-
escrow_id: z6.string(),
|
|
4691
|
-
request_id: z6.string(),
|
|
4692
|
-
provider_earned: z6.number(),
|
|
4693
|
-
network_fee: z6.number(),
|
|
4694
|
-
consumer_remaining: z6.number(),
|
|
4695
|
-
provider_balance: z6.number()
|
|
4696
|
-
});
|
|
4697
|
-
var BalanceSyncMessageSchema = z6.object({
|
|
4698
|
-
type: z6.literal("balance_sync"),
|
|
4699
|
-
agent_id: z6.string().min(1)
|
|
4700
|
-
});
|
|
4701
|
-
var BalanceSyncResponseMessageSchema = z6.object({
|
|
4702
|
-
type: z6.literal("balance_sync_response"),
|
|
4703
|
-
agent_id: z6.string(),
|
|
4704
|
-
balance: z6.number()
|
|
4705
|
-
});
|
|
4706
|
-
var RelayMessageSchema = z6.discriminatedUnion("type", [
|
|
4707
|
-
RegisterMessageSchema,
|
|
4708
|
-
RegisteredMessageSchema,
|
|
4709
|
-
RelayRequestMessageSchema,
|
|
4710
|
-
IncomingRequestMessageSchema,
|
|
4711
|
-
RelayResponseMessageSchema,
|
|
4712
|
-
ResponseMessageSchema,
|
|
4713
|
-
ErrorMessageSchema,
|
|
4714
|
-
RelayProgressMessageSchema,
|
|
4715
|
-
HeartbeatMessageSchema,
|
|
4716
|
-
EscrowHoldMessageSchema,
|
|
4717
|
-
EscrowHoldConfirmedMessageSchema,
|
|
4718
|
-
EscrowSettleMessageSchema,
|
|
4719
|
-
EscrowSettledMessageSchema,
|
|
4720
|
-
BalanceSyncMessageSchema,
|
|
4721
|
-
BalanceSyncResponseMessageSchema
|
|
4722
|
-
]);
|
|
4723
|
-
|
|
4724
4628
|
// src/relay/websocket-relay.ts
|
|
4725
|
-
import { randomUUID as
|
|
4629
|
+
import { randomUUID as randomUUID17 } from "crypto";
|
|
4726
4630
|
|
|
4727
4631
|
// src/relay/relay-credit.ts
|
|
4728
4632
|
function lookupCardPrice(registryDb, cardId, skillId) {
|
|
@@ -4852,10 +4756,10 @@ function settleWithNetworkFee(creditDb, escrowId, providerOwner) {
|
|
|
4852
4756
|
}
|
|
4853
4757
|
|
|
4854
4758
|
// src/hub-agent/relay-bridge.ts
|
|
4855
|
-
import { randomUUID as
|
|
4759
|
+
import { randomUUID as randomUUID16 } from "crypto";
|
|
4856
4760
|
|
|
4857
4761
|
// src/hub-agent/job-queue.ts
|
|
4858
|
-
import { randomUUID as
|
|
4762
|
+
import { randomUUID as randomUUID15 } from "crypto";
|
|
4859
4763
|
function updateJobStatus(db, jobId, status, result) {
|
|
4860
4764
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
4861
4765
|
if (result !== void 0) {
|
|
@@ -4984,7 +4888,7 @@ function registerWebSocketRelay(server, db, creditDb) {
|
|
|
4984
4888
|
function logAgentJoined(owner, cardName, cardId) {
|
|
4985
4889
|
try {
|
|
4986
4890
|
insertRequestLog(db, {
|
|
4987
|
-
id:
|
|
4891
|
+
id: randomUUID17(),
|
|
4988
4892
|
card_id: cardId,
|
|
4989
4893
|
card_name: cardName,
|
|
4990
4894
|
requester: owner,
|
|
@@ -5466,312 +5370,6 @@ function registerWebSocketRelay(server, db, creditDb) {
|
|
|
5466
5370
|
};
|
|
5467
5371
|
}
|
|
5468
5372
|
|
|
5469
|
-
// src/relay/websocket-client.ts
|
|
5470
|
-
import WebSocket from "ws";
|
|
5471
|
-
import { randomUUID as randomUUID17 } from "crypto";
|
|
5472
|
-
var RelayClient = class {
|
|
5473
|
-
ws = null;
|
|
5474
|
-
opts;
|
|
5475
|
-
pendingRequests = /* @__PURE__ */ new Map();
|
|
5476
|
-
reconnectAttempts = 0;
|
|
5477
|
-
reconnectTimer = null;
|
|
5478
|
-
intentionalClose = false;
|
|
5479
|
-
registered = false;
|
|
5480
|
-
pongTimeout = null;
|
|
5481
|
-
pingInterval = null;
|
|
5482
|
-
constructor(opts) {
|
|
5483
|
-
this.opts = opts;
|
|
5484
|
-
}
|
|
5485
|
-
/**
|
|
5486
|
-
* Connect to the registry relay and register.
|
|
5487
|
-
* Resolves when registration is acknowledged.
|
|
5488
|
-
*/
|
|
5489
|
-
async connect() {
|
|
5490
|
-
return new Promise((resolve, reject) => {
|
|
5491
|
-
this.intentionalClose = false;
|
|
5492
|
-
this.registered = false;
|
|
5493
|
-
const wsUrl = this.buildWsUrl();
|
|
5494
|
-
this.ws = new WebSocket(wsUrl);
|
|
5495
|
-
let resolved = false;
|
|
5496
|
-
this.ws.on("open", () => {
|
|
5497
|
-
this.reconnectAttempts = 0;
|
|
5498
|
-
this.startPingInterval();
|
|
5499
|
-
this.send({
|
|
5500
|
-
type: "register",
|
|
5501
|
-
owner: this.opts.owner,
|
|
5502
|
-
...this.opts.agent_id ? { agent_id: this.opts.agent_id } : {},
|
|
5503
|
-
...this.opts.server_id ? { server_id: this.opts.server_id } : {},
|
|
5504
|
-
token: this.opts.token,
|
|
5505
|
-
card: this.opts.card,
|
|
5506
|
-
...this.opts.cards && this.opts.cards.length > 0 ? { cards: this.opts.cards } : {},
|
|
5507
|
-
...this.opts.agents && this.opts.agents.length > 0 ? { agents: this.opts.agents } : {}
|
|
5508
|
-
});
|
|
5509
|
-
});
|
|
5510
|
-
this.ws.on("message", (raw) => {
|
|
5511
|
-
this.handleMessage(raw, (err) => {
|
|
5512
|
-
if (!resolved) {
|
|
5513
|
-
resolved = true;
|
|
5514
|
-
if (err) reject(err);
|
|
5515
|
-
else resolve();
|
|
5516
|
-
}
|
|
5517
|
-
});
|
|
5518
|
-
});
|
|
5519
|
-
this.ws.on("close", () => {
|
|
5520
|
-
this.cleanup();
|
|
5521
|
-
if (!this.intentionalClose) {
|
|
5522
|
-
if (!resolved) {
|
|
5523
|
-
resolved = true;
|
|
5524
|
-
reject(new Error("WebSocket closed before registration"));
|
|
5525
|
-
}
|
|
5526
|
-
this.scheduleReconnect();
|
|
5527
|
-
}
|
|
5528
|
-
});
|
|
5529
|
-
this.ws.on("error", (err) => {
|
|
5530
|
-
if (!resolved) {
|
|
5531
|
-
resolved = true;
|
|
5532
|
-
reject(err);
|
|
5533
|
-
}
|
|
5534
|
-
});
|
|
5535
|
-
setTimeout(() => {
|
|
5536
|
-
if (!resolved) {
|
|
5537
|
-
resolved = true;
|
|
5538
|
-
reject(new Error("Connection timeout"));
|
|
5539
|
-
this.ws?.close();
|
|
5540
|
-
}
|
|
5541
|
-
}, 1e4);
|
|
5542
|
-
});
|
|
5543
|
-
}
|
|
5544
|
-
/**
|
|
5545
|
-
* Disconnect from the registry relay.
|
|
5546
|
-
*/
|
|
5547
|
-
disconnect() {
|
|
5548
|
-
this.intentionalClose = true;
|
|
5549
|
-
this.cleanup();
|
|
5550
|
-
if (this.ws) {
|
|
5551
|
-
try {
|
|
5552
|
-
this.ws.close(1e3, "Client disconnect");
|
|
5553
|
-
} catch {
|
|
5554
|
-
}
|
|
5555
|
-
this.ws = null;
|
|
5556
|
-
}
|
|
5557
|
-
for (const [id, pending] of this.pendingRequests) {
|
|
5558
|
-
clearTimeout(pending.timeout);
|
|
5559
|
-
pending.reject(new Error("Client disconnected"));
|
|
5560
|
-
this.pendingRequests.delete(id);
|
|
5561
|
-
}
|
|
5562
|
-
}
|
|
5563
|
-
/**
|
|
5564
|
-
* Send a relay request to another agent via the registry.
|
|
5565
|
-
* @returns The result from the target agent.
|
|
5566
|
-
*/
|
|
5567
|
-
async request(opts) {
|
|
5568
|
-
if (!this.ws || this.ws.readyState !== WebSocket.OPEN || !this.registered) {
|
|
5569
|
-
throw new Error("Not connected to registry relay");
|
|
5570
|
-
}
|
|
5571
|
-
const id = randomUUID17();
|
|
5572
|
-
const timeoutMs = opts.timeoutMs ?? 3e5;
|
|
5573
|
-
return new Promise((resolve, reject) => {
|
|
5574
|
-
const timeout = setTimeout(() => {
|
|
5575
|
-
this.pendingRequests.delete(id);
|
|
5576
|
-
reject(new Error("Relay request timeout"));
|
|
5577
|
-
}, timeoutMs);
|
|
5578
|
-
this.pendingRequests.set(id, { resolve, reject, timeout, timeoutMs, onProgress: opts.onProgress });
|
|
5579
|
-
this.send({
|
|
5580
|
-
type: "relay_request",
|
|
5581
|
-
id,
|
|
5582
|
-
target_owner: opts.targetOwner,
|
|
5583
|
-
...opts.targetAgentId ? { target_agent_id: opts.targetAgentId } : {},
|
|
5584
|
-
card_id: opts.cardId,
|
|
5585
|
-
skill_id: opts.skillId,
|
|
5586
|
-
params: opts.params,
|
|
5587
|
-
requester: opts.requester ?? this.opts.owner,
|
|
5588
|
-
escrow_receipt: opts.escrowReceipt
|
|
5589
|
-
});
|
|
5590
|
-
});
|
|
5591
|
-
}
|
|
5592
|
-
/**
|
|
5593
|
-
* Send a relay_progress message to the relay server for a given request.
|
|
5594
|
-
* Used by the onRequest handler to forward SkillExecutor progress updates
|
|
5595
|
-
* to the requesting agent so it can reset its timeout window.
|
|
5596
|
-
*
|
|
5597
|
-
* @param requestId - The relay request ID to associate progress with.
|
|
5598
|
-
* @param info - Progress details (step, total, message).
|
|
5599
|
-
*/
|
|
5600
|
-
sendProgress(requestId, info) {
|
|
5601
|
-
this.send({
|
|
5602
|
-
type: "relay_progress",
|
|
5603
|
-
id: requestId,
|
|
5604
|
-
progress: Math.round(info.step / info.total * 100),
|
|
5605
|
-
message: info.message
|
|
5606
|
-
});
|
|
5607
|
-
}
|
|
5608
|
-
/** Whether the client is connected and registered */
|
|
5609
|
-
get isConnected() {
|
|
5610
|
-
return this.ws !== null && this.ws.readyState === WebSocket.OPEN && this.registered;
|
|
5611
|
-
}
|
|
5612
|
-
// ── Private methods ─────────────────────────────────────────────────────────
|
|
5613
|
-
buildWsUrl() {
|
|
5614
|
-
let url = this.opts.registryUrl;
|
|
5615
|
-
if (url.startsWith("http://")) {
|
|
5616
|
-
url = "ws://" + url.slice(7);
|
|
5617
|
-
} else if (url.startsWith("https://")) {
|
|
5618
|
-
url = "wss://" + url.slice(8);
|
|
5619
|
-
} else if (!url.startsWith("ws://") && !url.startsWith("wss://")) {
|
|
5620
|
-
url = "wss://" + url;
|
|
5621
|
-
}
|
|
5622
|
-
if (!url.endsWith("/ws")) {
|
|
5623
|
-
url = url.replace(/\/$/, "") + "/ws";
|
|
5624
|
-
}
|
|
5625
|
-
return url;
|
|
5626
|
-
}
|
|
5627
|
-
handleMessage(raw, onRegistered) {
|
|
5628
|
-
let data;
|
|
5629
|
-
try {
|
|
5630
|
-
data = JSON.parse(typeof raw === "string" ? raw : raw.toString("utf-8"));
|
|
5631
|
-
} catch {
|
|
5632
|
-
return;
|
|
5633
|
-
}
|
|
5634
|
-
const parsed = RelayMessageSchema.safeParse(data);
|
|
5635
|
-
if (!parsed.success) return;
|
|
5636
|
-
const msg = parsed.data;
|
|
5637
|
-
switch (msg.type) {
|
|
5638
|
-
case "registered":
|
|
5639
|
-
this.registered = true;
|
|
5640
|
-
if (!this.opts.silent) {
|
|
5641
|
-
console.log(` \u2713 Registered with registry (agent_id: ${msg.agent_id})`);
|
|
5642
|
-
}
|
|
5643
|
-
onRegistered?.();
|
|
5644
|
-
break;
|
|
5645
|
-
case "incoming_request":
|
|
5646
|
-
this.handleIncomingRequest(msg);
|
|
5647
|
-
break;
|
|
5648
|
-
case "response":
|
|
5649
|
-
this.handleResponse(msg);
|
|
5650
|
-
break;
|
|
5651
|
-
case "error":
|
|
5652
|
-
this.handleError(msg);
|
|
5653
|
-
break;
|
|
5654
|
-
case "relay_progress":
|
|
5655
|
-
this.handleProgress(msg);
|
|
5656
|
-
break;
|
|
5657
|
-
default:
|
|
5658
|
-
break;
|
|
5659
|
-
}
|
|
5660
|
-
}
|
|
5661
|
-
async handleIncomingRequest(msg) {
|
|
5662
|
-
try {
|
|
5663
|
-
const result = await this.opts.onRequest(msg);
|
|
5664
|
-
this.send({
|
|
5665
|
-
type: "relay_response",
|
|
5666
|
-
id: msg.id,
|
|
5667
|
-
result: result.result,
|
|
5668
|
-
error: result.error
|
|
5669
|
-
});
|
|
5670
|
-
} catch (err) {
|
|
5671
|
-
this.send({
|
|
5672
|
-
type: "relay_response",
|
|
5673
|
-
id: msg.id,
|
|
5674
|
-
error: {
|
|
5675
|
-
code: -32603,
|
|
5676
|
-
message: err instanceof Error ? err.message : "Internal error"
|
|
5677
|
-
}
|
|
5678
|
-
});
|
|
5679
|
-
}
|
|
5680
|
-
}
|
|
5681
|
-
handleResponse(msg) {
|
|
5682
|
-
const pending = this.pendingRequests.get(msg.id);
|
|
5683
|
-
if (!pending) return;
|
|
5684
|
-
clearTimeout(pending.timeout);
|
|
5685
|
-
this.pendingRequests.delete(msg.id);
|
|
5686
|
-
if (msg.error) {
|
|
5687
|
-
pending.reject(new Error(msg.error.message));
|
|
5688
|
-
} else {
|
|
5689
|
-
pending.resolve(msg.result);
|
|
5690
|
-
}
|
|
5691
|
-
}
|
|
5692
|
-
handleError(msg) {
|
|
5693
|
-
if (msg.request_id) {
|
|
5694
|
-
const pending = this.pendingRequests.get(msg.request_id);
|
|
5695
|
-
if (pending) {
|
|
5696
|
-
clearTimeout(pending.timeout);
|
|
5697
|
-
this.pendingRequests.delete(msg.request_id);
|
|
5698
|
-
pending.reject(new Error(`${msg.code}: ${msg.message}`));
|
|
5699
|
-
}
|
|
5700
|
-
}
|
|
5701
|
-
}
|
|
5702
|
-
handleProgress(msg) {
|
|
5703
|
-
const pending = this.pendingRequests.get(msg.id);
|
|
5704
|
-
if (!pending) return;
|
|
5705
|
-
clearTimeout(pending.timeout);
|
|
5706
|
-
const newTimeout = setTimeout(() => {
|
|
5707
|
-
this.pendingRequests.delete(msg.id);
|
|
5708
|
-
pending.reject(new Error("Relay request timeout"));
|
|
5709
|
-
}, pending.timeoutMs);
|
|
5710
|
-
pending.timeout = newTimeout;
|
|
5711
|
-
if (pending.onProgress) {
|
|
5712
|
-
pending.onProgress({ id: msg.id, progress: msg.progress, message: msg.message });
|
|
5713
|
-
}
|
|
5714
|
-
}
|
|
5715
|
-
send(msg) {
|
|
5716
|
-
if (this.ws && this.ws.readyState === WebSocket.OPEN) {
|
|
5717
|
-
this.ws.send(JSON.stringify(msg));
|
|
5718
|
-
}
|
|
5719
|
-
}
|
|
5720
|
-
startPingInterval() {
|
|
5721
|
-
this.stopPingInterval();
|
|
5722
|
-
this.pingInterval = setInterval(() => {
|
|
5723
|
-
if (this.ws && this.ws.readyState === WebSocket.OPEN) {
|
|
5724
|
-
this.ws.ping();
|
|
5725
|
-
this.pongTimeout = setTimeout(() => {
|
|
5726
|
-
if (!this.opts.silent) {
|
|
5727
|
-
console.log(" \u26A0 Registry pong timeout, reconnecting...");
|
|
5728
|
-
}
|
|
5729
|
-
this.ws?.terminate();
|
|
5730
|
-
}, 15e3);
|
|
5731
|
-
}
|
|
5732
|
-
}, 3e4);
|
|
5733
|
-
this.ws?.on("pong", () => {
|
|
5734
|
-
if (this.pongTimeout) {
|
|
5735
|
-
clearTimeout(this.pongTimeout);
|
|
5736
|
-
this.pongTimeout = null;
|
|
5737
|
-
}
|
|
5738
|
-
});
|
|
5739
|
-
}
|
|
5740
|
-
stopPingInterval() {
|
|
5741
|
-
if (this.pingInterval) {
|
|
5742
|
-
clearInterval(this.pingInterval);
|
|
5743
|
-
this.pingInterval = null;
|
|
5744
|
-
}
|
|
5745
|
-
if (this.pongTimeout) {
|
|
5746
|
-
clearTimeout(this.pongTimeout);
|
|
5747
|
-
this.pongTimeout = null;
|
|
5748
|
-
}
|
|
5749
|
-
}
|
|
5750
|
-
cleanup() {
|
|
5751
|
-
this.stopPingInterval();
|
|
5752
|
-
this.registered = false;
|
|
5753
|
-
}
|
|
5754
|
-
scheduleReconnect() {
|
|
5755
|
-
if (this.intentionalClose) return;
|
|
5756
|
-
if (this.reconnectTimer) return;
|
|
5757
|
-
const delay = Math.min(1e3 * Math.pow(2, this.reconnectAttempts), 3e4);
|
|
5758
|
-
this.reconnectAttempts++;
|
|
5759
|
-
if (!this.opts.silent) {
|
|
5760
|
-
console.log(` \u21BB Reconnecting to registry in ${delay / 1e3}s...`);
|
|
5761
|
-
}
|
|
5762
|
-
this.reconnectTimer = setTimeout(async () => {
|
|
5763
|
-
this.reconnectTimer = null;
|
|
5764
|
-
try {
|
|
5765
|
-
await this.connect();
|
|
5766
|
-
if (!this.opts.silent) {
|
|
5767
|
-
console.log(" \u2713 Reconnected to registry");
|
|
5768
|
-
}
|
|
5769
|
-
} catch {
|
|
5770
|
-
}
|
|
5771
|
-
}, delay);
|
|
5772
|
-
}
|
|
5773
|
-
};
|
|
5774
|
-
|
|
5775
5373
|
// src/onboarding/index.ts
|
|
5776
5374
|
import { randomUUID as randomUUID19 } from "crypto";
|
|
5777
5375
|
import { existsSync as existsSync5, readFileSync as readFileSync5 } from "fs";
|