agentbnb 5.1.11 → 7.0.0-beta.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 (60) hide show
  1. package/README.md +245 -39
  2. package/dist/{card-RSGDCHCV.js → card-REW7BSWW.js} +1 -1
  3. package/dist/{chunk-FLY3WIQR.js → chunk-2HSUPCBT.js} +3 -3
  4. package/dist/{chunk-WGZ5AGOX.js → chunk-3CIMVISQ.js} +24 -1
  5. package/dist/{chunk-NH2FIERR.js → chunk-574W3HHE.js} +1 -1
  6. package/dist/{chunk-WTXRY7R2.js → chunk-APEG4QIN.js} +157 -9
  7. package/dist/chunk-BP3L2TET.js +148 -0
  8. package/dist/{chunk-NLAWT4DT.js → chunk-CWYPTQRQ.js} +7 -7
  9. package/dist/{chunk-UKT6H7YT.js → chunk-DUW6RX6I.js} +5 -2
  10. package/dist/chunk-EAD4A4KG.js +430 -0
  11. package/dist/{chunk-QT7TEVNV.js → chunk-EHSHB7TY.js} +23 -1
  12. package/dist/{chunk-B5FTAGFN.js → chunk-ETGOKDFR.js} +75 -75
  13. package/dist/{chunk-5KFI5X7B.js → chunk-F53QQIM2.js} +1 -1
  14. package/dist/{chunk-MLS6IGGG.js → chunk-FK2MDNTB.js} +117 -117
  15. package/dist/{chunk-EGUOAHCW.js → chunk-GO4FVRVN.js} +15 -13
  16. package/dist/{chunk-CRFCWD6V.js → chunk-J2K5S5MX.js} +136 -173
  17. package/dist/chunk-K5FO42YF.js +1136 -0
  18. package/dist/{chunk-DFBX3BBD.js → chunk-KA2VIEGM.js} +211 -16
  19. package/dist/chunk-NWIQJ2CL.js +108 -0
  20. package/dist/chunk-OCSU2S6W.js +168 -0
  21. package/dist/{chunk-QQFBFV4V.js → chunk-PGDBUUGR.js} +60 -19
  22. package/dist/{chunk-QITOPASZ.js → chunk-PSQHUZ7X.js} +1 -1
  23. package/dist/{chunk-C6KPAFCC.js → chunk-PU7LXOQ3.js} +23 -1
  24. package/dist/{chunk-JOY533UH.js → chunk-TW65F5EU.js} +1 -1
  25. package/dist/{chunk-ZX5623ER.js → chunk-VMH2YS2I.js} +1 -1
  26. package/dist/{chunk-XND2DWTZ.js → chunk-VPQ44XKE.js} +2 -2
  27. package/dist/{chunk-CSATDXZC.js → chunk-Y7T6IMM3.js} +1 -1
  28. package/dist/cli/index.js +755 -379
  29. package/dist/{client-T5MTY3CS.js → client-HRYRJKSA.js} +3 -3
  30. package/dist/{conduct-WU3VEXB6.js → conduct-JNYJCDHQ.js} +14 -13
  31. package/dist/conduct-KJUD2RTB.js +22 -0
  32. package/dist/{conductor-mode-ZMTFZGJP.js → conductor-mode-2VVFMKVE.js} +313 -14
  33. package/dist/conductor-mode-VGUU54QI.js +276 -0
  34. package/dist/execute-I4PKSNJM.js +12 -0
  35. package/dist/execute-MOXSSA3Q.js +15 -0
  36. package/dist/index.d.ts +795 -2
  37. package/dist/index.js +861 -111
  38. package/dist/{process-guard-CC7CNRQJ.js → process-guard-QCCBGILS.js} +1 -1
  39. package/dist/publish-capability-TS6CNR5G.js +12 -0
  40. package/dist/reliability-metrics-QG7WC5QK.js +18 -0
  41. package/dist/{request-VOXBFUOG.js → request-E7TA7COA.js} +19 -18
  42. package/dist/{serve-skill-IH7UAJNR.js → serve-skill-HIOWYKRU.js} +13 -11
  43. package/dist/{server-JVQW2TID.js → server-I63CXFX3.js} +17 -16
  44. package/dist/{service-coordinator-EYRDTHL5.js → service-coordinator-XBNT3SMU.js} +369 -260
  45. package/dist/skill-config-FETXPNVP.js +22 -0
  46. package/dist/skills/agentbnb/bootstrap.js +430 -84
  47. package/dist/websocket-client-5MH6QRJK.js +7 -0
  48. package/dist/{websocket-client-WRN3HO73.js → websocket-client-PFGVTXNE.js} +1 -1
  49. package/openclaw.plugin.json +2 -2
  50. package/package.json +2 -1
  51. package/skills/agentbnb/SKILL.md +35 -0
  52. package/skills/agentbnb/bootstrap.ts +126 -8
  53. package/skills/agentbnb/install.sh +49 -9
  54. package/dist/chunk-EANI2N2V.js +0 -309
  55. package/dist/chunk-EPIWHNB2.js +0 -946
  56. package/dist/conduct-6LKIJJKQ.js +0 -21
  57. package/dist/conductor-mode-Q4IIDY5E.js +0 -123
  58. package/dist/execute-4D4ITQCL.js +0 -10
  59. package/dist/execute-T7Y6RKSW.js +0 -13
  60. package/dist/websocket-client-6IIDGXKB.js +0 -7
@@ -1,6 +1,13 @@
1
+ import {
2
+ executeCapabilityBatch,
3
+ executeCapabilityRequest
4
+ } from "./chunk-PGDBUUGR.js";
1
5
  import {
2
6
  StructuredFeedbackSchema
3
7
  } from "./chunk-AUBHR7HH.js";
8
+ import {
9
+ RelayMessageSchema
10
+ } from "./chunk-EHSHB7TY.js";
4
11
  import {
5
12
  KNOWN_API_KEYS,
6
13
  announceGateway,
@@ -8,17 +15,19 @@ import {
8
15
  detectApiKeys,
9
16
  getPricingStats,
10
17
  stopAnnouncement
11
- } from "./chunk-MLS6IGGG.js";
18
+ } from "./chunk-FK2MDNTB.js";
12
19
  import {
13
20
  deriveAgentId
14
- } from "./chunk-QITOPASZ.js";
21
+ } from "./chunk-PSQHUZ7X.js";
22
+ import "./chunk-DUW6RX6I.js";
15
23
  import {
16
24
  createLedger,
17
25
  identityAuthPlugin
18
- } from "./chunk-FLY3WIQR.js";
26
+ } from "./chunk-2HSUPCBT.js";
19
27
  import {
20
- RelayMessageSchema
21
- } from "./chunk-QT7TEVNV.js";
28
+ ApiSkillConfigSchema,
29
+ parseSkillsFile
30
+ } from "./chunk-OCSU2S6W.js";
22
31
  import {
23
32
  interpolateObject
24
33
  } from "./chunk-3MJT4PZG.js";
@@ -28,58 +37,55 @@ import {
28
37
  insertAuditEvent,
29
38
  listPendingRequests,
30
39
  resolvePendingRequest
31
- } from "./chunk-CSATDXZC.js";
40
+ } from "./chunk-Y7T6IMM3.js";
32
41
  import {
33
42
  buildReputationMap,
34
43
  computeReputation,
35
44
  filterCards,
36
45
  searchCards
37
- } from "./chunk-NH2FIERR.js";
46
+ } from "./chunk-574W3HHE.js";
47
+ import {
48
+ bootstrapAgent,
49
+ getBalance,
50
+ getTransactions,
51
+ holdEscrow,
52
+ migrateOwner,
53
+ openCreditDb,
54
+ releaseEscrow,
55
+ settleEscrow
56
+ } from "./chunk-J2K5S5MX.js";
57
+ import "./chunk-NWIQJ2CL.js";
58
+ import {
59
+ generateKeyPair,
60
+ verifyEscrowReceipt
61
+ } from "./chunk-F53QQIM2.js";
38
62
  import {
39
63
  getConfigDir
40
64
  } from "./chunk-75OC6E4F.js";
41
- import {
42
- executeCapabilityBatch,
43
- executeCapabilityRequest
44
- } from "./chunk-QQFBFV4V.js";
45
- import "./chunk-UKT6H7YT.js";
46
65
  import {
47
66
  getActivityFeed,
48
67
  getCard,
68
+ getCardsBySkillCapability,
49
69
  getEvolutionHistory,
70
+ getFeedbackForProvider,
71
+ getFeedbackForSkill,
50
72
  getLatestEvolution,
51
73
  getRequestLog,
52
74
  getSkillRequestCount,
53
75
  insertCard,
54
76
  insertEvolution,
77
+ insertFeedback,
55
78
  insertRequestLog,
56
79
  listCards,
57
80
  openDatabase,
58
81
  updateCard,
59
82
  updateSkillAvailability,
60
83
  updateSkillIdleRate
61
- } from "./chunk-DFBX3BBD.js";
62
- import {
63
- bootstrapAgent,
64
- getBalance,
65
- getFeedbackForProvider,
66
- getFeedbackForSkill,
67
- getTransactions,
68
- holdEscrow,
69
- insertFeedback,
70
- migrateOwner,
71
- openCreditDb,
72
- releaseEscrow,
73
- settleEscrow
74
- } from "./chunk-EANI2N2V.js";
75
- import {
76
- generateKeyPair,
77
- verifyEscrowReceipt
78
- } from "./chunk-5KFI5X7B.js";
84
+ } from "./chunk-KA2VIEGM.js";
79
85
  import {
80
86
  AgentBnBError,
81
87
  AnyCardSchema
82
- } from "./chunk-WGZ5AGOX.js";
88
+ } from "./chunk-3CIMVISQ.js";
83
89
 
84
90
  // src/runtime/agent-runtime.ts
85
91
  import { readFileSync, existsSync } from "fs";
@@ -88,13 +94,16 @@ import { readFileSync, existsSync } from "fs";
88
94
  var SkillExecutor = class {
89
95
  skillMap;
90
96
  modeMap;
97
+ concurrencyGuard;
91
98
  /**
92
99
  * @param configs - Parsed SkillConfig array (from parseSkillsFile).
93
100
  * @param modes - Map from skill type string to its executor implementation.
101
+ * @param concurrencyGuard - Optional ConcurrencyGuard to enforce max_concurrent limits.
94
102
  */
95
- constructor(configs, modes) {
103
+ constructor(configs, modes, concurrencyGuard) {
96
104
  this.skillMap = new Map(configs.map((c) => [c.id, c]));
97
105
  this.modeMap = modes;
106
+ this.concurrencyGuard = concurrencyGuard;
98
107
  }
99
108
  /**
100
109
  * Execute a skill by ID with the given input parameters.
@@ -127,6 +136,18 @@ var SkillExecutor = class {
127
136
  latency_ms: Date.now() - startTime
128
137
  };
129
138
  }
139
+ const maxConcurrent = config.capacity?.max_concurrent ?? Infinity;
140
+ if (this.concurrencyGuard && maxConcurrent !== Infinity) {
141
+ if (!this.concurrencyGuard.canAccept(skillId, maxConcurrent)) {
142
+ return {
143
+ success: false,
144
+ error: `Skill ${skillId} at capacity (${maxConcurrent} concurrent max)`,
145
+ latency_ms: Date.now() - startTime,
146
+ failure_reason: "overload"
147
+ };
148
+ }
149
+ this.concurrencyGuard.acquire(skillId);
150
+ }
130
151
  try {
131
152
  const modeResult = await mode.execute(config, params, onProgress);
132
153
  return {
@@ -140,6 +161,10 @@ var SkillExecutor = class {
140
161
  error: message,
141
162
  latency_ms: Date.now() - startTime
142
163
  };
164
+ } finally {
165
+ if (this.concurrencyGuard && maxConcurrent !== Infinity) {
166
+ this.concurrencyGuard.release(skillId);
167
+ }
143
168
  }
144
169
  }
145
170
  /**
@@ -160,137 +185,8 @@ var SkillExecutor = class {
160
185
  return this.skillMap.get(skillId);
161
186
  }
162
187
  };
163
- function createSkillExecutor(configs, modes) {
164
- return new SkillExecutor(configs, modes);
165
- }
166
-
167
- // src/skills/skill-config.ts
168
- import { z } from "zod";
169
- import yaml from "js-yaml";
170
- var PricingSchema = z.object({
171
- credits_per_call: z.number().nonnegative(),
172
- credits_per_minute: z.number().nonnegative().optional(),
173
- free_tier: z.number().nonnegative().optional()
174
- });
175
- var ApiAuthSchema = z.discriminatedUnion("type", [
176
- z.object({
177
- type: z.literal("bearer"),
178
- token: z.string()
179
- }),
180
- z.object({
181
- type: z.literal("apikey"),
182
- header: z.string().default("X-API-Key"),
183
- key: z.string()
184
- }),
185
- z.object({
186
- type: z.literal("basic"),
187
- username: z.string(),
188
- password: z.string()
189
- })
190
- ]);
191
- var ApiSkillConfigSchema = z.object({
192
- id: z.string().min(1),
193
- type: z.literal("api"),
194
- name: z.string().min(1),
195
- endpoint: z.string().min(1),
196
- method: z.enum(["GET", "POST", "PUT", "DELETE"]),
197
- auth: ApiAuthSchema.optional(),
198
- input_mapping: z.record(z.string()).default({}),
199
- output_mapping: z.record(z.string()).default({}),
200
- pricing: PricingSchema,
201
- timeout_ms: z.number().positive().default(3e4),
202
- retries: z.number().nonnegative().int().default(0),
203
- provider: z.string().optional()
204
- });
205
- var PipelineStepSchema = z.union([
206
- z.object({
207
- skill_id: z.string().min(1),
208
- input_mapping: z.record(z.string()).default({})
209
- }),
210
- z.object({
211
- command: z.string().min(1),
212
- input_mapping: z.record(z.string()).default({})
213
- })
214
- ]);
215
- var PipelineSkillConfigSchema = z.object({
216
- id: z.string().min(1),
217
- type: z.literal("pipeline"),
218
- name: z.string().min(1),
219
- steps: z.array(PipelineStepSchema).min(1),
220
- pricing: PricingSchema,
221
- timeout_ms: z.number().positive().optional()
222
- });
223
- var OpenClawSkillConfigSchema = z.object({
224
- id: z.string().min(1),
225
- type: z.literal("openclaw"),
226
- name: z.string().min(1),
227
- agent_name: z.string().min(1),
228
- channel: z.enum(["telegram", "webhook", "process"]),
229
- pricing: PricingSchema,
230
- timeout_ms: z.number().positive().optional()
231
- });
232
- var CommandSkillConfigSchema = z.object({
233
- id: z.string().min(1),
234
- type: z.literal("command"),
235
- name: z.string().min(1),
236
- command: z.string().min(1),
237
- output_type: z.enum(["json", "text", "file"]),
238
- allowed_commands: z.array(z.string()).optional(),
239
- working_dir: z.string().optional(),
240
- timeout_ms: z.number().positive().default(3e4),
241
- pricing: PricingSchema
242
- });
243
- var ConductorSkillConfigSchema = z.object({
244
- id: z.string().min(1),
245
- type: z.literal("conductor"),
246
- name: z.string().min(1),
247
- conductor_skill: z.enum(["orchestrate", "plan"]),
248
- pricing: PricingSchema,
249
- timeout_ms: z.number().positive().optional()
250
- });
251
- var SkillConfigSchema = z.discriminatedUnion("type", [
252
- ApiSkillConfigSchema,
253
- PipelineSkillConfigSchema,
254
- OpenClawSkillConfigSchema,
255
- CommandSkillConfigSchema,
256
- ConductorSkillConfigSchema
257
- ]);
258
- var SkillsFileSchema = z.object({
259
- skills: z.array(SkillConfigSchema)
260
- });
261
- function expandEnvVars(value) {
262
- return value.replace(/\$\{([^}]+)\}/g, (_match, varName) => {
263
- if (/[.a-z]/.test(varName)) {
264
- return _match;
265
- }
266
- const envValue = process.env[varName];
267
- if (envValue === void 0) {
268
- throw new Error(`Environment variable "${varName}" is not defined`);
269
- }
270
- return envValue;
271
- });
272
- }
273
- function expandEnvVarsDeep(value) {
274
- if (typeof value === "string") {
275
- return expandEnvVars(value);
276
- }
277
- if (Array.isArray(value)) {
278
- return value.map(expandEnvVarsDeep);
279
- }
280
- if (value !== null && typeof value === "object") {
281
- const result = {};
282
- for (const [k, v] of Object.entries(value)) {
283
- result[k] = expandEnvVarsDeep(v);
284
- }
285
- return result;
286
- }
287
- return value;
288
- }
289
- function parseSkillsFile(yamlContent) {
290
- const raw = yaml.load(yamlContent);
291
- const expanded = expandEnvVarsDeep(raw);
292
- const result = SkillsFileSchema.parse(expanded);
293
- return result.skills;
188
+ function createSkillExecutor(configs, modes, concurrencyGuard) {
189
+ return new SkillExecutor(configs, modes, concurrencyGuard);
294
190
  }
295
191
 
296
192
  // src/skills/api-executor.ts
@@ -766,14 +662,32 @@ var CommandExecutor = class {
766
662
  const cmdConfig = config;
767
663
  const baseCommand = cmdConfig.command.trim().split(/\s+/)[0] ?? "";
768
664
  if (cmdConfig.allowed_commands && cmdConfig.allowed_commands.length > 0) {
769
- if (!cmdConfig.allowed_commands.includes(baseCommand)) {
665
+ const effectiveAllowed = cmdConfig.claude_code ? [.../* @__PURE__ */ new Set([...cmdConfig.allowed_commands, "claude"])] : cmdConfig.allowed_commands;
666
+ const commandToCheck = cmdConfig.claude_code ? "claude" : baseCommand;
667
+ if (!effectiveAllowed.includes(commandToCheck)) {
770
668
  return {
771
669
  success: false,
772
- error: `Command not allowed: "${baseCommand}". Allowed: ${cmdConfig.allowed_commands.join(", ")}`
670
+ error: `Command not allowed: "${commandToCheck}". Allowed: ${effectiveAllowed.join(", ")}`
773
671
  };
774
672
  }
775
673
  }
776
- const interpolatedCommand = safeInterpolateCommand2(cmdConfig.command, { params });
674
+ let interpolatedCommand;
675
+ if (cmdConfig.claude_code) {
676
+ const parts = ["claude", "--print"];
677
+ if (cmdConfig.claude_code.auto_mode) {
678
+ parts.push("--dangerously-skip-permissions");
679
+ }
680
+ if (cmdConfig.claude_code.model) {
681
+ parts.push("--model", cmdConfig.claude_code.model);
682
+ }
683
+ if (cmdConfig.claude_code.system_prompt) {
684
+ parts.push("-p", shellEscape2(cmdConfig.claude_code.system_prompt));
685
+ }
686
+ const interpolatedPrompt = safeInterpolateCommand2(cmdConfig.command, { params });
687
+ interpolatedCommand = parts.join(" ") + " " + interpolatedPrompt;
688
+ } else {
689
+ interpolatedCommand = safeInterpolateCommand2(cmdConfig.command, { params });
690
+ }
777
691
  const timeout = cmdConfig.timeout_ms ?? 3e4;
778
692
  const cwd = cmdConfig.working_dir ?? process.cwd();
779
693
  let stdout;
@@ -914,8 +828,8 @@ var AgentRuntime = class {
914
828
  }
915
829
  const modes = /* @__PURE__ */ new Map();
916
830
  if (this.conductorEnabled) {
917
- const { ConductorMode } = await import("./conductor-mode-Q4IIDY5E.js");
918
- const { registerConductorCard, CONDUCTOR_OWNER } = await import("./card-RSGDCHCV.js");
831
+ const { ConductorMode } = await import("./conductor-mode-VGUU54QI.js");
832
+ const { registerConductorCard, CONDUCTOR_OWNER } = await import("./card-REW7BSWW.js");
919
833
  const { loadPeers } = await import("./peers-K7FSHPN3.js");
920
834
  registerConductorCard(this.registryDb);
921
835
  const resolveAgentUrl = (owner) => {
@@ -1021,6 +935,7 @@ var AgentRuntime = class {
1021
935
 
1022
936
  // src/gateway/server.ts
1023
937
  import Fastify from "fastify";
938
+ import { randomUUID } from "crypto";
1024
939
  var VERSION = "0.0.1";
1025
940
  function createGatewayServer(opts) {
1026
941
  const {
@@ -1034,6 +949,8 @@ function createGatewayServer(opts) {
1034
949
  } = opts;
1035
950
  const fastify = Fastify({ logger: !silent });
1036
951
  const tokenSet = new Set(tokens);
952
+ const inFlight = /* @__PURE__ */ new Map();
953
+ const OVERLOAD_RETRY_MS = 5e3;
1037
954
  fastify.addHook("onRequest", async (request) => {
1038
955
  if (request.method === "GET" && request.url === "/health") return;
1039
956
  const auth = request.headers.authorization;
@@ -1099,18 +1016,63 @@ function createGatewayServer(opts) {
1099
1016
  }
1100
1017
  const requester = params.requester ?? "unknown";
1101
1018
  const receipt = params.escrow_receipt;
1102
- const result = await executeCapabilityRequest({
1103
- registryDb,
1104
- creditDb,
1105
- cardId,
1106
- skillId,
1107
- params,
1108
- requester,
1109
- escrowReceipt: receipt,
1110
- skillExecutor,
1111
- handlerUrl,
1112
- timeoutMs
1113
- });
1019
+ if (skillExecutor && skillId && typeof skillExecutor.getSkillConfig === "function") {
1020
+ const skillConfig = skillExecutor.getSkillConfig(skillId);
1021
+ const maxConcurrent = skillConfig?.capacity?.max_concurrent;
1022
+ if (maxConcurrent !== void 0) {
1023
+ const current = inFlight.get(skillId) ?? 0;
1024
+ if (current >= maxConcurrent) {
1025
+ try {
1026
+ insertRequestLog(registryDb, {
1027
+ id: randomUUID(),
1028
+ card_id: cardId,
1029
+ card_name: "<overload>",
1030
+ requester,
1031
+ status: "failure",
1032
+ latency_ms: 0,
1033
+ credits_charged: 0,
1034
+ created_at: (/* @__PURE__ */ new Date()).toISOString(),
1035
+ skill_id: skillId,
1036
+ failure_reason: "overload"
1037
+ });
1038
+ } catch {
1039
+ }
1040
+ return reply.status(200).send({
1041
+ jsonrpc: "2.0",
1042
+ id,
1043
+ error: {
1044
+ code: -32e3,
1045
+ message: "overload",
1046
+ data: { error: "overload", retry_after_ms: OVERLOAD_RETRY_MS }
1047
+ }
1048
+ });
1049
+ }
1050
+ }
1051
+ }
1052
+ const trackKey = skillId ?? cardId;
1053
+ inFlight.set(trackKey, (inFlight.get(trackKey) ?? 0) + 1);
1054
+ let result;
1055
+ try {
1056
+ result = await executeCapabilityRequest({
1057
+ registryDb,
1058
+ creditDb,
1059
+ cardId,
1060
+ skillId,
1061
+ params,
1062
+ requester,
1063
+ escrowReceipt: receipt,
1064
+ skillExecutor,
1065
+ handlerUrl,
1066
+ timeoutMs
1067
+ });
1068
+ } finally {
1069
+ const next = (inFlight.get(trackKey) ?? 1) - 1;
1070
+ if (next <= 0) {
1071
+ inFlight.delete(trackKey);
1072
+ } else {
1073
+ inFlight.set(trackKey, next);
1074
+ }
1075
+ }
1114
1076
  if (result.success) {
1115
1077
  return reply.send({ jsonrpc: "2.0", id, result: result.result });
1116
1078
  } else {
@@ -1130,10 +1092,10 @@ import fastifyWebsocket from "@fastify/websocket";
1130
1092
  import { join, dirname } from "path";
1131
1093
  import { fileURLToPath } from "url";
1132
1094
  import { existsSync as existsSync2 } from "fs";
1133
- import { z as z5 } from "zod";
1095
+ import { z as z4 } from "zod";
1134
1096
 
1135
1097
  // src/relay/websocket-relay.ts
1136
- import { randomUUID as randomUUID3 } from "crypto";
1098
+ import { randomUUID as randomUUID4 } from "crypto";
1137
1099
 
1138
1100
  // src/relay/relay-credit.ts
1139
1101
  function lookupCardPrice(registryDb, cardId, skillId) {
@@ -1191,10 +1153,10 @@ function releaseForRelay(creditDb, escrowId) {
1191
1153
  }
1192
1154
 
1193
1155
  // src/hub-agent/relay-bridge.ts
1194
- import { randomUUID as randomUUID2 } from "crypto";
1156
+ import { randomUUID as randomUUID3 } from "crypto";
1195
1157
 
1196
1158
  // src/hub-agent/job-queue.ts
1197
- import { randomUUID } from "crypto";
1159
+ import { randomUUID as randomUUID2 } from "crypto";
1198
1160
  function initJobQueue(db) {
1199
1161
  db.exec(`
1200
1162
  CREATE TABLE IF NOT EXISTS hub_agent_jobs (
@@ -1213,7 +1175,7 @@ function initJobQueue(db) {
1213
1175
  `);
1214
1176
  }
1215
1177
  function insertJob(db, input) {
1216
- const id = randomUUID();
1178
+ const id = randomUUID2();
1217
1179
  const now = (/* @__PURE__ */ new Date()).toISOString();
1218
1180
  const paramsJson = JSON.stringify(input.params);
1219
1181
  db.prepare(`
@@ -1425,7 +1387,7 @@ function createRelayBridge(opts) {
1425
1387
  updateJobStatus(registryDb, job.id, "dispatched");
1426
1388
  const agent = getHubAgent(registryDb, job.hub_agent_id);
1427
1389
  const cardId = agent ? agent.agent_id.padEnd(32, "0").replace(/^(.{8})(.{4})(.{4})(.{4})(.{12}).*$/, "$1-$2-$3-$4-$5") : job.hub_agent_id;
1428
- const requestId = randomUUID2();
1390
+ const requestId = randomUUID3();
1429
1391
  let params = {};
1430
1392
  try {
1431
1393
  params = JSON.parse(job.params);
@@ -1495,6 +1457,7 @@ function registerWebSocketRelay(server, db, creditDb) {
1495
1457
  const connections = /* @__PURE__ */ new Map();
1496
1458
  const pendingRequests = /* @__PURE__ */ new Map();
1497
1459
  const rateLimits = /* @__PURE__ */ new Map();
1460
+ const agentCapacities = /* @__PURE__ */ new Map();
1498
1461
  let onAgentOnlineCallback;
1499
1462
  function checkRateLimit(owner) {
1500
1463
  const now = Date.now();
@@ -1571,7 +1534,7 @@ function registerWebSocketRelay(server, db, creditDb) {
1571
1534
  function logAgentJoined(owner, cardName, cardId) {
1572
1535
  try {
1573
1536
  insertRequestLog(db, {
1574
- id: randomUUID3(),
1537
+ id: randomUUID4(),
1575
1538
  card_id: cardId,
1576
1539
  card_name: cardName,
1577
1540
  requester: owner,
@@ -1798,6 +1761,7 @@ function registerWebSocketRelay(server, db, creditDb) {
1798
1761
  if (!owner) return;
1799
1762
  connections.delete(owner);
1800
1763
  rateLimits.delete(owner);
1764
+ agentCapacities.delete(owner);
1801
1765
  markOwnerOffline(owner);
1802
1766
  for (const [reqId, pending] of pendingRequests) {
1803
1767
  if (pending.targetOwner === owner) {
@@ -1831,6 +1795,9 @@ function registerWebSocketRelay(server, db, creditDb) {
1831
1795
  }
1832
1796
  }
1833
1797
  }
1798
+ function handleHeartbeat(msg) {
1799
+ agentCapacities.set(msg.owner, msg.capacity);
1800
+ }
1834
1801
  void server.register(async (app) => {
1835
1802
  app.get("/ws", { websocket: true }, (rawSocket, _request) => {
1836
1803
  const socket = rawSocket;
@@ -1876,15 +1843,23 @@ function registerWebSocketRelay(server, db, creditDb) {
1876
1843
  case "relay_progress":
1877
1844
  handleRelayProgress(msg);
1878
1845
  break;
1846
+ case "heartbeat":
1847
+ handleHeartbeat(msg);
1848
+ break;
1879
1849
  default:
1880
1850
  break;
1881
1851
  }
1882
1852
  })();
1883
1853
  });
1854
+ const pingInterval = setInterval(() => {
1855
+ if (socket.readyState === 1) socket.ping();
1856
+ }, 3e4);
1884
1857
  socket.on("close", () => {
1858
+ clearInterval(pingInterval);
1885
1859
  handleDisconnect(registeredOwner);
1886
1860
  });
1887
1861
  socket.on("error", () => {
1862
+ clearInterval(pingInterval);
1888
1863
  handleDisconnect(registeredOwner);
1889
1864
  });
1890
1865
  });
@@ -1905,6 +1880,7 @@ function registerWebSocketRelay(server, db, creditDb) {
1905
1880
  }
1906
1881
  pendingRequests.clear();
1907
1882
  rateLimits.clear();
1883
+ agentCapacities.clear();
1908
1884
  },
1909
1885
  setOnAgentOnline: (cb) => {
1910
1886
  onAgentOnlineCallback = cb;
@@ -1913,21 +1889,23 @@ function registerWebSocketRelay(server, db, creditDb) {
1913
1889
  getPendingRequests: () => pendingRequests,
1914
1890
  sendMessage: (ws, msg) => {
1915
1891
  sendMessage(ws, msg);
1916
- }
1892
+ },
1893
+ getAgentCapacity: (owner) => agentCapacities.get(owner),
1894
+ getAllCapacities: () => new Map(agentCapacities)
1917
1895
  };
1918
1896
  }
1919
1897
 
1920
1898
  // src/identity/guarantor.ts
1921
- import { z as z2 } from "zod";
1922
- import { randomUUID as randomUUID4 } from "crypto";
1899
+ import { z } from "zod";
1900
+ import { randomUUID as randomUUID5 } from "crypto";
1923
1901
  var MAX_AGENTS_PER_GUARANTOR = 10;
1924
1902
  var GUARANTOR_CREDIT_POOL = 50;
1925
- var GuarantorRecordSchema = z2.object({
1926
- id: z2.string().uuid(),
1927
- github_login: z2.string().min(1),
1928
- agent_count: z2.number().int().nonnegative(),
1929
- credit_pool: z2.number().int().nonnegative(),
1930
- created_at: z2.string().datetime()
1903
+ var GuarantorRecordSchema = z.object({
1904
+ id: z.string().uuid(),
1905
+ github_login: z.string().min(1),
1906
+ agent_count: z.number().int().nonnegative(),
1907
+ credit_pool: z.number().int().nonnegative(),
1908
+ created_at: z.string().datetime()
1931
1909
  });
1932
1910
  var GUARANTOR_SCHEMA = `
1933
1911
  CREATE TABLE IF NOT EXISTS guarantors (
@@ -1958,7 +1936,7 @@ function registerGuarantor(db, githubLogin) {
1958
1936
  );
1959
1937
  }
1960
1938
  const record = {
1961
- id: randomUUID4(),
1939
+ id: randomUUID5(),
1962
1940
  github_login: githubLogin,
1963
1941
  agent_count: 0,
1964
1942
  credit_pool: GUARANTOR_CREDIT_POOL,
@@ -2032,7 +2010,7 @@ function getAgentGuarantor(db, agentId) {
2032
2010
  function initiateGithubAuth() {
2033
2011
  return {
2034
2012
  auth_url: "https://github.com/login/oauth/authorize?client_id=PLACEHOLDER&scope=read:user",
2035
- state: randomUUID4()
2013
+ state: randomUUID5()
2036
2014
  };
2037
2015
  }
2038
2016
 
@@ -2459,38 +2437,38 @@ var HubAgentExecutor = class {
2459
2437
  };
2460
2438
 
2461
2439
  // src/hub-agent/types.ts
2462
- import { z as z3 } from "zod";
2463
- var SkillRouteSchema = z3.discriminatedUnion("mode", [
2464
- z3.object({
2465
- skill_id: z3.string().min(1),
2466
- mode: z3.literal("direct_api"),
2440
+ import { z as z2 } from "zod";
2441
+ var SkillRouteSchema = z2.discriminatedUnion("mode", [
2442
+ z2.object({
2443
+ skill_id: z2.string().min(1),
2444
+ mode: z2.literal("direct_api"),
2467
2445
  config: ApiSkillConfigSchema
2468
2446
  }),
2469
- z3.object({
2470
- skill_id: z3.string().min(1),
2471
- mode: z3.literal("relay"),
2472
- config: z3.object({ relay_owner: z3.string().min(1) })
2447
+ z2.object({
2448
+ skill_id: z2.string().min(1),
2449
+ mode: z2.literal("relay"),
2450
+ config: z2.object({ relay_owner: z2.string().min(1) })
2473
2451
  }),
2474
- z3.object({
2475
- skill_id: z3.string().min(1),
2476
- mode: z3.literal("queue"),
2477
- config: z3.object({ relay_owner: z3.string().min(1) }).passthrough()
2452
+ z2.object({
2453
+ skill_id: z2.string().min(1),
2454
+ mode: z2.literal("queue"),
2455
+ config: z2.object({ relay_owner: z2.string().min(1) }).passthrough()
2478
2456
  })
2479
2457
  ]);
2480
- var HubAgentSchema = z3.object({
2481
- agent_id: z3.string().min(1),
2482
- name: z3.string().min(1),
2483
- owner_public_key: z3.string().min(1),
2484
- public_key: z3.string().min(1),
2485
- skill_routes: z3.array(SkillRouteSchema),
2486
- status: z3.enum(["active", "paused"]),
2487
- created_at: z3.string(),
2488
- updated_at: z3.string()
2458
+ var HubAgentSchema = z2.object({
2459
+ agent_id: z2.string().min(1),
2460
+ name: z2.string().min(1),
2461
+ owner_public_key: z2.string().min(1),
2462
+ public_key: z2.string().min(1),
2463
+ skill_routes: z2.array(SkillRouteSchema),
2464
+ status: z2.enum(["active", "paused"]),
2465
+ created_at: z2.string(),
2466
+ updated_at: z2.string()
2489
2467
  });
2490
- var CreateAgentRequestSchema = z3.object({
2491
- name: z3.string().min(1),
2492
- skill_routes: z3.array(SkillRouteSchema),
2493
- secrets: z3.record(z3.string()).optional()
2468
+ var CreateAgentRequestSchema = z2.object({
2469
+ name: z2.string().min(1),
2470
+ skill_routes: z2.array(SkillRouteSchema),
2471
+ secrets: z2.record(z2.string()).optional()
2494
2472
  });
2495
2473
 
2496
2474
  // src/hub-agent/routes.ts
@@ -3037,28 +3015,28 @@ var feedbackPlugin = async (fastify, opts) => {
3037
3015
  var api_default = feedbackPlugin;
3038
3016
 
3039
3017
  // src/evolution/schema.ts
3040
- import { z as z4 } from "zod";
3041
- var CoreMemoryEntrySchema = z4.object({
3042
- category: z4.string(),
3043
- importance: z4.number().min(0).max(1),
3044
- content: z4.string(),
3045
- scope: z4.string().optional()
3018
+ import { z as z3 } from "zod";
3019
+ var CoreMemoryEntrySchema = z3.object({
3020
+ category: z3.string(),
3021
+ importance: z3.number().min(0).max(1),
3022
+ content: z3.string(),
3023
+ scope: z3.string().optional()
3046
3024
  });
3047
- var TemplateEvolutionSchema = z4.object({
3025
+ var TemplateEvolutionSchema = z3.object({
3048
3026
  /** e.g. "genesis-template" */
3049
- template_name: z4.string().min(1),
3027
+ template_name: z3.string().min(1),
3050
3028
  /** Semantic version string, e.g. "1.2.3" */
3051
- template_version: z4.string().regex(/^\d+\.\d+\.\d+$/, "Must be a valid semver string (e.g. 1.2.3)"),
3029
+ template_version: z3.string().regex(/^\d+\.\d+\.\d+$/, "Must be a valid semver string (e.g. 1.2.3)"),
3052
3030
  /** Identifier of the agent publishing this evolution */
3053
- publisher_agent: z4.string().min(1),
3031
+ publisher_agent: z3.string().min(1),
3054
3032
  /** Human-readable description of what changed in this evolution */
3055
- changelog: z4.string().max(1e3),
3033
+ changelog: z3.string().max(1e3),
3056
3034
  /** Snapshot of the agent's core memory at the time of evolution (max 50 entries) */
3057
- core_memory_snapshot: z4.array(CoreMemoryEntrySchema).max(50),
3035
+ core_memory_snapshot: z3.array(CoreMemoryEntrySchema).max(50),
3058
3036
  /** Delta in fitness score from before evolution (range -1 to 1) */
3059
- fitness_improvement: z4.number().min(-1).max(1),
3037
+ fitness_improvement: z3.number().min(-1).max(1),
3060
3038
  /** ISO 8601 datetime string */
3061
- timestamp: z4.string().datetime()
3039
+ timestamp: z3.string().datetime()
3062
3040
  });
3063
3041
 
3064
3042
  // src/evolution/api.ts
@@ -3184,7 +3162,7 @@ function createRegistryServer(opts) {
3184
3162
  openapi: "3.0.3",
3185
3163
  info: {
3186
3164
  title: "AgentBnB Registry API",
3187
- description: "P2P Agent Capability Sharing Protocol \u2014 discover, publish, and exchange agent capabilities",
3165
+ description: "Where AI agents hire AI agents \u2014 discover, publish, and coordinate agent capabilities",
3188
3166
  version: "3.1.6"
3189
3167
  },
3190
3168
  servers: [{ url: "/", description: "Registry server" }],
@@ -3216,7 +3194,7 @@ function createRegistryServer(opts) {
3216
3194
  });
3217
3195
  void server.register(cors, {
3218
3196
  origin: true,
3219
- methods: ["GET", "POST", "PATCH", "OPTIONS"],
3197
+ methods: ["GET", "POST", "PATCH", "DELETE", "OPTIONS"],
3220
3198
  allowedHeaders: ["Content-Type", "Authorization", "X-Agent-PublicKey", "X-Agent-Signature", "X-Agent-Timestamp"]
3221
3199
  });
3222
3200
  void server.register(fastifyWebsocket);
@@ -3295,6 +3273,7 @@ function createRegistryServer(opts) {
3295
3273
  min_success_rate: { type: "number", description: "Minimum success rate (0-1)" },
3296
3274
  max_latency_ms: { type: "number", description: "Maximum average latency in ms" },
3297
3275
  min_reputation: { type: "number", description: "Minimum reputation score (0-1) based on peer feedback" },
3276
+ capability_type: { type: "string", description: "Filter cards whose skills declare this capability_type (e.g. tts, code_gen)" },
3298
3277
  sort: { type: "string", enum: ["popular", "rated", "success_rate", "cheapest", "newest", "latency", "reputation_desc", "reputation_asc"], description: "Sort order" },
3299
3278
  limit: { type: "integer", default: 20, description: "Max items per page (max 100)" },
3300
3279
  offset: { type: "integer", default: 0, description: "Pagination offset" }
@@ -3321,6 +3300,7 @@ function createRegistryServer(opts) {
3321
3300
  const onlineRaw = query.online;
3322
3301
  const online = onlineRaw === "true" ? true : onlineRaw === "false" ? false : void 0;
3323
3302
  const tag = query.tag?.trim();
3303
+ const capabilityType = query.capability_type?.trim() || void 0;
3324
3304
  const minSuccessRate = query.min_success_rate !== void 0 ? parseFloat(query.min_success_rate) : void 0;
3325
3305
  const maxLatencyMs = query.max_latency_ms !== void 0 ? parseFloat(query.max_latency_ms) : void 0;
3326
3306
  const minReputation = query.min_reputation !== void 0 ? parseFloat(query.min_reputation) : void 0;
@@ -3336,6 +3316,12 @@ function createRegistryServer(opts) {
3336
3316
  cards = filterCards(db, { level, online, min_reputation: minReputation });
3337
3317
  }
3338
3318
  cards = cards.filter((c) => !c.owner.includes(":req:"));
3319
+ if (capabilityType !== void 0) {
3320
+ const capTypeIds = new Set(
3321
+ getCardsBySkillCapability(db, capabilityType).map((c) => c.id)
3322
+ );
3323
+ cards = cards.filter((c) => capTypeIds.has(c.id));
3324
+ }
3339
3325
  if (tag !== void 0 && tag.length > 0) {
3340
3326
  cards = cards.filter((c) => {
3341
3327
  const rootTags = c.metadata?.tags ?? [];
@@ -3371,7 +3357,9 @@ function createRegistryServer(opts) {
3371
3357
  const trustStmt = db.prepare(`
3372
3358
  SELECT cc.owner,
3373
3359
  COUNT(rl.id) as total_exec,
3374
- SUM(CASE WHEN rl.status IN ('success','failure','timeout','refunded') THEN 1 ELSE 0 END) as terminal_exec,
3360
+ SUM(CASE WHEN rl.status IN ('success','failure','timeout','refunded')
3361
+ AND (rl.failure_reason IS NULL OR rl.failure_reason IN ('bad_execution','auth_error'))
3362
+ THEN 1 ELSE 0 END) as terminal_exec,
3375
3363
  SUM(CASE WHEN rl.status = 'success' THEN 1 ELSE 0 END) as success_exec,
3376
3364
  AVG(CASE WHEN rl.status = 'success' THEN rl.latency_ms END) as avg_latency
3377
3365
  FROM capability_cards cc
@@ -3605,21 +3593,32 @@ function createRegistryServer(opts) {
3605
3593
  api.delete("/cards/:id", {
3606
3594
  schema: {
3607
3595
  tags: ["cards"],
3608
- summary: "Delete a capability card",
3596
+ summary: "Delete a capability card (requires Bearer auth)",
3597
+ security: [{ bearerAuth: [] }],
3609
3598
  params: { type: "object", properties: { id: { type: "string" } }, required: ["id"] },
3610
3599
  response: {
3611
- 200: { type: "object", properties: { ok: { type: "boolean" }, id: { type: "string" } } },
3600
+ 204: { type: "null", description: "Card deleted successfully" },
3601
+ 401: { type: "object", properties: { error: { type: "string" } } },
3602
+ 403: { type: "object", properties: { error: { type: "string" } } },
3612
3603
  404: { type: "object", properties: { error: { type: "string" } } }
3613
3604
  }
3614
3605
  }
3615
3606
  }, async (request, reply) => {
3607
+ const auth = request.headers.authorization;
3608
+ const token = auth?.startsWith("Bearer ") ? auth.slice(7).trim() : null;
3609
+ if (!token || !opts.ownerApiKey || token !== opts.ownerApiKey) {
3610
+ return reply.code(401).send({ error: "Unauthorized" });
3611
+ }
3616
3612
  const { id } = request.params;
3617
3613
  const card = getCard(db, id);
3618
3614
  if (!card) {
3619
3615
  return reply.code(404).send({ error: "Not found" });
3620
3616
  }
3617
+ if (opts.ownerName && card.owner !== opts.ownerName) {
3618
+ return reply.code(403).send({ error: "Forbidden" });
3619
+ }
3621
3620
  db.prepare("DELETE FROM capability_cards WHERE id = ?").run(id);
3622
- return reply.send({ ok: true, id });
3621
+ return reply.code(204).send();
3623
3622
  });
3624
3623
  api.get("/api/agents", {
3625
3624
  schema: {
@@ -3704,7 +3703,8 @@ function createRegistryServer(opts) {
3704
3703
  const lastActive = lastActiveRow?.last_req ?? memberRow?.latest ?? joinedAt;
3705
3704
  const metricsStmt = db.prepare(`
3706
3705
  SELECT
3707
- COUNT(*) as total,
3706
+ SUM(CASE WHEN rl.failure_reason IS NULL OR rl.failure_reason IN ('bad_execution','auth_error')
3707
+ THEN 1 ELSE 0 END) as total,
3708
3708
  SUM(CASE WHEN rl.status = 'success' THEN 1 ELSE 0 END) as successes,
3709
3709
  AVG(CASE WHEN rl.status = 'success' THEN rl.latency_ms END) as avg_latency,
3710
3710
  COUNT(DISTINCT rl.requester) as unique_requesters,
@@ -4032,16 +4032,16 @@ function createRegistryServer(opts) {
4032
4032
  const gptActions = convertToGptActions(openapiSpec, serverUrl);
4033
4033
  return reply.send(gptActions);
4034
4034
  });
4035
- const BatchRequestBodySchema = z5.object({
4036
- requests: z5.array(
4037
- z5.object({
4038
- skill_id: z5.string().min(1),
4039
- params: z5.record(z5.unknown()).default({}),
4040
- max_credits: z5.number().positive()
4035
+ const BatchRequestBodySchema = z4.object({
4036
+ requests: z4.array(
4037
+ z4.object({
4038
+ skill_id: z4.string().min(1),
4039
+ params: z4.record(z4.unknown()).default({}),
4040
+ max_credits: z4.number().positive()
4041
4041
  })
4042
4042
  ).min(1),
4043
- strategy: z5.enum(["parallel", "sequential", "best_effort"]),
4044
- total_budget: z5.number().positive()
4043
+ strategy: z4.enum(["parallel", "sequential", "best_effort"]),
4044
+ total_budget: z4.number().positive()
4045
4045
  });
4046
4046
  api.post("/api/request/batch", {
4047
4047
  schema: {
@@ -4297,6 +4297,110 @@ function createRegistryServer(opts) {
4297
4297
  });
4298
4298
  });
4299
4299
  }
4300
+ api.get("/api/providers/:owner/reliability", {
4301
+ schema: {
4302
+ tags: ["agents"],
4303
+ summary: "Get provider reliability metrics",
4304
+ params: { type: "object", properties: { owner: { type: "string" } }, required: ["owner"] },
4305
+ response: {
4306
+ 200: {
4307
+ type: "object",
4308
+ properties: {
4309
+ current_streak: { type: "integer" },
4310
+ longest_streak: { type: "integer" },
4311
+ total_hires: { type: "integer" },
4312
+ repeat_hires: { type: "integer" },
4313
+ repeat_hire_rate: { type: "number" },
4314
+ avg_feedback_score: { type: "number" },
4315
+ availability_rate: { type: "number" }
4316
+ }
4317
+ },
4318
+ 404: { type: "object", properties: { error: { type: "string" } } }
4319
+ }
4320
+ }
4321
+ }, async (request, reply) => {
4322
+ const { owner } = request.params;
4323
+ if (!opts.creditDb) {
4324
+ return reply.code(404).send({ error: "Credit system not enabled" });
4325
+ }
4326
+ const { getReliabilityMetrics } = await import("./reliability-metrics-QG7WC5QK.js");
4327
+ const metrics = getReliabilityMetrics(opts.creditDb, owner);
4328
+ if (!metrics) {
4329
+ return reply.code(404).send({ error: "No reliability data for this provider" });
4330
+ }
4331
+ return reply.send(metrics);
4332
+ });
4333
+ api.get("/api/fleet/:owner", {
4334
+ schema: {
4335
+ tags: ["agents"],
4336
+ summary: "Agent fleet overview for an owner",
4337
+ params: { type: "object", properties: { owner: { type: "string" } }, required: ["owner"] },
4338
+ response: {
4339
+ 200: { type: "object", properties: { agents: { type: "array" } } }
4340
+ }
4341
+ }
4342
+ }, async (request, reply) => {
4343
+ const { owner } = request.params;
4344
+ const rows = db.prepare(
4345
+ "SELECT id, data FROM capability_cards WHERE owner = ?"
4346
+ ).all(owner);
4347
+ const agents = [];
4348
+ for (const row of rows) {
4349
+ try {
4350
+ const card = JSON.parse(row.data);
4351
+ let earnings = 0;
4352
+ let spend = 0;
4353
+ if (opts.creditDb) {
4354
+ const earningRow = opts.creditDb.prepare(
4355
+ "SELECT COALESCE(SUM(amount), 0) as total FROM credit_transactions WHERE owner = ? AND reason = 'settlement' AND amount > 0"
4356
+ ).get(owner);
4357
+ earnings = earningRow.total;
4358
+ const spendRow = opts.creditDb.prepare(
4359
+ "SELECT COALESCE(SUM(ABS(amount)), 0) as total FROM credit_transactions WHERE owner = ? AND reason = 'escrow_hold'"
4360
+ ).get(owner);
4361
+ spend = spendRow.total;
4362
+ }
4363
+ const successCount = db.prepare(
4364
+ "SELECT COUNT(*) as cnt FROM request_log WHERE card_id = ? AND status = 'success' AND (action_type IS NULL OR action_type = 'auto_share')"
4365
+ ).get(row.id).cnt;
4366
+ const failureCount = db.prepare(
4367
+ "SELECT COUNT(*) as cnt FROM request_log WHERE card_id = ? AND status IN ('failure', 'timeout', 'refunded') AND (action_type IS NULL OR action_type = 'auto_share')"
4368
+ ).get(row.id).cnt;
4369
+ const totalExec = successCount + failureCount;
4370
+ const successRate = totalExec > 0 ? successCount / totalExec : 0;
4371
+ let failureBreakdown = {};
4372
+ try {
4373
+ const failureRows = db.prepare(
4374
+ "SELECT failure_reason, COUNT(*) as cnt FROM request_log WHERE card_id = ? AND status IN ('failure', 'timeout', 'refunded') AND failure_reason IS NOT NULL GROUP BY failure_reason"
4375
+ ).all(row.id);
4376
+ for (const fr of failureRows) {
4377
+ failureBreakdown[fr.failure_reason] = fr.cnt;
4378
+ }
4379
+ } catch {
4380
+ }
4381
+ let reliability = null;
4382
+ if (opts.creditDb) {
4383
+ const { getReliabilityMetrics } = await import("./reliability-metrics-QG7WC5QK.js");
4384
+ reliability = getReliabilityMetrics(opts.creditDb, owner);
4385
+ }
4386
+ agents.push({
4387
+ id: row.id,
4388
+ name: card.name ?? card.agent_name ?? owner,
4389
+ online: card.availability?.online ?? false,
4390
+ current_load: 0,
4391
+ // Will be populated from relay heartbeat data in future
4392
+ success_rate: successRate,
4393
+ total_executions: totalExec,
4394
+ earnings,
4395
+ spend,
4396
+ failure_breakdown: failureBreakdown,
4397
+ reliability
4398
+ });
4399
+ } catch {
4400
+ }
4401
+ }
4402
+ return reply.send({ agents });
4403
+ });
4300
4404
  });
4301
4405
  return { server, relayState };
4302
4406
  }
@@ -4400,7 +4504,7 @@ import { createRequire } from "module";
4400
4504
  import { existsSync as existsSync3, readFileSync as readFileSync2 } from "fs";
4401
4505
  import { fileURLToPath as fileURLToPath2 } from "url";
4402
4506
  import { dirname as dirname2, join as join2, resolve } from "path";
4403
- import { randomUUID as randomUUID5 } from "crypto";
4507
+ import { randomUUID as randomUUID6 } from "crypto";
4404
4508
  var ServiceCoordinator = class {
4405
4509
  config;
4406
4510
  guard;
@@ -4541,7 +4645,7 @@ var ServiceCoordinator = class {
4541
4645
  console.log("Conductor mode enabled \u2014 orchestrate/plan skills available via gateway");
4542
4646
  }
4543
4647
  if (opts.conductorEnabled && this.config.conductor?.public) {
4544
- const { buildConductorCard } = await import("./card-RSGDCHCV.js");
4648
+ const { buildConductorCard } = await import("./card-REW7BSWW.js");
4545
4649
  const conductorCard = buildConductorCard(this.config.owner);
4546
4650
  const now = (/* @__PURE__ */ new Date()).toISOString();
4547
4651
  const existing = this.runtime.registryDb.prepare("SELECT id FROM capability_cards WHERE id = ?").get(conductorCard.id);
@@ -4598,11 +4702,11 @@ var ServiceCoordinator = class {
4598
4702
  }
4599
4703
  }
4600
4704
  if (opts.registryUrl && opts.relay) {
4601
- const { RelayClient } = await import("./websocket-client-6IIDGXKB.js");
4602
- const { executeCapabilityRequest: executeCapabilityRequest2 } = await import("./execute-T7Y6RKSW.js");
4705
+ const { RelayClient } = await import("./websocket-client-5MH6QRJK.js");
4706
+ const { executeCapabilityRequest: executeCapabilityRequest2 } = await import("./execute-MOXSSA3Q.js");
4603
4707
  const cards = listCards(this.runtime.registryDb, this.config.owner);
4604
4708
  const card = cards[0] ?? {
4605
- id: randomUUID5(),
4709
+ id: randomUUID6(),
4606
4710
  owner: this.config.owner,
4607
4711
  name: this.config.owner,
4608
4712
  description: "Agent registered via CLI",
@@ -4615,7 +4719,7 @@ var ServiceCoordinator = class {
4615
4719
  };
4616
4720
  const additionalCards = [];
4617
4721
  if (this.config.conductor?.public) {
4618
- const { buildConductorCard } = await import("./card-RSGDCHCV.js");
4722
+ const { buildConductorCard } = await import("./card-REW7BSWW.js");
4619
4723
  additionalCards.push(
4620
4724
  buildConductorCard(this.config.owner)
4621
4725
  );
@@ -4865,7 +4969,6 @@ var ServiceCoordinator = class {
4865
4969
  })();
4866
4970
  };
4867
4971
  };
4868
- var require2 = createRequire(import.meta.url);
4869
4972
  function loadPersistedRuntime(configDir) {
4870
4973
  const runtimePath = join2(configDir, "runtime.json");
4871
4974
  if (!existsSync3(runtimePath)) return null;
@@ -4893,6 +4996,12 @@ function resolveNodeExecutable(runtime) {
4893
4996
  return process.execPath;
4894
4997
  }
4895
4998
  function resolveCliLaunchArgs(serveArgs) {
4999
+ const require2 = createRequire(import.meta.url);
5000
+ try {
5001
+ const distCli2 = require2.resolve("agentbnb/dist/cli/index.js");
5002
+ return [distCli2, "serve", ...serveArgs];
5003
+ } catch {
5004
+ }
4896
5005
  const projectRoot = resolve(dirname2(fileURLToPath2(import.meta.url)), "..", "..");
4897
5006
  const distCli = join2(projectRoot, "dist", "cli", "index.js");
4898
5007
  if (existsSync3(distCli)) {