agentbnb 9.1.0 → 9.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +29 -4
- package/dist/{card-VVT3XBOI.js → card-U2HQRPYN.js} +2 -1
- package/dist/{card-NQHAGTQQ.js → card-VVXNKHDX.js} +2 -1
- package/dist/{chunk-3Y76PHEY.js → chunk-53Q2HHHH.js} +154 -88
- package/dist/{chunk-5CC6O6SO.js → chunk-AA25Z6FW.js} +1 -1
- package/dist/{chunk-PIO2FMX4.js → chunk-B6AKTLXB.js} +5 -5
- package/dist/{chunk-VJ2Q33AP.js → chunk-BPPFY72X.js} +4 -0
- package/dist/{chunk-JKD6QRUD.js → chunk-C56X7EFJ.js} +4 -0
- package/dist/{chunk-PYZGF5QH.js → chunk-CMGJ52SX.js} +215 -98
- package/dist/{chunk-4DBSSFHG.js → chunk-EC6DIVE5.js} +3 -3
- package/dist/{chunk-4M6IAIVK.js → chunk-FK54LVDR.js} +2 -2
- package/dist/{chunk-JJHQAZWE.js → chunk-GGRH5PCD.js} +10 -10
- package/dist/chunk-GZUTU6IZ.js +153 -0
- package/dist/{chunk-W6LOCBWQ.js → chunk-IWAK4WHK.js} +1 -1
- package/dist/{chunk-ZYOMPJGG.js → chunk-KKFP5Y2Z.js} +2 -2
- package/dist/{chunk-XL5XD3IG.js → chunk-MPS4RE7T.js} +7 -7
- package/dist/{chunk-DBO2335D.js → chunk-MQIT2F5V.js} +8 -8
- package/dist/{chunk-GAZCZCAZ.js → chunk-RNALIVRR.js} +1 -1
- package/dist/{chunk-4UIUIHST.js → chunk-UPWAXWY2.js} +1 -1
- package/dist/{chunk-UXL7DV7P.js → chunk-V5TJXK3F.js} +3 -3
- package/dist/{chunk-AR7Z3EQB.js → chunk-WEZ7PSOE.js} +14 -14
- package/dist/{chunk-LENX5NUW.js → chunk-Z7XWQ63B.js} +55 -2
- package/dist/cli/index.js +76 -61
- package/dist/{client-XOSXFC7Q.js → client-KL67WZVJ.js} +2 -2
- package/dist/{conduct-VSSHJHVH.js → conduct-JRLLA4PB.js} +12 -11
- package/dist/{conduct-6C6JWZKZ.js → conduct-QLWXU2ZU.js} +12 -11
- package/dist/{conductor-mode-KKPSNN7V.js → conductor-mode-66IITI4I.js} +13 -12
- package/dist/{conductor-mode-NKHIZG4N.js → conductor-mode-PFO2VLH6.js} +14 -13
- package/dist/{credits-action-N3WB4WSI.js → credits-action-XERUEDF3.js} +6 -6
- package/dist/{did-action-3PNFYLX2.js → did-action-ODWTBVXL.js} +3 -3
- package/dist/{execute-QHP4KUV2.js → execute-NOQVN7ZG.js} +10 -9
- package/dist/{execute-IEQ3RV7I.js → execute-YBNCDAOX.js} +8 -7
- package/dist/index.js +350 -147
- package/dist/{openclaw-setup-PKGFB4IH.js → openclaw-setup-4RIZRMXA.js} +12 -11
- package/dist/{openclaw-skills-5VJDA6SX.js → openclaw-skills-TQ2JVBRM.js} +2 -2
- package/dist/provider-events-GTTJPYHS.js +13 -0
- package/dist/{publish-capability-CHMPZ6W3.js → publish-capability-2FMD3K6Z.js} +3 -2
- package/dist/{request-6TBVP3GR.js → request-EYN4CVXC.js} +12 -11
- package/dist/{serve-skill-BRUHUDRA.js → serve-skill-NWERGVH5.js} +13 -12
- package/dist/{server-N4BJW4TS.js → server-UPOPLZ24.js} +17 -16
- package/dist/{service-coordinator-M2CBDEUQ.js → service-coordinator-ZOZTW2U6.js} +419 -58
- package/dist/{session-action-67J57636.js → session-action-OSBZB4TX.js} +3 -3
- package/dist/signing-AQTKYJDB.js +16 -0
- package/dist/skills/agentbnb/bootstrap.js +426 -65
- package/dist/{store-A4YPEHDV.js → store-74EWU77V.js} +2 -1
- package/dist/{vc-action-TSAIABUM.js → vc-action-A6VBKERF.js} +3 -3
- package/package.json +3 -1
- package/dist/{chunk-YNBZLXYS.js → chunk-65GNX2KC.js} +0 -0
- package/dist/{daemon-OM2K3U7J.js → daemon-ETXXE4IS.js} +1 -1
|
@@ -8,34 +8,37 @@ import {
|
|
|
8
8
|
releaseEscrow,
|
|
9
9
|
resolveTargetCapability,
|
|
10
10
|
settleEscrow
|
|
11
|
-
} from "./chunk-
|
|
11
|
+
} from "./chunk-MPS4RE7T.js";
|
|
12
|
+
import {
|
|
13
|
+
getCard,
|
|
14
|
+
updateReputation
|
|
15
|
+
} from "./chunk-BPPFY72X.js";
|
|
16
|
+
import {
|
|
17
|
+
insertRequestLog
|
|
18
|
+
} from "./chunk-4XTYT4JW.js";
|
|
19
|
+
import {
|
|
20
|
+
emitProviderEvent
|
|
21
|
+
} from "./chunk-GZUTU6IZ.js";
|
|
12
22
|
import {
|
|
13
23
|
canonicalizeCreditOwner
|
|
14
24
|
} from "./chunk-6QMDJVMS.js";
|
|
25
|
+
import {
|
|
26
|
+
lookupAgent
|
|
27
|
+
} from "./chunk-EE3V3DXK.js";
|
|
15
28
|
import {
|
|
16
29
|
generateKeyPair,
|
|
17
30
|
loadKeyPair,
|
|
18
31
|
saveKeyPair,
|
|
19
32
|
signEscrowReceipt,
|
|
20
33
|
verifyEscrowReceipt
|
|
21
|
-
} from "./chunk-
|
|
34
|
+
} from "./chunk-65GNX2KC.js";
|
|
35
|
+
import {
|
|
36
|
+
AgentBnBError
|
|
37
|
+
} from "./chunk-UVCNMRPS.js";
|
|
22
38
|
import {
|
|
23
39
|
getConfigDir,
|
|
24
40
|
loadConfig
|
|
25
41
|
} from "./chunk-IVOYM3WG.js";
|
|
26
|
-
import {
|
|
27
|
-
getCard,
|
|
28
|
-
updateReputation
|
|
29
|
-
} from "./chunk-VJ2Q33AP.js";
|
|
30
|
-
import {
|
|
31
|
-
insertRequestLog
|
|
32
|
-
} from "./chunk-4XTYT4JW.js";
|
|
33
|
-
import {
|
|
34
|
-
lookupAgent
|
|
35
|
-
} from "./chunk-EE3V3DXK.js";
|
|
36
|
-
import {
|
|
37
|
-
AgentBnBError
|
|
38
|
-
} from "./chunk-UVCNMRPS.js";
|
|
39
42
|
|
|
40
43
|
// src/gateway/execute.ts
|
|
41
44
|
import { randomUUID } from "crypto";
|
|
@@ -388,6 +391,58 @@ function signRequest(method, path, body, privateKey, publicKeyHex, agentIdOverri
|
|
|
388
391
|
"X-Agent-Timestamp": timestamp
|
|
389
392
|
};
|
|
390
393
|
}
|
|
394
|
+
async function tryVerifyIdentity(request, options = {}) {
|
|
395
|
+
const agentIdHeader = request.headers["x-agent-id"];
|
|
396
|
+
const publicKeyHeader = request.headers["x-agent-publickey"];
|
|
397
|
+
const signatureHeader = request.headers["x-agent-signature"];
|
|
398
|
+
const timestampHeader = request.headers["x-agent-timestamp"];
|
|
399
|
+
const agentId = agentIdHeader?.trim();
|
|
400
|
+
const publicKeyHex = publicKeyHeader?.trim();
|
|
401
|
+
const signature = signatureHeader?.trim();
|
|
402
|
+
const timestamp = timestampHeader?.trim();
|
|
403
|
+
if (!agentId || !publicKeyHex || !signature || !timestamp) {
|
|
404
|
+
return { valid: false, reason: "missing_headers" };
|
|
405
|
+
}
|
|
406
|
+
const requestTime = new Date(timestamp).getTime();
|
|
407
|
+
if (isNaN(requestTime) || Math.abs(Date.now() - requestTime) > MAX_REQUEST_AGE_MS) {
|
|
408
|
+
return { valid: false, reason: "expired" };
|
|
409
|
+
}
|
|
410
|
+
if (!/^[0-9a-fA-F]+$/.test(publicKeyHex) || publicKeyHex.length % 2 !== 0) {
|
|
411
|
+
return { valid: false, reason: "invalid_key" };
|
|
412
|
+
}
|
|
413
|
+
let expectedAgentId;
|
|
414
|
+
try {
|
|
415
|
+
expectedAgentId = deriveAgentId(publicKeyHex);
|
|
416
|
+
} catch {
|
|
417
|
+
return { valid: false, reason: "invalid_key" };
|
|
418
|
+
}
|
|
419
|
+
if (agentId !== expectedAgentId) {
|
|
420
|
+
return { valid: false, reason: "agent_id_mismatch" };
|
|
421
|
+
}
|
|
422
|
+
let publicKeyBuffer;
|
|
423
|
+
try {
|
|
424
|
+
publicKeyBuffer = Buffer.from(publicKeyHex, "hex");
|
|
425
|
+
} catch {
|
|
426
|
+
return { valid: false, reason: "invalid_key" };
|
|
427
|
+
}
|
|
428
|
+
const knownAgent = options.agentDb ? lookupAgent(options.agentDb, agentId) : null;
|
|
429
|
+
if (knownAgent && knownAgent.public_key.toLowerCase() !== publicKeyHex.toLowerCase()) {
|
|
430
|
+
return { valid: false, reason: "key_drift" };
|
|
431
|
+
}
|
|
432
|
+
const payload = buildIdentityPayload(
|
|
433
|
+
request.method,
|
|
434
|
+
request.url,
|
|
435
|
+
timestamp,
|
|
436
|
+
publicKeyHex,
|
|
437
|
+
agentId,
|
|
438
|
+
request.body
|
|
439
|
+
);
|
|
440
|
+
const valid = verifyEscrowReceipt(payload, signature, publicKeyBuffer);
|
|
441
|
+
if (!valid) {
|
|
442
|
+
return { valid: false, reason: "invalid_signature" };
|
|
443
|
+
}
|
|
444
|
+
return { valid: true, agentId, publicKey: publicKeyHex };
|
|
445
|
+
}
|
|
391
446
|
|
|
392
447
|
// src/credit/registry-credit-ledger.ts
|
|
393
448
|
var HTTP_TIMEOUT_MS = 1e4;
|
|
@@ -654,72 +709,133 @@ async function syncCreditsFromRegistry(config, localDb) {
|
|
|
654
709
|
}
|
|
655
710
|
}
|
|
656
711
|
|
|
657
|
-
// src/gateway/
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
712
|
+
// src/gateway/provider-notifier.ts
|
|
713
|
+
var EVENT_EMOJI = {
|
|
714
|
+
"skill.received": "\u{1F4E5}",
|
|
715
|
+
"skill.executed": "\u2705",
|
|
716
|
+
"skill.failed": "\u274C",
|
|
717
|
+
"skill.rejected": "\u{1F6AB}",
|
|
718
|
+
"session.opened": "\u{1F517}",
|
|
719
|
+
"session.message": "\u{1F4AC}",
|
|
720
|
+
"session.ended": "\u{1F3C1}",
|
|
721
|
+
"session.failed": "\u{1F4A5}"
|
|
722
|
+
};
|
|
723
|
+
function formatEventMessage(event, balance) {
|
|
724
|
+
const emoji = EVENT_EMOJI[event.event_type] ?? "\u{1F4CB}";
|
|
725
|
+
const meta = event.metadata ?? {};
|
|
726
|
+
const skillLabel = event.skill_id ?? "unknown";
|
|
727
|
+
switch (event.event_type) {
|
|
728
|
+
case "skill.received":
|
|
729
|
+
return [
|
|
730
|
+
`${emoji} [AgentBnB] Incoming request`,
|
|
731
|
+
`Skill: ${skillLabel}`,
|
|
732
|
+
`Requester: ${event.requester}`,
|
|
733
|
+
`Cost: ${event.credits} credits`,
|
|
734
|
+
`Status: Executing...`
|
|
735
|
+
].join("\n");
|
|
736
|
+
case "skill.executed":
|
|
737
|
+
return [
|
|
738
|
+
`${emoji} [AgentBnB] Skill executed`,
|
|
739
|
+
`Skill: ${skillLabel}`,
|
|
740
|
+
`Requester: ${event.requester}`,
|
|
741
|
+
`Earned: +${event.credits} credits`,
|
|
742
|
+
...balance !== void 0 ? [`Balance: ${balance} credits`] : [],
|
|
743
|
+
`Latency: ${event.duration_ms}ms`
|
|
744
|
+
].join("\n");
|
|
745
|
+
case "skill.failed":
|
|
746
|
+
return [
|
|
747
|
+
`${emoji} [AgentBnB] Skill failed`,
|
|
748
|
+
`Skill: ${skillLabel}`,
|
|
749
|
+
`Requester: ${event.requester}`,
|
|
750
|
+
`Reason: ${meta["failure_reason"] ?? "unknown"}`,
|
|
751
|
+
...meta["error"] ? [`Error: ${String(meta["error"]).slice(0, 200)}`] : [],
|
|
752
|
+
...balance !== void 0 ? [`Balance: ${balance} credits`] : [],
|
|
753
|
+
`Latency: ${event.duration_ms}ms`
|
|
754
|
+
].join("\n");
|
|
755
|
+
case "skill.rejected":
|
|
756
|
+
return [
|
|
757
|
+
`${emoji} [AgentBnB] Request rejected`,
|
|
758
|
+
`Skill: ${skillLabel}`,
|
|
759
|
+
`Requester: ${event.requester}`,
|
|
760
|
+
`Reason: ${meta["reason"] ?? "unknown"}`
|
|
761
|
+
].join("\n");
|
|
762
|
+
case "session.opened":
|
|
763
|
+
return [
|
|
764
|
+
`${emoji} [AgentBnB] Session opened`,
|
|
765
|
+
`Session: ${event.session_id?.slice(0, 8)}...`,
|
|
766
|
+
`Requester: ${event.requester}`,
|
|
767
|
+
`Skill: ${skillLabel}`,
|
|
768
|
+
`Pricing: ${meta["pricing_model"] ?? "unknown"}`,
|
|
769
|
+
`Budget: ${event.credits} credits`
|
|
770
|
+
].join("\n");
|
|
771
|
+
case "session.message": {
|
|
772
|
+
const msgCount = meta["message_count"] ?? "?";
|
|
773
|
+
const runningCost = meta["running_cost"] ?? event.credits;
|
|
774
|
+
return [
|
|
775
|
+
`${emoji} [AgentBnB] Session message #${msgCount}`,
|
|
776
|
+
`Session: ${event.session_id?.slice(0, 8)}...`,
|
|
777
|
+
`Running cost: ${runningCost} credits`
|
|
778
|
+
].join("\n");
|
|
779
|
+
}
|
|
780
|
+
case "session.ended": {
|
|
781
|
+
const totalMsgs = meta["total_messages"] ?? "?";
|
|
782
|
+
const durationMin = Math.round(event.duration_ms / 6e4);
|
|
783
|
+
const refunded = Number(meta["refunded"] ?? 0);
|
|
784
|
+
return [
|
|
785
|
+
`${emoji} [AgentBnB] Session ended`,
|
|
786
|
+
`Session: ${event.session_id?.slice(0, 8)}...`,
|
|
787
|
+
`Total: ${totalMsgs} messages, ${event.credits} credits`,
|
|
788
|
+
`Duration: ${durationMin} minutes`,
|
|
789
|
+
...refunded > 0 ? [`Refunded: ${refunded} credits`] : []
|
|
790
|
+
].join("\n");
|
|
791
|
+
}
|
|
792
|
+
case "session.failed": {
|
|
793
|
+
const lastMsgs = Array.isArray(meta["last_messages"]) ? meta["last_messages"] : [];
|
|
794
|
+
const lines = [
|
|
795
|
+
`${emoji} [AgentBnB] Session failed`,
|
|
796
|
+
`Session: ${event.session_id?.slice(0, 8)}...`,
|
|
797
|
+
`Reason: ${meta["reason"] ?? "error"}`,
|
|
798
|
+
`Cost: ${event.credits} credits`
|
|
799
|
+
];
|
|
800
|
+
if (lastMsgs.length > 0) {
|
|
801
|
+
lines.push("", "Last messages:");
|
|
802
|
+
for (const m of lastMsgs) {
|
|
803
|
+
lines.push(` ${m.sender}: ${m.content.slice(0, 100)}`);
|
|
804
|
+
}
|
|
805
|
+
}
|
|
806
|
+
return lines.join("\n");
|
|
807
|
+
}
|
|
808
|
+
default:
|
|
809
|
+
return `${emoji} [AgentBnB] ${event.event_type}: ${skillLabel}`;
|
|
810
|
+
}
|
|
702
811
|
}
|
|
703
|
-
async function
|
|
812
|
+
async function notifyProviderEvent(event, creditDb, owner) {
|
|
704
813
|
const cfg = loadConfig();
|
|
705
|
-
if (cfg
|
|
814
|
+
if (!cfg) return;
|
|
815
|
+
const telegramEnabled = cfg.telegram_notifications === true;
|
|
816
|
+
const gateNotify = cfg.provider_gate === "notify";
|
|
817
|
+
if (!telegramEnabled && !gateNotify) return;
|
|
818
|
+
const filters = cfg.notification_filters ?? ["session.message"];
|
|
819
|
+
if (filters.includes(event.event_type)) return;
|
|
706
820
|
const token = cfg.telegram_bot_token ?? process.env["TELEGRAM_BOT_TOKEN"];
|
|
707
821
|
const chatId = cfg.telegram_chat_id ?? process.env["TELEGRAM_CHAT_ID"];
|
|
708
822
|
if (!token || !chatId) return;
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
823
|
+
let balance;
|
|
824
|
+
if (creditDb && owner && (event.event_type === "skill.executed" || event.event_type === "skill.failed")) {
|
|
825
|
+
try {
|
|
826
|
+
balance = getBalance(creditDb, owner);
|
|
827
|
+
} catch {
|
|
828
|
+
}
|
|
829
|
+
}
|
|
830
|
+
const text = formatEventMessage(event, balance);
|
|
717
831
|
await fetch(`https://api.telegram.org/bot${token}/sendMessage`, {
|
|
718
832
|
method: "POST",
|
|
719
833
|
headers: { "Content-Type": "application/json" },
|
|
720
834
|
body: JSON.stringify({ chat_id: chatId, text })
|
|
721
835
|
});
|
|
722
836
|
}
|
|
837
|
+
|
|
838
|
+
// src/gateway/execute.ts
|
|
723
839
|
async function executeCapabilityRequest(opts) {
|
|
724
840
|
const {
|
|
725
841
|
registryDb,
|
|
@@ -822,6 +938,10 @@ async function executeCapabilityRequest(opts) {
|
|
|
822
938
|
const blacklist = providerCfg?.provider_blacklist ?? [];
|
|
823
939
|
if (blacklist.includes(requester)) {
|
|
824
940
|
if (escrowId) releaseEscrow(creditDb, escrowId);
|
|
941
|
+
try {
|
|
942
|
+
emitProviderEvent(registryDb, { event_type: "skill.rejected", skill_id: resolvedSkillId ?? null, session_id: null, requester, credits: 0, duration_ms: 0, metadata: { reason: "blacklisted" } });
|
|
943
|
+
} catch {
|
|
944
|
+
}
|
|
825
945
|
return { success: false, error: { code: -32097, message: "Requester is blocked by provider" } };
|
|
826
946
|
}
|
|
827
947
|
}
|
|
@@ -832,6 +952,10 @@ async function executeCapabilityRequest(opts) {
|
|
|
832
952
|
const todayCount = countTodayExecutions(registryDb);
|
|
833
953
|
if (todayCount >= dailyLimit) {
|
|
834
954
|
if (escrowId) releaseEscrow(creditDb, escrowId);
|
|
955
|
+
try {
|
|
956
|
+
emitProviderEvent(registryDb, { event_type: "skill.rejected", skill_id: resolvedSkillId ?? null, session_id: null, requester, credits: 0, duration_ms: 0, metadata: { reason: "daily_limit", limit: dailyLimit } });
|
|
957
|
+
} catch {
|
|
958
|
+
}
|
|
835
959
|
return {
|
|
836
960
|
success: false,
|
|
837
961
|
error: { code: -32099, message: `Provider daily execution limit reached (${dailyLimit}/day)` }
|
|
@@ -839,13 +963,13 @@ async function executeCapabilityRequest(opts) {
|
|
|
839
963
|
}
|
|
840
964
|
}
|
|
841
965
|
}
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
}
|
|
848
|
-
}
|
|
966
|
+
const receivedEvent = { event_type: "skill.received", skill_id: resolvedSkillId ?? null, session_id: null, requester, credits: creditsNeeded, duration_ms: 0, metadata: { gate_mode: providerCfg?.provider_gate ?? "auto" } };
|
|
967
|
+
try {
|
|
968
|
+
const emitted = emitProviderEvent(registryDb, receivedEvent);
|
|
969
|
+
notifyProviderEvent(emitted, creditDb, card.owner).catch(() => {
|
|
970
|
+
});
|
|
971
|
+
} catch {
|
|
972
|
+
}
|
|
849
973
|
const startMs = Date.now();
|
|
850
974
|
const handleFailure = (status, latencyMs, message, failureReason = "bad_execution") => {
|
|
851
975
|
if (escrowId) releaseEscrow(creditDb, escrowId);
|
|
@@ -867,17 +991,12 @@ async function executeCapabilityRequest(opts) {
|
|
|
867
991
|
});
|
|
868
992
|
} catch {
|
|
869
993
|
}
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
latencyMs,
|
|
877
|
-
failureReason,
|
|
878
|
-
message
|
|
879
|
-
}).catch(() => {
|
|
880
|
-
});
|
|
994
|
+
try {
|
|
995
|
+
const emitted = emitProviderEvent(registryDb, { event_type: "skill.failed", skill_id: resolvedSkillId ?? null, session_id: null, requester, credits: 0, duration_ms: latencyMs, metadata: { failure_reason: failureReason, error: message } });
|
|
996
|
+
notifyProviderEvent(emitted, creditDb, card.owner).catch(() => {
|
|
997
|
+
});
|
|
998
|
+
} catch {
|
|
999
|
+
}
|
|
881
1000
|
return { success: false, error: { code: -32603, message } };
|
|
882
1001
|
};
|
|
883
1002
|
const handleSuccess = (result, latencyMs) => {
|
|
@@ -899,16 +1018,12 @@ async function executeCapabilityRequest(opts) {
|
|
|
899
1018
|
});
|
|
900
1019
|
} catch {
|
|
901
1020
|
}
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
creditsEarned: creditsNeeded,
|
|
909
|
-
latencyMs
|
|
910
|
-
}).catch(() => {
|
|
911
|
-
});
|
|
1021
|
+
try {
|
|
1022
|
+
const emitted = emitProviderEvent(registryDb, { event_type: "skill.executed", skill_id: resolvedSkillId ?? null, session_id: null, requester, credits: creditsNeeded, duration_ms: latencyMs, metadata: null });
|
|
1023
|
+
notifyProviderEvent(emitted, creditDb, card.owner).catch(() => {
|
|
1024
|
+
});
|
|
1025
|
+
} catch {
|
|
1026
|
+
}
|
|
912
1027
|
return { success: true, result };
|
|
913
1028
|
};
|
|
914
1029
|
if (skillExecutor) {
|
|
@@ -1145,8 +1260,10 @@ export {
|
|
|
1145
1260
|
loadOrRepairIdentity,
|
|
1146
1261
|
ensureIdentity,
|
|
1147
1262
|
identityAuthPlugin,
|
|
1263
|
+
tryVerifyIdentity,
|
|
1148
1264
|
createLedger,
|
|
1149
1265
|
syncCreditsFromRegistry,
|
|
1266
|
+
notifyProviderEvent,
|
|
1150
1267
|
executeCapabilityRequest,
|
|
1151
1268
|
executeCapabilityBatch
|
|
1152
1269
|
};
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
+
import {
|
|
2
|
+
getFeedbackForProvider
|
|
3
|
+
} from "./chunk-C56X7EFJ.js";
|
|
1
4
|
import {
|
|
2
5
|
loadCoreConfig
|
|
3
6
|
} from "./chunk-QXRNW4OJ.js";
|
|
4
|
-
import {
|
|
5
|
-
getFeedbackForProvider
|
|
6
|
-
} from "./chunk-JKD6QRUD.js";
|
|
7
7
|
|
|
8
8
|
// src/feedback/reputation.ts
|
|
9
9
|
var coreReputation = loadCoreConfig("reputation");
|
|
@@ -3,10 +3,10 @@ import {
|
|
|
3
3
|
} from "./chunk-ELFGYC22.js";
|
|
4
4
|
import {
|
|
5
5
|
searchCards
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-EC6DIVE5.js";
|
|
7
7
|
import {
|
|
8
8
|
getCard
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-C56X7EFJ.js";
|
|
10
10
|
import {
|
|
11
11
|
resolveCanonicalIdentity
|
|
12
12
|
} from "./chunk-J4RFJVXI.js";
|
|
@@ -1,19 +1,19 @@
|
|
|
1
1
|
import {
|
|
2
2
|
createPendingRequest
|
|
3
3
|
} from "./chunk-5PV5YCSN.js";
|
|
4
|
-
import {
|
|
5
|
-
getAutonomyTier,
|
|
6
|
-
insertAuditEvent
|
|
7
|
-
} from "./chunk-G5WKW3ED.js";
|
|
8
4
|
import {
|
|
9
5
|
resolveTargetCapability
|
|
10
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-FK54LVDR.js";
|
|
11
7
|
import {
|
|
12
8
|
fetchRemoteCards
|
|
13
9
|
} from "./chunk-ELFGYC22.js";
|
|
10
|
+
import {
|
|
11
|
+
getAutonomyTier,
|
|
12
|
+
insertAuditEvent
|
|
13
|
+
} from "./chunk-G5WKW3ED.js";
|
|
14
14
|
import {
|
|
15
15
|
searchCards
|
|
16
|
-
} from "./chunk-
|
|
16
|
+
} from "./chunk-EC6DIVE5.js";
|
|
17
17
|
import {
|
|
18
18
|
holdEscrow,
|
|
19
19
|
releaseEscrow,
|
|
@@ -25,16 +25,16 @@ import {
|
|
|
25
25
|
import {
|
|
26
26
|
requestCapability,
|
|
27
27
|
requestViaRelay
|
|
28
|
-
} from "./chunk-
|
|
29
|
-
import {
|
|
30
|
-
findPeer
|
|
31
|
-
} from "./chunk-3YQ73ZM6.js";
|
|
28
|
+
} from "./chunk-IWAK4WHK.js";
|
|
32
29
|
import {
|
|
33
30
|
resolveCanonicalIdentity
|
|
34
31
|
} from "./chunk-J4RFJVXI.js";
|
|
35
32
|
import {
|
|
36
33
|
AgentBnBError
|
|
37
34
|
} from "./chunk-UVCNMRPS.js";
|
|
35
|
+
import {
|
|
36
|
+
findPeer
|
|
37
|
+
} from "./chunk-3YQ73ZM6.js";
|
|
38
38
|
|
|
39
39
|
// src/gateway/relay-dispatch.ts
|
|
40
40
|
import { randomUUID } from "crypto";
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
// src/registry/provider-events.ts
|
|
2
|
+
import { randomUUID } from "crypto";
|
|
3
|
+
var PROVIDER_EVENTS_SCHEMA = `
|
|
4
|
+
CREATE TABLE IF NOT EXISTS provider_events (
|
|
5
|
+
id TEXT PRIMARY KEY,
|
|
6
|
+
event_type TEXT NOT NULL,
|
|
7
|
+
skill_id TEXT,
|
|
8
|
+
session_id TEXT,
|
|
9
|
+
requester TEXT,
|
|
10
|
+
credits INTEGER DEFAULT 0,
|
|
11
|
+
duration_ms INTEGER DEFAULT 0,
|
|
12
|
+
metadata TEXT,
|
|
13
|
+
created_at TEXT NOT NULL
|
|
14
|
+
);
|
|
15
|
+
|
|
16
|
+
CREATE INDEX IF NOT EXISTS idx_provider_events_type
|
|
17
|
+
ON provider_events(event_type);
|
|
18
|
+
CREATE INDEX IF NOT EXISTS idx_provider_events_created
|
|
19
|
+
ON provider_events(created_at DESC);
|
|
20
|
+
`;
|
|
21
|
+
function ensureProviderEventsTable(db) {
|
|
22
|
+
db.exec(PROVIDER_EVENTS_SCHEMA);
|
|
23
|
+
}
|
|
24
|
+
function emitProviderEvent(db, event) {
|
|
25
|
+
const id = randomUUID();
|
|
26
|
+
const created_at = (/* @__PURE__ */ new Date()).toISOString();
|
|
27
|
+
const metadataJson = event.metadata ? JSON.stringify(event.metadata) : null;
|
|
28
|
+
db.prepare(`
|
|
29
|
+
INSERT INTO provider_events (id, event_type, skill_id, session_id, requester, credits, duration_ms, metadata, created_at)
|
|
30
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
31
|
+
`).run(id, event.event_type, event.skill_id, event.session_id, event.requester, event.credits, event.duration_ms, metadataJson, created_at);
|
|
32
|
+
return { ...event, id, created_at };
|
|
33
|
+
}
|
|
34
|
+
function getProviderEvents(db, opts = {}) {
|
|
35
|
+
const limit = Math.min(opts.limit ?? 50, 200);
|
|
36
|
+
const conditions = [];
|
|
37
|
+
const params = [];
|
|
38
|
+
if (opts.since) {
|
|
39
|
+
conditions.push("created_at > ?");
|
|
40
|
+
params.push(opts.since);
|
|
41
|
+
}
|
|
42
|
+
if (opts.event_type) {
|
|
43
|
+
conditions.push("event_type = ?");
|
|
44
|
+
params.push(opts.event_type);
|
|
45
|
+
}
|
|
46
|
+
const where = conditions.length > 0 ? `WHERE ${conditions.join(" AND ")}` : "";
|
|
47
|
+
const sql = `SELECT * FROM provider_events ${where} ORDER BY created_at DESC LIMIT ?`;
|
|
48
|
+
params.push(limit);
|
|
49
|
+
const rows = db.prepare(sql).all(...params);
|
|
50
|
+
return rows.map(parseEventRow);
|
|
51
|
+
}
|
|
52
|
+
var PERIOD_MS = {
|
|
53
|
+
"24h": 24 * 60 * 60 * 1e3,
|
|
54
|
+
"7d": 7 * 24 * 60 * 60 * 1e3,
|
|
55
|
+
"30d": 30 * 24 * 60 * 60 * 1e3
|
|
56
|
+
};
|
|
57
|
+
function getProviderStats(db, period = "7d") {
|
|
58
|
+
const cutoff = new Date(Date.now() - (PERIOD_MS[period] ?? PERIOD_MS["7d"])).toISOString();
|
|
59
|
+
const summary = db.prepare(`
|
|
60
|
+
SELECT
|
|
61
|
+
COALESCE(SUM(CASE WHEN event_type = 'skill.executed' THEN credits ELSE 0 END), 0) as total_earnings,
|
|
62
|
+
COUNT(CASE WHEN event_type IN ('skill.executed', 'skill.failed') THEN 1 END) as total_executions,
|
|
63
|
+
COUNT(CASE WHEN event_type = 'skill.executed' THEN 1 END) as success_count,
|
|
64
|
+
COUNT(CASE WHEN event_type = 'skill.failed' THEN 1 END) as failure_count
|
|
65
|
+
FROM provider_events
|
|
66
|
+
WHERE created_at >= ?
|
|
67
|
+
`).get(cutoff);
|
|
68
|
+
const activeSessions = db.prepare(`
|
|
69
|
+
SELECT COUNT(DISTINCT session_id) as cnt
|
|
70
|
+
FROM provider_events
|
|
71
|
+
WHERE event_type = 'session.opened'
|
|
72
|
+
AND session_id NOT IN (
|
|
73
|
+
SELECT DISTINCT session_id FROM provider_events
|
|
74
|
+
WHERE event_type IN ('session.ended', 'session.failed')
|
|
75
|
+
AND session_id IS NOT NULL
|
|
76
|
+
)
|
|
77
|
+
AND session_id IS NOT NULL
|
|
78
|
+
`).get();
|
|
79
|
+
const topSkills = db.prepare(`
|
|
80
|
+
SELECT skill_id, COUNT(*) as count, COALESCE(SUM(credits), 0) as earnings
|
|
81
|
+
FROM provider_events
|
|
82
|
+
WHERE event_type = 'skill.executed' AND created_at >= ? AND skill_id IS NOT NULL
|
|
83
|
+
GROUP BY skill_id
|
|
84
|
+
ORDER BY count DESC
|
|
85
|
+
LIMIT 10
|
|
86
|
+
`).all(cutoff);
|
|
87
|
+
const topRequesters = db.prepare(`
|
|
88
|
+
SELECT requester, COUNT(*) as count
|
|
89
|
+
FROM provider_events
|
|
90
|
+
WHERE event_type IN ('skill.executed', 'session.opened') AND created_at >= ? AND requester IS NOT NULL
|
|
91
|
+
GROUP BY requester
|
|
92
|
+
ORDER BY count DESC
|
|
93
|
+
LIMIT 10
|
|
94
|
+
`).all(cutoff);
|
|
95
|
+
const sevenDaysAgo = new Date(Date.now() - 7 * 24 * 60 * 60 * 1e3).toISOString();
|
|
96
|
+
const timelineRows = db.prepare(`
|
|
97
|
+
SELECT DATE(created_at) as date, COALESCE(SUM(credits), 0) as earnings
|
|
98
|
+
FROM provider_events
|
|
99
|
+
WHERE event_type = 'skill.executed' AND created_at >= ?
|
|
100
|
+
GROUP BY DATE(created_at)
|
|
101
|
+
ORDER BY date ASC
|
|
102
|
+
`).all(sevenDaysAgo);
|
|
103
|
+
const timelineMap = new Map(timelineRows.map((r) => [r.date, r.earnings]));
|
|
104
|
+
const earnings_timeline = [];
|
|
105
|
+
for (let i = 6; i >= 0; i--) {
|
|
106
|
+
const d = new Date(Date.now() - i * 24 * 60 * 60 * 1e3);
|
|
107
|
+
const dateStr = d.toISOString().slice(0, 10);
|
|
108
|
+
earnings_timeline.push({ date: dateStr, earnings: timelineMap.get(dateStr) ?? 0 });
|
|
109
|
+
}
|
|
110
|
+
const successRate = summary.total_executions > 0 ? summary.success_count / summary.total_executions : 1;
|
|
111
|
+
return {
|
|
112
|
+
total_earnings: summary.total_earnings,
|
|
113
|
+
total_spending: 0,
|
|
114
|
+
// Filled by API layer (reads credit_transactions)
|
|
115
|
+
net_pnl: summary.total_earnings,
|
|
116
|
+
total_executions: summary.total_executions,
|
|
117
|
+
success_count: summary.success_count,
|
|
118
|
+
failure_count: summary.failure_count,
|
|
119
|
+
success_rate: Math.round(successRate * 1e3) / 1e3,
|
|
120
|
+
active_sessions: activeSessions.cnt,
|
|
121
|
+
top_skills: topSkills,
|
|
122
|
+
top_requesters: topRequesters,
|
|
123
|
+
earnings_timeline
|
|
124
|
+
};
|
|
125
|
+
}
|
|
126
|
+
function parseEventRow(row) {
|
|
127
|
+
let metadata = null;
|
|
128
|
+
if (typeof row["metadata"] === "string") {
|
|
129
|
+
try {
|
|
130
|
+
metadata = JSON.parse(row["metadata"]);
|
|
131
|
+
} catch {
|
|
132
|
+
metadata = null;
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
return {
|
|
136
|
+
id: row["id"],
|
|
137
|
+
event_type: row["event_type"],
|
|
138
|
+
skill_id: row["skill_id"] ?? null,
|
|
139
|
+
session_id: row["session_id"] ?? null,
|
|
140
|
+
requester: row["requester"] ?? null,
|
|
141
|
+
credits: row["credits"] ?? 0,
|
|
142
|
+
duration_ms: row["duration_ms"] ?? 0,
|
|
143
|
+
metadata,
|
|
144
|
+
created_at: row["created_at"]
|
|
145
|
+
};
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
export {
|
|
149
|
+
ensureProviderEventsTable,
|
|
150
|
+
emitProviderEvent,
|
|
151
|
+
getProviderEvents,
|
|
152
|
+
getProviderStats
|
|
153
|
+
};
|
|
@@ -1,16 +1,13 @@
|
|
|
1
|
+
import {
|
|
2
|
+
getCard,
|
|
3
|
+
getFeedbackForProvider
|
|
4
|
+
} from "./chunk-BPPFY72X.js";
|
|
1
5
|
import {
|
|
2
6
|
canonicalizeCreditOwner,
|
|
3
7
|
ensureReliabilityTable,
|
|
4
8
|
migrateCreditOwnerData,
|
|
5
9
|
recordSuccessfulHire
|
|
6
10
|
} from "./chunk-6QMDJVMS.js";
|
|
7
|
-
import {
|
|
8
|
-
loadCoreConfig
|
|
9
|
-
} from "./chunk-QXRNW4OJ.js";
|
|
10
|
-
import {
|
|
11
|
-
getCard,
|
|
12
|
-
getFeedbackForProvider
|
|
13
|
-
} from "./chunk-VJ2Q33AP.js";
|
|
14
11
|
import {
|
|
15
12
|
ensureAgentsTable,
|
|
16
13
|
resolveCanonicalIdentity
|
|
@@ -18,6 +15,9 @@ import {
|
|
|
18
15
|
import {
|
|
19
16
|
AgentBnBError
|
|
20
17
|
} from "./chunk-UVCNMRPS.js";
|
|
18
|
+
import {
|
|
19
|
+
loadCoreConfig
|
|
20
|
+
} from "./chunk-QXRNW4OJ.js";
|
|
21
21
|
|
|
22
22
|
// src/credit/ledger.ts
|
|
23
23
|
import Database from "better-sqlite3";
|