agentbnb 9.2.0 → 9.2.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +22 -0
- package/dist/{card-VVXNKHDX.js → card-L3ZPPBVI.js} +2 -2
- package/dist/{chunk-Z7XWQ63B.js → chunk-2KSRFDKF.js} +1 -1
- package/dist/{chunk-WEZ7PSOE.js → chunk-563ZZUOA.js} +56 -22
- package/dist/chunk-5FXLZ5FX.js +16 -0
- package/dist/{chunk-ELFGYC22.js → chunk-7YJOBVWN.js} +3 -0
- package/dist/{chunk-V5TJXK3F.js → chunk-COOBXNXU.js} +5 -5
- package/dist/{chunk-EC6DIVE5.js → chunk-CPSV5WR2.js} +1 -1
- package/dist/{process-guard-6324CZDC.js → chunk-DG4FQ4MD.js} +1 -1
- package/dist/{chunk-MPS4RE7T.js → chunk-DT2IEL5U.js} +11 -0
- package/dist/chunk-EMVVFP2L.js +54 -0
- package/dist/{chunk-FK54LVDR.js → chunk-FVLHEI3Y.js} +5 -5
- package/dist/chunk-GIK2AZQH.js +23 -0
- package/dist/{chunk-B6AKTLXB.js → chunk-NISX3N7K.js} +16 -7
- package/dist/{chunk-CMGJ52SX.js → chunk-NLGLGR2K.js} +1 -1
- package/dist/{chunk-RNALIVRR.js → chunk-OFIRWD6B.js} +1 -1
- package/dist/{chunk-GGRH5PCD.js → chunk-OI46BKQF.js} +9 -9
- package/dist/{chunk-MQIT2F5V.js → chunk-OTAZIF65.js} +1 -1
- package/dist/{chunk-KKFP5Y2Z.js → chunk-OXU4QJSZ.js} +2 -2
- package/dist/{chunk-53Q2HHHH.js → chunk-PFAEZI32.js} +9 -9
- package/dist/{chunk-D7NH6YLM.js → chunk-UJXDBOKV.js} +12 -1
- package/dist/{chunk-UPWAXWY2.js → chunk-VDYHCI5F.js} +22 -1
- package/dist/{chunk-QG2LLVXP.js → chunk-WA23XRTN.js} +1 -1
- package/dist/cli/index.js +787 -97
- package/dist/{conduct-QLWXU2ZU.js → conduct-65BGO2EU.js} +13 -11
- package/dist/{conduct-JRLLA4PB.js → conduct-AALDEKTH.js} +13 -11
- package/dist/{conductor-mode-PFO2VLH6.js → conductor-mode-6S6ADNLW.js} +15 -15
- package/dist/{conductor-mode-66IITI4I.js → conductor-mode-HJHU4XLT.js} +2 -2
- package/dist/{credits-action-XERUEDF3.js → credits-action-CLLPNRDT.js} +15 -6
- package/dist/{execute-NOQVN7ZG.js → execute-R5STYWLD.js} +10 -10
- package/dist/{execute-YBNCDAOX.js → execute-YMPHTJPN.js} +2 -2
- package/dist/{openclaw-setup-4RIZRMXA.js → openclaw-setup-HUOBTGN4.js} +14 -12
- package/dist/{openclaw-skills-TQ2JVBRM.js → openclaw-skills-74372B6I.js} +2 -2
- package/dist/process-guard-IUMZ2GSD.js +8 -0
- package/dist/{publish-capability-2FMD3K6Z.js → publish-capability-OYXXXYAU.js} +3 -3
- package/dist/remote-registry-5TM7DMCO.js +16 -0
- package/dist/{request-EYN4CVXC.js → request-NEA66RCW.js} +63 -21
- package/dist/{serve-skill-NWERGVH5.js → serve-skill-VKNRBVWE.js} +16 -15
- package/dist/{server-UPOPLZ24.js → server-4TACULIV.js} +21 -17
- package/dist/{service-coordinator-ZOZTW2U6.js → service-coordinator-RE2KPWO4.js} +91 -31
- package/dist/{session-action-OSBZB4TX.js → session-action-UBWJTQVQ.js} +17 -2
- package/dist/skills/agentbnb/bootstrap.js +213 -24
- package/dist/{store-74EWU77V.js → store-GJJFFEQZ.js} +2 -2
- package/dist/{vc-action-A6VBKERF.js → vc-action-72TQVMY2.js} +13 -3
- package/openclaw.plugin.json +36 -5
- package/package.json +12 -18
- package/skills/agentbnb/SKILL.md +106 -75
- package/skills/agentbnb/install.sh +0 -0
- package/dist/{chunk-C56X7EFJ.js → chunk-QE42IJC4.js} +3 -3
- package/dist/{daemon-ETXXE4IS.js → daemon-OM2K3U7J.js} +1 -1
- package/dist/{did-action-ODWTBVXL.js → did-action-ERXWCVEJ.js} +1 -1
|
@@ -16,7 +16,7 @@ import {
|
|
|
16
16
|
requestViaTemporaryRelay,
|
|
17
17
|
resolvePendingRequest,
|
|
18
18
|
verifyUCAN
|
|
19
|
-
} from "../../chunk-
|
|
19
|
+
} from "../../chunk-OTAZIF65.js";
|
|
20
20
|
import {
|
|
21
21
|
createLedger,
|
|
22
22
|
deriveAgentId,
|
|
@@ -28,7 +28,7 @@ import {
|
|
|
28
28
|
notifyProviderEvent,
|
|
29
29
|
syncCreditsFromRegistry,
|
|
30
30
|
tryVerifyIdentity
|
|
31
|
-
} from "../../chunk-
|
|
31
|
+
} from "../../chunk-NLGLGR2K.js";
|
|
32
32
|
import {
|
|
33
33
|
NETWORK_FEE_RATE,
|
|
34
34
|
bootstrapAgent,
|
|
@@ -38,6 +38,7 @@ import {
|
|
|
38
38
|
fetchRemoteCards,
|
|
39
39
|
filterCards,
|
|
40
40
|
getBalance,
|
|
41
|
+
getEscrowStatus,
|
|
41
42
|
getTransactions,
|
|
42
43
|
holdEscrow,
|
|
43
44
|
markEscrowAbandoned,
|
|
@@ -49,7 +50,7 @@ import {
|
|
|
49
50
|
releaseEscrow,
|
|
50
51
|
searchCards,
|
|
51
52
|
settleEscrow
|
|
52
|
-
} from "../../chunk-
|
|
53
|
+
} from "../../chunk-DT2IEL5U.js";
|
|
53
54
|
import {
|
|
54
55
|
attachCanonicalAgentId,
|
|
55
56
|
getCard,
|
|
@@ -1505,7 +1506,7 @@ var AgentRuntime = class {
|
|
|
1505
1506
|
}
|
|
1506
1507
|
const modes = /* @__PURE__ */ new Map();
|
|
1507
1508
|
if (this.conductorEnabled) {
|
|
1508
|
-
const { ConductorMode } = await import("../../conductor-mode-
|
|
1509
|
+
const { ConductorMode } = await import("../../conductor-mode-HJHU4XLT.js");
|
|
1509
1510
|
const { registerConductorCard, CONDUCTOR_OWNER } = await import("../../card-U2HQRPYN.js");
|
|
1510
1511
|
const { loadPeers: loadPeers2 } = await import("../../peers-IOVCBWAI.js");
|
|
1511
1512
|
registerConductorCard(this.registryDb);
|
|
@@ -3943,6 +3944,39 @@ async function creditRoutesPlugin(fastify, options) {
|
|
|
3943
3944
|
const transactions = getTransactions(creditDb, owner, { limit, after: since });
|
|
3944
3945
|
return reply.send({ owner, transactions, limit });
|
|
3945
3946
|
});
|
|
3947
|
+
fastify.get("/api/credits/escrow/:id", {
|
|
3948
|
+
schema: {
|
|
3949
|
+
tags: ["credits"],
|
|
3950
|
+
summary: "Get escrow status by ID (public, no auth required)",
|
|
3951
|
+
params: {
|
|
3952
|
+
type: "object",
|
|
3953
|
+
properties: { id: { type: "string" } },
|
|
3954
|
+
required: ["id"]
|
|
3955
|
+
},
|
|
3956
|
+
response: {
|
|
3957
|
+
200: {
|
|
3958
|
+
type: "object",
|
|
3959
|
+
properties: {
|
|
3960
|
+
id: { type: "string" },
|
|
3961
|
+
owner: { type: "string" },
|
|
3962
|
+
amount: { type: "number" },
|
|
3963
|
+
card_id: { type: "string" },
|
|
3964
|
+
status: { type: "string" },
|
|
3965
|
+
created_at: { type: "string" },
|
|
3966
|
+
settled_at: { type: ["string", "null"] }
|
|
3967
|
+
}
|
|
3968
|
+
},
|
|
3969
|
+
404: { type: "object", properties: { error: { type: "string" } } }
|
|
3970
|
+
}
|
|
3971
|
+
}
|
|
3972
|
+
}, async (request, reply) => {
|
|
3973
|
+
const { id } = request.params;
|
|
3974
|
+
const escrow = getEscrowStatus(creditDb, id);
|
|
3975
|
+
if (!escrow) {
|
|
3976
|
+
return reply.code(404).send({ error: "Escrow record not found" });
|
|
3977
|
+
}
|
|
3978
|
+
return reply.send(escrow);
|
|
3979
|
+
});
|
|
3946
3980
|
await fastify.register(async (scope) => {
|
|
3947
3981
|
identityAuthPlugin(scope, { agentDb: creditDb });
|
|
3948
3982
|
scope.post("/api/credits/hold", {
|
|
@@ -6965,6 +6999,56 @@ import { existsSync as existsSync5, readFileSync as readFileSync4 } from "fs";
|
|
|
6965
6999
|
import { join as join4 } from "path";
|
|
6966
7000
|
import { randomUUID as randomUUID9 } from "crypto";
|
|
6967
7001
|
import { Cron as Cron2 } from "croner";
|
|
7002
|
+
|
|
7003
|
+
// src/utils/runtime-mode.ts
|
|
7004
|
+
function isTestMode() {
|
|
7005
|
+
return process.env["AGENTBNB_TEST_MODE"] === "1" || process.env["NODE_ENV"] === "test" || process.env["VITEST"] === "true";
|
|
7006
|
+
}
|
|
7007
|
+
function isOfflineMode() {
|
|
7008
|
+
return process.env["AGENTBNB_OFFLINE"] === "1";
|
|
7009
|
+
}
|
|
7010
|
+
function shouldSkipNetwork() {
|
|
7011
|
+
return isTestMode() || isOfflineMode();
|
|
7012
|
+
}
|
|
7013
|
+
|
|
7014
|
+
// src/utils/network-probe.ts
|
|
7015
|
+
var PROBE_TIMEOUT_MS = 2e3;
|
|
7016
|
+
async function probeRegistry(registryUrl, timeoutMs = PROBE_TIMEOUT_MS) {
|
|
7017
|
+
if (shouldSkipNetwork()) return false;
|
|
7018
|
+
const controller = new AbortController();
|
|
7019
|
+
const timer = setTimeout(() => controller.abort(), timeoutMs);
|
|
7020
|
+
try {
|
|
7021
|
+
const url = `${registryUrl.replace(/\/$/, "")}/health`;
|
|
7022
|
+
const res = await fetch(url, { method: "GET", signal: controller.signal });
|
|
7023
|
+
return res.ok;
|
|
7024
|
+
} catch {
|
|
7025
|
+
return false;
|
|
7026
|
+
} finally {
|
|
7027
|
+
clearTimeout(timer);
|
|
7028
|
+
}
|
|
7029
|
+
}
|
|
7030
|
+
|
|
7031
|
+
// src/utils/with-timeout.ts
|
|
7032
|
+
var TimeoutError = class extends Error {
|
|
7033
|
+
constructor(timeoutMs) {
|
|
7034
|
+
super(`Operation timed out after ${timeoutMs}ms`);
|
|
7035
|
+
this.name = "TimeoutError";
|
|
7036
|
+
}
|
|
7037
|
+
};
|
|
7038
|
+
async function withTimeout(promise, timeoutMs) {
|
|
7039
|
+
let timer;
|
|
7040
|
+
const timeoutPromise = new Promise((_, reject) => {
|
|
7041
|
+
timer = setTimeout(() => reject(new TimeoutError(timeoutMs)), timeoutMs);
|
|
7042
|
+
});
|
|
7043
|
+
try {
|
|
7044
|
+
return await Promise.race([promise, timeoutPromise]);
|
|
7045
|
+
} finally {
|
|
7046
|
+
if (timer) clearTimeout(timer);
|
|
7047
|
+
}
|
|
7048
|
+
}
|
|
7049
|
+
|
|
7050
|
+
// src/runtime/service-coordinator.ts
|
|
7051
|
+
var STARTUP_SYNC_BUDGET_MS = 3e3;
|
|
6968
7052
|
function buildFallbackRelayCard(owner) {
|
|
6969
7053
|
return {
|
|
6970
7054
|
id: randomUUID9(),
|
|
@@ -7168,11 +7252,28 @@ var ServiceCoordinator = class {
|
|
|
7168
7252
|
this.runtime.registerJob(idleJob);
|
|
7169
7253
|
console.log("IdleMonitor started (60s poll interval, 70% idle threshold)");
|
|
7170
7254
|
if (this.config.registry) {
|
|
7171
|
-
|
|
7172
|
-
|
|
7173
|
-
console.log(`[agentbnb] credits synced: ${startupSync.remoteBalance} (was ${startupSync.localWas})`);
|
|
7255
|
+
if (shouldSkipNetwork()) {
|
|
7256
|
+
console.warn("[agentbnb] credit sync skipped: test/offline mode");
|
|
7174
7257
|
} else {
|
|
7175
|
-
|
|
7258
|
+
const reachable = await probeRegistry(this.config.registry);
|
|
7259
|
+
if (!reachable) {
|
|
7260
|
+
console.warn("[agentbnb] credit sync skipped: registry unreachable (will retry every 5m)");
|
|
7261
|
+
} else {
|
|
7262
|
+
try {
|
|
7263
|
+
const startupSync = await withTimeout(
|
|
7264
|
+
syncCreditsFromRegistry(this.config, this.runtime.creditDb),
|
|
7265
|
+
STARTUP_SYNC_BUDGET_MS
|
|
7266
|
+
);
|
|
7267
|
+
if (startupSync.synced) {
|
|
7268
|
+
console.log(`[agentbnb] credits synced: ${startupSync.remoteBalance} (was ${startupSync.localWas})`);
|
|
7269
|
+
} else {
|
|
7270
|
+
console.warn(`[agentbnb] credit sync skipped: ${startupSync.error}`);
|
|
7271
|
+
}
|
|
7272
|
+
} catch (err) {
|
|
7273
|
+
const reason = err instanceof TimeoutError ? `timeout after ${STARTUP_SYNC_BUDGET_MS}ms` : err.message;
|
|
7274
|
+
console.warn(`[agentbnb] credit sync skipped: ${reason} (will retry every 5m)`);
|
|
7275
|
+
}
|
|
7276
|
+
}
|
|
7176
7277
|
}
|
|
7177
7278
|
this.creditSyncJob = new Cron2("*/5 * * * *", async () => {
|
|
7178
7279
|
const result = await syncCreditsFromRegistry(this.config, this.runtime.creditDb);
|
|
@@ -7213,7 +7314,7 @@ var ServiceCoordinator = class {
|
|
|
7213
7314
|
}
|
|
7214
7315
|
if (opts.registryUrl && opts.relay) {
|
|
7215
7316
|
const { RelayClient: RelayClient2 } = await import("../../websocket-client-RT4KLJL4.js");
|
|
7216
|
-
const { executeCapabilityRequest: executeCapabilityRequest2 } = await import("../../execute-
|
|
7317
|
+
const { executeCapabilityRequest: executeCapabilityRequest2 } = await import("../../execute-YMPHTJPN.js");
|
|
7217
7318
|
const localCards = listCards(this.runtime.registryDb, this.config.owner);
|
|
7218
7319
|
const { primaryCard, additionalCards } = buildRelayRegistrationCards(this.config.owner, localCards);
|
|
7219
7320
|
if (this.config.conductor?.public) {
|
|
@@ -7959,6 +8060,56 @@ async function handleDiscover(args, ctx) {
|
|
|
7959
8060
|
|
|
7960
8061
|
// src/mcp/tools/request.ts
|
|
7961
8062
|
import { z as z9 } from "zod";
|
|
8063
|
+
|
|
8064
|
+
// src/autonomy/consumer-autonomy.ts
|
|
8065
|
+
var DEFAULT_CONSUMER_AUTONOMY = {
|
|
8066
|
+
session_budget: 50,
|
|
8067
|
+
single_request_max: 20,
|
|
8068
|
+
multi_skill_policy: "notify"
|
|
8069
|
+
};
|
|
8070
|
+
function createSessionState() {
|
|
8071
|
+
return { totalSpent: 0, paidCallCount: 0 };
|
|
8072
|
+
}
|
|
8073
|
+
function checkConsumerBudget(config, session, estimatedCost) {
|
|
8074
|
+
if (estimatedCost <= 0) {
|
|
8075
|
+
return { allowed: true };
|
|
8076
|
+
}
|
|
8077
|
+
if (estimatedCost > config.single_request_max) {
|
|
8078
|
+
return {
|
|
8079
|
+
allowed: false,
|
|
8080
|
+
error: `Request cost (${estimatedCost} credits) exceeds single_request_max (${config.single_request_max}). Adjust consumer_autonomy.single_request_max in config to allow higher-cost requests.`
|
|
8081
|
+
};
|
|
8082
|
+
}
|
|
8083
|
+
if (session.totalSpent + estimatedCost > config.session_budget) {
|
|
8084
|
+
return {
|
|
8085
|
+
allowed: false,
|
|
8086
|
+
error: `Session budget exceeded: spent ${session.totalSpent} + requested ${estimatedCost} = ${session.totalSpent + estimatedCost} credits, but session_budget is ${config.session_budget}. This session has already made ${session.paidCallCount} paid call(s).`
|
|
8087
|
+
};
|
|
8088
|
+
}
|
|
8089
|
+
if (session.paidCallCount > 0) {
|
|
8090
|
+
if (config.multi_skill_policy === "block") {
|
|
8091
|
+
return {
|
|
8092
|
+
allowed: false,
|
|
8093
|
+
error: `Multi-skill block: this would be paid call #${session.paidCallCount + 1} in this session (total spent: ${session.totalSpent}, this request: ${estimatedCost} credits). consumer_autonomy.multi_skill_policy is "block". Only one paid skill call is allowed per session unless policy is changed.`
|
|
8094
|
+
};
|
|
8095
|
+
}
|
|
8096
|
+
if (config.multi_skill_policy === "notify") {
|
|
8097
|
+
return {
|
|
8098
|
+
allowed: true,
|
|
8099
|
+
warning: `This is paid call #${session.paidCallCount + 1} in this session. Cumulative spend: ${session.totalSpent} + ${estimatedCost} = ${session.totalSpent + estimatedCost} credits (session budget: ${config.session_budget}).`
|
|
8100
|
+
};
|
|
8101
|
+
}
|
|
8102
|
+
}
|
|
8103
|
+
return { allowed: true };
|
|
8104
|
+
}
|
|
8105
|
+
function recordConsumerSpend(session, creditsSpent) {
|
|
8106
|
+
if (creditsSpent > 0) {
|
|
8107
|
+
session.totalSpent += creditsSpent;
|
|
8108
|
+
session.paidCallCount += 1;
|
|
8109
|
+
}
|
|
8110
|
+
}
|
|
8111
|
+
|
|
8112
|
+
// src/mcp/tools/request.ts
|
|
7962
8113
|
var requestInputSchema = {
|
|
7963
8114
|
query: z9.string().optional().describe("Search query to find a matching capability (auto-request mode)"),
|
|
7964
8115
|
card_id: z9.string().optional().describe("Direct card ID to request (skips search)"),
|
|
@@ -7996,7 +8147,17 @@ function deriveTimeoutHintFromCard(remoteCard, skillId) {
|
|
|
7996
8147
|
async function handleRequest(args, ctx) {
|
|
7997
8148
|
try {
|
|
7998
8149
|
const maxCost = args.max_cost ?? 50;
|
|
8150
|
+
const consumerConfig = ctx.config.consumer_autonomy ?? DEFAULT_CONSUMER_AUTONOMY;
|
|
8151
|
+
if (!ctx.consumerSession) {
|
|
8152
|
+
ctx.consumerSession = createSessionState();
|
|
8153
|
+
}
|
|
7999
8154
|
if (args.query) {
|
|
8155
|
+
const budgetCheck = checkConsumerBudget(consumerConfig, ctx.consumerSession, maxCost);
|
|
8156
|
+
if (!budgetCheck.allowed) {
|
|
8157
|
+
return {
|
|
8158
|
+
content: [{ type: "text", text: JSON.stringify({ success: false, error: budgetCheck.error, budget_exceeded: true }) }]
|
|
8159
|
+
};
|
|
8160
|
+
}
|
|
8000
8161
|
const registryDb = openDatabase(ctx.config.db_path);
|
|
8001
8162
|
const creditDb = openCreditDb(ctx.config.credit_db_path);
|
|
8002
8163
|
registryDb.pragma("busy_timeout = 5000");
|
|
@@ -8020,8 +8181,12 @@ async function handleRequest(args, ctx) {
|
|
|
8020
8181
|
maxCostCredits: maxCost,
|
|
8021
8182
|
params: args.params
|
|
8022
8183
|
});
|
|
8184
|
+
const creditsUsed = typeof result?.creditsSpent === "number" ? result.creditsSpent : 0;
|
|
8185
|
+
recordConsumerSpend(ctx.consumerSession, creditsUsed);
|
|
8186
|
+
const response = { success: true, ...result };
|
|
8187
|
+
if (budgetCheck.warning) response.spend_warning = budgetCheck.warning;
|
|
8023
8188
|
return {
|
|
8024
|
-
content: [{ type: "text", text: JSON.stringify(
|
|
8189
|
+
content: [{ type: "text", text: JSON.stringify(response, null, 2) }]
|
|
8025
8190
|
};
|
|
8026
8191
|
} finally {
|
|
8027
8192
|
registryDb.close();
|
|
@@ -8088,17 +8253,23 @@ async function handleRequest(args, ctx) {
|
|
|
8088
8253
|
const targetAgentId = typeof remoteCard["agent_id"] === "string" ? remoteCard["agent_id"] : void 0;
|
|
8089
8254
|
const gatewayUrl = remoteCard["gateway_url"];
|
|
8090
8255
|
const timeoutHint = deriveTimeoutHintFromCard(remoteCard, args.skill_id);
|
|
8256
|
+
let remoteCost = 0;
|
|
8257
|
+
const remoteSkills = remoteCard["skills"];
|
|
8258
|
+
if (Array.isArray(remoteSkills)) {
|
|
8259
|
+
const matchedSkill = args.skill_id ? remoteSkills.find((s) => s.id === args.skill_id) : remoteSkills[0];
|
|
8260
|
+
remoteCost = matchedSkill?.pricing?.credits_per_call ?? 0;
|
|
8261
|
+
} else {
|
|
8262
|
+
const remotePricing = remoteCard["pricing"];
|
|
8263
|
+
remoteCost = remotePricing?.credits_per_call ?? 0;
|
|
8264
|
+
}
|
|
8091
8265
|
if (gatewayUrl) {
|
|
8092
|
-
let remoteCost = 0;
|
|
8093
|
-
const remoteSkills = remoteCard["skills"];
|
|
8094
|
-
if (Array.isArray(remoteSkills)) {
|
|
8095
|
-
const matchedSkill = args.skill_id ? remoteSkills.find((s) => s.id === args.skill_id) : remoteSkills[0];
|
|
8096
|
-
remoteCost = matchedSkill?.pricing?.credits_per_call ?? 0;
|
|
8097
|
-
} else {
|
|
8098
|
-
const remotePricing = remoteCard["pricing"];
|
|
8099
|
-
remoteCost = remotePricing?.credits_per_call ?? 0;
|
|
8100
|
-
}
|
|
8101
8266
|
if (remoteCost > 0) {
|
|
8267
|
+
const budgetCheck = checkConsumerBudget(consumerConfig, ctx.consumerSession, remoteCost);
|
|
8268
|
+
if (!budgetCheck.allowed) {
|
|
8269
|
+
return {
|
|
8270
|
+
content: [{ type: "text", text: JSON.stringify({ success: false, error: budgetCheck.error, budget_exceeded: true }) }]
|
|
8271
|
+
};
|
|
8272
|
+
}
|
|
8102
8273
|
if (!targetOwner) {
|
|
8103
8274
|
return {
|
|
8104
8275
|
content: [{ type: "text", text: JSON.stringify({ success: false, error: "Paid remote request requires a target owner for relay routing" }) }]
|
|
@@ -8115,8 +8286,11 @@ async function handleRequest(args, ctx) {
|
|
|
8115
8286
|
params: { ...args.params ?? {}, ...args.skill_id ? { skill_id: args.skill_id } : {}, requester: ctx.config.owner },
|
|
8116
8287
|
timeoutMs: args.timeout_ms
|
|
8117
8288
|
});
|
|
8289
|
+
recordConsumerSpend(ctx.consumerSession, remoteCost);
|
|
8290
|
+
const response = { success: true, result, creditsSpent: remoteCost };
|
|
8291
|
+
if (budgetCheck.warning) response.spend_warning = budgetCheck.warning;
|
|
8118
8292
|
return {
|
|
8119
|
-
content: [{ type: "text", text: JSON.stringify(
|
|
8293
|
+
content: [{ type: "text", text: JSON.stringify(response, null, 2) }]
|
|
8120
8294
|
};
|
|
8121
8295
|
} else {
|
|
8122
8296
|
const result = await requestCapability({
|
|
@@ -8134,6 +8308,14 @@ async function handleRequest(args, ctx) {
|
|
|
8134
8308
|
}
|
|
8135
8309
|
}
|
|
8136
8310
|
if (targetOwner) {
|
|
8311
|
+
if (remoteCost > 0) {
|
|
8312
|
+
const budgetCheck = checkConsumerBudget(consumerConfig, ctx.consumerSession, remoteCost);
|
|
8313
|
+
if (!budgetCheck.allowed) {
|
|
8314
|
+
return {
|
|
8315
|
+
content: [{ type: "text", text: JSON.stringify({ success: false, error: budgetCheck.error, budget_exceeded: true }) }]
|
|
8316
|
+
};
|
|
8317
|
+
}
|
|
8318
|
+
}
|
|
8137
8319
|
const result = await requestViaTemporaryRelay({
|
|
8138
8320
|
registryUrl: ctx.config.registry,
|
|
8139
8321
|
owner: ctx.config.owner,
|
|
@@ -8145,8 +8327,13 @@ async function handleRequest(args, ctx) {
|
|
|
8145
8327
|
params: { ...args.params ?? {}, ...args.skill_id ? { skill_id: args.skill_id } : {} },
|
|
8146
8328
|
timeoutMs: args.timeout_ms
|
|
8147
8329
|
});
|
|
8330
|
+
if (remoteCost > 0) {
|
|
8331
|
+
recordConsumerSpend(ctx.consumerSession, remoteCost);
|
|
8332
|
+
}
|
|
8333
|
+
const response = { success: true, result };
|
|
8334
|
+
if (remoteCost > 0) response.creditsSpent = remoteCost;
|
|
8148
8335
|
return {
|
|
8149
|
-
content: [{ type: "text", text: JSON.stringify(
|
|
8336
|
+
content: [{ type: "text", text: JSON.stringify(response, null, 2) }]
|
|
8150
8337
|
};
|
|
8151
8338
|
}
|
|
8152
8339
|
return {
|
|
@@ -8257,7 +8444,7 @@ async function conductAction(task, opts) {
|
|
|
8257
8444
|
);
|
|
8258
8445
|
};
|
|
8259
8446
|
let relay;
|
|
8260
|
-
if (config.registry) {
|
|
8447
|
+
if (config.registry && !shouldSkipNetwork()) {
|
|
8261
8448
|
relay = new RelayClient({
|
|
8262
8449
|
registryUrl: config.registry,
|
|
8263
8450
|
owner: config.owner,
|
|
@@ -8267,8 +8454,10 @@ async function conductAction(task, opts) {
|
|
|
8267
8454
|
silent: true
|
|
8268
8455
|
});
|
|
8269
8456
|
try {
|
|
8270
|
-
await relay.connect();
|
|
8271
|
-
} catch {
|
|
8457
|
+
await withTimeout(relay.connect(), 1e4);
|
|
8458
|
+
} catch (err) {
|
|
8459
|
+
if (err instanceof TimeoutError) {
|
|
8460
|
+
}
|
|
8272
8461
|
relay = void 0;
|
|
8273
8462
|
}
|
|
8274
8463
|
}
|
|
@@ -12,11 +12,11 @@ import {
|
|
|
12
12
|
updateReputation,
|
|
13
13
|
updateSkillAvailability,
|
|
14
14
|
updateSkillIdleRate
|
|
15
|
-
} from "./chunk-
|
|
15
|
+
} from "./chunk-QE42IJC4.js";
|
|
16
|
+
import "./chunk-4XTYT4JW.js";
|
|
16
17
|
import "./chunk-GZUTU6IZ.js";
|
|
17
18
|
import "./chunk-J4RFJVXI.js";
|
|
18
19
|
import "./chunk-UVCNMRPS.js";
|
|
19
|
-
import "./chunk-4XTYT4JW.js";
|
|
20
20
|
import "./chunk-3RG5ZIWI.js";
|
|
21
21
|
export {
|
|
22
22
|
attachCanonicalAgentId,
|
|
@@ -1,12 +1,15 @@
|
|
|
1
|
+
import {
|
|
2
|
+
shouldSkipNetwork
|
|
3
|
+
} from "./chunk-5FXLZ5FX.js";
|
|
1
4
|
import {
|
|
2
5
|
loadIdentity
|
|
3
6
|
} from "./chunk-AA25Z6FW.js";
|
|
4
7
|
import "./chunk-65GNX2KC.js";
|
|
5
|
-
import "./chunk-UVCNMRPS.js";
|
|
6
8
|
import {
|
|
7
9
|
getConfigDir,
|
|
8
10
|
loadConfig
|
|
9
11
|
} from "./chunk-3XPBFF6H.js";
|
|
12
|
+
import "./chunk-UVCNMRPS.js";
|
|
10
13
|
import "./chunk-3RG5ZIWI.js";
|
|
11
14
|
|
|
12
15
|
// src/cli/vc-action.ts
|
|
@@ -22,13 +25,20 @@ async function vcShow(opts) {
|
|
|
22
25
|
console.error("Error: no registry configured. Run `agentbnb config set registry <url>`");
|
|
23
26
|
process.exit(1);
|
|
24
27
|
}
|
|
28
|
+
if (shouldSkipNetwork()) {
|
|
29
|
+
console.log("VC show: skipped (offline or test mode). Run again when online.");
|
|
30
|
+
return;
|
|
31
|
+
}
|
|
25
32
|
const registryUrl = config.registry.replace(/\/$/, "");
|
|
26
33
|
const agentId = identity.agent_id;
|
|
27
34
|
let res;
|
|
28
35
|
try {
|
|
29
|
-
res = await fetch(`${registryUrl}/api/credentials/${encodeURIComponent(agentId)}
|
|
36
|
+
res = await fetch(`${registryUrl}/api/credentials/${encodeURIComponent(agentId)}`, {
|
|
37
|
+
signal: AbortSignal.timeout(1e4)
|
|
38
|
+
});
|
|
30
39
|
} catch (err) {
|
|
31
|
-
|
|
40
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
41
|
+
console.error(`Error: failed to connect to registry \u2014 ${msg}`);
|
|
32
42
|
process.exit(1);
|
|
33
43
|
}
|
|
34
44
|
if (res.status === 404) {
|
package/openclaw.plugin.json
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"id": "agentbnb",
|
|
3
3
|
"name": "AgentBnB",
|
|
4
|
-
"description": "
|
|
5
|
-
"version": "
|
|
4
|
+
"description": "P2P capability sharing protocol for AI agents. Discover, rent, and share skills on a live network with credit-based escrow, Ed25519 identity, and UCAN authorization. 1,700+ tests, MIT license.",
|
|
5
|
+
"version": "9.2.2",
|
|
6
6
|
"kind": "tools",
|
|
7
7
|
"configSchema": {
|
|
8
8
|
"type": "object",
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
},
|
|
15
15
|
"registry": {
|
|
16
16
|
"type": "string",
|
|
17
|
-
"default": "https://
|
|
17
|
+
"default": "https://agentbnb.fly.dev",
|
|
18
18
|
"description": "Registry URL for the AgentBnB network"
|
|
19
19
|
},
|
|
20
20
|
"tier1Threshold": {
|
|
@@ -26,6 +26,22 @@
|
|
|
26
26
|
"type": "number",
|
|
27
27
|
"default": 50,
|
|
28
28
|
"description": "Max credits per call for notify-after-action"
|
|
29
|
+
},
|
|
30
|
+
"sessionBudget": {
|
|
31
|
+
"type": "number",
|
|
32
|
+
"default": 50,
|
|
33
|
+
"description": "Max cumulative credits per MCP session (consumer autonomy guard)"
|
|
34
|
+
},
|
|
35
|
+
"singleRequestMax": {
|
|
36
|
+
"type": "number",
|
|
37
|
+
"default": 20,
|
|
38
|
+
"description": "Max credits per single request (consumer autonomy guard)"
|
|
39
|
+
},
|
|
40
|
+
"multiSkillPolicy": {
|
|
41
|
+
"type": "string",
|
|
42
|
+
"enum": ["auto", "notify", "block"],
|
|
43
|
+
"default": "notify",
|
|
44
|
+
"description": "Policy for subsequent paid skill calls: auto (allow), notify (warn), block (reject)"
|
|
29
45
|
}
|
|
30
46
|
}
|
|
31
47
|
},
|
|
@@ -37,8 +53,8 @@
|
|
|
37
53
|
},
|
|
38
54
|
"registry": {
|
|
39
55
|
"label": "Registry URL",
|
|
40
|
-
"placeholder": "https://
|
|
41
|
-
"help": "AgentBnB public registry. Change only if self-hosting."
|
|
56
|
+
"placeholder": "https://agentbnb.fly.dev",
|
|
57
|
+
"help": "AgentBnB public registry and relay. Change only if self-hosting."
|
|
42
58
|
},
|
|
43
59
|
"tier1Threshold": {
|
|
44
60
|
"label": "Tier 1 Threshold (credits)",
|
|
@@ -49,6 +65,21 @@
|
|
|
49
65
|
"label": "Tier 2 Threshold (credits)",
|
|
50
66
|
"help": "Actions below this cost notify after completion. Above = ask before acting.",
|
|
51
67
|
"advanced": true
|
|
68
|
+
},
|
|
69
|
+
"sessionBudget": {
|
|
70
|
+
"label": "Session Budget (credits)",
|
|
71
|
+
"help": "Max credits an agent can spend in a single MCP session. Prevents runaway multi-skill spending.",
|
|
72
|
+
"advanced": true
|
|
73
|
+
},
|
|
74
|
+
"singleRequestMax": {
|
|
75
|
+
"label": "Single Request Max (credits)",
|
|
76
|
+
"help": "Max credits per individual request. Requests above this are blocked.",
|
|
77
|
+
"advanced": true
|
|
78
|
+
},
|
|
79
|
+
"multiSkillPolicy": {
|
|
80
|
+
"label": "Multi-Skill Policy",
|
|
81
|
+
"help": "What happens when a second paid skill is called in the same session. 'notify' adds a spend warning.",
|
|
82
|
+
"advanced": true
|
|
52
83
|
}
|
|
53
84
|
}
|
|
54
85
|
}
|
package/package.json
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"workspaces": [
|
|
4
4
|
"packages/*"
|
|
5
5
|
],
|
|
6
|
-
"version": "9.2.
|
|
6
|
+
"version": "9.2.2",
|
|
7
7
|
"description": "P2P Agent Capability Sharing Protocol — Airbnb for AI agent pipelines",
|
|
8
8
|
"type": "module",
|
|
9
9
|
"main": "dist/index.js",
|
|
@@ -40,18 +40,6 @@
|
|
|
40
40
|
"import": "./dist/identity/index.js"
|
|
41
41
|
}
|
|
42
42
|
},
|
|
43
|
-
"scripts": {
|
|
44
|
-
"build": "tsup",
|
|
45
|
-
"build:hub": "cd hub && pnpm install && pnpm build",
|
|
46
|
-
"build:all": "pnpm build && pnpm build:hub",
|
|
47
|
-
"dev": "tsx watch src/cli/index.ts",
|
|
48
|
-
"test": "vitest run",
|
|
49
|
-
"test:run": "vitest run",
|
|
50
|
-
"test:watch": "vitest",
|
|
51
|
-
"lint": "eslint src/",
|
|
52
|
-
"typecheck": "tsc --noEmit",
|
|
53
|
-
"prepublishOnly": "pnpm run build && pnpm run typecheck && pnpm run test:run"
|
|
54
|
-
},
|
|
55
43
|
"keywords": [
|
|
56
44
|
"ai",
|
|
57
45
|
"agent",
|
|
@@ -104,9 +92,15 @@
|
|
|
104
92
|
"engines": {
|
|
105
93
|
"node": ">=20.0.0 <25.0.0"
|
|
106
94
|
},
|
|
107
|
-
"
|
|
108
|
-
"
|
|
109
|
-
|
|
110
|
-
|
|
95
|
+
"scripts": {
|
|
96
|
+
"build": "tsup",
|
|
97
|
+
"build:hub": "cd hub && pnpm install && pnpm build",
|
|
98
|
+
"build:all": "pnpm build && pnpm build:hub",
|
|
99
|
+
"dev": "tsx watch src/cli/index.ts",
|
|
100
|
+
"test": "vitest run",
|
|
101
|
+
"test:run": "vitest run",
|
|
102
|
+
"test:watch": "vitest",
|
|
103
|
+
"lint": "eslint src/",
|
|
104
|
+
"typecheck": "tsc --noEmit"
|
|
111
105
|
}
|
|
112
|
-
}
|
|
106
|
+
}
|