agentbnb 4.0.0 → 4.0.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 (36) hide show
  1. package/dist/{card-IE5UV5QX.js → card-4XH4AOTE.js} +11 -4
  2. package/dist/chunk-3MJT4PZG.js +50 -0
  3. package/dist/{conduct-IQYAT6ZU.js → chunk-3UKAVIMC.js} +70 -33
  4. package/dist/chunk-5AH3CMOX.js +62 -0
  5. package/dist/{chunk-UJWYE7VL.js → chunk-6K5WUVF3.js} +28 -111
  6. package/dist/chunk-75OC6E4F.js +33 -0
  7. package/dist/{chunk-QO67IGCW.js → chunk-DVAS2443.js} +1 -1
  8. package/dist/{chunk-XA63SD4T.js → chunk-FNKBHBYK.js} +3 -0
  9. package/dist/{websocket-client-5TIQDYQ4.js → chunk-JOY533UH.js} +38 -4
  10. package/dist/{chunk-RSX4SCPN.js → chunk-KJG2UJV5.js} +3 -3
  11. package/dist/chunk-M3G5NR2Z.js +90 -0
  12. package/dist/{chunk-HEVXCYCY.js → chunk-MQKYGY5I.js} +61 -24
  13. package/dist/chunk-ODBGCCEH.js +358 -0
  14. package/dist/{chunk-CUVIWPQO.js → chunk-Q7HRI666.js} +7 -6
  15. package/dist/chunk-QJEOCKVF.js +148 -0
  16. package/dist/{chunk-3Y36WQDV.js → chunk-QT7TEVNV.js} +14 -2
  17. package/dist/{chunk-UOGDK2S2.js → chunk-TLU7ALCZ.js} +1 -1
  18. package/dist/{chunk-QVV2P3FN.js → chunk-XQHN6ITI.js} +1 -1
  19. package/dist/cli/index.js +2665 -845
  20. package/dist/{client-IOTK6GOS.js → client-BTPIFY7E.js} +3 -3
  21. package/dist/conduct-CW62HBPT.js +52 -0
  22. package/dist/conduct-FXLVGKD5.js +19 -0
  23. package/dist/{conductor-mode-XU7ONJWC.js → conductor-mode-3JS4VWCR.js} +16 -9
  24. package/dist/execute-EXOITLHN.js +10 -0
  25. package/dist/index.d.ts +1005 -916
  26. package/dist/index.js +516 -120
  27. package/dist/{peers-G36URZYB.js → peers-K7FSHPN3.js} +2 -1
  28. package/dist/request-CNZ3XIVX.js +196 -0
  29. package/dist/serve-skill-SUOGUM7N.js +104 -0
  30. package/dist/server-2LWHL24P.js +295 -0
  31. package/dist/types-FGBUZ3QV.js +18 -0
  32. package/dist/websocket-client-6IIDGXKB.js +7 -0
  33. package/package.json +1 -1
  34. package/dist/chunk-BEI5MTNZ.js +0 -91
  35. package/dist/cli/index.d.ts +0 -1
  36. package/dist/execute-GDGBU6DJ.js +0 -10
@@ -0,0 +1,90 @@
1
+ import {
2
+ generateKeyPair,
3
+ loadKeyPair,
4
+ saveKeyPair
5
+ } from "./chunk-DVAS2443.js";
6
+
7
+ // src/identity/identity.ts
8
+ import { z } from "zod";
9
+ import { createHash } from "crypto";
10
+ import { readFileSync, writeFileSync, existsSync, mkdirSync } from "fs";
11
+ import { join } from "path";
12
+ var AgentIdentitySchema = z.object({
13
+ /** Deterministic ID derived from public key: sha256(hex).slice(0, 16). */
14
+ agent_id: z.string().min(1),
15
+ /** Human-readable owner name (from config or init). */
16
+ owner: z.string().min(1),
17
+ /** Hex-encoded Ed25519 public key. */
18
+ public_key: z.string().min(1),
19
+ /** ISO 8601 timestamp of identity creation. */
20
+ created_at: z.string().datetime(),
21
+ /** Optional guarantor info if linked to a human. */
22
+ guarantor: z.object({
23
+ github_login: z.string().min(1),
24
+ verified_at: z.string().datetime()
25
+ }).optional()
26
+ });
27
+ var AgentCertificateSchema = z.object({
28
+ identity: AgentIdentitySchema,
29
+ /** ISO 8601 timestamp of certificate issuance. */
30
+ issued_at: z.string().datetime(),
31
+ /** ISO 8601 timestamp of certificate expiry. */
32
+ expires_at: z.string().datetime(),
33
+ /** Hex-encoded public key of the issuer (same as identity for self-signed). */
34
+ issuer_public_key: z.string().min(1),
35
+ /** Base64url Ed25519 signature over { identity, issued_at, expires_at, issuer_public_key }. */
36
+ signature: z.string().min(1)
37
+ });
38
+ var IDENTITY_FILENAME = "identity.json";
39
+ function deriveAgentId(publicKeyHex) {
40
+ return createHash("sha256").update(publicKeyHex, "hex").digest("hex").slice(0, 16);
41
+ }
42
+ function createIdentity(configDir, owner) {
43
+ if (!existsSync(configDir)) {
44
+ mkdirSync(configDir, { recursive: true });
45
+ }
46
+ let keys;
47
+ try {
48
+ keys = loadKeyPair(configDir);
49
+ } catch {
50
+ keys = generateKeyPair();
51
+ saveKeyPair(configDir, keys);
52
+ }
53
+ const publicKeyHex = keys.publicKey.toString("hex");
54
+ const agentId = deriveAgentId(publicKeyHex);
55
+ const identity = {
56
+ agent_id: agentId,
57
+ owner,
58
+ public_key: publicKeyHex,
59
+ created_at: (/* @__PURE__ */ new Date()).toISOString()
60
+ };
61
+ saveIdentity(configDir, identity);
62
+ return identity;
63
+ }
64
+ function loadIdentity(configDir) {
65
+ const filePath = join(configDir, IDENTITY_FILENAME);
66
+ if (!existsSync(filePath)) return null;
67
+ try {
68
+ const raw = readFileSync(filePath, "utf-8");
69
+ return AgentIdentitySchema.parse(JSON.parse(raw));
70
+ } catch {
71
+ return null;
72
+ }
73
+ }
74
+ function saveIdentity(configDir, identity) {
75
+ if (!existsSync(configDir)) {
76
+ mkdirSync(configDir, { recursive: true });
77
+ }
78
+ const filePath = join(configDir, IDENTITY_FILENAME);
79
+ writeFileSync(filePath, JSON.stringify(identity, null, 2), "utf-8");
80
+ }
81
+ function ensureIdentity(configDir, owner) {
82
+ const existing = loadIdentity(configDir);
83
+ if (existing) return existing;
84
+ return createIdentity(configDir, owner);
85
+ }
86
+
87
+ export {
88
+ deriveAgentId,
89
+ ensureIdentity
90
+ };
@@ -1,11 +1,16 @@
1
1
  import {
2
- interpolateObject,
3
- scorePeers,
2
+ interpolateObject
3
+ } from "./chunk-3MJT4PZG.js";
4
+ import {
5
+ scorePeers
6
+ } from "./chunk-6K5WUVF3.js";
7
+ import {
8
+ fetchRemoteCards,
4
9
  searchCards
5
- } from "./chunk-UJWYE7VL.js";
10
+ } from "./chunk-QJEOCKVF.js";
6
11
  import {
7
12
  requestCapability
8
- } from "./chunk-RSX4SCPN.js";
13
+ } from "./chunk-KJG2UJV5.js";
9
14
 
10
15
  // src/conductor/task-decomposer.ts
11
16
  import { randomUUID } from "crypto";
@@ -118,10 +123,17 @@ function decompose(task, _availableCapabilities) {
118
123
 
119
124
  // src/conductor/capability-matcher.ts
120
125
  var MAX_ALTERNATIVES = 2;
121
- function matchSubTasks(opts) {
122
- const { db, subtasks, conductorOwner } = opts;
123
- return subtasks.map((subtask) => {
124
- const cards = searchCards(db, subtask.required_capability, { online: true });
126
+ async function matchSubTasks(opts) {
127
+ const { db, subtasks, conductorOwner, registryUrl } = opts;
128
+ return Promise.all(subtasks.map(async (subtask) => {
129
+ let cards = searchCards(db, subtask.required_capability, { online: true });
130
+ if (cards.length === 0 && registryUrl) {
131
+ try {
132
+ cards = await fetchRemoteCards(registryUrl, { q: subtask.required_capability, online: true });
133
+ } catch {
134
+ cards = [];
135
+ }
136
+ }
125
137
  const candidates = [];
126
138
  for (const card of cards) {
127
139
  const cardAsV2 = card;
@@ -163,11 +175,12 @@ function matchSubTasks(opts) {
163
175
  subtask_id: subtask.id,
164
176
  selected_agent: top.card.owner,
165
177
  selected_skill: top.skillId ?? "",
178
+ selected_card_id: top.card.id,
166
179
  score: top.rawScore,
167
180
  credits: top.cost,
168
181
  alternatives
169
182
  };
170
- });
183
+ }));
171
184
  }
172
185
 
173
186
  // src/conductor/budget-controller.ts
@@ -262,7 +275,7 @@ function computeWaves(subtasks) {
262
275
  return waves;
263
276
  }
264
277
  async function orchestrate(opts) {
265
- const { subtasks, matches, gatewayToken, resolveAgentUrl, timeoutMs = 3e4, maxBudget } = opts;
278
+ const { subtasks, matches, gatewayToken, resolveAgentUrl, timeoutMs = 3e5, maxBudget, relayClient, requesterOwner } = opts;
266
279
  const startTime = Date.now();
267
280
  if (subtasks.length === 0) {
268
281
  return {
@@ -313,26 +326,50 @@ async function orchestrate(opts) {
313
326
  );
314
327
  const primary = resolveAgentUrl(m.selected_agent);
315
328
  try {
316
- const res = await requestCapability({
317
- gatewayUrl: primary.url,
318
- token: gatewayToken,
319
- cardId: primary.cardId,
320
- params: interpolatedParams,
321
- timeoutMs
322
- });
329
+ let res;
330
+ if (primary.url.startsWith("relay://") && relayClient) {
331
+ const targetOwner = primary.url.replace("relay://", "");
332
+ res = await relayClient.request({
333
+ targetOwner,
334
+ cardId: primary.cardId,
335
+ params: interpolatedParams,
336
+ requester: requesterOwner,
337
+ timeoutMs
338
+ });
339
+ } else {
340
+ res = await requestCapability({
341
+ gatewayUrl: primary.url,
342
+ token: gatewayToken,
343
+ cardId: primary.cardId,
344
+ params: interpolatedParams,
345
+ timeoutMs
346
+ });
347
+ }
323
348
  return { taskId, result: res, credits: m.credits };
324
349
  } catch (primaryErr) {
325
350
  if (m.alternatives.length > 0) {
326
351
  const alt = m.alternatives[0];
327
352
  const altAgent = resolveAgentUrl(alt.agent);
328
353
  try {
329
- const altRes = await requestCapability({
330
- gatewayUrl: altAgent.url,
331
- token: gatewayToken,
332
- cardId: altAgent.cardId,
333
- params: interpolatedParams,
334
- timeoutMs
335
- });
354
+ let altRes;
355
+ if (altAgent.url.startsWith("relay://") && relayClient) {
356
+ const targetOwner = altAgent.url.replace("relay://", "");
357
+ altRes = await relayClient.request({
358
+ targetOwner,
359
+ cardId: altAgent.cardId,
360
+ params: interpolatedParams,
361
+ requester: requesterOwner,
362
+ timeoutMs
363
+ });
364
+ } else {
365
+ altRes = await requestCapability({
366
+ gatewayUrl: altAgent.url,
367
+ token: gatewayToken,
368
+ cardId: altAgent.cardId,
369
+ params: interpolatedParams,
370
+ timeoutMs
371
+ });
372
+ }
336
373
  return { taskId, result: altRes, credits: alt.credits };
337
374
  } catch (altErr) {
338
375
  throw new Error(
@@ -0,0 +1,358 @@
1
+ import {
2
+ bootstrapAgent,
3
+ getBalance,
4
+ getTransactions,
5
+ holdEscrow,
6
+ openCreditDb,
7
+ releaseEscrow,
8
+ settleEscrow
9
+ } from "./chunk-XQHN6ITI.js";
10
+ import {
11
+ signEscrowReceipt,
12
+ verifyEscrowReceipt
13
+ } from "./chunk-DVAS2443.js";
14
+ import {
15
+ AgentBnBError
16
+ } from "./chunk-FNKBHBYK.js";
17
+
18
+ // src/credit/local-credit-ledger.ts
19
+ var LocalCreditLedger = class {
20
+ constructor(db) {
21
+ this.db = db;
22
+ }
23
+ /**
24
+ * Holds credits in escrow during capability execution.
25
+ *
26
+ * @param owner - Agent identifier (requester).
27
+ * @param amount - Number of credits to hold.
28
+ * @param cardId - Capability Card ID being requested.
29
+ * @returns EscrowResult with the new escrowId.
30
+ * @throws {AgentBnBError} with code 'INSUFFICIENT_CREDITS' if balance < amount.
31
+ */
32
+ async hold(owner, amount, cardId) {
33
+ const escrowId = holdEscrow(this.db, owner, amount, cardId);
34
+ return { escrowId };
35
+ }
36
+ /**
37
+ * Settles an escrow — transfers held credits to the capability provider.
38
+ *
39
+ * @param escrowId - The escrow ID to settle.
40
+ * @param recipientOwner - Agent identifier who will receive the credits.
41
+ * @throws {AgentBnBError} with code 'ESCROW_NOT_FOUND' if escrow does not exist.
42
+ * @throws {AgentBnBError} with code 'ESCROW_ALREADY_SETTLED' if escrow is not in 'held' status.
43
+ */
44
+ async settle(escrowId, recipientOwner) {
45
+ settleEscrow(this.db, escrowId, recipientOwner);
46
+ }
47
+ /**
48
+ * Releases an escrow — refunds credits back to the requester.
49
+ *
50
+ * @param escrowId - The escrow ID to release.
51
+ * @throws {AgentBnBError} with code 'ESCROW_NOT_FOUND' if escrow does not exist.
52
+ * @throws {AgentBnBError} with code 'ESCROW_ALREADY_SETTLED' if escrow is not in 'held' status.
53
+ */
54
+ async release(escrowId) {
55
+ releaseEscrow(this.db, escrowId);
56
+ }
57
+ /**
58
+ * Returns the current credit balance for an agent.
59
+ *
60
+ * @param owner - Agent identifier.
61
+ * @returns Current balance in credits (0 if agent is unknown).
62
+ */
63
+ async getBalance(owner) {
64
+ return getBalance(this.db, owner);
65
+ }
66
+ /**
67
+ * Returns the transaction history for an agent, newest first.
68
+ *
69
+ * @param owner - Agent identifier.
70
+ * @param limit - Maximum number of transactions to return. Defaults to 100.
71
+ * @returns Array of credit transactions ordered newest first.
72
+ */
73
+ async getHistory(owner, limit) {
74
+ return getTransactions(this.db, owner, limit);
75
+ }
76
+ /**
77
+ * Grants initial credits to an agent (bootstrap grant).
78
+ * Idempotent — calling multiple times has no additional effect on balance.
79
+ *
80
+ * @param owner - Agent identifier.
81
+ * @param amount - Number of credits to grant. Defaults to 100.
82
+ */
83
+ async grant(owner, amount) {
84
+ bootstrapAgent(this.db, owner, amount);
85
+ }
86
+ };
87
+
88
+ // src/registry/identity-auth.ts
89
+ var MAX_REQUEST_AGE_MS = 5 * 60 * 1e3;
90
+ async function verifyIdentity(request, reply) {
91
+ const publicKeyHex = request.headers["x-agent-publickey"];
92
+ const signature = request.headers["x-agent-signature"];
93
+ const timestamp = request.headers["x-agent-timestamp"];
94
+ if (!publicKeyHex || !signature || !timestamp) {
95
+ await reply.code(401).send({ error: "Missing identity headers" });
96
+ return false;
97
+ }
98
+ const requestTime = new Date(timestamp).getTime();
99
+ if (isNaN(requestTime) || Math.abs(Date.now() - requestTime) > MAX_REQUEST_AGE_MS) {
100
+ await reply.code(401).send({ error: "Request expired" });
101
+ return false;
102
+ }
103
+ const payload = {
104
+ method: request.method,
105
+ path: request.url,
106
+ timestamp,
107
+ publicKey: publicKeyHex
108
+ };
109
+ let publicKeyBuffer;
110
+ try {
111
+ publicKeyBuffer = Buffer.from(publicKeyHex, "hex");
112
+ } catch {
113
+ await reply.code(401).send({ error: "Invalid identity signature" });
114
+ return false;
115
+ }
116
+ const valid = verifyEscrowReceipt(payload, signature, publicKeyBuffer);
117
+ if (!valid) {
118
+ await reply.code(401).send({ error: "Invalid identity signature" });
119
+ return false;
120
+ }
121
+ request.agentPublicKey = publicKeyHex;
122
+ return true;
123
+ }
124
+ function identityAuthPlugin(fastify) {
125
+ fastify.addHook("onRequest", async (request, reply) => {
126
+ await verifyIdentity(request, reply);
127
+ });
128
+ }
129
+ function signRequest(method, path, body, privateKey, publicKeyHex) {
130
+ const timestamp = (/* @__PURE__ */ new Date()).toISOString();
131
+ const payload = {
132
+ method,
133
+ path,
134
+ timestamp,
135
+ publicKey: publicKeyHex
136
+ };
137
+ void body;
138
+ const signature = signEscrowReceipt(payload, privateKey);
139
+ return {
140
+ "X-Agent-PublicKey": publicKeyHex,
141
+ "X-Agent-Signature": signature,
142
+ "X-Agent-Timestamp": timestamp
143
+ };
144
+ }
145
+
146
+ // src/credit/registry-credit-ledger.ts
147
+ var HTTP_TIMEOUT_MS = 1e4;
148
+ var RegistryCreditLedger = class {
149
+ config;
150
+ constructor(config) {
151
+ this.config = config;
152
+ }
153
+ /**
154
+ * Holds credits in escrow during capability execution.
155
+ *
156
+ * @param owner - Agent identifier (requester).
157
+ * @param amount - Number of credits to hold.
158
+ * @param cardId - Capability Card ID being requested.
159
+ * @returns EscrowResult with the new escrowId.
160
+ * @throws {AgentBnBError} with code 'INSUFFICIENT_CREDITS' if balance < amount.
161
+ */
162
+ async hold(owner, amount, cardId) {
163
+ if (this.config.mode === "direct") {
164
+ const escrowId = holdEscrow(this.config.db, owner, amount, cardId);
165
+ return { escrowId };
166
+ }
167
+ const data = await this.post("/api/credits/hold", owner, {
168
+ owner,
169
+ amount,
170
+ cardId
171
+ });
172
+ return { escrowId: data.escrowId };
173
+ }
174
+ /**
175
+ * Settles an escrow — transfers held credits to the capability provider.
176
+ *
177
+ * @param escrowId - The escrow ID to settle.
178
+ * @param recipientOwner - Agent identifier who will receive the credits.
179
+ * @throws {AgentBnBError} with code 'ESCROW_NOT_FOUND' if escrow does not exist.
180
+ * @throws {AgentBnBError} with code 'ESCROW_ALREADY_SETTLED' if escrow is not in 'held' status.
181
+ */
182
+ async settle(escrowId, recipientOwner) {
183
+ if (this.config.mode === "direct") {
184
+ settleEscrow(this.config.db, escrowId, recipientOwner);
185
+ return;
186
+ }
187
+ await this.post("/api/credits/settle", null, { escrowId, recipientOwner });
188
+ }
189
+ /**
190
+ * Releases an escrow — refunds credits back to the requester.
191
+ *
192
+ * @param escrowId - The escrow ID to release.
193
+ * @throws {AgentBnBError} with code 'ESCROW_NOT_FOUND' if escrow does not exist.
194
+ * @throws {AgentBnBError} with code 'ESCROW_ALREADY_SETTLED' if escrow is not in 'held' status.
195
+ */
196
+ async release(escrowId) {
197
+ if (this.config.mode === "direct") {
198
+ releaseEscrow(this.config.db, escrowId);
199
+ return;
200
+ }
201
+ await this.post("/api/credits/release", null, { escrowId });
202
+ }
203
+ /**
204
+ * Returns the current credit balance for an agent.
205
+ *
206
+ * @param owner - Agent identifier.
207
+ * @returns Current balance in credits (0 if agent is unknown).
208
+ */
209
+ async getBalance(owner) {
210
+ if (this.config.mode === "direct") {
211
+ return getBalance(this.config.db, owner);
212
+ }
213
+ const data = await this.get(`/api/credits/${owner}`, owner);
214
+ return data.balance;
215
+ }
216
+ /**
217
+ * Returns the transaction history for an agent, newest first.
218
+ *
219
+ * @param owner - Agent identifier.
220
+ * @param limit - Maximum number of transactions to return. Defaults to 100.
221
+ * @returns Array of credit transactions ordered newest first.
222
+ */
223
+ async getHistory(owner, limit = 100) {
224
+ if (this.config.mode === "direct") {
225
+ return getTransactions(this.config.db, owner, limit);
226
+ }
227
+ const data = await this.get(
228
+ `/api/credits/${owner}/history?limit=${limit}`,
229
+ owner
230
+ );
231
+ return data.transactions;
232
+ }
233
+ /**
234
+ * Grants initial credits to an agent (bootstrap grant).
235
+ * Idempotent — calling multiple times has no additional effect on balance.
236
+ *
237
+ * @param owner - Agent identifier.
238
+ * @param amount - Number of credits to grant. Defaults to 100.
239
+ */
240
+ async grant(owner, amount = 100) {
241
+ if (this.config.mode === "direct") {
242
+ bootstrapAgent(this.config.db, owner, amount);
243
+ return;
244
+ }
245
+ await this.post("/api/credits/grant", owner, { owner, amount });
246
+ }
247
+ // ─── Private HTTP helpers ─────────────────────────────────────────────────
248
+ /**
249
+ * Makes an authenticated POST request to the Registry HTTP API.
250
+ * Includes a 10s timeout via AbortController.
251
+ *
252
+ * @param path - API path (e.g., '/api/credits/hold').
253
+ * @param ownerForHeader - Agent owner identifier for X-Agent-Owner header, or null to omit.
254
+ * @param body - JSON body to send.
255
+ * @returns Parsed JSON response body.
256
+ * @throws {AgentBnBError} on non-2xx responses or network errors.
257
+ */
258
+ async post(path, ownerForHeader, body) {
259
+ const cfg = this.config;
260
+ const controller = new AbortController();
261
+ const timeoutId = setTimeout(() => controller.abort(), HTTP_TIMEOUT_MS);
262
+ try {
263
+ const authHeaders = signRequest("POST", path, body, cfg.privateKey, cfg.ownerPublicKey);
264
+ const headers = {
265
+ "Content-Type": "application/json",
266
+ ...authHeaders
267
+ };
268
+ void ownerForHeader;
269
+ const res = await fetch(`${cfg.registryUrl}${path}`, {
270
+ method: "POST",
271
+ headers,
272
+ body: JSON.stringify(body),
273
+ signal: controller.signal
274
+ });
275
+ return await this.handleResponse(res);
276
+ } catch (err) {
277
+ if (err instanceof AgentBnBError) throw err;
278
+ throw new AgentBnBError(
279
+ `Registry unreachable: ${err.message}`,
280
+ "REGISTRY_UNREACHABLE"
281
+ );
282
+ } finally {
283
+ clearTimeout(timeoutId);
284
+ }
285
+ }
286
+ /**
287
+ * Makes an authenticated GET request to the Registry HTTP API.
288
+ * Includes a 10s timeout via AbortController.
289
+ *
290
+ * @param path - API path (e.g., '/api/credits/owner-id').
291
+ * @param owner - Agent owner identifier for X-Agent-Owner header.
292
+ * @returns Parsed JSON response body.
293
+ * @throws {AgentBnBError} on non-2xx responses or network errors.
294
+ */
295
+ async get(path, owner) {
296
+ const cfg = this.config;
297
+ const controller = new AbortController();
298
+ const timeoutId = setTimeout(() => controller.abort(), HTTP_TIMEOUT_MS);
299
+ try {
300
+ const authHeaders = signRequest("GET", path, null, cfg.privateKey, cfg.ownerPublicKey);
301
+ void owner;
302
+ const res = await fetch(`${cfg.registryUrl}${path}`, {
303
+ method: "GET",
304
+ headers: {
305
+ "Content-Type": "application/json",
306
+ ...authHeaders
307
+ },
308
+ signal: controller.signal
309
+ });
310
+ return await this.handleResponse(res);
311
+ } catch (err) {
312
+ if (err instanceof AgentBnBError) throw err;
313
+ throw new AgentBnBError(
314
+ `Registry unreachable: ${err.message}`,
315
+ "REGISTRY_UNREACHABLE"
316
+ );
317
+ } finally {
318
+ clearTimeout(timeoutId);
319
+ }
320
+ }
321
+ /**
322
+ * Handles an HTTP response — returns parsed JSON on 2xx, throws AgentBnBError on error.
323
+ */
324
+ async handleResponse(res) {
325
+ const json = await res.json();
326
+ if (!res.ok) {
327
+ const code = typeof json["code"] === "string" ? json["code"] : "REGISTRY_ERROR";
328
+ const message = typeof json["error"] === "string" ? json["error"] : `HTTP ${res.status}`;
329
+ throw new AgentBnBError(message, code);
330
+ }
331
+ return json;
332
+ }
333
+ };
334
+
335
+ // src/credit/create-ledger.ts
336
+ function createLedger(opts) {
337
+ if ("registryUrl" in opts && opts.registryUrl !== void 0) {
338
+ return new RegistryCreditLedger({
339
+ mode: "http",
340
+ registryUrl: opts.registryUrl,
341
+ ownerPublicKey: opts.ownerPublicKey,
342
+ privateKey: opts.privateKey
343
+ });
344
+ }
345
+ if ("db" in opts && opts.db !== void 0) {
346
+ return new RegistryCreditLedger({
347
+ mode: "direct",
348
+ db: opts.db
349
+ });
350
+ }
351
+ const db = openCreditDb(opts.creditDbPath);
352
+ return new LocalCreditLedger(db);
353
+ }
354
+
355
+ export {
356
+ identityAuthPlugin,
357
+ createLedger
358
+ };
@@ -2,7 +2,7 @@ import {
2
2
  getCard,
3
3
  insertRequestLog,
4
4
  updateReputation
5
- } from "./chunk-UOGDK2S2.js";
5
+ } from "./chunk-TLU7ALCZ.js";
6
6
  import {
7
7
  confirmEscrowDebit,
8
8
  getBalance,
@@ -10,13 +10,13 @@ import {
10
10
  recordEarning,
11
11
  releaseEscrow,
12
12
  settleEscrow
13
- } from "./chunk-QVV2P3FN.js";
13
+ } from "./chunk-XQHN6ITI.js";
14
14
  import {
15
15
  verifyEscrowReceipt
16
- } from "./chunk-QO67IGCW.js";
16
+ } from "./chunk-DVAS2443.js";
17
17
  import {
18
18
  AgentBnBError
19
- } from "./chunk-XA63SD4T.js";
19
+ } from "./chunk-FNKBHBYK.js";
20
20
 
21
21
  // src/gateway/execute.ts
22
22
  import { randomUUID } from "crypto";
@@ -51,7 +51,8 @@ async function executeCapabilityRequest(opts) {
51
51
  escrowReceipt: receipt,
52
52
  skillExecutor,
53
53
  handlerUrl,
54
- timeoutMs = 3e4
54
+ timeoutMs = 3e5,
55
+ onProgress
55
56
  } = opts;
56
57
  const card = getCard(registryDb, cardId);
57
58
  if (!card) {
@@ -158,7 +159,7 @@ async function executeCapabilityRequest(opts) {
158
159
  if (skillExecutor) {
159
160
  const targetSkillId = resolvedSkillId ?? skillId ?? cardId;
160
161
  try {
161
- const execResult = await skillExecutor.execute(targetSkillId, params);
162
+ const execResult = await skillExecutor.execute(targetSkillId, params, onProgress);
162
163
  if (!execResult.success) {
163
164
  return handleFailure("failure", execResult.latency_ms, execResult.error ?? "Execution failed");
164
165
  }