agentbnb 9.0.3 → 9.1.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/README.md +29 -4
- package/dist/{card-6KL6L4GF.js → card-U2HQRPYN.js} +4 -1
- package/dist/{card-NKQFB3HD.js → card-UF465O7O.js} +4 -1
- package/dist/{chunk-77HAL2ZL.js → chunk-2HH2F3DM.js} +189 -68
- package/dist/chunk-3RG5ZIWI.js +10 -0
- package/dist/chunk-4HLGFR72.js +155 -0
- package/dist/chunk-4XTYT4JW.js +147 -0
- package/dist/{chunk-NLQCHO7N.js → chunk-7VZ4M4CT.js} +7 -134
- package/dist/{chunk-UQCQ2JCG.js → chunk-AMABG5SI.js} +7 -7
- package/dist/{chunk-N3TXLBGK.js → chunk-AW4VSROG.js} +1 -1
- package/dist/{chunk-PG3CLSAH.js → chunk-BPPFY72X.js} +7 -134
- package/dist/{chunk-Z4IDXMSP.js → chunk-D7NH6YLM.js} +6 -1
- package/dist/{chunk-SLZBE2I5.js → chunk-F2CIPAN2.js} +19 -14
- package/dist/{chunk-FUGWPKXN.js → chunk-G4TF4LB4.js} +1 -1
- package/dist/chunk-GZUTU6IZ.js +153 -0
- package/dist/{chunk-QEDVPJKP.js → chunk-I4E5ERDN.js} +20 -16
- package/dist/{chunk-74OZGLIT.js → chunk-LENX5NUW.js} +1 -1
- package/dist/{chunk-BNS76U6K.js → chunk-MPS4RE7T.js} +26 -20
- package/dist/{chunk-ERT77HKY.js → chunk-O44N3KR7.js} +2 -2
- package/dist/chunk-Q5OFZ2JR.js +292 -0
- package/dist/{chunk-YJ3RGKPU.js → chunk-QG2LLVXP.js} +6 -2
- package/dist/chunk-QXRNW4OJ.js +35 -0
- package/dist/{chunk-76YORWFJ.js → chunk-RVOZHVM7.js} +186 -63
- package/dist/{chunk-2SOHHB2O.js → chunk-TCA63C42.js} +39 -16
- package/dist/{chunk-UR3MISL2.js → chunk-UPNREF4L.js} +1 -1
- package/dist/{chunk-SMQDT7CT.js → chunk-WARYO57F.js} +7 -3
- package/dist/{chunk-DYJ7YGBM.js → chunk-WOVESOQ7.js} +237 -124
- package/dist/{chunk-I3RRMAAD.js → chunk-Y7CO3VLF.js} +8 -8
- package/dist/{chunk-FMKBCO2Q.js → chunk-ZYOMPJGG.js} +2 -2
- package/dist/cli/index.js +147 -63
- package/dist/{client-YB3IYO3S.js → client-XOSXFC7Q.js} +1 -0
- package/dist/conduct-MALC6HEK.js +30 -0
- package/dist/{conduct-URYWMA5T.js → conduct-UT6ZYSJD.js} +16 -12
- package/dist/{conductor-mode-2UFN6BUL.js → conductor-mode-3WLLERB4.js} +23 -19
- package/dist/{conductor-mode-NRSVP2AU.js → conductor-mode-UJKMO2GW.js} +15 -11
- package/dist/{config-IRWLG6IW.js → config-ZFWBAGDU.js} +1 -0
- package/dist/{credits-action-24EPLUHG.js → credits-action-KOUJNR36.js} +7 -5
- package/dist/{daemon-A7DXZIQW.js → daemon-ETXXE4IS.js} +2 -1
- package/dist/{did-action-MQLDT4RF.js → did-action-UHUYMA4Y.js} +2 -1
- package/dist/{execute-DNRNU3HM.js → execute-3RADNI74.js} +9 -5
- package/dist/{execute-2Z3XIUHR.js → execute-UFMGTXET.js} +12 -8
- package/dist/index.d.ts +412 -275
- package/dist/index.js +1198 -391
- package/dist/{openclaw-setup-WA625DZA.js → openclaw-setup-HEWZZOY7.js} +21 -17
- package/dist/{openclaw-skills-76ZWXHFM.js → openclaw-skills-5XLQFRWT.js} +7 -6
- package/dist/{peers-F2EWUMVQ.js → peers-7BMU2775.js} +1 -0
- package/dist/{peers-CJ7T4RJO.js → peers-IOVCBWAI.js} +1 -0
- package/dist/{process-guard-QDBIOLY4.js → process-guard-6324CZDC.js} +1 -0
- package/dist/provider-events-GTTJPYHS.js +13 -0
- package/dist/{publish-capability-FOCHYNYE.js → publish-capability-LM4RSQXX.js} +5 -2
- package/dist/{reliability-metrics-JSOY3PNW.js → reliability-metrics-22JTZGB4.js} +1 -0
- package/dist/{reliability-metrics-KKUFFVB6.js → reliability-metrics-MIJ3TJWL.js} +1 -0
- package/dist/{request-KPKWBL5W.js → request-LID2N42Y.js} +17 -13
- package/dist/request-log-2D253WML.js +17 -0
- package/dist/request-log-SIGTGOFA.js +16 -0
- package/dist/{scanner-GP4AOCW6.js → scanner-EFU6NBEJ.js} +1 -0
- package/dist/{schema-7BSSLZ4S.js → schema-FABVZKSI.js} +1 -0
- package/dist/{serve-skill-QSUIK3ZF.js → serve-skill-CDNSHTEE.js} +17 -13
- package/dist/{server-OCCAVVDF.js → server-QIAO3YSK.js} +23 -15
- package/dist/{service-coordinator-4JAUUNUL.js → service-coordinator-FB44QL7L.js} +721 -69
- package/dist/session-5AIRM7YF.js +144 -0
- package/dist/session-action-GYITLYOE.js +131 -0
- package/dist/{skill-config-5O2VR546.js → skill-config-VYNF7BCY.js} +1 -0
- package/dist/{skill-wrap-YLCJMFEJ.js → skill-wrap-IAZHOYM4.js} +1 -0
- package/dist/skills/agentbnb/bootstrap.js +750 -98
- package/dist/{store-S22F3I7G.js → store-C4DLIXYM.js} +4 -1
- package/dist/{vc-action-SUD7TMN2.js → vc-action-BWGNQ77Y.js} +2 -1
- package/dist/websocket-client-FCPZOE4S.js +9 -0
- package/dist/websocket-client-RT4KLJL4.js +8 -0
- package/dist/{writer-4QJ3U3WE.js → writer-V7JBWKKZ.js} +1 -0
- package/package.json +3 -1
- package/dist/chunk-3466S65P.js +0 -179
- package/dist/conduct-UAEEMVFD.js +0 -26
- package/dist/websocket-client-5CRE36Z5.js +0 -7
- package/dist/websocket-client-WHEHIYIZ.js +0 -6
package/README.md
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# AgentBnB
|
|
2
2
|
|
|
3
3
|
[](https://www.npmjs.com/package/agentbnb)
|
|
4
|
-
[](https://github.com/Xiaoher-C/agentbnb)
|
|
5
5
|
[](https://nodejs.org/)
|
|
6
6
|
[](LICENSE)
|
|
7
7
|
[](https://agentbnb.fly.dev)
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
<h3 align="center"><strong>Your AI agent doesn't need to do everything itself. It can hire another AI agent.</strong></h3>
|
|
14
14
|
<p align="center">Agents discover, hire, form teams, and settle payment — with cryptographic identity, relay-enforced escrow, and portable reputation.</p>
|
|
15
15
|
|
|
16
|
-
<p align="center"><code>v9.
|
|
16
|
+
<p align="center"><code>v9.1 · 1,800+ tests · DID + UCAN + VCs · Sessions · Provider Dashboard · relay-only settlement · 5% network fee · MIT</code></p>
|
|
17
17
|
|
|
18
18
|
---
|
|
19
19
|
|
|
@@ -257,7 +257,7 @@ The agent is the user, not the human. Agents hold their own Ed25519 keypairs, ea
|
|
|
257
257
|
| **Hub** | Discover agents and capabilities across the network |
|
|
258
258
|
| **Team Formation** | Decompose tasks, match providers, form execution teams |
|
|
259
259
|
| **Conductor** | Orchestrate multi-agent DAG workflows with dependency resolution |
|
|
260
|
-
| **Execution** | 5 modes
|
|
260
|
+
| **Execution** | 5 skill modes (API, Command, Pipeline, OpenClaw, Conductor) + interactive Sessions |
|
|
261
261
|
| **Routing** | Multi-factor scoring (trust × cost × availability) |
|
|
262
262
|
| **Reputation** | Feedback-driven trust with failure classification (overload ≠ bad work) |
|
|
263
263
|
| **Escrow** | Ed25519 signed, relay-enforced credit settlement |
|
|
@@ -267,6 +267,31 @@ The agent is the user, not the human. Agents hold their own Ed25519 keypairs, ea
|
|
|
267
267
|
| **Identity** | W3C DID (did:key + did:agentbnb) · UCAN scoped delegation · Verifiable Credentials · Key rotation · EVM bridge |
|
|
268
268
|
| **Framework Adapters** | LangChain, CrewAI, AutoGen |
|
|
269
269
|
|
|
270
|
+
### New in v9.1
|
|
271
|
+
|
|
272
|
+
| Feature | What It Does |
|
|
273
|
+
|---------|-------------|
|
|
274
|
+
| **Agent-to-Agent Sessions** | Interactive turn-based conversations between agents. Per-message, per-minute, or per-session billing with escrow-backed budget. `agentbnb session open` / `send` / `end`. |
|
|
275
|
+
| **Provider Dashboard** | Real-time web UI at `/#/dashboard` — see earnings, active sessions, skill performance, and event feed. Polling-based, no setup needed. |
|
|
276
|
+
| **Provider Event Stream** | Unified `provider_events` SQLite table with 7 dot-notation event types. Powers both Telegram notifications and the Dashboard. |
|
|
277
|
+
| **Provider Gate** | Control who can rent your skills: `provider-accepting` (on/off), `provider-blacklist`, `provider-whitelist`, `provider-daily-limit`. Natural-language control via OpenClaw Telegram bot. |
|
|
278
|
+
| **Telegram Notifications** | Real-time alerts when skills are rented: incoming request, execution result, session lifecycle. Configurable `notification-filters` to suppress noisy events. |
|
|
279
|
+
| **OpenClaw Provider Bridge** | OpenClaw agents can now serve as AgentBnB providers. `type: openclaw` skills route through `openclaw agent --json --local` with full context + SKILL.md instructions. |
|
|
280
|
+
| **Core Config Loader** | Algorithm parameters (reputation weights, network fees, rate limits) load from `@agentbnb/core` if installed, with built-in defaults for open-source users. |
|
|
281
|
+
|
|
282
|
+
### Provider Gate (new)
|
|
283
|
+
|
|
284
|
+
Protect your API keys from unauthorized rental usage:
|
|
285
|
+
|
|
286
|
+
```bash
|
|
287
|
+
agentbnb config set provider-gate notify # Telegram alert before execution
|
|
288
|
+
agentbnb config set provider-daily-limit 20 # Max 20 executions per day
|
|
289
|
+
agentbnb config set provider-blacklist agent-xxx # Block specific agents
|
|
290
|
+
agentbnb config set provider-accepting false # Stop accepting all requests
|
|
291
|
+
```
|
|
292
|
+
|
|
293
|
+
Whitelisted agents bypass all gates: `agentbnb config set provider-whitelist agent-trusted`
|
|
294
|
+
|
|
270
295
|
---
|
|
271
296
|
|
|
272
297
|
## Credit System
|
|
@@ -397,7 +422,7 @@ Read the full spec: [ADR-020: UCAN Token Specification](./docs/adr/020-ucan-toke
|
|
|
397
422
|
|
|
398
423
|
```bash
|
|
399
424
|
pnpm install # Install dependencies
|
|
400
|
-
pnpm test:run # Run all tests (1,
|
|
425
|
+
pnpm test:run # Run all tests (1,800+ tests)
|
|
401
426
|
pnpm typecheck # Type check
|
|
402
427
|
pnpm build:all # Build everything
|
|
403
428
|
```
|
|
@@ -1,10 +1,13 @@
|
|
|
1
1
|
import {
|
|
2
2
|
attachCanonicalAgentId
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-BPPFY72X.js";
|
|
4
|
+
import "./chunk-4XTYT4JW.js";
|
|
5
|
+
import "./chunk-GZUTU6IZ.js";
|
|
4
6
|
import "./chunk-EE3V3DXK.js";
|
|
5
7
|
import {
|
|
6
8
|
CapabilityCardV2Schema
|
|
7
9
|
} from "./chunk-UVCNMRPS.js";
|
|
10
|
+
import "./chunk-3RG5ZIWI.js";
|
|
8
11
|
|
|
9
12
|
// src/conductor/card.ts
|
|
10
13
|
import { createHash } from "crypto";
|
|
@@ -1,10 +1,13 @@
|
|
|
1
1
|
import {
|
|
2
2
|
attachCanonicalAgentId
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-7VZ4M4CT.js";
|
|
4
4
|
import "./chunk-J4RFJVXI.js";
|
|
5
5
|
import {
|
|
6
6
|
CapabilityCardV2Schema
|
|
7
7
|
} from "./chunk-UVCNMRPS.js";
|
|
8
|
+
import "./chunk-4XTYT4JW.js";
|
|
9
|
+
import "./chunk-GZUTU6IZ.js";
|
|
10
|
+
import "./chunk-3RG5ZIWI.js";
|
|
8
11
|
|
|
9
12
|
// src/conductor/card.ts
|
|
10
13
|
import { createHash } from "crypto";
|
|
@@ -8,10 +8,23 @@ 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,
|
|
@@ -19,21 +32,13 @@ import {
|
|
|
19
32
|
signEscrowReceipt,
|
|
20
33
|
verifyEscrowReceipt
|
|
21
34
|
} from "./chunk-YNBZLXYS.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
|
-
insertRequestLog,
|
|
29
|
-
updateReputation
|
|
30
|
-
} from "./chunk-PG3CLSAH.js";
|
|
31
|
-
import {
|
|
32
|
-
lookupAgent
|
|
33
|
-
} from "./chunk-EE3V3DXK.js";
|
|
34
|
-
import {
|
|
35
|
-
AgentBnBError
|
|
36
|
-
} from "./chunk-UVCNMRPS.js";
|
|
37
42
|
|
|
38
43
|
// src/gateway/execute.ts
|
|
39
44
|
import { randomUUID } from "crypto";
|
|
@@ -652,52 +657,133 @@ async function syncCreditsFromRegistry(config, localDb) {
|
|
|
652
657
|
}
|
|
653
658
|
}
|
|
654
659
|
|
|
655
|
-
// src/gateway/
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
660
|
+
// src/gateway/provider-notifier.ts
|
|
661
|
+
var EVENT_EMOJI = {
|
|
662
|
+
"skill.received": "\u{1F4E5}",
|
|
663
|
+
"skill.executed": "\u2705",
|
|
664
|
+
"skill.failed": "\u274C",
|
|
665
|
+
"skill.rejected": "\u{1F6AB}",
|
|
666
|
+
"session.opened": "\u{1F517}",
|
|
667
|
+
"session.message": "\u{1F4AC}",
|
|
668
|
+
"session.ended": "\u{1F3C1}",
|
|
669
|
+
"session.failed": "\u{1F4A5}"
|
|
670
|
+
};
|
|
671
|
+
function formatEventMessage(event, balance) {
|
|
672
|
+
const emoji = EVENT_EMOJI[event.event_type] ?? "\u{1F4CB}";
|
|
673
|
+
const meta = event.metadata ?? {};
|
|
674
|
+
const skillLabel = event.skill_id ?? "unknown";
|
|
675
|
+
switch (event.event_type) {
|
|
676
|
+
case "skill.received":
|
|
677
|
+
return [
|
|
678
|
+
`${emoji} [AgentBnB] Incoming request`,
|
|
679
|
+
`Skill: ${skillLabel}`,
|
|
680
|
+
`Requester: ${event.requester}`,
|
|
681
|
+
`Cost: ${event.credits} credits`,
|
|
682
|
+
`Status: Executing...`
|
|
683
|
+
].join("\n");
|
|
684
|
+
case "skill.executed":
|
|
685
|
+
return [
|
|
686
|
+
`${emoji} [AgentBnB] Skill executed`,
|
|
687
|
+
`Skill: ${skillLabel}`,
|
|
688
|
+
`Requester: ${event.requester}`,
|
|
689
|
+
`Earned: +${event.credits} credits`,
|
|
690
|
+
...balance !== void 0 ? [`Balance: ${balance} credits`] : [],
|
|
691
|
+
`Latency: ${event.duration_ms}ms`
|
|
692
|
+
].join("\n");
|
|
693
|
+
case "skill.failed":
|
|
694
|
+
return [
|
|
695
|
+
`${emoji} [AgentBnB] Skill failed`,
|
|
696
|
+
`Skill: ${skillLabel}`,
|
|
697
|
+
`Requester: ${event.requester}`,
|
|
698
|
+
`Reason: ${meta["failure_reason"] ?? "unknown"}`,
|
|
699
|
+
...meta["error"] ? [`Error: ${String(meta["error"]).slice(0, 200)}`] : [],
|
|
700
|
+
...balance !== void 0 ? [`Balance: ${balance} credits`] : [],
|
|
701
|
+
`Latency: ${event.duration_ms}ms`
|
|
702
|
+
].join("\n");
|
|
703
|
+
case "skill.rejected":
|
|
704
|
+
return [
|
|
705
|
+
`${emoji} [AgentBnB] Request rejected`,
|
|
706
|
+
`Skill: ${skillLabel}`,
|
|
707
|
+
`Requester: ${event.requester}`,
|
|
708
|
+
`Reason: ${meta["reason"] ?? "unknown"}`
|
|
709
|
+
].join("\n");
|
|
710
|
+
case "session.opened":
|
|
711
|
+
return [
|
|
712
|
+
`${emoji} [AgentBnB] Session opened`,
|
|
713
|
+
`Session: ${event.session_id?.slice(0, 8)}...`,
|
|
714
|
+
`Requester: ${event.requester}`,
|
|
715
|
+
`Skill: ${skillLabel}`,
|
|
716
|
+
`Pricing: ${meta["pricing_model"] ?? "unknown"}`,
|
|
717
|
+
`Budget: ${event.credits} credits`
|
|
718
|
+
].join("\n");
|
|
719
|
+
case "session.message": {
|
|
720
|
+
const msgCount = meta["message_count"] ?? "?";
|
|
721
|
+
const runningCost = meta["running_cost"] ?? event.credits;
|
|
722
|
+
return [
|
|
723
|
+
`${emoji} [AgentBnB] Session message #${msgCount}`,
|
|
724
|
+
`Session: ${event.session_id?.slice(0, 8)}...`,
|
|
725
|
+
`Running cost: ${runningCost} credits`
|
|
726
|
+
].join("\n");
|
|
727
|
+
}
|
|
728
|
+
case "session.ended": {
|
|
729
|
+
const totalMsgs = meta["total_messages"] ?? "?";
|
|
730
|
+
const durationMin = Math.round(event.duration_ms / 6e4);
|
|
731
|
+
const refunded = Number(meta["refunded"] ?? 0);
|
|
732
|
+
return [
|
|
733
|
+
`${emoji} [AgentBnB] Session ended`,
|
|
734
|
+
`Session: ${event.session_id?.slice(0, 8)}...`,
|
|
735
|
+
`Total: ${totalMsgs} messages, ${event.credits} credits`,
|
|
736
|
+
`Duration: ${durationMin} minutes`,
|
|
737
|
+
...refunded > 0 ? [`Refunded: ${refunded} credits`] : []
|
|
738
|
+
].join("\n");
|
|
739
|
+
}
|
|
740
|
+
case "session.failed": {
|
|
741
|
+
const lastMsgs = Array.isArray(meta["last_messages"]) ? meta["last_messages"] : [];
|
|
742
|
+
const lines = [
|
|
743
|
+
`${emoji} [AgentBnB] Session failed`,
|
|
744
|
+
`Session: ${event.session_id?.slice(0, 8)}...`,
|
|
745
|
+
`Reason: ${meta["reason"] ?? "error"}`,
|
|
746
|
+
`Cost: ${event.credits} credits`
|
|
747
|
+
];
|
|
748
|
+
if (lastMsgs.length > 0) {
|
|
749
|
+
lines.push("", "Last messages:");
|
|
750
|
+
for (const m of lastMsgs) {
|
|
751
|
+
lines.push(` ${m.sender}: ${m.content.slice(0, 100)}`);
|
|
752
|
+
}
|
|
753
|
+
}
|
|
754
|
+
return lines.join("\n");
|
|
755
|
+
}
|
|
756
|
+
default:
|
|
757
|
+
return `${emoji} [AgentBnB] ${event.event_type}: ${skillLabel}`;
|
|
758
|
+
}
|
|
677
759
|
}
|
|
678
|
-
async function
|
|
760
|
+
async function notifyProviderEvent(event, creditDb, owner) {
|
|
679
761
|
const cfg = loadConfig();
|
|
680
|
-
if (!cfg
|
|
762
|
+
if (!cfg) return;
|
|
763
|
+
const telegramEnabled = cfg.telegram_notifications === true;
|
|
764
|
+
const gateNotify = cfg.provider_gate === "notify";
|
|
765
|
+
if (!telegramEnabled && !gateNotify) return;
|
|
766
|
+
const filters = cfg.notification_filters ?? ["session.message"];
|
|
767
|
+
if (filters.includes(event.event_type)) return;
|
|
681
768
|
const token = cfg.telegram_bot_token ?? process.env["TELEGRAM_BOT_TOKEN"];
|
|
682
769
|
const chatId = cfg.telegram_chat_id ?? process.env["TELEGRAM_CHAT_ID"];
|
|
683
770
|
if (!token || !chatId) return;
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
`Balance: ${balance} credits`,
|
|
693
|
-
`Latency: ${opts.latencyMs}ms`
|
|
694
|
-
].join("\n");
|
|
771
|
+
let balance;
|
|
772
|
+
if (creditDb && owner && (event.event_type === "skill.executed" || event.event_type === "skill.failed")) {
|
|
773
|
+
try {
|
|
774
|
+
balance = getBalance(creditDb, owner);
|
|
775
|
+
} catch {
|
|
776
|
+
}
|
|
777
|
+
}
|
|
778
|
+
const text = formatEventMessage(event, balance);
|
|
695
779
|
await fetch(`https://api.telegram.org/bot${token}/sendMessage`, {
|
|
696
780
|
method: "POST",
|
|
697
781
|
headers: { "Content-Type": "application/json" },
|
|
698
782
|
body: JSON.stringify({ chat_id: chatId, text })
|
|
699
783
|
});
|
|
700
784
|
}
|
|
785
|
+
|
|
786
|
+
// src/gateway/execute.ts
|
|
701
787
|
async function executeCapabilityRequest(opts) {
|
|
702
788
|
const {
|
|
703
789
|
registryDb,
|
|
@@ -789,6 +875,49 @@ async function executeCapabilityRequest(opts) {
|
|
|
789
875
|
return { success: false, error: { code: -32603, message: msg } };
|
|
790
876
|
}
|
|
791
877
|
}
|
|
878
|
+
const providerCfg = loadConfig();
|
|
879
|
+
const providerWhitelist = providerCfg?.provider_whitelist ?? [];
|
|
880
|
+
const isWhitelisted = providerWhitelist.includes(requester);
|
|
881
|
+
if (providerCfg?.provider_accepting === false && !isWhitelisted) {
|
|
882
|
+
if (escrowId) releaseEscrow(creditDb, escrowId);
|
|
883
|
+
return { success: false, error: { code: -32098, message: "Provider is not accepting requests" } };
|
|
884
|
+
}
|
|
885
|
+
if (!isWhitelisted) {
|
|
886
|
+
const blacklist = providerCfg?.provider_blacklist ?? [];
|
|
887
|
+
if (blacklist.includes(requester)) {
|
|
888
|
+
if (escrowId) releaseEscrow(creditDb, escrowId);
|
|
889
|
+
try {
|
|
890
|
+
emitProviderEvent(registryDb, { event_type: "skill.rejected", skill_id: resolvedSkillId ?? null, session_id: null, requester, credits: 0, duration_ms: 0, metadata: { reason: "blacklisted" } });
|
|
891
|
+
} catch {
|
|
892
|
+
}
|
|
893
|
+
return { success: false, error: { code: -32097, message: "Requester is blocked by provider" } };
|
|
894
|
+
}
|
|
895
|
+
}
|
|
896
|
+
if (!isWhitelisted) {
|
|
897
|
+
const dailyLimit = providerCfg?.provider_daily_limit ?? 0;
|
|
898
|
+
if (dailyLimit > 0) {
|
|
899
|
+
const { countTodayExecutions } = await import("./request-log-2D253WML.js");
|
|
900
|
+
const todayCount = countTodayExecutions(registryDb);
|
|
901
|
+
if (todayCount >= dailyLimit) {
|
|
902
|
+
if (escrowId) releaseEscrow(creditDb, escrowId);
|
|
903
|
+
try {
|
|
904
|
+
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 } });
|
|
905
|
+
} catch {
|
|
906
|
+
}
|
|
907
|
+
return {
|
|
908
|
+
success: false,
|
|
909
|
+
error: { code: -32099, message: `Provider daily execution limit reached (${dailyLimit}/day)` }
|
|
910
|
+
};
|
|
911
|
+
}
|
|
912
|
+
}
|
|
913
|
+
}
|
|
914
|
+
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" } };
|
|
915
|
+
try {
|
|
916
|
+
const emitted = emitProviderEvent(registryDb, receivedEvent);
|
|
917
|
+
notifyProviderEvent(emitted, creditDb, card.owner).catch(() => {
|
|
918
|
+
});
|
|
919
|
+
} catch {
|
|
920
|
+
}
|
|
792
921
|
const startMs = Date.now();
|
|
793
922
|
const handleFailure = (status, latencyMs, message, failureReason = "bad_execution") => {
|
|
794
923
|
if (escrowId) releaseEscrow(creditDb, escrowId);
|
|
@@ -810,17 +939,12 @@ async function executeCapabilityRequest(opts) {
|
|
|
810
939
|
});
|
|
811
940
|
} catch {
|
|
812
941
|
}
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
latencyMs,
|
|
820
|
-
failureReason,
|
|
821
|
-
message
|
|
822
|
-
}).catch(() => {
|
|
823
|
-
});
|
|
942
|
+
try {
|
|
943
|
+
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 } });
|
|
944
|
+
notifyProviderEvent(emitted, creditDb, card.owner).catch(() => {
|
|
945
|
+
});
|
|
946
|
+
} catch {
|
|
947
|
+
}
|
|
824
948
|
return { success: false, error: { code: -32603, message } };
|
|
825
949
|
};
|
|
826
950
|
const handleSuccess = (result, latencyMs) => {
|
|
@@ -842,16 +966,12 @@ async function executeCapabilityRequest(opts) {
|
|
|
842
966
|
});
|
|
843
967
|
} catch {
|
|
844
968
|
}
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
creditsEarned: creditsNeeded,
|
|
852
|
-
latencyMs
|
|
853
|
-
}).catch(() => {
|
|
854
|
-
});
|
|
969
|
+
try {
|
|
970
|
+
const emitted = emitProviderEvent(registryDb, { event_type: "skill.executed", skill_id: resolvedSkillId ?? null, session_id: null, requester, credits: creditsNeeded, duration_ms: latencyMs, metadata: null });
|
|
971
|
+
notifyProviderEvent(emitted, creditDb, card.owner).catch(() => {
|
|
972
|
+
});
|
|
973
|
+
} catch {
|
|
974
|
+
}
|
|
855
975
|
return { success: true, result };
|
|
856
976
|
};
|
|
857
977
|
if (skillExecutor) {
|
|
@@ -1090,6 +1210,7 @@ export {
|
|
|
1090
1210
|
identityAuthPlugin,
|
|
1091
1211
|
createLedger,
|
|
1092
1212
|
syncCreditsFromRegistry,
|
|
1213
|
+
notifyProviderEvent,
|
|
1093
1214
|
executeCapabilityRequest,
|
|
1094
1215
|
executeCapabilityBatch
|
|
1095
1216
|
};
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
|
|
2
|
+
get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
|
|
3
|
+
}) : x)(function(x) {
|
|
4
|
+
if (typeof require !== "undefined") return require.apply(this, arguments);
|
|
5
|
+
throw Error('Dynamic require of "' + x + '" is not supported');
|
|
6
|
+
});
|
|
7
|
+
|
|
8
|
+
export {
|
|
9
|
+
__require
|
|
10
|
+
};
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
|
|
2
|
+
get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
|
|
3
|
+
}) : x)(function(x) {
|
|
4
|
+
if (typeof require !== "undefined") return require.apply(this, arguments);
|
|
5
|
+
throw Error('Dynamic require of "' + x + '" is not supported');
|
|
6
|
+
});
|
|
7
|
+
|
|
8
|
+
// src/registry/request-log.ts
|
|
9
|
+
var SINCE_MS = {
|
|
10
|
+
"24h": 864e5,
|
|
11
|
+
"7d": 6048e5,
|
|
12
|
+
"30d": 2592e6
|
|
13
|
+
};
|
|
14
|
+
function createRequestLogTable(db) {
|
|
15
|
+
db.exec(`
|
|
16
|
+
CREATE TABLE IF NOT EXISTS request_log (
|
|
17
|
+
id TEXT PRIMARY KEY,
|
|
18
|
+
card_id TEXT NOT NULL,
|
|
19
|
+
card_name TEXT NOT NULL,
|
|
20
|
+
requester TEXT NOT NULL,
|
|
21
|
+
status TEXT NOT NULL CHECK(status IN ('success', 'failure', 'timeout')),
|
|
22
|
+
latency_ms INTEGER NOT NULL,
|
|
23
|
+
credits_charged INTEGER NOT NULL,
|
|
24
|
+
created_at TEXT NOT NULL
|
|
25
|
+
);
|
|
26
|
+
|
|
27
|
+
CREATE INDEX IF NOT EXISTS request_log_created_at_idx
|
|
28
|
+
ON request_log (created_at DESC);
|
|
29
|
+
`);
|
|
30
|
+
try {
|
|
31
|
+
db.exec("ALTER TABLE request_log ADD COLUMN skill_id TEXT");
|
|
32
|
+
} catch {
|
|
33
|
+
}
|
|
34
|
+
try {
|
|
35
|
+
db.exec("ALTER TABLE request_log ADD COLUMN action_type TEXT");
|
|
36
|
+
} catch {
|
|
37
|
+
}
|
|
38
|
+
try {
|
|
39
|
+
db.exec("ALTER TABLE request_log ADD COLUMN tier_invoked INTEGER");
|
|
40
|
+
} catch {
|
|
41
|
+
}
|
|
42
|
+
try {
|
|
43
|
+
db.exec("ALTER TABLE request_log ADD COLUMN failure_reason TEXT");
|
|
44
|
+
} catch {
|
|
45
|
+
}
|
|
46
|
+
try {
|
|
47
|
+
db.exec("ALTER TABLE request_log ADD COLUMN team_id TEXT");
|
|
48
|
+
} catch {
|
|
49
|
+
}
|
|
50
|
+
try {
|
|
51
|
+
db.exec("ALTER TABLE request_log ADD COLUMN role TEXT");
|
|
52
|
+
} catch {
|
|
53
|
+
}
|
|
54
|
+
try {
|
|
55
|
+
db.exec("ALTER TABLE request_log ADD COLUMN capability_type TEXT");
|
|
56
|
+
} catch {
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
function insertRequestLog(db, entry) {
|
|
60
|
+
const stmt = db.prepare(`
|
|
61
|
+
INSERT INTO request_log (id, card_id, card_name, requester, status, latency_ms, credits_charged, created_at, skill_id, action_type, tier_invoked, failure_reason, team_id, role, capability_type)
|
|
62
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
63
|
+
`);
|
|
64
|
+
stmt.run(
|
|
65
|
+
entry.id,
|
|
66
|
+
entry.card_id,
|
|
67
|
+
entry.card_name,
|
|
68
|
+
entry.requester,
|
|
69
|
+
entry.status,
|
|
70
|
+
entry.latency_ms,
|
|
71
|
+
entry.credits_charged,
|
|
72
|
+
entry.created_at,
|
|
73
|
+
entry.skill_id ?? null,
|
|
74
|
+
entry.action_type ?? null,
|
|
75
|
+
entry.tier_invoked ?? null,
|
|
76
|
+
entry.failure_reason ?? null,
|
|
77
|
+
entry.team_id ?? null,
|
|
78
|
+
entry.role ?? null,
|
|
79
|
+
entry.capability_type ?? null
|
|
80
|
+
);
|
|
81
|
+
}
|
|
82
|
+
function getSkillRequestCount(db, skillId, windowMs) {
|
|
83
|
+
const cutoff = new Date(Date.now() - windowMs).toISOString();
|
|
84
|
+
const stmt = db.prepare(
|
|
85
|
+
`SELECT COUNT(*) as cnt FROM request_log
|
|
86
|
+
WHERE skill_id = ? AND created_at >= ? AND status = 'success' AND action_type IS NULL`
|
|
87
|
+
);
|
|
88
|
+
const row = stmt.get(skillId, cutoff);
|
|
89
|
+
return row.cnt;
|
|
90
|
+
}
|
|
91
|
+
function getActivityFeed(db, limit = 20, since) {
|
|
92
|
+
const effectiveLimit = Math.min(limit, 100);
|
|
93
|
+
if (since !== void 0) {
|
|
94
|
+
const stmt2 = db.prepare(`
|
|
95
|
+
SELECT r.id, r.card_name, r.requester, c.owner AS provider,
|
|
96
|
+
r.status, r.credits_charged, r.latency_ms, r.created_at, r.action_type
|
|
97
|
+
FROM request_log r
|
|
98
|
+
LEFT JOIN capability_cards c ON r.card_id = c.id
|
|
99
|
+
WHERE (r.action_type IS NULL OR r.action_type IN ('auto_share', 'agent_joined'))
|
|
100
|
+
AND r.created_at > ?
|
|
101
|
+
ORDER BY r.created_at DESC
|
|
102
|
+
LIMIT ?
|
|
103
|
+
`);
|
|
104
|
+
return stmt2.all(since, effectiveLimit);
|
|
105
|
+
}
|
|
106
|
+
const stmt = db.prepare(`
|
|
107
|
+
SELECT r.id, r.card_name, r.requester, c.owner AS provider,
|
|
108
|
+
r.status, r.credits_charged, r.latency_ms, r.created_at, r.action_type
|
|
109
|
+
FROM request_log r
|
|
110
|
+
LEFT JOIN capability_cards c ON r.card_id = c.id
|
|
111
|
+
WHERE (r.action_type IS NULL OR r.action_type IN ('auto_share', 'agent_joined'))
|
|
112
|
+
ORDER BY r.created_at DESC
|
|
113
|
+
LIMIT ?
|
|
114
|
+
`);
|
|
115
|
+
return stmt.all(effectiveLimit);
|
|
116
|
+
}
|
|
117
|
+
function countTodayExecutions(db) {
|
|
118
|
+
const today = (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
|
|
119
|
+
const stmt = db.prepare(
|
|
120
|
+
`SELECT COUNT(*) as cnt FROM request_log
|
|
121
|
+
WHERE created_at >= ? AND action_type IS NULL`
|
|
122
|
+
);
|
|
123
|
+
const row = stmt.get(today + "T00:00:00.000Z");
|
|
124
|
+
return row.cnt;
|
|
125
|
+
}
|
|
126
|
+
function getRequestLog(db, limit = 10, since) {
|
|
127
|
+
if (since !== void 0) {
|
|
128
|
+
const cutoff = new Date(Date.now() - SINCE_MS[since]).toISOString();
|
|
129
|
+
const stmt2 = db.prepare(`
|
|
130
|
+
SELECT id, card_id, card_name, requester, status, latency_ms, credits_charged, created_at, skill_id, action_type, tier_invoked, failure_reason, team_id, role, capability_type
|
|
131
|
+
FROM request_log
|
|
132
|
+
WHERE created_at >= ?
|
|
133
|
+
ORDER BY created_at DESC
|
|
134
|
+
LIMIT ?
|
|
135
|
+
`);
|
|
136
|
+
return stmt2.all(cutoff, limit);
|
|
137
|
+
}
|
|
138
|
+
const stmt = db.prepare(`
|
|
139
|
+
SELECT id, card_id, card_name, requester, status, latency_ms, credits_charged, created_at, skill_id, action_type, tier_invoked, failure_reason, team_id, role
|
|
140
|
+
FROM request_log
|
|
141
|
+
ORDER BY created_at DESC
|
|
142
|
+
LIMIT ?
|
|
143
|
+
`);
|
|
144
|
+
return stmt.all(limit);
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
export {
|
|
148
|
+
__require,
|
|
149
|
+
createRequestLogTable,
|
|
150
|
+
insertRequestLog,
|
|
151
|
+
getSkillRequestCount,
|
|
152
|
+
getActivityFeed,
|
|
153
|
+
countTodayExecutions,
|
|
154
|
+
getRequestLog
|
|
155
|
+
};
|