agentbnb 8.2.0 → 8.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{chunk-TBJ3FZKZ.js → chunk-7Q2XUXSA.js} +1 -1
- package/dist/{chunk-LJM7FHPM.js → chunk-BZOJ7HBT.js} +33 -1
- package/dist/{chunk-FTZTEHYG.js → chunk-DEWY7OQK.js} +135 -8
- package/dist/{chunk-CUONY5TO.js → chunk-EJKW57ZV.js} +19 -1
- package/dist/chunk-EZVOG7QS.js +161 -0
- package/dist/{chunk-E2OKP5CY.js → chunk-GJETGML6.js} +181 -83
- package/dist/{chunk-YHY7OG6S.js → chunk-GWMMYVLL.js} +4 -4
- package/dist/{chunk-D6RKW2XG.js → chunk-JLNHMNES.js} +16 -3
- package/dist/{chunk-5AAFG2V2.js → chunk-KBQNTUTN.js} +239 -24
- package/dist/{chunk-C537SFHV.js → chunk-LOUEJI6X.js} +4 -4
- package/dist/{chunk-ALX4WS3A.js → chunk-NP55V7RQ.js} +1 -1
- package/dist/{chunk-X32NE6V4.js → chunk-RBXTWWUH.js} +1 -1
- package/dist/{chunk-O2OYBAVR.js → chunk-SRBVKO2V.js} +9 -0
- package/dist/{chunk-7EF3HYVZ.js → chunk-STJLWMXH.js} +48 -4
- package/dist/{chunk-5GME4KJZ.js → chunk-UYCD3JBZ.js} +3 -3
- package/dist/{chunk-P4LOYSLA.js → chunk-WKWJWKX7.js} +286 -81
- package/dist/cli/index.js +35 -57
- package/dist/{client-HKV3QWZ3.js → client-66TFS7RS.js} +4 -2
- package/dist/{conduct-W6XF6DJW.js → conduct-A6COHLHY.js} +8 -8
- package/dist/{conduct-YB64OHI6.js → conduct-IUVAXUAV.js} +8 -8
- package/dist/{conductor-mode-TFCVCQHU.js → conductor-mode-D5TFQW5L.js} +2 -2
- package/dist/{conductor-mode-AKREGDIU.js → conductor-mode-L2MB44BW.js} +7 -7
- package/dist/{execute-AYQWORVH.js → execute-5AWLARB5.js} +5 -5
- package/dist/{execute-EPE6MZLT.js → execute-WOS457HW.js} +2 -2
- package/dist/index.js +438 -92
- package/dist/{publish-capability-AH2HDW54.js → publish-capability-JJCBBMSX.js} +2 -2
- package/dist/{request-HCCXSKAY.js → request-6YQLA7K3.js} +13 -8
- package/dist/{serve-skill-SZAQT5T5.js → serve-skill-X7TZSILV.js} +5 -5
- package/dist/{server-LMY2A3GT.js → server-5TSP4DBX.js} +10 -12
- package/dist/{service-coordinator-WGH6B2VT.js → service-coordinator-WTUSMPY6.js} +69 -46
- package/dist/skills/agentbnb/bootstrap.js +459 -189
- package/package.json +13 -17
- package/skills/agentbnb/bootstrap.test.ts +8 -6
- package/skills/agentbnb/bootstrap.ts +21 -13
- package/skills/agentbnb/install.sh +0 -0
- package/dist/chunk-64AK4FJM.js +0 -84
- package/dist/chunk-OH7BP5NP.js +0 -96
- package/dist/index.d.ts +0 -5069
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
import {
|
|
2
2
|
settleProviderEarning
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-RBXTWWUH.js";
|
|
4
4
|
import {
|
|
5
5
|
getBalance,
|
|
6
6
|
holdEscrow,
|
|
7
7
|
releaseEscrow,
|
|
8
8
|
settleEscrow
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-JLNHMNES.js";
|
|
10
10
|
import {
|
|
11
11
|
verifyEscrowReceipt
|
|
12
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-EJKW57ZV.js";
|
|
13
13
|
import {
|
|
14
14
|
loadConfig
|
|
15
15
|
} from "./chunk-75OC6E4F.js";
|
|
@@ -17,7 +17,7 @@ import {
|
|
|
17
17
|
getCard,
|
|
18
18
|
insertRequestLog,
|
|
19
19
|
updateReputation
|
|
20
|
-
} from "./chunk-
|
|
20
|
+
} from "./chunk-SRBVKO2V.js";
|
|
21
21
|
import {
|
|
22
22
|
AgentBnBError
|
|
23
23
|
} from "./chunk-WVY2W7AA.js";
|
|
@@ -498,6 +498,15 @@ function openDatabase(path = ":memory:") {
|
|
|
498
498
|
tags,
|
|
499
499
|
content=""
|
|
500
500
|
);
|
|
501
|
+
|
|
502
|
+
-- Expression index for capability_type lookups (used by Conductor routing).
|
|
503
|
+
-- Turns json_extract full-table-scan into O(log n) B-tree lookup.
|
|
504
|
+
CREATE INDEX IF NOT EXISTS idx_cards_capability_type
|
|
505
|
+
ON capability_cards(json_extract(data, '$.capability_type'));
|
|
506
|
+
|
|
507
|
+
-- Owner index for listCards(owner) and other owner-scoped queries.
|
|
508
|
+
CREATE INDEX IF NOT EXISTS idx_cards_owner
|
|
509
|
+
ON capability_cards(owner);
|
|
501
510
|
`);
|
|
502
511
|
createRequestLogTable(db);
|
|
503
512
|
initFeedbackTable(db);
|
|
@@ -502,6 +502,15 @@ function openDatabase(path = ":memory:") {
|
|
|
502
502
|
tags,
|
|
503
503
|
content=""
|
|
504
504
|
);
|
|
505
|
+
|
|
506
|
+
-- Expression index for capability_type lookups (used by Conductor routing).
|
|
507
|
+
-- Turns json_extract full-table-scan into O(log n) B-tree lookup.
|
|
508
|
+
CREATE INDEX IF NOT EXISTS idx_cards_capability_type
|
|
509
|
+
ON capability_cards(json_extract(data, '$.capability_type'));
|
|
510
|
+
|
|
511
|
+
-- Owner index for listCards(owner) and other owner-scoped queries.
|
|
512
|
+
CREATE INDEX IF NOT EXISTS idx_cards_owner
|
|
513
|
+
ON capability_cards(owner);
|
|
505
514
|
`);
|
|
506
515
|
createRequestLogTable(db);
|
|
507
516
|
initFeedbackTable(db);
|
|
@@ -759,6 +768,9 @@ var AGENTS_SCHEMA = `
|
|
|
759
768
|
function ensureAgentsTable(db) {
|
|
760
769
|
db.exec(AGENTS_SCHEMA);
|
|
761
770
|
}
|
|
771
|
+
function lookupAgent(db, agentId) {
|
|
772
|
+
return db.prepare("SELECT * FROM agents WHERE agent_id = ?").get(agentId) ?? null;
|
|
773
|
+
}
|
|
762
774
|
|
|
763
775
|
// src/credit/ledger.ts
|
|
764
776
|
var CREDIT_SCHEMA = `
|
|
@@ -839,10 +851,23 @@ function getBalance(db, owner) {
|
|
|
839
851
|
const row = db.prepare("SELECT balance FROM credit_balances WHERE owner = ?").get(owner);
|
|
840
852
|
return row?.balance ?? 0;
|
|
841
853
|
}
|
|
842
|
-
function getTransactions(db, owner,
|
|
854
|
+
function getTransactions(db, owner, opts = 100) {
|
|
855
|
+
const page = typeof opts === "number" ? { limit: opts } : opts;
|
|
856
|
+
const limit = page.limit ?? 100;
|
|
857
|
+
const conditions = ["owner = ?"];
|
|
858
|
+
const params = [owner];
|
|
859
|
+
if (page.before) {
|
|
860
|
+
conditions.push("created_at < ?");
|
|
861
|
+
params.push(page.before);
|
|
862
|
+
}
|
|
863
|
+
if (page.after) {
|
|
864
|
+
conditions.push("created_at > ?");
|
|
865
|
+
params.push(page.after);
|
|
866
|
+
}
|
|
867
|
+
params.push(limit);
|
|
843
868
|
return db.prepare(
|
|
844
|
-
|
|
845
|
-
).all(
|
|
869
|
+
`SELECT id, owner, amount, reason, reference_id, created_at FROM credit_transactions WHERE ${conditions.join(" AND ")} ORDER BY created_at DESC LIMIT ?`
|
|
870
|
+
).all(...params);
|
|
846
871
|
}
|
|
847
872
|
function registerProvider(db, owner) {
|
|
848
873
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
@@ -1100,7 +1125,25 @@ function loadKeyPair(configDir) {
|
|
|
1100
1125
|
};
|
|
1101
1126
|
}
|
|
1102
1127
|
function canonicalJson(data) {
|
|
1103
|
-
return JSON.stringify(
|
|
1128
|
+
return JSON.stringify(sortForCanonicalJson(data));
|
|
1129
|
+
}
|
|
1130
|
+
function sortForCanonicalJson(value) {
|
|
1131
|
+
if (Array.isArray(value)) {
|
|
1132
|
+
return value.map((item) => sortForCanonicalJson(item));
|
|
1133
|
+
}
|
|
1134
|
+
if (value !== null && typeof value === "object") {
|
|
1135
|
+
const proto = Object.getPrototypeOf(value);
|
|
1136
|
+
if (proto === Object.prototype || proto === null) {
|
|
1137
|
+
const input = value;
|
|
1138
|
+
const output = {};
|
|
1139
|
+
const sortedKeys = Object.keys(input).sort();
|
|
1140
|
+
for (const key of sortedKeys) {
|
|
1141
|
+
output[key] = sortForCanonicalJson(input[key]);
|
|
1142
|
+
}
|
|
1143
|
+
return output;
|
|
1144
|
+
}
|
|
1145
|
+
}
|
|
1146
|
+
return value;
|
|
1104
1147
|
}
|
|
1105
1148
|
function signEscrowReceipt(data, privateKey) {
|
|
1106
1149
|
const message = Buffer.from(canonicalJson(data), "utf-8");
|
|
@@ -1140,6 +1183,7 @@ export {
|
|
|
1140
1183
|
listCards,
|
|
1141
1184
|
getCardsByCapabilityType,
|
|
1142
1185
|
getCardsBySkillCapability,
|
|
1186
|
+
lookupAgent,
|
|
1143
1187
|
openCreditDb,
|
|
1144
1188
|
bootstrapAgent,
|
|
1145
1189
|
getBalance,
|
|
@@ -8,16 +8,16 @@ import {
|
|
|
8
8
|
} from "./chunk-GKVTD4EZ.js";
|
|
9
9
|
import {
|
|
10
10
|
searchCards
|
|
11
|
-
} from "./chunk-
|
|
11
|
+
} from "./chunk-BZOJ7HBT.js";
|
|
12
12
|
import {
|
|
13
13
|
getBalance,
|
|
14
14
|
holdEscrow,
|
|
15
15
|
releaseEscrow,
|
|
16
16
|
settleEscrow
|
|
17
|
-
} from "./chunk-
|
|
17
|
+
} from "./chunk-JLNHMNES.js";
|
|
18
18
|
import {
|
|
19
19
|
requestCapability
|
|
20
|
-
} from "./chunk-
|
|
20
|
+
} from "./chunk-EZVOG7QS.js";
|
|
21
21
|
import {
|
|
22
22
|
findPeer
|
|
23
23
|
} from "./chunk-5AH3CMOX.js";
|
|
@@ -8,7 +8,7 @@ import {
|
|
|
8
8
|
releaseEscrow,
|
|
9
9
|
settleEscrow,
|
|
10
10
|
signEscrowReceipt
|
|
11
|
-
} from "./chunk-
|
|
11
|
+
} from "./chunk-STJLWMXH.js";
|
|
12
12
|
import {
|
|
13
13
|
AgentBnBError
|
|
14
14
|
} from "./chunk-WVY2W7AA.js";
|
|
@@ -258,6 +258,13 @@ function decompose(task, _availableCapabilities) {
|
|
|
258
258
|
|
|
259
259
|
// src/gateway/client.ts
|
|
260
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
|
+
});
|
|
261
268
|
async function requestCapability(opts) {
|
|
262
269
|
const { gatewayUrl, token, cardId, params = {}, timeoutMs = 3e5, escrowReceipt, identity } = opts;
|
|
263
270
|
const id = randomUUID2();
|
|
@@ -288,7 +295,9 @@ async function requestCapability(opts) {
|
|
|
288
295
|
method: "POST",
|
|
289
296
|
headers,
|
|
290
297
|
body: JSON.stringify(payload),
|
|
291
|
-
signal: controller.signal
|
|
298
|
+
signal: controller.signal,
|
|
299
|
+
// undici dispatcher for connection pooling (Node.js 20+)
|
|
300
|
+
dispatcher: gatewayAgent
|
|
292
301
|
});
|
|
293
302
|
} catch (err) {
|
|
294
303
|
clearTimeout(timer);
|
|
@@ -306,6 +315,73 @@ async function requestCapability(opts) {
|
|
|
306
315
|
}
|
|
307
316
|
return body.result;
|
|
308
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
|
+
}
|
|
309
385
|
async function requestViaRelay(relay, opts) {
|
|
310
386
|
try {
|
|
311
387
|
return await relay.request({
|
|
@@ -376,7 +452,37 @@ function getReputationScore(db, agentId) {
|
|
|
376
452
|
}
|
|
377
453
|
|
|
378
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
|
+
}
|
|
379
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
|
+
}
|
|
380
486
|
const words = query.trim().split(/\s+/).map((w) => w.replace(/["*^{}():]/g, "")).filter((w) => w.length > 0);
|
|
381
487
|
if (words.length === 0) return [];
|
|
382
488
|
const ftsQuery = words.map((w) => `"${w}"`).join(" OR ");
|
|
@@ -414,6 +520,8 @@ function searchCards(db, query, filters = {}) {
|
|
|
414
520
|
if (filters.min_reputation !== void 0 && filters.min_reputation > 0) {
|
|
415
521
|
filtered = applyReputationFilter(db, filtered, filters.min_reputation);
|
|
416
522
|
}
|
|
523
|
+
evictCache(cache);
|
|
524
|
+
cache.set(key, { results: filtered, expiresAt: Date.now() + CACHE_TTL_MS });
|
|
417
525
|
return filtered;
|
|
418
526
|
}
|
|
419
527
|
function filterCards(db, filters) {
|
|
@@ -1087,6 +1195,65 @@ function computeWaves(subtasks) {
|
|
|
1087
1195
|
}
|
|
1088
1196
|
return waves;
|
|
1089
1197
|
}
|
|
1198
|
+
async function executeSingleTask(pt, gatewayToken, timeoutMs, requesterOwner, relayClient, resolveAgentUrl) {
|
|
1199
|
+
const { taskId, match: m, interpolatedParams, primary, teamId, capabilityType } = pt;
|
|
1200
|
+
try {
|
|
1201
|
+
let res;
|
|
1202
|
+
if (primary.url.startsWith("relay://") && relayClient) {
|
|
1203
|
+
const targetOwner = primary.url.replace("relay://", "");
|
|
1204
|
+
res = await relayClient.request({
|
|
1205
|
+
targetOwner,
|
|
1206
|
+
cardId: primary.cardId,
|
|
1207
|
+
params: interpolatedParams,
|
|
1208
|
+
requester: requesterOwner,
|
|
1209
|
+
timeoutMs
|
|
1210
|
+
});
|
|
1211
|
+
} else {
|
|
1212
|
+
res = await requestCapability({
|
|
1213
|
+
gatewayUrl: primary.url,
|
|
1214
|
+
token: gatewayToken,
|
|
1215
|
+
cardId: primary.cardId,
|
|
1216
|
+
params: { ...interpolatedParams, requester: requesterOwner },
|
|
1217
|
+
timeoutMs
|
|
1218
|
+
});
|
|
1219
|
+
}
|
|
1220
|
+
return { taskId, result: res, credits: m.credits, team_id: teamId, capability_type: capabilityType };
|
|
1221
|
+
} catch (primaryErr) {
|
|
1222
|
+
if (m.alternatives.length > 0) {
|
|
1223
|
+
const alt = m.alternatives[0];
|
|
1224
|
+
const altResolved = resolveAgentUrl ? resolveAgentUrl(alt.agent) : { url: `http://${alt.agent}:7700`, cardId: `card-${alt.agent}` };
|
|
1225
|
+
try {
|
|
1226
|
+
let altRes;
|
|
1227
|
+
if (altResolved.url.startsWith("relay://") && relayClient) {
|
|
1228
|
+
const targetOwner = altResolved.url.replace("relay://", "");
|
|
1229
|
+
altRes = await relayClient.request({
|
|
1230
|
+
targetOwner,
|
|
1231
|
+
cardId: altResolved.cardId,
|
|
1232
|
+
params: interpolatedParams,
|
|
1233
|
+
requester: requesterOwner,
|
|
1234
|
+
timeoutMs
|
|
1235
|
+
});
|
|
1236
|
+
} else {
|
|
1237
|
+
altRes = await requestCapability({
|
|
1238
|
+
gatewayUrl: altResolved.url,
|
|
1239
|
+
token: gatewayToken,
|
|
1240
|
+
cardId: altResolved.cardId,
|
|
1241
|
+
params: { ...interpolatedParams, requester: requesterOwner },
|
|
1242
|
+
timeoutMs
|
|
1243
|
+
});
|
|
1244
|
+
}
|
|
1245
|
+
return { taskId, result: altRes, credits: alt.credits, team_id: teamId, capability_type: capabilityType };
|
|
1246
|
+
} catch (altErr) {
|
|
1247
|
+
throw new Error(
|
|
1248
|
+
`Task ${taskId}: primary (${m.selected_agent}) failed: ${primaryErr instanceof Error ? primaryErr.message : String(primaryErr)}; alternative (${alt.agent}) failed: ${altErr instanceof Error ? altErr.message : String(altErr)}`
|
|
1249
|
+
);
|
|
1250
|
+
}
|
|
1251
|
+
}
|
|
1252
|
+
throw new Error(
|
|
1253
|
+
`Task ${taskId}: ${primaryErr instanceof Error ? primaryErr.message : String(primaryErr)}`
|
|
1254
|
+
);
|
|
1255
|
+
}
|
|
1256
|
+
}
|
|
1090
1257
|
async function orchestrate(opts) {
|
|
1091
1258
|
const { subtasks, matches, gatewayToken, resolveAgentUrl, timeoutMs = 3e5, maxBudget, relayClient, requesterOwner } = opts;
|
|
1092
1259
|
const startTime = Date.now();
|
|
@@ -1124,89 +1291,127 @@ async function orchestrate(opts) {
|
|
|
1124
1291
|
}
|
|
1125
1292
|
executableIds.push(taskId);
|
|
1126
1293
|
}
|
|
1127
|
-
const
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
|
|
1131
|
-
|
|
1132
|
-
|
|
1133
|
-
|
|
1134
|
-
|
|
1135
|
-
|
|
1136
|
-
|
|
1137
|
-
|
|
1138
|
-
|
|
1139
|
-
|
|
1140
|
-
|
|
1141
|
-
|
|
1142
|
-
|
|
1143
|
-
|
|
1144
|
-
|
|
1145
|
-
|
|
1146
|
-
|
|
1147
|
-
|
|
1148
|
-
|
|
1149
|
-
|
|
1150
|
-
|
|
1151
|
-
|
|
1152
|
-
|
|
1153
|
-
|
|
1154
|
-
|
|
1155
|
-
|
|
1156
|
-
|
|
1157
|
-
|
|
1158
|
-
|
|
1159
|
-
|
|
1160
|
-
|
|
1161
|
-
|
|
1162
|
-
|
|
1163
|
-
|
|
1164
|
-
|
|
1165
|
-
|
|
1166
|
-
|
|
1167
|
-
|
|
1168
|
-
|
|
1169
|
-
|
|
1170
|
-
|
|
1171
|
-
|
|
1172
|
-
|
|
1173
|
-
|
|
1174
|
-
|
|
1175
|
-
|
|
1176
|
-
const
|
|
1294
|
+
const preparedTasks = [];
|
|
1295
|
+
for (const taskId of executableIds) {
|
|
1296
|
+
const subtask = subtaskMap.get(taskId);
|
|
1297
|
+
const m = matches.get(taskId);
|
|
1298
|
+
if (!m) {
|
|
1299
|
+
errors.push(`No match found for subtask ${taskId}`);
|
|
1300
|
+
continue;
|
|
1301
|
+
}
|
|
1302
|
+
const stepsContext = {};
|
|
1303
|
+
for (const [id, val] of results) stepsContext[id] = val;
|
|
1304
|
+
const interpContext = { steps: stepsContext, prev: void 0 };
|
|
1305
|
+
if (subtask.depends_on.length > 0) {
|
|
1306
|
+
const lastDep = subtask.depends_on[subtask.depends_on.length - 1];
|
|
1307
|
+
interpContext.prev = results.get(lastDep);
|
|
1308
|
+
}
|
|
1309
|
+
const interpolatedParams = interpolateObject(
|
|
1310
|
+
subtask.params,
|
|
1311
|
+
interpContext
|
|
1312
|
+
);
|
|
1313
|
+
const teamMember = teamMemberMap.get(taskId);
|
|
1314
|
+
const agentOwner = teamMember?.agent ?? m.selected_agent;
|
|
1315
|
+
const primary = resolveAgentUrl(agentOwner);
|
|
1316
|
+
preparedTasks.push({
|
|
1317
|
+
taskId,
|
|
1318
|
+
subtask,
|
|
1319
|
+
match: m,
|
|
1320
|
+
interpolatedParams,
|
|
1321
|
+
agentOwner,
|
|
1322
|
+
primary,
|
|
1323
|
+
teamId: opts.team?.team_id ?? null,
|
|
1324
|
+
capabilityType: teamMember?.capability_type ?? null
|
|
1325
|
+
});
|
|
1326
|
+
}
|
|
1327
|
+
const httpGroups = /* @__PURE__ */ new Map();
|
|
1328
|
+
const relayTasks = [];
|
|
1329
|
+
for (const pt of preparedTasks) {
|
|
1330
|
+
if (pt.primary.url.startsWith("relay://") && relayClient) {
|
|
1331
|
+
relayTasks.push(pt);
|
|
1332
|
+
} else {
|
|
1333
|
+
const group = httpGroups.get(pt.primary.url) ?? [];
|
|
1334
|
+
group.push(pt);
|
|
1335
|
+
httpGroups.set(pt.primary.url, group);
|
|
1336
|
+
}
|
|
1337
|
+
}
|
|
1338
|
+
const batchPromises = [];
|
|
1339
|
+
for (const [gatewayUrl, group] of httpGroups) {
|
|
1340
|
+
if (group.length >= 2) {
|
|
1341
|
+
batchPromises.push(
|
|
1342
|
+
(async () => {
|
|
1343
|
+
const items = group.map((pt) => ({
|
|
1344
|
+
id: pt.taskId,
|
|
1345
|
+
cardId: pt.primary.cardId,
|
|
1346
|
+
params: { ...pt.interpolatedParams, requester: requesterOwner },
|
|
1347
|
+
_pt: pt
|
|
1348
|
+
}));
|
|
1177
1349
|
try {
|
|
1178
|
-
|
|
1179
|
-
|
|
1180
|
-
|
|
1181
|
-
|
|
1182
|
-
|
|
1183
|
-
cardId: altAgent.cardId,
|
|
1184
|
-
params: interpolatedParams,
|
|
1185
|
-
requester: requesterOwner,
|
|
1186
|
-
timeoutMs
|
|
1187
|
-
});
|
|
1188
|
-
} else {
|
|
1189
|
-
altRes = await requestCapability({
|
|
1190
|
-
gatewayUrl: altAgent.url,
|
|
1191
|
-
token: gatewayToken,
|
|
1192
|
-
cardId: altAgent.cardId,
|
|
1193
|
-
params: { ...interpolatedParams, requester: requesterOwner },
|
|
1194
|
-
timeoutMs
|
|
1195
|
-
});
|
|
1196
|
-
}
|
|
1197
|
-
return { taskId, result: altRes, credits: alt.credits, team_id: teamId, capability_type: taskCapabilityType };
|
|
1198
|
-
} catch (altErr) {
|
|
1199
|
-
throw new Error(
|
|
1200
|
-
`Task ${taskId}: primary (${m.selected_agent}) failed: ${primaryErr instanceof Error ? primaryErr.message : String(primaryErr)}; alternative (${alt.agent}) failed: ${altErr instanceof Error ? altErr.message : String(altErr)}`
|
|
1350
|
+
const batchResults = await requestCapabilityBatch(
|
|
1351
|
+
gatewayUrl,
|
|
1352
|
+
gatewayToken,
|
|
1353
|
+
items.map(({ _pt, ...item }) => item),
|
|
1354
|
+
{ timeoutMs }
|
|
1201
1355
|
);
|
|
1356
|
+
return items.map((item) => {
|
|
1357
|
+
const res = batchResults.get(item.id);
|
|
1358
|
+
if (res instanceof Error) {
|
|
1359
|
+
return {
|
|
1360
|
+
status: "rejected",
|
|
1361
|
+
reason: new Error(`Task ${item.id}: ${res.message}`)
|
|
1362
|
+
};
|
|
1363
|
+
}
|
|
1364
|
+
return {
|
|
1365
|
+
status: "fulfilled",
|
|
1366
|
+
value: {
|
|
1367
|
+
taskId: item.id,
|
|
1368
|
+
result: res,
|
|
1369
|
+
credits: item._pt.match.credits,
|
|
1370
|
+
team_id: item._pt.teamId,
|
|
1371
|
+
capability_type: item._pt.capabilityType
|
|
1372
|
+
}
|
|
1373
|
+
};
|
|
1374
|
+
});
|
|
1375
|
+
} catch (batchErr) {
|
|
1376
|
+
return Promise.all(group.map(async (pt) => {
|
|
1377
|
+
try {
|
|
1378
|
+
const res = await executeSingleTask(pt, gatewayToken, timeoutMs, requesterOwner, relayClient, resolveAgentUrl);
|
|
1379
|
+
return { status: "fulfilled", value: res };
|
|
1380
|
+
} catch (err) {
|
|
1381
|
+
return { status: "rejected", reason: err };
|
|
1382
|
+
}
|
|
1383
|
+
}));
|
|
1202
1384
|
}
|
|
1385
|
+
})()
|
|
1386
|
+
);
|
|
1387
|
+
} else {
|
|
1388
|
+
const pt = group[0];
|
|
1389
|
+
batchPromises.push(
|
|
1390
|
+
(async () => {
|
|
1391
|
+
try {
|
|
1392
|
+
const res = await executeSingleTask(pt, gatewayToken, timeoutMs, requesterOwner, relayClient, resolveAgentUrl);
|
|
1393
|
+
return [{ status: "fulfilled", value: res }];
|
|
1394
|
+
} catch (err) {
|
|
1395
|
+
return [{ status: "rejected", reason: err }];
|
|
1396
|
+
}
|
|
1397
|
+
})()
|
|
1398
|
+
);
|
|
1399
|
+
}
|
|
1400
|
+
}
|
|
1401
|
+
for (const pt of relayTasks) {
|
|
1402
|
+
batchPromises.push(
|
|
1403
|
+
(async () => {
|
|
1404
|
+
try {
|
|
1405
|
+
const res = await executeSingleTask(pt, gatewayToken, timeoutMs, requesterOwner, relayClient, resolveAgentUrl);
|
|
1406
|
+
return [{ status: "fulfilled", value: res }];
|
|
1407
|
+
} catch (err) {
|
|
1408
|
+
return [{ status: "rejected", reason: err }];
|
|
1203
1409
|
}
|
|
1204
|
-
|
|
1205
|
-
|
|
1206
|
-
|
|
1207
|
-
|
|
1208
|
-
|
|
1209
|
-
);
|
|
1410
|
+
})()
|
|
1411
|
+
);
|
|
1412
|
+
}
|
|
1413
|
+
const allBatchResults = await Promise.all(batchPromises);
|
|
1414
|
+
const waveResults = allBatchResults.flat();
|
|
1210
1415
|
for (const settlement of waveResults) {
|
|
1211
1416
|
if (settlement.status === "fulfilled") {
|
|
1212
1417
|
const { taskId, result, credits, team_id, capability_type } = settlement.value;
|