agentbnb 9.1.0 → 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.
Files changed (42) hide show
  1. package/README.md +29 -4
  2. package/dist/{card-VVT3XBOI.js → card-U2HQRPYN.js} +2 -1
  3. package/dist/{card-NQHAGTQQ.js → card-UF465O7O.js} +2 -1
  4. package/dist/{chunk-PYZGF5QH.js → chunk-2HH2F3DM.js} +161 -97
  5. package/dist/{chunk-JKD6QRUD.js → chunk-7VZ4M4CT.js} +4 -0
  6. package/dist/{chunk-JJHQAZWE.js → chunk-AMABG5SI.js} +5 -5
  7. package/dist/{chunk-GAZCZCAZ.js → chunk-AW4VSROG.js} +1 -1
  8. package/dist/{chunk-VJ2Q33AP.js → chunk-BPPFY72X.js} +4 -0
  9. package/dist/{chunk-DBO2335D.js → chunk-F2CIPAN2.js} +7 -7
  10. package/dist/{chunk-4UIUIHST.js → chunk-G4TF4LB4.js} +1 -1
  11. package/dist/chunk-GZUTU6IZ.js +153 -0
  12. package/dist/{chunk-4DBSSFHG.js → chunk-I4E5ERDN.js} +3 -3
  13. package/dist/{chunk-XL5XD3IG.js → chunk-MPS4RE7T.js} +7 -7
  14. package/dist/{chunk-4M6IAIVK.js → chunk-O44N3KR7.js} +2 -2
  15. package/dist/{chunk-3Y76PHEY.js → chunk-RVOZHVM7.js} +153 -87
  16. package/dist/{chunk-AR7Z3EQB.js → chunk-TCA63C42.js} +8 -8
  17. package/dist/{chunk-UXL7DV7P.js → chunk-WARYO57F.js} +2 -2
  18. package/dist/{chunk-PIO2FMX4.js → chunk-Y7CO3VLF.js} +5 -5
  19. package/dist/cli/index.js +61 -46
  20. package/dist/{conduct-VSSHJHVH.js → conduct-MALC6HEK.js} +9 -8
  21. package/dist/{conduct-6C6JWZKZ.js → conduct-UT6ZYSJD.js} +9 -8
  22. package/dist/{conductor-mode-NKHIZG4N.js → conductor-mode-3WLLERB4.js} +11 -10
  23. package/dist/{conductor-mode-KKPSNN7V.js → conductor-mode-UJKMO2GW.js} +12 -11
  24. package/dist/{execute-IEQ3RV7I.js → execute-3RADNI74.js} +7 -6
  25. package/dist/{execute-QHP4KUV2.js → execute-UFMGTXET.js} +6 -5
  26. package/dist/index.js +350 -147
  27. package/dist/{openclaw-setup-PKGFB4IH.js → openclaw-setup-HEWZZOY7.js} +9 -8
  28. package/dist/{openclaw-skills-5VJDA6SX.js → openclaw-skills-5XLQFRWT.js} +2 -2
  29. package/dist/provider-events-GTTJPYHS.js +13 -0
  30. package/dist/{publish-capability-CHMPZ6W3.js → publish-capability-LM4RSQXX.js} +3 -2
  31. package/dist/{request-6TBVP3GR.js → request-LID2N42Y.js} +9 -8
  32. package/dist/{serve-skill-BRUHUDRA.js → serve-skill-CDNSHTEE.js} +9 -8
  33. package/dist/{server-N4BJW4TS.js → server-QIAO3YSK.js} +14 -13
  34. package/dist/{service-coordinator-M2CBDEUQ.js → service-coordinator-FB44QL7L.js} +201 -38
  35. package/dist/skills/agentbnb/bootstrap.js +210 -47
  36. package/dist/{store-A4YPEHDV.js → store-C4DLIXYM.js} +2 -1
  37. package/package.json +3 -1
  38. package/dist/{credits-action-N3WB4WSI.js → credits-action-KOUJNR36.js} +2 -2
  39. package/dist/{daemon-OM2K3U7J.js → daemon-ETXXE4IS.js} +1 -1
  40. package/dist/{did-action-3PNFYLX2.js → did-action-UHUYMA4Y.js} +1 -1
  41. package/dist/{session-action-67J57636.js → session-action-GYITLYOE.js} +1 -1
  42. package/dist/{vc-action-TSAIABUM.js → vc-action-BWGNQ77Y.js} +1 -1
package/README.md CHANGED
@@ -1,7 +1,7 @@
1
1
  # AgentBnB
2
2
 
3
3
  [![npm version](https://img.shields.io/npm/v/agentbnb.svg)](https://www.npmjs.com/package/agentbnb)
4
- [![Tests](https://img.shields.io/badge/tests-1%2C700%2B%20passing-brightgreen.svg)](https://github.com/Xiaoher-C/agentbnb)
4
+ [![Tests](https://img.shields.io/badge/tests-1%2C800%2B%20passing-brightgreen.svg)](https://github.com/Xiaoher-C/agentbnb)
5
5
  [![Node.js](https://img.shields.io/badge/node-%3E%3D20-brightgreen.svg)](https://nodejs.org/)
6
6
  [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)
7
7
  [![Relay](https://img.shields.io/badge/relay-agentbnb.fly.dev-blue.svg)](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.0 · 1,700+ tests · DID + UCAN + Verifiable Credentials · relay-only settlement · 5% network fee · MIT</code></p>
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: API, Command, Proxy, MCP, OpenClaw plugin |
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,700+ tests)
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,7 +1,8 @@
1
1
  import {
2
2
  attachCanonicalAgentId
3
- } from "./chunk-VJ2Q33AP.js";
3
+ } from "./chunk-BPPFY72X.js";
4
4
  import "./chunk-4XTYT4JW.js";
5
+ import "./chunk-GZUTU6IZ.js";
5
6
  import "./chunk-EE3V3DXK.js";
6
7
  import {
7
8
  CapabilityCardV2Schema
@@ -1,11 +1,12 @@
1
1
  import {
2
2
  attachCanonicalAgentId
3
- } from "./chunk-JKD6QRUD.js";
3
+ } from "./chunk-7VZ4M4CT.js";
4
4
  import "./chunk-J4RFJVXI.js";
5
5
  import {
6
6
  CapabilityCardV2Schema
7
7
  } from "./chunk-UVCNMRPS.js";
8
8
  import "./chunk-4XTYT4JW.js";
9
+ import "./chunk-GZUTU6IZ.js";
9
10
  import "./chunk-3RG5ZIWI.js";
10
11
 
11
12
  // src/conductor/card.ts
@@ -8,10 +8,23 @@ import {
8
8
  releaseEscrow,
9
9
  resolveTargetCapability,
10
10
  settleEscrow
11
- } from "./chunk-XL5XD3IG.js";
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,23 +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
- 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";
@@ -654,72 +657,133 @@ async function syncCreditsFromRegistry(config, localDb) {
654
657
  }
655
658
  }
656
659
 
657
- // src/gateway/execute.ts
658
- async function notifyTelegramSkillExecuted(opts) {
659
- const cfg = loadConfig();
660
- if (!cfg?.telegram_notifications) return;
661
- const token = cfg.telegram_bot_token ?? process.env["TELEGRAM_BOT_TOKEN"];
662
- const chatId = cfg.telegram_chat_id ?? process.env["TELEGRAM_CHAT_ID"];
663
- if (!token || !chatId) return;
664
- const balance = getBalance(opts.creditDb, opts.owner);
665
- const skillLabel = opts.skillId ? `${opts.skillName} (${opts.skillId})` : opts.skillName;
666
- const text = [
667
- "[AgentBnB] Skill executed",
668
- `Skill: ${skillLabel}`,
669
- `Requester: ${opts.requester}`,
670
- `Earned: +${opts.creditsEarned} credits`,
671
- `Balance: ${balance} credits`,
672
- `Latency: ${opts.latencyMs}ms`
673
- ].join("\n");
674
- await fetch(`https://api.telegram.org/bot${token}/sendMessage`, {
675
- method: "POST",
676
- headers: { "Content-Type": "application/json" },
677
- body: JSON.stringify({ chat_id: chatId, text })
678
- });
679
- }
680
- async function notifyTelegramSkillFailed(opts) {
681
- const cfg = loadConfig();
682
- if (!cfg?.telegram_notifications) return;
683
- const token = cfg.telegram_bot_token ?? process.env["TELEGRAM_BOT_TOKEN"];
684
- const chatId = cfg.telegram_chat_id ?? process.env["TELEGRAM_CHAT_ID"];
685
- if (!token || !chatId) return;
686
- const balance = getBalance(opts.creditDb, opts.owner);
687
- const skillLabel = opts.skillId ? `${opts.skillName} (${opts.skillId})` : opts.skillName;
688
- const text = [
689
- "[AgentBnB] Skill failed",
690
- `Skill: ${skillLabel}`,
691
- `Requester: ${opts.requester}`,
692
- `Reason: ${opts.failureReason}`,
693
- `Error: ${opts.message}`,
694
- `Balance: ${balance} credits`,
695
- `Latency: ${opts.latencyMs}ms`
696
- ].join("\n");
697
- await fetch(`https://api.telegram.org/bot${token}/sendMessage`, {
698
- method: "POST",
699
- headers: { "Content-Type": "application/json" },
700
- body: JSON.stringify({ chat_id: chatId, text })
701
- });
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
+ }
702
759
  }
703
- async function notifyTelegramSkillReceived(opts) {
760
+ async function notifyProviderEvent(event, creditDb, owner) {
704
761
  const cfg = loadConfig();
705
- if (cfg?.provider_gate !== "notify") return;
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;
706
768
  const token = cfg.telegram_bot_token ?? process.env["TELEGRAM_BOT_TOKEN"];
707
769
  const chatId = cfg.telegram_chat_id ?? process.env["TELEGRAM_CHAT_ID"];
708
770
  if (!token || !chatId) return;
709
- const skillLabel = opts.skillId ? `${opts.skillName} (${opts.skillId})` : opts.skillName;
710
- const text = [
711
- "\u{1F4E5} [AgentBnB] Incoming rental request",
712
- `Skill: ${skillLabel}`,
713
- `Requester: ${opts.requester}`,
714
- `Cost: ${opts.cost} credits`,
715
- `Status: Executing...`
716
- ].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);
717
779
  await fetch(`https://api.telegram.org/bot${token}/sendMessage`, {
718
780
  method: "POST",
719
781
  headers: { "Content-Type": "application/json" },
720
782
  body: JSON.stringify({ chat_id: chatId, text })
721
783
  });
722
784
  }
785
+
786
+ // src/gateway/execute.ts
723
787
  async function executeCapabilityRequest(opts) {
724
788
  const {
725
789
  registryDb,
@@ -822,6 +886,10 @@ async function executeCapabilityRequest(opts) {
822
886
  const blacklist = providerCfg?.provider_blacklist ?? [];
823
887
  if (blacklist.includes(requester)) {
824
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
+ }
825
893
  return { success: false, error: { code: -32097, message: "Requester is blocked by provider" } };
826
894
  }
827
895
  }
@@ -832,6 +900,10 @@ async function executeCapabilityRequest(opts) {
832
900
  const todayCount = countTodayExecutions(registryDb);
833
901
  if (todayCount >= dailyLimit) {
834
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
+ }
835
907
  return {
836
908
  success: false,
837
909
  error: { code: -32099, message: `Provider daily execution limit reached (${dailyLimit}/day)` }
@@ -839,13 +911,13 @@ async function executeCapabilityRequest(opts) {
839
911
  }
840
912
  }
841
913
  }
842
- notifyTelegramSkillReceived({
843
- skillName: cardName,
844
- skillId: resolvedSkillId ?? null,
845
- requester,
846
- cost: creditsNeeded
847
- }).catch(() => {
848
- });
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
+ }
849
921
  const startMs = Date.now();
850
922
  const handleFailure = (status, latencyMs, message, failureReason = "bad_execution") => {
851
923
  if (escrowId) releaseEscrow(creditDb, escrowId);
@@ -867,17 +939,12 @@ async function executeCapabilityRequest(opts) {
867
939
  });
868
940
  } catch {
869
941
  }
870
- notifyTelegramSkillFailed({
871
- creditDb,
872
- owner: card.owner,
873
- skillName: cardName,
874
- skillId: resolvedSkillId ?? null,
875
- requester,
876
- latencyMs,
877
- failureReason,
878
- message
879
- }).catch(() => {
880
- });
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
+ }
881
948
  return { success: false, error: { code: -32603, message } };
882
949
  };
883
950
  const handleSuccess = (result, latencyMs) => {
@@ -899,16 +966,12 @@ async function executeCapabilityRequest(opts) {
899
966
  });
900
967
  } catch {
901
968
  }
902
- notifyTelegramSkillExecuted({
903
- creditDb,
904
- owner: card.owner,
905
- skillName: cardName,
906
- skillId: resolvedSkillId ?? null,
907
- requester,
908
- creditsEarned: creditsNeeded,
909
- latencyMs
910
- }).catch(() => {
911
- });
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
+ }
912
975
  return { success: true, result };
913
976
  };
914
977
  if (skillExecutor) {
@@ -1147,6 +1210,7 @@ export {
1147
1210
  identityAuthPlugin,
1148
1211
  createLedger,
1149
1212
  syncCreditsFromRegistry,
1213
+ notifyProviderEvent,
1150
1214
  executeCapabilityRequest,
1151
1215
  executeCapabilityBatch
1152
1216
  };
@@ -10,6 +10,9 @@ import {
10
10
  import {
11
11
  createRequestLogTable
12
12
  } from "./chunk-4XTYT4JW.js";
13
+ import {
14
+ ensureProviderEventsTable
15
+ } from "./chunk-GZUTU6IZ.js";
13
16
 
14
17
  // src/registry/store.ts
15
18
  import Database from "better-sqlite3";
@@ -399,6 +402,7 @@ function openDatabase(path = ":memory:") {
399
402
  `);
400
403
  createRequestLogTable(db);
401
404
  ensureAgentsTable(db);
405
+ ensureProviderEventsTable(db);
402
406
  initFeedbackTable(db);
403
407
  initEvolutionTable(db);
404
408
  runMigrations(db);
@@ -7,13 +7,13 @@ import {
7
7
  } from "./chunk-G5WKW3ED.js";
8
8
  import {
9
9
  resolveTargetCapability
10
- } from "./chunk-4M6IAIVK.js";
10
+ } from "./chunk-O44N3KR7.js";
11
11
  import {
12
12
  fetchRemoteCards
13
13
  } from "./chunk-ELFGYC22.js";
14
14
  import {
15
15
  searchCards
16
- } from "./chunk-4DBSSFHG.js";
16
+ } from "./chunk-I4E5ERDN.js";
17
17
  import {
18
18
  holdEscrow,
19
19
  releaseEscrow,
@@ -26,15 +26,15 @@ import {
26
26
  requestCapability,
27
27
  requestViaRelay
28
28
  } from "./chunk-W6LOCBWQ.js";
29
- import {
30
- findPeer
31
- } from "./chunk-3YQ73ZM6.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";
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  insertCard
3
- } from "./chunk-JKD6QRUD.js";
3
+ } from "./chunk-7VZ4M4CT.js";
4
4
  import {
5
5
  CapabilityCardSchema
6
6
  } from "./chunk-UVCNMRPS.js";
@@ -1,6 +1,9 @@
1
1
  import {
2
2
  createRequestLogTable
3
3
  } from "./chunk-4XTYT4JW.js";
4
+ import {
5
+ ensureProviderEventsTable
6
+ } from "./chunk-GZUTU6IZ.js";
4
7
  import {
5
8
  ensureAgentsTable,
6
9
  resolveCanonicalIdentity
@@ -399,6 +402,7 @@ function openDatabase(path = ":memory:") {
399
402
  `);
400
403
  createRequestLogTable(db);
401
404
  ensureAgentsTable(db);
405
+ ensureProviderEventsTable(db);
402
406
  initFeedbackTable(db);
403
407
  initEvolutionTable(db);
404
408
  runMigrations(db);
@@ -6,12 +6,18 @@ import {
6
6
  resolveTargetCapability,
7
7
  searchCards,
8
8
  settleEscrow
9
- } from "./chunk-XL5XD3IG.js";
9
+ } from "./chunk-MPS4RE7T.js";
10
+ import {
11
+ resolveCanonicalIdentity
12
+ } from "./chunk-EE3V3DXK.js";
10
13
  import {
11
14
  requestCapability,
12
15
  requestCapabilityBatch,
13
16
  requestViaRelay
14
17
  } from "./chunk-W6LOCBWQ.js";
18
+ import {
19
+ AgentBnBError
20
+ } from "./chunk-UVCNMRPS.js";
15
21
  import {
16
22
  RelayClient
17
23
  } from "./chunk-WOVESOQ7.js";
@@ -21,12 +27,6 @@ import {
21
27
  import {
22
28
  findPeer
23
29
  } from "./chunk-HLUEOLSZ.js";
24
- import {
25
- resolveCanonicalIdentity
26
- } from "./chunk-EE3V3DXK.js";
27
- import {
28
- AgentBnBError
29
- } from "./chunk-UVCNMRPS.js";
30
30
 
31
31
  // src/conductor/decomposition-validator.ts
32
32
  function validateAndNormalizeSubtasks(raw, context) {
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  searchCards
3
- } from "./chunk-4DBSSFHG.js";
3
+ } from "./chunk-I4E5ERDN.js";
4
4
 
5
5
  // src/registry/pricing.ts
6
6
  function getPricingStats(db, query) {