agentbnb 8.2.0 → 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-TBJ3FZKZ.js → chunk-4IPJJRTP.js} +1 -1
- package/dist/chunk-CKOOVZOI.js +158 -0
- package/dist/chunk-CQFBNTGT.js +145 -0
- package/dist/{chunk-P4LOYSLA.js → chunk-DYQOFGGI.js} +331 -416
- package/dist/{chunk-ALX4WS3A.js → chunk-EG6RS4JC.js} +70 -46
- package/dist/{chunk-CUONY5TO.js → chunk-EJKW57ZV.js} +19 -1
- package/dist/{chunk-5AAFG2V2.js → chunk-LKLKYXLV.js} +239 -24
- package/dist/{chunk-7EF3HYVZ.js → chunk-MCED4GDW.js} +499 -86
- package/dist/{chunk-YHY7OG6S.js → chunk-MWOXW7JQ.js} +7 -7
- package/dist/{chunk-E2OKP5CY.js → chunk-QCGIG7WW.js} +182 -86
- package/dist/{chunk-5GME4KJZ.js → chunk-QHZGOG3O.js} +148 -46
- package/dist/{chunk-D6RKW2XG.js → chunk-RYISHSHB.js} +302 -4
- package/dist/{chunk-O2OYBAVR.js → chunk-S3V6R3EN.js} +75 -39
- package/dist/{chunk-X32NE6V4.js → chunk-WNXXLCV5.js} +1 -1
- package/dist/{chunk-C537SFHV.js → chunk-XBGVQMQJ.js} +72 -48
- package/dist/{chunk-FTZTEHYG.js → chunk-Z2GEFFDO.js} +135 -8
- package/dist/cli/index.js +42 -67
- package/dist/{client-HKV3QWZ3.js → client-XOLP5IUZ.js} +4 -2
- package/dist/{conduct-W6XF6DJW.js → conduct-AZFLNUX3.js} +10 -11
- package/dist/{conduct-YB64OHI6.js → conduct-VPUYTNEA.js} +10 -11
- package/dist/{conductor-mode-AKREGDIU.js → conductor-mode-PLTB6MS3.js} +7 -8
- package/dist/{conductor-mode-TFCVCQHU.js → conductor-mode-WKB42PYM.js} +6 -3
- package/dist/{execute-EPE6MZLT.js → execute-NNDCXTN4.js} +3 -2
- package/dist/{execute-AYQWORVH.js → execute-RIRHTIBU.js} +6 -5
- package/dist/index.d.ts +8 -8
- package/dist/index.js +637 -693
- package/dist/{publish-capability-AH2HDW54.js → publish-capability-QDR2QIZ2.js} +2 -2
- package/dist/{request-HCCXSKAY.js → request-NX7GSPIG.js} +31 -36
- package/dist/{serve-skill-SZAQT5T5.js → serve-skill-E6EJQYAK.js} +10 -9
- package/dist/{server-LMY2A3GT.js → server-VBCT32FC.js} +12 -18
- package/dist/{service-coordinator-WGH6B2VT.js → service-coordinator-KMSA6BST.js} +137 -69
- package/dist/skills/agentbnb/bootstrap.js +561 -247
- 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-KF3TZHA5.js +0 -91
- package/dist/chunk-LJM7FHPM.js +0 -138
- package/dist/chunk-OH7BP5NP.js +0 -96
|
@@ -1,28 +1,28 @@
|
|
|
1
|
-
import {
|
|
2
|
-
RelayClient
|
|
3
|
-
} from "./chunk-Z4MCGKTL.js";
|
|
4
1
|
import {
|
|
5
2
|
BudgetController,
|
|
6
3
|
ORCHESTRATION_FEE,
|
|
7
4
|
decompose,
|
|
8
5
|
matchSubTasks,
|
|
9
6
|
orchestrate
|
|
10
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-QCGIG7WW.js";
|
|
11
8
|
import {
|
|
12
9
|
BudgetManager
|
|
13
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-QHZGOG3O.js";
|
|
14
11
|
import {
|
|
15
12
|
openCreditDb
|
|
16
|
-
} from "./chunk-
|
|
13
|
+
} from "./chunk-RYISHSHB.js";
|
|
17
14
|
import {
|
|
18
15
|
loadPeers
|
|
19
16
|
} from "./chunk-5AH3CMOX.js";
|
|
20
17
|
import {
|
|
21
18
|
loadConfig
|
|
22
19
|
} from "./chunk-75OC6E4F.js";
|
|
20
|
+
import {
|
|
21
|
+
RelayClient
|
|
22
|
+
} from "./chunk-Z4MCGKTL.js";
|
|
23
23
|
import {
|
|
24
24
|
openDatabase
|
|
25
|
-
} from "./chunk-
|
|
25
|
+
} from "./chunk-S3V6R3EN.js";
|
|
26
26
|
|
|
27
27
|
// src/cli/conduct.ts
|
|
28
28
|
async function conductAction(task, opts) {
|
|
@@ -3,16 +3,15 @@ import {
|
|
|
3
3
|
} from "./chunk-3MJT4PZG.js";
|
|
4
4
|
import {
|
|
5
5
|
scorePeers
|
|
6
|
-
} from "./chunk-
|
|
7
|
-
import {
|
|
8
|
-
fetchRemoteCards
|
|
9
|
-
} from "./chunk-KF3TZHA5.js";
|
|
6
|
+
} from "./chunk-QHZGOG3O.js";
|
|
10
7
|
import {
|
|
8
|
+
fetchRemoteCards,
|
|
11
9
|
searchCards
|
|
12
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-RYISHSHB.js";
|
|
13
11
|
import {
|
|
14
|
-
requestCapability
|
|
15
|
-
|
|
12
|
+
requestCapability,
|
|
13
|
+
requestCapabilityBatch
|
|
14
|
+
} from "./chunk-CKOOVZOI.js";
|
|
16
15
|
|
|
17
16
|
// src/conductor/decomposition-validator.ts
|
|
18
17
|
function validateAndNormalizeSubtasks(raw, context) {
|
|
@@ -410,6 +409,65 @@ function computeWaves(subtasks) {
|
|
|
410
409
|
}
|
|
411
410
|
return waves;
|
|
412
411
|
}
|
|
412
|
+
async function executeSingleTask(pt, gatewayToken, timeoutMs, requesterOwner, relayClient, resolveAgentUrl) {
|
|
413
|
+
const { taskId, match: m, interpolatedParams, primary, teamId, capabilityType } = pt;
|
|
414
|
+
try {
|
|
415
|
+
let res;
|
|
416
|
+
if (primary.url.startsWith("relay://") && relayClient) {
|
|
417
|
+
const targetOwner = primary.url.replace("relay://", "");
|
|
418
|
+
res = await relayClient.request({
|
|
419
|
+
targetOwner,
|
|
420
|
+
cardId: primary.cardId,
|
|
421
|
+
params: interpolatedParams,
|
|
422
|
+
requester: requesterOwner,
|
|
423
|
+
timeoutMs
|
|
424
|
+
});
|
|
425
|
+
} else {
|
|
426
|
+
res = await requestCapability({
|
|
427
|
+
gatewayUrl: primary.url,
|
|
428
|
+
token: gatewayToken,
|
|
429
|
+
cardId: primary.cardId,
|
|
430
|
+
params: { ...interpolatedParams, requester: requesterOwner },
|
|
431
|
+
timeoutMs
|
|
432
|
+
});
|
|
433
|
+
}
|
|
434
|
+
return { taskId, result: res, credits: m.credits, team_id: teamId, capability_type: capabilityType };
|
|
435
|
+
} catch (primaryErr) {
|
|
436
|
+
if (m.alternatives.length > 0) {
|
|
437
|
+
const alt = m.alternatives[0];
|
|
438
|
+
const altResolved = resolveAgentUrl ? resolveAgentUrl(alt.agent) : { url: `http://${alt.agent}:7700`, cardId: `card-${alt.agent}` };
|
|
439
|
+
try {
|
|
440
|
+
let altRes;
|
|
441
|
+
if (altResolved.url.startsWith("relay://") && relayClient) {
|
|
442
|
+
const targetOwner = altResolved.url.replace("relay://", "");
|
|
443
|
+
altRes = await relayClient.request({
|
|
444
|
+
targetOwner,
|
|
445
|
+
cardId: altResolved.cardId,
|
|
446
|
+
params: interpolatedParams,
|
|
447
|
+
requester: requesterOwner,
|
|
448
|
+
timeoutMs
|
|
449
|
+
});
|
|
450
|
+
} else {
|
|
451
|
+
altRes = await requestCapability({
|
|
452
|
+
gatewayUrl: altResolved.url,
|
|
453
|
+
token: gatewayToken,
|
|
454
|
+
cardId: altResolved.cardId,
|
|
455
|
+
params: { ...interpolatedParams, requester: requesterOwner },
|
|
456
|
+
timeoutMs
|
|
457
|
+
});
|
|
458
|
+
}
|
|
459
|
+
return { taskId, result: altRes, credits: alt.credits, team_id: teamId, capability_type: capabilityType };
|
|
460
|
+
} catch (altErr) {
|
|
461
|
+
throw new Error(
|
|
462
|
+
`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)}`
|
|
463
|
+
);
|
|
464
|
+
}
|
|
465
|
+
}
|
|
466
|
+
throw new Error(
|
|
467
|
+
`Task ${taskId}: ${primaryErr instanceof Error ? primaryErr.message : String(primaryErr)}`
|
|
468
|
+
);
|
|
469
|
+
}
|
|
470
|
+
}
|
|
413
471
|
async function orchestrate(opts) {
|
|
414
472
|
const { subtasks, matches, gatewayToken, resolveAgentUrl, timeoutMs = 3e5, maxBudget, relayClient, requesterOwner } = opts;
|
|
415
473
|
const startTime = Date.now();
|
|
@@ -447,89 +505,127 @@ async function orchestrate(opts) {
|
|
|
447
505
|
}
|
|
448
506
|
executableIds.push(taskId);
|
|
449
507
|
}
|
|
450
|
-
const
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
const
|
|
508
|
+
const preparedTasks = [];
|
|
509
|
+
for (const taskId of executableIds) {
|
|
510
|
+
const subtask = subtaskMap.get(taskId);
|
|
511
|
+
const m = matches.get(taskId);
|
|
512
|
+
if (!m) {
|
|
513
|
+
errors.push(`No match found for subtask ${taskId}`);
|
|
514
|
+
continue;
|
|
515
|
+
}
|
|
516
|
+
const stepsContext = {};
|
|
517
|
+
for (const [id, val] of results) stepsContext[id] = val;
|
|
518
|
+
const interpContext = { steps: stepsContext, prev: void 0 };
|
|
519
|
+
if (subtask.depends_on.length > 0) {
|
|
520
|
+
const lastDep = subtask.depends_on[subtask.depends_on.length - 1];
|
|
521
|
+
interpContext.prev = results.get(lastDep);
|
|
522
|
+
}
|
|
523
|
+
const interpolatedParams = interpolateObject(
|
|
524
|
+
subtask.params,
|
|
525
|
+
interpContext
|
|
526
|
+
);
|
|
527
|
+
const teamMember = teamMemberMap.get(taskId);
|
|
528
|
+
const agentOwner = teamMember?.agent ?? m.selected_agent;
|
|
529
|
+
const primary = resolveAgentUrl(agentOwner);
|
|
530
|
+
preparedTasks.push({
|
|
531
|
+
taskId,
|
|
532
|
+
subtask,
|
|
533
|
+
match: m,
|
|
534
|
+
interpolatedParams,
|
|
535
|
+
agentOwner,
|
|
536
|
+
primary,
|
|
537
|
+
teamId: opts.team?.team_id ?? null,
|
|
538
|
+
capabilityType: teamMember?.capability_type ?? null
|
|
539
|
+
});
|
|
540
|
+
}
|
|
541
|
+
const httpGroups = /* @__PURE__ */ new Map();
|
|
542
|
+
const relayTasks = [];
|
|
543
|
+
for (const pt of preparedTasks) {
|
|
544
|
+
if (pt.primary.url.startsWith("relay://") && relayClient) {
|
|
545
|
+
relayTasks.push(pt);
|
|
546
|
+
} else {
|
|
547
|
+
const group = httpGroups.get(pt.primary.url) ?? [];
|
|
548
|
+
group.push(pt);
|
|
549
|
+
httpGroups.set(pt.primary.url, group);
|
|
550
|
+
}
|
|
551
|
+
}
|
|
552
|
+
const batchPromises = [];
|
|
553
|
+
for (const [gatewayUrl, group] of httpGroups) {
|
|
554
|
+
if (group.length >= 2) {
|
|
555
|
+
batchPromises.push(
|
|
556
|
+
(async () => {
|
|
557
|
+
const items = group.map((pt) => ({
|
|
558
|
+
id: pt.taskId,
|
|
559
|
+
cardId: pt.primary.cardId,
|
|
560
|
+
params: { ...pt.interpolatedParams, requester: requesterOwner },
|
|
561
|
+
_pt: pt
|
|
562
|
+
}));
|
|
500
563
|
try {
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
cardId: altAgent.cardId,
|
|
507
|
-
params: interpolatedParams,
|
|
508
|
-
requester: requesterOwner,
|
|
509
|
-
timeoutMs
|
|
510
|
-
});
|
|
511
|
-
} else {
|
|
512
|
-
altRes = await requestCapability({
|
|
513
|
-
gatewayUrl: altAgent.url,
|
|
514
|
-
token: gatewayToken,
|
|
515
|
-
cardId: altAgent.cardId,
|
|
516
|
-
params: { ...interpolatedParams, requester: requesterOwner },
|
|
517
|
-
timeoutMs
|
|
518
|
-
});
|
|
519
|
-
}
|
|
520
|
-
return { taskId, result: altRes, credits: alt.credits, team_id: teamId, capability_type: taskCapabilityType };
|
|
521
|
-
} catch (altErr) {
|
|
522
|
-
throw new Error(
|
|
523
|
-
`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)}`
|
|
564
|
+
const batchResults = await requestCapabilityBatch(
|
|
565
|
+
gatewayUrl,
|
|
566
|
+
gatewayToken,
|
|
567
|
+
items.map(({ _pt, ...item }) => item),
|
|
568
|
+
{ timeoutMs }
|
|
524
569
|
);
|
|
570
|
+
return items.map((item) => {
|
|
571
|
+
const res = batchResults.get(item.id);
|
|
572
|
+
if (res instanceof Error) {
|
|
573
|
+
return {
|
|
574
|
+
status: "rejected",
|
|
575
|
+
reason: new Error(`Task ${item.id}: ${res.message}`)
|
|
576
|
+
};
|
|
577
|
+
}
|
|
578
|
+
return {
|
|
579
|
+
status: "fulfilled",
|
|
580
|
+
value: {
|
|
581
|
+
taskId: item.id,
|
|
582
|
+
result: res,
|
|
583
|
+
credits: item._pt.match.credits,
|
|
584
|
+
team_id: item._pt.teamId,
|
|
585
|
+
capability_type: item._pt.capabilityType
|
|
586
|
+
}
|
|
587
|
+
};
|
|
588
|
+
});
|
|
589
|
+
} catch (batchErr) {
|
|
590
|
+
return Promise.all(group.map(async (pt) => {
|
|
591
|
+
try {
|
|
592
|
+
const res = await executeSingleTask(pt, gatewayToken, timeoutMs, requesterOwner, relayClient, resolveAgentUrl);
|
|
593
|
+
return { status: "fulfilled", value: res };
|
|
594
|
+
} catch (err) {
|
|
595
|
+
return { status: "rejected", reason: err };
|
|
596
|
+
}
|
|
597
|
+
}));
|
|
598
|
+
}
|
|
599
|
+
})()
|
|
600
|
+
);
|
|
601
|
+
} else {
|
|
602
|
+
const pt = group[0];
|
|
603
|
+
batchPromises.push(
|
|
604
|
+
(async () => {
|
|
605
|
+
try {
|
|
606
|
+
const res = await executeSingleTask(pt, gatewayToken, timeoutMs, requesterOwner, relayClient, resolveAgentUrl);
|
|
607
|
+
return [{ status: "fulfilled", value: res }];
|
|
608
|
+
} catch (err) {
|
|
609
|
+
return [{ status: "rejected", reason: err }];
|
|
525
610
|
}
|
|
611
|
+
})()
|
|
612
|
+
);
|
|
613
|
+
}
|
|
614
|
+
}
|
|
615
|
+
for (const pt of relayTasks) {
|
|
616
|
+
batchPromises.push(
|
|
617
|
+
(async () => {
|
|
618
|
+
try {
|
|
619
|
+
const res = await executeSingleTask(pt, gatewayToken, timeoutMs, requesterOwner, relayClient, resolveAgentUrl);
|
|
620
|
+
return [{ status: "fulfilled", value: res }];
|
|
621
|
+
} catch (err) {
|
|
622
|
+
return [{ status: "rejected", reason: err }];
|
|
526
623
|
}
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
);
|
|
624
|
+
})()
|
|
625
|
+
);
|
|
626
|
+
}
|
|
627
|
+
const allBatchResults = await Promise.all(batchPromises);
|
|
628
|
+
const waveResults = allBatchResults.flat();
|
|
533
629
|
for (const settlement of waveResults) {
|
|
534
630
|
if (settlement.status === "fulfilled") {
|
|
535
631
|
const { taskId, result, credits, team_id, capability_type } = settlement.value;
|
|
@@ -1,23 +1,23 @@
|
|
|
1
|
-
import {
|
|
2
|
-
fetchRemoteCards
|
|
3
|
-
} from "./chunk-KF3TZHA5.js";
|
|
4
1
|
import {
|
|
5
2
|
createPendingRequest,
|
|
6
3
|
getAutonomyTier,
|
|
7
4
|
insertAuditEvent
|
|
8
5
|
} from "./chunk-GKVTD4EZ.js";
|
|
9
6
|
import {
|
|
10
|
-
|
|
11
|
-
} from "./chunk-
|
|
7
|
+
resolveTargetCapability
|
|
8
|
+
} from "./chunk-CQFBNTGT.js";
|
|
12
9
|
import {
|
|
10
|
+
fetchRemoteCards,
|
|
13
11
|
getBalance,
|
|
14
12
|
holdEscrow,
|
|
15
13
|
releaseEscrow,
|
|
14
|
+
searchCards,
|
|
16
15
|
settleEscrow
|
|
17
|
-
} from "./chunk-
|
|
16
|
+
} from "./chunk-RYISHSHB.js";
|
|
18
17
|
import {
|
|
19
|
-
requestCapability
|
|
20
|
-
|
|
18
|
+
requestCapability,
|
|
19
|
+
requestViaRelay
|
|
20
|
+
} from "./chunk-CKOOVZOI.js";
|
|
21
21
|
import {
|
|
22
22
|
findPeer
|
|
23
23
|
} from "./chunk-5AH3CMOX.js";
|
|
@@ -68,6 +68,7 @@ var BudgetManager = class {
|
|
|
68
68
|
};
|
|
69
69
|
|
|
70
70
|
// src/autonomy/auto-request.ts
|
|
71
|
+
import { randomUUID } from "crypto";
|
|
71
72
|
function minMaxNormalize(values) {
|
|
72
73
|
if (values.length === 0) return [];
|
|
73
74
|
if (values.length === 1) return [1];
|
|
@@ -190,88 +191,189 @@ var AutoRequestor = class {
|
|
|
190
191
|
}
|
|
191
192
|
}
|
|
192
193
|
const scored = scorePeers(candidates, this.owner);
|
|
194
|
+
const resolverOptions = {
|
|
195
|
+
registryDb: this.registryDb,
|
|
196
|
+
registryUrl: this.registryUrl,
|
|
197
|
+
onlineOnly: true
|
|
198
|
+
};
|
|
199
|
+
let resolvedTarget = null;
|
|
193
200
|
if (scored.length === 0) {
|
|
201
|
+
resolvedTarget = await resolveTargetCapability(need.query, resolverOptions);
|
|
202
|
+
if (!resolvedTarget || resolvedTarget.owner === this.owner || resolvedTarget.credits_per_call > need.maxCostCredits) {
|
|
203
|
+
this.logFailure("auto_request_failed", "system", "none", 3, 0, "none", "No eligible peer found");
|
|
204
|
+
return { status: "no_peer", reason: "No eligible peer found" };
|
|
205
|
+
}
|
|
206
|
+
} else {
|
|
207
|
+
const top = scored[0];
|
|
208
|
+
const targetKey = top.skillId ?? top.card.id;
|
|
209
|
+
resolvedTarget = await resolveTargetCapability(targetKey, resolverOptions) ?? await resolveTargetCapability(need.query, resolverOptions);
|
|
210
|
+
if (!resolvedTarget || resolvedTarget.owner === this.owner) {
|
|
211
|
+
this.logFailure("auto_request_failed", top.card.id, top.skillId ?? "none", 3, top.cost, top.card.owner, "No eligible peer found");
|
|
212
|
+
return { status: "no_peer", reason: "No eligible peer found" };
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
if (!resolvedTarget) {
|
|
194
216
|
this.logFailure("auto_request_failed", "system", "none", 3, 0, "none", "No eligible peer found");
|
|
195
217
|
return { status: "no_peer", reason: "No eligible peer found" };
|
|
196
218
|
}
|
|
197
|
-
const
|
|
198
|
-
const
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
const tier = getAutonomyTier(top.cost, this.autonomyConfig);
|
|
219
|
+
const selectedCardId = resolvedTarget.cardId;
|
|
220
|
+
const selectedSkillId = resolvedTarget.skillId;
|
|
221
|
+
const selectedPeer = resolvedTarget.owner;
|
|
222
|
+
const selectedCost = resolvedTarget.credits_per_call;
|
|
223
|
+
const selectedViaRelay = resolvedTarget.via_relay;
|
|
224
|
+
const tier = getAutonomyTier(selectedCost, this.autonomyConfig);
|
|
204
225
|
if (tier === 3) {
|
|
205
226
|
createPendingRequest(this.registryDb, {
|
|
206
227
|
skill_query: need.query,
|
|
207
228
|
max_cost_credits: need.maxCostCredits,
|
|
208
|
-
credits:
|
|
209
|
-
selected_peer:
|
|
210
|
-
selected_card_id:
|
|
211
|
-
selected_skill_id:
|
|
229
|
+
credits: selectedCost,
|
|
230
|
+
selected_peer: selectedPeer,
|
|
231
|
+
selected_card_id: selectedCardId,
|
|
232
|
+
selected_skill_id: selectedSkillId,
|
|
212
233
|
params: need.params
|
|
213
234
|
});
|
|
214
235
|
insertAuditEvent(this.registryDb, {
|
|
215
236
|
type: "auto_request_pending",
|
|
216
|
-
card_id:
|
|
217
|
-
skill_id:
|
|
237
|
+
card_id: selectedCardId,
|
|
238
|
+
skill_id: selectedSkillId ?? selectedCardId,
|
|
218
239
|
tier_invoked: 3,
|
|
219
|
-
credits:
|
|
220
|
-
peer:
|
|
240
|
+
credits: selectedCost,
|
|
241
|
+
peer: selectedPeer
|
|
221
242
|
});
|
|
222
243
|
return {
|
|
223
244
|
status: "tier_blocked",
|
|
224
245
|
reason: "Tier 3: owner approval required",
|
|
225
|
-
peer:
|
|
246
|
+
peer: selectedPeer
|
|
226
247
|
};
|
|
227
248
|
}
|
|
228
|
-
if (!this.budgetManager.canSpend(
|
|
229
|
-
this.logFailure(
|
|
249
|
+
if (!this.budgetManager.canSpend(selectedCost)) {
|
|
250
|
+
this.logFailure(
|
|
251
|
+
"auto_request_failed",
|
|
252
|
+
selectedCardId,
|
|
253
|
+
selectedSkillId ?? "none",
|
|
254
|
+
tier,
|
|
255
|
+
selectedCost,
|
|
256
|
+
selectedPeer,
|
|
257
|
+
"Budget reserve would be breached"
|
|
258
|
+
);
|
|
230
259
|
return { status: "budget_blocked", reason: "Insufficient credits \u2014 reserve floor would be breached" };
|
|
231
260
|
}
|
|
232
|
-
const escrowId = holdEscrow(this.creditDb, this.owner,
|
|
261
|
+
const escrowId = holdEscrow(this.creditDb, this.owner, selectedCost, selectedCardId);
|
|
233
262
|
try {
|
|
234
|
-
const
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
263
|
+
const requestParams = selectedSkillId ? { skill_id: selectedSkillId, ...need.params, requester: this.owner } : { ...need.params, requester: this.owner };
|
|
264
|
+
let execResult;
|
|
265
|
+
if (selectedViaRelay) {
|
|
266
|
+
if (!this.registryUrl) {
|
|
267
|
+
this.logFailure(
|
|
268
|
+
"auto_request_failed",
|
|
269
|
+
selectedCardId,
|
|
270
|
+
selectedSkillId ?? "none",
|
|
271
|
+
tier,
|
|
272
|
+
selectedCost,
|
|
273
|
+
selectedPeer,
|
|
274
|
+
"Relay target found but registryUrl is not configured"
|
|
275
|
+
);
|
|
276
|
+
releaseEscrow(this.creditDb, escrowId);
|
|
277
|
+
return { status: "no_peer", reason: "Relay target found but registryUrl is not configured" };
|
|
278
|
+
}
|
|
279
|
+
const relayRequesterOwner = `${this.owner}:req:${randomUUID()}`;
|
|
280
|
+
const { RelayClient } = await import("./websocket-client-QOVARTRN.js");
|
|
281
|
+
const relayClient = new RelayClient({
|
|
282
|
+
registryUrl: this.registryUrl,
|
|
283
|
+
owner: relayRequesterOwner,
|
|
284
|
+
token: "auto-request-token",
|
|
285
|
+
card: {
|
|
286
|
+
spec_version: "1.0",
|
|
287
|
+
id: randomUUID(),
|
|
288
|
+
owner: relayRequesterOwner,
|
|
289
|
+
name: relayRequesterOwner,
|
|
290
|
+
description: "Auto-request requester",
|
|
291
|
+
level: 1,
|
|
292
|
+
inputs: [],
|
|
293
|
+
outputs: [],
|
|
294
|
+
pricing: { credits_per_call: 1 },
|
|
295
|
+
availability: { online: false }
|
|
296
|
+
},
|
|
297
|
+
onRequest: async () => ({ error: { code: -32601, message: "Auto-request relay requester does not serve capabilities" } }),
|
|
298
|
+
silent: true
|
|
299
|
+
});
|
|
300
|
+
try {
|
|
301
|
+
await relayClient.connect();
|
|
302
|
+
execResult = await requestViaRelay(relayClient, {
|
|
303
|
+
targetOwner: selectedPeer,
|
|
304
|
+
cardId: selectedCardId,
|
|
305
|
+
skillId: selectedSkillId,
|
|
306
|
+
params: requestParams,
|
|
307
|
+
requester: this.owner
|
|
308
|
+
});
|
|
309
|
+
} finally {
|
|
310
|
+
relayClient.disconnect();
|
|
311
|
+
}
|
|
312
|
+
} else {
|
|
313
|
+
const peerConfig = findPeer(selectedPeer);
|
|
314
|
+
if (!peerConfig) {
|
|
315
|
+
this.logFailure(
|
|
316
|
+
"auto_request_failed",
|
|
317
|
+
selectedCardId,
|
|
318
|
+
selectedSkillId ?? "none",
|
|
319
|
+
tier,
|
|
320
|
+
selectedCost,
|
|
321
|
+
selectedPeer,
|
|
322
|
+
"No gateway config for peer"
|
|
323
|
+
);
|
|
324
|
+
releaseEscrow(this.creditDb, escrowId);
|
|
325
|
+
return { status: "no_peer", reason: "No gateway config for peer" };
|
|
326
|
+
}
|
|
327
|
+
execResult = await requestCapability({
|
|
328
|
+
gatewayUrl: peerConfig.url,
|
|
329
|
+
token: peerConfig.token,
|
|
330
|
+
cardId: selectedCardId,
|
|
331
|
+
params: requestParams
|
|
332
|
+
});
|
|
333
|
+
}
|
|
334
|
+
settleEscrow(this.creditDb, escrowId, selectedPeer);
|
|
241
335
|
if (tier === 2) {
|
|
242
336
|
insertAuditEvent(this.registryDb, {
|
|
243
337
|
type: "auto_request_notify",
|
|
244
|
-
card_id:
|
|
245
|
-
skill_id:
|
|
338
|
+
card_id: selectedCardId,
|
|
339
|
+
skill_id: selectedSkillId ?? selectedCardId,
|
|
246
340
|
tier_invoked: 2,
|
|
247
|
-
credits:
|
|
248
|
-
peer:
|
|
341
|
+
credits: selectedCost,
|
|
342
|
+
peer: selectedPeer
|
|
249
343
|
});
|
|
250
344
|
} else {
|
|
251
345
|
insertAuditEvent(this.registryDb, {
|
|
252
346
|
type: "auto_request",
|
|
253
|
-
card_id:
|
|
254
|
-
skill_id:
|
|
347
|
+
card_id: selectedCardId,
|
|
348
|
+
skill_id: selectedSkillId ?? selectedCardId,
|
|
255
349
|
tier_invoked: 1,
|
|
256
|
-
credits:
|
|
257
|
-
peer:
|
|
350
|
+
credits: selectedCost,
|
|
351
|
+
peer: selectedPeer
|
|
258
352
|
});
|
|
259
353
|
}
|
|
260
354
|
return {
|
|
261
355
|
status: "success",
|
|
262
356
|
result: execResult,
|
|
263
357
|
escrowId,
|
|
264
|
-
peer:
|
|
265
|
-
creditsSpent:
|
|
358
|
+
peer: selectedPeer,
|
|
359
|
+
creditsSpent: selectedCost
|
|
266
360
|
};
|
|
267
361
|
} catch (err) {
|
|
268
362
|
releaseEscrow(this.creditDb, escrowId);
|
|
269
363
|
const reason = err instanceof Error ? err.message : String(err);
|
|
270
|
-
this.logFailure(
|
|
364
|
+
this.logFailure(
|
|
365
|
+
"auto_request_failed",
|
|
366
|
+
selectedCardId,
|
|
367
|
+
selectedSkillId ?? "none",
|
|
368
|
+
tier,
|
|
369
|
+
selectedCost,
|
|
370
|
+
selectedPeer,
|
|
371
|
+
`Execution failed: ${reason}`
|
|
372
|
+
);
|
|
271
373
|
return {
|
|
272
374
|
status: "failed",
|
|
273
375
|
reason: `Execution failed: ${reason}`,
|
|
274
|
-
peer:
|
|
376
|
+
peer: selectedPeer
|
|
275
377
|
};
|
|
276
378
|
}
|
|
277
379
|
}
|