agentbnb 9.1.0 → 9.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +29 -4
- package/dist/{card-VVT3XBOI.js → card-U2HQRPYN.js} +2 -1
- package/dist/{card-NQHAGTQQ.js → card-VVXNKHDX.js} +2 -1
- package/dist/{chunk-3Y76PHEY.js → chunk-53Q2HHHH.js} +154 -88
- package/dist/{chunk-5CC6O6SO.js → chunk-AA25Z6FW.js} +1 -1
- package/dist/{chunk-PIO2FMX4.js → chunk-B6AKTLXB.js} +5 -5
- package/dist/{chunk-VJ2Q33AP.js → chunk-BPPFY72X.js} +4 -0
- package/dist/{chunk-JKD6QRUD.js → chunk-C56X7EFJ.js} +4 -0
- package/dist/{chunk-PYZGF5QH.js → chunk-CMGJ52SX.js} +215 -98
- package/dist/{chunk-4DBSSFHG.js → chunk-EC6DIVE5.js} +3 -3
- package/dist/{chunk-4M6IAIVK.js → chunk-FK54LVDR.js} +2 -2
- package/dist/{chunk-JJHQAZWE.js → chunk-GGRH5PCD.js} +10 -10
- package/dist/chunk-GZUTU6IZ.js +153 -0
- package/dist/{chunk-W6LOCBWQ.js → chunk-IWAK4WHK.js} +1 -1
- package/dist/{chunk-ZYOMPJGG.js → chunk-KKFP5Y2Z.js} +2 -2
- package/dist/{chunk-XL5XD3IG.js → chunk-MPS4RE7T.js} +7 -7
- package/dist/{chunk-DBO2335D.js → chunk-MQIT2F5V.js} +8 -8
- package/dist/{chunk-GAZCZCAZ.js → chunk-RNALIVRR.js} +1 -1
- package/dist/{chunk-4UIUIHST.js → chunk-UPWAXWY2.js} +1 -1
- package/dist/{chunk-UXL7DV7P.js → chunk-V5TJXK3F.js} +3 -3
- package/dist/{chunk-AR7Z3EQB.js → chunk-WEZ7PSOE.js} +14 -14
- package/dist/{chunk-LENX5NUW.js → chunk-Z7XWQ63B.js} +55 -2
- package/dist/cli/index.js +76 -61
- package/dist/{client-XOSXFC7Q.js → client-KL67WZVJ.js} +2 -2
- package/dist/{conduct-VSSHJHVH.js → conduct-JRLLA4PB.js} +12 -11
- package/dist/{conduct-6C6JWZKZ.js → conduct-QLWXU2ZU.js} +12 -11
- package/dist/{conductor-mode-KKPSNN7V.js → conductor-mode-66IITI4I.js} +13 -12
- package/dist/{conductor-mode-NKHIZG4N.js → conductor-mode-PFO2VLH6.js} +14 -13
- package/dist/{credits-action-N3WB4WSI.js → credits-action-XERUEDF3.js} +6 -6
- package/dist/{did-action-3PNFYLX2.js → did-action-ODWTBVXL.js} +3 -3
- package/dist/{execute-QHP4KUV2.js → execute-NOQVN7ZG.js} +10 -9
- package/dist/{execute-IEQ3RV7I.js → execute-YBNCDAOX.js} +8 -7
- package/dist/index.js +350 -147
- package/dist/{openclaw-setup-PKGFB4IH.js → openclaw-setup-4RIZRMXA.js} +12 -11
- package/dist/{openclaw-skills-5VJDA6SX.js → openclaw-skills-TQ2JVBRM.js} +2 -2
- package/dist/provider-events-GTTJPYHS.js +13 -0
- package/dist/{publish-capability-CHMPZ6W3.js → publish-capability-2FMD3K6Z.js} +3 -2
- package/dist/{request-6TBVP3GR.js → request-EYN4CVXC.js} +12 -11
- package/dist/{serve-skill-BRUHUDRA.js → serve-skill-NWERGVH5.js} +13 -12
- package/dist/{server-N4BJW4TS.js → server-UPOPLZ24.js} +17 -16
- package/dist/{service-coordinator-M2CBDEUQ.js → service-coordinator-ZOZTW2U6.js} +419 -58
- package/dist/{session-action-67J57636.js → session-action-OSBZB4TX.js} +3 -3
- package/dist/signing-AQTKYJDB.js +16 -0
- package/dist/skills/agentbnb/bootstrap.js +426 -65
- package/dist/{store-A4YPEHDV.js → store-74EWU77V.js} +2 -1
- package/dist/{vc-action-TSAIABUM.js → vc-action-A6VBKERF.js} +3 -3
- package/package.json +3 -1
- package/dist/{chunk-YNBZLXYS.js → chunk-65GNX2KC.js} +0 -0
- package/dist/{daemon-OM2K3U7J.js → daemon-ETXXE4IS.js} +1 -1
|
@@ -1,13 +1,3 @@
|
|
|
1
|
-
import {
|
|
2
|
-
createLedger,
|
|
3
|
-
deriveAgentId,
|
|
4
|
-
ensureIdentity,
|
|
5
|
-
executeCapabilityBatch,
|
|
6
|
-
executeCapabilityRequest,
|
|
7
|
-
identityAuthPlugin,
|
|
8
|
-
loadOrRepairIdentity,
|
|
9
|
-
syncCreditsFromRegistry
|
|
10
|
-
} from "../../chunk-PYZGF5QH.js";
|
|
11
1
|
import {
|
|
12
2
|
AutoRequestor,
|
|
13
3
|
BudgetController,
|
|
@@ -26,7 +16,19 @@ import {
|
|
|
26
16
|
requestViaTemporaryRelay,
|
|
27
17
|
resolvePendingRequest,
|
|
28
18
|
verifyUCAN
|
|
29
|
-
} from "../../chunk-
|
|
19
|
+
} from "../../chunk-MQIT2F5V.js";
|
|
20
|
+
import {
|
|
21
|
+
createLedger,
|
|
22
|
+
deriveAgentId,
|
|
23
|
+
ensureIdentity,
|
|
24
|
+
executeCapabilityBatch,
|
|
25
|
+
executeCapabilityRequest,
|
|
26
|
+
identityAuthPlugin,
|
|
27
|
+
loadOrRepairIdentity,
|
|
28
|
+
notifyProviderEvent,
|
|
29
|
+
syncCreditsFromRegistry,
|
|
30
|
+
tryVerifyIdentity
|
|
31
|
+
} from "../../chunk-CMGJ52SX.js";
|
|
30
32
|
import {
|
|
31
33
|
NETWORK_FEE_RATE,
|
|
32
34
|
bootstrapAgent,
|
|
@@ -47,18 +49,49 @@ import {
|
|
|
47
49
|
releaseEscrow,
|
|
48
50
|
searchCards,
|
|
49
51
|
settleEscrow
|
|
50
|
-
} from "../../chunk-
|
|
52
|
+
} from "../../chunk-MPS4RE7T.js";
|
|
53
|
+
import {
|
|
54
|
+
attachCanonicalAgentId,
|
|
55
|
+
getCard,
|
|
56
|
+
getCardsBySkillCapability,
|
|
57
|
+
getEvolutionHistory,
|
|
58
|
+
getFeedbackForProvider,
|
|
59
|
+
getFeedbackForSkill,
|
|
60
|
+
getLatestEvolution,
|
|
61
|
+
insertCard,
|
|
62
|
+
insertEvolution,
|
|
63
|
+
insertFeedback,
|
|
64
|
+
listCards,
|
|
65
|
+
openDatabase,
|
|
66
|
+
updateCard,
|
|
67
|
+
updateSkillAvailability,
|
|
68
|
+
updateSkillIdleRate
|
|
69
|
+
} from "../../chunk-BPPFY72X.js";
|
|
70
|
+
import {
|
|
71
|
+
getActivityFeed,
|
|
72
|
+
getRequestLog,
|
|
73
|
+
getSkillRequestCount,
|
|
74
|
+
insertRequestLog
|
|
75
|
+
} from "../../chunk-4XTYT4JW.js";
|
|
76
|
+
import {
|
|
77
|
+
emitProviderEvent
|
|
78
|
+
} from "../../chunk-GZUTU6IZ.js";
|
|
51
79
|
import "../../chunk-6QMDJVMS.js";
|
|
80
|
+
import "../../chunk-EE3V3DXK.js";
|
|
52
81
|
import {
|
|
53
82
|
requestCapability,
|
|
54
83
|
requestViaRelay
|
|
55
|
-
} from "../../chunk-
|
|
84
|
+
} from "../../chunk-IWAK4WHK.js";
|
|
56
85
|
import {
|
|
57
86
|
generateKeyPair,
|
|
58
87
|
loadKeyPair,
|
|
59
88
|
signEscrowReceipt,
|
|
60
89
|
verifyEscrowReceipt
|
|
61
|
-
} from "../../chunk-
|
|
90
|
+
} from "../../chunk-65GNX2KC.js";
|
|
91
|
+
import {
|
|
92
|
+
AgentBnBError,
|
|
93
|
+
AnyCardSchema
|
|
94
|
+
} from "../../chunk-UVCNMRPS.js";
|
|
62
95
|
import {
|
|
63
96
|
RelayClient,
|
|
64
97
|
RelayMessageSchema,
|
|
@@ -78,38 +111,10 @@ import {
|
|
|
78
111
|
getConfigDir,
|
|
79
112
|
loadConfig
|
|
80
113
|
} from "../../chunk-IVOYM3WG.js";
|
|
81
|
-
import {
|
|
82
|
-
attachCanonicalAgentId,
|
|
83
|
-
getCard,
|
|
84
|
-
getCardsBySkillCapability,
|
|
85
|
-
getEvolutionHistory,
|
|
86
|
-
getFeedbackForProvider,
|
|
87
|
-
getFeedbackForSkill,
|
|
88
|
-
getLatestEvolution,
|
|
89
|
-
insertCard,
|
|
90
|
-
insertEvolution,
|
|
91
|
-
insertFeedback,
|
|
92
|
-
listCards,
|
|
93
|
-
openDatabase,
|
|
94
|
-
updateCard,
|
|
95
|
-
updateSkillAvailability,
|
|
96
|
-
updateSkillIdleRate
|
|
97
|
-
} from "../../chunk-VJ2Q33AP.js";
|
|
98
|
-
import {
|
|
99
|
-
getActivityFeed,
|
|
100
|
-
getRequestLog,
|
|
101
|
-
getSkillRequestCount,
|
|
102
|
-
insertRequestLog
|
|
103
|
-
} from "../../chunk-4XTYT4JW.js";
|
|
104
|
-
import "../../chunk-EE3V3DXK.js";
|
|
105
|
-
import {
|
|
106
|
-
AgentBnBError,
|
|
107
|
-
AnyCardSchema
|
|
108
|
-
} from "../../chunk-UVCNMRPS.js";
|
|
109
114
|
import "../../chunk-3RG5ZIWI.js";
|
|
110
115
|
|
|
111
116
|
// skills/agentbnb/bootstrap.ts
|
|
112
|
-
import { join as join6, basename as
|
|
117
|
+
import { join as join6, basename as basename3, dirname as dirname4 } from "path";
|
|
113
118
|
import { existsSync as existsSync7, writeFileSync as writeFileSync2 } from "fs";
|
|
114
119
|
import { homedir as homedir4 } from "os";
|
|
115
120
|
import { exec } from "child_process";
|
|
@@ -287,7 +292,7 @@ function isPidFileContent(value) {
|
|
|
287
292
|
}
|
|
288
293
|
|
|
289
294
|
// src/runtime/agent-runtime.ts
|
|
290
|
-
import { readFileSync as
|
|
295
|
+
import { readFileSync as readFileSync3, existsSync as existsSync2 } from "fs";
|
|
291
296
|
|
|
292
297
|
// src/skills/executor.ts
|
|
293
298
|
function buildTimeoutError(skillId, timeoutMs) {
|
|
@@ -1100,7 +1105,30 @@ var OpenClawBridge = class {
|
|
|
1100
1105
|
|
|
1101
1106
|
// src/skills/command-executor.ts
|
|
1102
1107
|
import { spawn } from "child_process";
|
|
1108
|
+
import { readFileSync as readFileSync2, statSync } from "fs";
|
|
1109
|
+
import { basename, extname } from "path";
|
|
1103
1110
|
var KILL_GRACE_MS = 5e3;
|
|
1111
|
+
var MAX_INLINE_FILE_BYTES = 5 * 1024 * 1024;
|
|
1112
|
+
var MIME_TYPES = {
|
|
1113
|
+
".mp3": "audio/mpeg",
|
|
1114
|
+
".wav": "audio/wav",
|
|
1115
|
+
".ogg": "audio/ogg",
|
|
1116
|
+
".m4a": "audio/mp4",
|
|
1117
|
+
".pdf": "application/pdf",
|
|
1118
|
+
".png": "image/png",
|
|
1119
|
+
".jpg": "image/jpeg",
|
|
1120
|
+
".jpeg": "image/jpeg",
|
|
1121
|
+
".gif": "image/gif",
|
|
1122
|
+
".webp": "image/webp",
|
|
1123
|
+
".svg": "image/svg+xml",
|
|
1124
|
+
".json": "application/json",
|
|
1125
|
+
".txt": "text/plain",
|
|
1126
|
+
".md": "text/markdown",
|
|
1127
|
+
".csv": "text/csv"
|
|
1128
|
+
};
|
|
1129
|
+
function guessMimeType(filePath) {
|
|
1130
|
+
return MIME_TYPES[extname(filePath).toLowerCase()] ?? "application/octet-stream";
|
|
1131
|
+
}
|
|
1104
1132
|
function shellEscape2(value) {
|
|
1105
1133
|
return "'" + value.replace(/'/g, "'\\''") + "'";
|
|
1106
1134
|
}
|
|
@@ -1316,8 +1344,34 @@ var CommandExecutor = class {
|
|
|
1316
1344
|
};
|
|
1317
1345
|
}
|
|
1318
1346
|
}
|
|
1319
|
-
case "file":
|
|
1320
|
-
|
|
1347
|
+
case "file": {
|
|
1348
|
+
try {
|
|
1349
|
+
const stats = statSync(rawOutput);
|
|
1350
|
+
if (stats.size > MAX_INLINE_FILE_BYTES) {
|
|
1351
|
+
return {
|
|
1352
|
+
success: false,
|
|
1353
|
+
error: `File too large for inline return: ${stats.size} bytes (max ${MAX_INLINE_FILE_BYTES})`
|
|
1354
|
+
};
|
|
1355
|
+
}
|
|
1356
|
+
const buffer = readFileSync2(rawOutput);
|
|
1357
|
+
return {
|
|
1358
|
+
success: true,
|
|
1359
|
+
result: {
|
|
1360
|
+
file: {
|
|
1361
|
+
name: basename(rawOutput),
|
|
1362
|
+
mime_type: guessMimeType(rawOutput),
|
|
1363
|
+
size_bytes: stats.size,
|
|
1364
|
+
data_base64: buffer.toString("base64")
|
|
1365
|
+
},
|
|
1366
|
+
// Keep file_path for backward compat (local workflows)
|
|
1367
|
+
file_path: rawOutput
|
|
1368
|
+
}
|
|
1369
|
+
};
|
|
1370
|
+
} catch (err) {
|
|
1371
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
1372
|
+
return { success: false, error: `Failed to read file "${rawOutput}": ${msg}` };
|
|
1373
|
+
}
|
|
1374
|
+
}
|
|
1321
1375
|
default:
|
|
1322
1376
|
return {
|
|
1323
1377
|
success: false,
|
|
@@ -1446,13 +1500,13 @@ var AgentRuntime = class {
|
|
|
1446
1500
|
}
|
|
1447
1501
|
let configs = [];
|
|
1448
1502
|
if (hasSkillsYaml) {
|
|
1449
|
-
const yamlContent =
|
|
1503
|
+
const yamlContent = readFileSync3(this.skillsYamlPath, "utf8");
|
|
1450
1504
|
configs = parseSkillsFile(yamlContent);
|
|
1451
1505
|
}
|
|
1452
1506
|
const modes = /* @__PURE__ */ new Map();
|
|
1453
1507
|
if (this.conductorEnabled) {
|
|
1454
|
-
const { ConductorMode } = await import("../../conductor-mode-
|
|
1455
|
-
const { registerConductorCard, CONDUCTOR_OWNER } = await import("../../card-
|
|
1508
|
+
const { ConductorMode } = await import("../../conductor-mode-66IITI4I.js");
|
|
1509
|
+
const { registerConductorCard, CONDUCTOR_OWNER } = await import("../../card-U2HQRPYN.js");
|
|
1456
1510
|
const { loadPeers: loadPeers2 } = await import("../../peers-IOVCBWAI.js");
|
|
1457
1511
|
registerConductorCard(this.registryDb);
|
|
1458
1512
|
const resolveAgentUrl = (owner) => {
|
|
@@ -2517,12 +2571,14 @@ var SessionManager = class {
|
|
|
2517
2571
|
escrow;
|
|
2518
2572
|
config;
|
|
2519
2573
|
sendToAgent;
|
|
2574
|
+
registryDb;
|
|
2520
2575
|
/** Maps agent connection key → set of session IDs they participate in. */
|
|
2521
2576
|
agentSessions = /* @__PURE__ */ new Map();
|
|
2522
2577
|
constructor(opts) {
|
|
2523
2578
|
this.escrow = new SessionEscrow(opts.creditDb);
|
|
2524
2579
|
this.config = opts.config ?? loadSessionConfig();
|
|
2525
2580
|
this.sendToAgent = opts.sendToAgent;
|
|
2581
|
+
this.registryDb = opts.registryDb ?? null;
|
|
2526
2582
|
}
|
|
2527
2583
|
/**
|
|
2528
2584
|
* Open a new session between requester and provider.
|
|
@@ -2581,6 +2637,15 @@ var SessionManager = class {
|
|
|
2581
2637
|
}
|
|
2582
2638
|
this.resetIdleTimer(session.id);
|
|
2583
2639
|
this.startDurationTimer(session.id);
|
|
2640
|
+
this.emitEvent({
|
|
2641
|
+
event_type: "session.opened",
|
|
2642
|
+
skill_id: session.skill_id,
|
|
2643
|
+
session_id: session.id,
|
|
2644
|
+
requester: session.requester_id,
|
|
2645
|
+
credits: session.budget,
|
|
2646
|
+
duration_ms: 0,
|
|
2647
|
+
metadata: { engine: "session", pricing_model: session.pricing_model }
|
|
2648
|
+
});
|
|
2584
2649
|
return session;
|
|
2585
2650
|
}
|
|
2586
2651
|
/**
|
|
@@ -2641,6 +2706,15 @@ var SessionManager = class {
|
|
|
2641
2706
|
content: msg.content,
|
|
2642
2707
|
metadata: msg.metadata
|
|
2643
2708
|
});
|
|
2709
|
+
this.emitEvent({
|
|
2710
|
+
event_type: "session.message",
|
|
2711
|
+
skill_id: session.skill_id,
|
|
2712
|
+
session_id: session.id,
|
|
2713
|
+
requester: session.requester_id,
|
|
2714
|
+
credits: session.spent,
|
|
2715
|
+
duration_ms: Date.now() - new Date(session.created_at).getTime(),
|
|
2716
|
+
metadata: { message_count: session.messages.length, running_cost: session.spent, sender: msg.sender }
|
|
2717
|
+
});
|
|
2644
2718
|
this.resetIdleTimer(session.id);
|
|
2645
2719
|
}
|
|
2646
2720
|
/**
|
|
@@ -2684,6 +2758,19 @@ var SessionManager = class {
|
|
|
2684
2758
|
this.durationTimers.clear();
|
|
2685
2759
|
}
|
|
2686
2760
|
// -------------------------------------------------------------------------
|
|
2761
|
+
// Event emission
|
|
2762
|
+
// -------------------------------------------------------------------------
|
|
2763
|
+
/** Emit a provider event + Telegram notification. Silently no-ops on failure. */
|
|
2764
|
+
emitEvent(event) {
|
|
2765
|
+
if (!this.registryDb) return;
|
|
2766
|
+
try {
|
|
2767
|
+
const emitted = emitProviderEvent(this.registryDb, event);
|
|
2768
|
+
notifyProviderEvent(emitted).catch(() => {
|
|
2769
|
+
});
|
|
2770
|
+
} catch {
|
|
2771
|
+
}
|
|
2772
|
+
}
|
|
2773
|
+
// -------------------------------------------------------------------------
|
|
2687
2774
|
// Internal helpers
|
|
2688
2775
|
// -------------------------------------------------------------------------
|
|
2689
2776
|
endSessionInternal(session, reason) {
|
|
@@ -2707,6 +2794,27 @@ var SessionManager = class {
|
|
|
2707
2794
|
};
|
|
2708
2795
|
session.status = "settled";
|
|
2709
2796
|
session.updated_at = (/* @__PURE__ */ new Date()).toISOString();
|
|
2797
|
+
const isFailed = reason === "error";
|
|
2798
|
+
const eventMetadata = {
|
|
2799
|
+
total_messages: session.messages.length,
|
|
2800
|
+
reason,
|
|
2801
|
+
refunded: session.budget - session.spent
|
|
2802
|
+
};
|
|
2803
|
+
if (isFailed) {
|
|
2804
|
+
eventMetadata["last_messages"] = session.messages.slice(-3).map((m) => ({
|
|
2805
|
+
sender: m.sender,
|
|
2806
|
+
content: m.content.slice(0, 200)
|
|
2807
|
+
}));
|
|
2808
|
+
}
|
|
2809
|
+
this.emitEvent({
|
|
2810
|
+
event_type: isFailed ? "session.failed" : "session.ended",
|
|
2811
|
+
skill_id: session.skill_id,
|
|
2812
|
+
session_id: session.id,
|
|
2813
|
+
requester: session.requester_id,
|
|
2814
|
+
credits: session.spent,
|
|
2815
|
+
duration_ms: durationMs,
|
|
2816
|
+
metadata: eventMetadata
|
|
2817
|
+
});
|
|
2710
2818
|
this.sendToAgent(session.requester_id, settledMsg);
|
|
2711
2819
|
this.sendToAgent(session.provider_id, settledMsg);
|
|
2712
2820
|
session.status = "closed";
|
|
@@ -3669,6 +3777,75 @@ function initiateGithubAuth() {
|
|
|
3669
3777
|
};
|
|
3670
3778
|
}
|
|
3671
3779
|
|
|
3780
|
+
// src/registry/hub-identities.ts
|
|
3781
|
+
import { randomBytes as randomBytes2, createHash } from "crypto";
|
|
3782
|
+
var HUB_IDENTITIES_SCHEMA = `
|
|
3783
|
+
CREATE TABLE IF NOT EXISTS hub_identities (
|
|
3784
|
+
email TEXT PRIMARY KEY,
|
|
3785
|
+
agent_id TEXT NOT NULL UNIQUE,
|
|
3786
|
+
public_key TEXT NOT NULL,
|
|
3787
|
+
encrypted_private_key TEXT NOT NULL,
|
|
3788
|
+
kdf_salt TEXT NOT NULL,
|
|
3789
|
+
display_name TEXT NOT NULL,
|
|
3790
|
+
created_at TEXT NOT NULL
|
|
3791
|
+
);
|
|
3792
|
+
|
|
3793
|
+
CREATE INDEX IF NOT EXISTS idx_hub_identities_agent_id
|
|
3794
|
+
ON hub_identities(agent_id);
|
|
3795
|
+
`;
|
|
3796
|
+
var CHALLENGES_SCHEMA = `
|
|
3797
|
+
CREATE TABLE IF NOT EXISTS hub_challenges (
|
|
3798
|
+
challenge TEXT PRIMARY KEY,
|
|
3799
|
+
expires_at TEXT NOT NULL,
|
|
3800
|
+
consumed_at TEXT
|
|
3801
|
+
);
|
|
3802
|
+
`;
|
|
3803
|
+
function ensureHubIdentitiesTables(db) {
|
|
3804
|
+
db.exec(HUB_IDENTITIES_SCHEMA);
|
|
3805
|
+
db.exec(CHALLENGES_SCHEMA);
|
|
3806
|
+
}
|
|
3807
|
+
function deriveAgentId2(publicKeyHex) {
|
|
3808
|
+
const hash = createHash("sha256").update(publicKeyHex, "hex").digest("hex");
|
|
3809
|
+
return `agent-${hash.slice(0, 16)}`;
|
|
3810
|
+
}
|
|
3811
|
+
var CHALLENGE_TTL_MS = 10 * 60 * 1e3;
|
|
3812
|
+
function createChallenge(db) {
|
|
3813
|
+
const challenge = randomBytes2(32).toString("hex");
|
|
3814
|
+
const expires_at = new Date(Date.now() + CHALLENGE_TTL_MS).toISOString();
|
|
3815
|
+
db.prepare("INSERT INTO hub_challenges (challenge, expires_at) VALUES (?, ?)").run(challenge, expires_at);
|
|
3816
|
+
return { challenge, expires_at };
|
|
3817
|
+
}
|
|
3818
|
+
function consumeChallenge(db, challenge) {
|
|
3819
|
+
const row = db.prepare("SELECT expires_at, consumed_at FROM hub_challenges WHERE challenge = ?").get(challenge);
|
|
3820
|
+
if (!row) return false;
|
|
3821
|
+
if (row.consumed_at) return false;
|
|
3822
|
+
if (new Date(row.expires_at).getTime() < Date.now()) return false;
|
|
3823
|
+
const consumed_at = (/* @__PURE__ */ new Date()).toISOString();
|
|
3824
|
+
db.prepare("UPDATE hub_challenges SET consumed_at = ? WHERE challenge = ?").run(consumed_at, challenge);
|
|
3825
|
+
return true;
|
|
3826
|
+
}
|
|
3827
|
+
function pruneChallenges(db) {
|
|
3828
|
+
const cutoff = new Date(Date.now() - 24 * 60 * 60 * 1e3).toISOString();
|
|
3829
|
+
db.prepare("DELETE FROM hub_challenges WHERE expires_at < ? OR consumed_at IS NOT NULL").run(cutoff);
|
|
3830
|
+
}
|
|
3831
|
+
function registerHubIdentity(db, input) {
|
|
3832
|
+
const agent_id = deriveAgentId2(input.public_key);
|
|
3833
|
+
const created_at = (/* @__PURE__ */ new Date()).toISOString();
|
|
3834
|
+
db.prepare(`
|
|
3835
|
+
INSERT INTO hub_identities (email, agent_id, public_key, encrypted_private_key, kdf_salt, display_name, created_at)
|
|
3836
|
+
VALUES (?, ?, ?, ?, ?, ?, ?)
|
|
3837
|
+
`).run(input.email, agent_id, input.public_key, input.encrypted_private_key, input.kdf_salt, input.display_name, created_at);
|
|
3838
|
+
return { ...input, agent_id, created_at };
|
|
3839
|
+
}
|
|
3840
|
+
function getHubIdentityByEmail(db, email) {
|
|
3841
|
+
const row = db.prepare("SELECT * FROM hub_identities WHERE email = ?").get(email);
|
|
3842
|
+
return row ?? null;
|
|
3843
|
+
}
|
|
3844
|
+
function getHubIdentityByAgentId(db, agent_id) {
|
|
3845
|
+
const row = db.prepare("SELECT * FROM hub_identities WHERE agent_id = ?").get(agent_id);
|
|
3846
|
+
return row ?? null;
|
|
3847
|
+
}
|
|
3848
|
+
|
|
3672
3849
|
// src/registry/free-tier.ts
|
|
3673
3850
|
function initFreeTierTable(db) {
|
|
3674
3851
|
db.exec(`
|
|
@@ -5698,6 +5875,121 @@ function createRegistryServer(opts) {
|
|
|
5698
5875
|
throw err;
|
|
5699
5876
|
}
|
|
5700
5877
|
});
|
|
5878
|
+
ensureHubIdentitiesTables(db);
|
|
5879
|
+
try {
|
|
5880
|
+
pruneChallenges(db);
|
|
5881
|
+
} catch {
|
|
5882
|
+
}
|
|
5883
|
+
api.get("/api/agents/challenge", {
|
|
5884
|
+
schema: {
|
|
5885
|
+
tags: ["hub-auth"],
|
|
5886
|
+
summary: "Get a registration challenge",
|
|
5887
|
+
response: {
|
|
5888
|
+
200: {
|
|
5889
|
+
type: "object",
|
|
5890
|
+
properties: {
|
|
5891
|
+
challenge: { type: "string" },
|
|
5892
|
+
expires_at: { type: "string" }
|
|
5893
|
+
}
|
|
5894
|
+
}
|
|
5895
|
+
}
|
|
5896
|
+
}
|
|
5897
|
+
}, async (_request, reply) => {
|
|
5898
|
+
const { challenge, expires_at } = createChallenge(db);
|
|
5899
|
+
return reply.send({ challenge, expires_at });
|
|
5900
|
+
});
|
|
5901
|
+
api.post("/api/agents/register", {
|
|
5902
|
+
schema: {
|
|
5903
|
+
tags: ["hub-auth"],
|
|
5904
|
+
summary: "Register a new Hub-managed agent identity",
|
|
5905
|
+
body: {
|
|
5906
|
+
type: "object",
|
|
5907
|
+
required: ["email", "public_key", "encrypted_private_key", "kdf_salt", "display_name", "challenge", "signature"],
|
|
5908
|
+
properties: {
|
|
5909
|
+
email: { type: "string", format: "email" },
|
|
5910
|
+
public_key: { type: "string" },
|
|
5911
|
+
encrypted_private_key: { type: "string" },
|
|
5912
|
+
kdf_salt: { type: "string" },
|
|
5913
|
+
display_name: { type: "string" },
|
|
5914
|
+
challenge: { type: "string" },
|
|
5915
|
+
signature: { type: "string" }
|
|
5916
|
+
}
|
|
5917
|
+
},
|
|
5918
|
+
response: {
|
|
5919
|
+
201: { type: "object", additionalProperties: true },
|
|
5920
|
+
400: { type: "object", properties: { error: { type: "string" } } },
|
|
5921
|
+
409: { type: "object", properties: { error: { type: "string" } } }
|
|
5922
|
+
}
|
|
5923
|
+
}
|
|
5924
|
+
}, async (request, reply) => {
|
|
5925
|
+
const body = request.body;
|
|
5926
|
+
if (!consumeChallenge(db, body.challenge)) {
|
|
5927
|
+
return reply.code(400).send({ error: "Invalid or expired challenge" });
|
|
5928
|
+
}
|
|
5929
|
+
if (!/^[0-9a-fA-F]+$/.test(body.public_key) || body.public_key.length % 2 !== 0) {
|
|
5930
|
+
return reply.code(400).send({ error: "Invalid public_key format" });
|
|
5931
|
+
}
|
|
5932
|
+
try {
|
|
5933
|
+
const { verifyEscrowReceipt: verifyEscrowReceipt2 } = await import("../../signing-AQTKYJDB.js");
|
|
5934
|
+
const publicKeyBuffer = Buffer.from(body.public_key, "hex");
|
|
5935
|
+
const valid = verifyEscrowReceipt2({ challenge: body.challenge }, body.signature, publicKeyBuffer);
|
|
5936
|
+
if (!valid) {
|
|
5937
|
+
return reply.code(400).send({ error: "Invalid signature" });
|
|
5938
|
+
}
|
|
5939
|
+
} catch (err) {
|
|
5940
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
5941
|
+
return reply.code(400).send({ error: `Signature verification failed: ${msg}` });
|
|
5942
|
+
}
|
|
5943
|
+
const existing = getHubIdentityByEmail(db, body.email.toLowerCase());
|
|
5944
|
+
if (existing) {
|
|
5945
|
+
return reply.code(409).send({ error: "Email already registered" });
|
|
5946
|
+
}
|
|
5947
|
+
const agent_id = deriveAgentId2(body.public_key);
|
|
5948
|
+
const existingByAgentId = getHubIdentityByAgentId(db, agent_id);
|
|
5949
|
+
if (existingByAgentId) {
|
|
5950
|
+
return reply.code(409).send({ error: "Agent already registered" });
|
|
5951
|
+
}
|
|
5952
|
+
const identity = registerHubIdentity(db, {
|
|
5953
|
+
email: body.email.toLowerCase(),
|
|
5954
|
+
public_key: body.public_key,
|
|
5955
|
+
encrypted_private_key: body.encrypted_private_key,
|
|
5956
|
+
kdf_salt: body.kdf_salt,
|
|
5957
|
+
display_name: body.display_name
|
|
5958
|
+
});
|
|
5959
|
+
return reply.code(201).send({
|
|
5960
|
+
agent_id: identity.agent_id,
|
|
5961
|
+
did: `did:agentbnb:${identity.agent_id}`,
|
|
5962
|
+
created_at: identity.created_at
|
|
5963
|
+
});
|
|
5964
|
+
});
|
|
5965
|
+
api.post("/api/agents/login", {
|
|
5966
|
+
schema: {
|
|
5967
|
+
tags: ["hub-auth"],
|
|
5968
|
+
summary: "Fetch encrypted identity blob for login",
|
|
5969
|
+
body: {
|
|
5970
|
+
type: "object",
|
|
5971
|
+
required: ["email"],
|
|
5972
|
+
properties: { email: { type: "string", format: "email" } }
|
|
5973
|
+
},
|
|
5974
|
+
response: {
|
|
5975
|
+
200: { type: "object", additionalProperties: true },
|
|
5976
|
+
404: { type: "object", properties: { error: { type: "string" } } }
|
|
5977
|
+
}
|
|
5978
|
+
}
|
|
5979
|
+
}, async (request, reply) => {
|
|
5980
|
+
const body = request.body;
|
|
5981
|
+
const identity = getHubIdentityByEmail(db, body.email.toLowerCase());
|
|
5982
|
+
if (!identity) {
|
|
5983
|
+
return reply.code(404).send({ error: "Identity not found" });
|
|
5984
|
+
}
|
|
5985
|
+
return reply.send({
|
|
5986
|
+
agent_id: identity.agent_id,
|
|
5987
|
+
public_key: identity.public_key,
|
|
5988
|
+
encrypted_private_key: identity.encrypted_private_key,
|
|
5989
|
+
kdf_salt: identity.kdf_salt,
|
|
5990
|
+
display_name: identity.display_name
|
|
5991
|
+
});
|
|
5992
|
+
});
|
|
5701
5993
|
api.post("/api/identity/link", {
|
|
5702
5994
|
schema: {
|
|
5703
5995
|
tags: ["identity"],
|
|
@@ -5997,7 +6289,7 @@ function createRegistryServer(opts) {
|
|
|
5997
6289
|
});
|
|
5998
6290
|
await relayClient.connect();
|
|
5999
6291
|
}
|
|
6000
|
-
const { requestViaRelay: requestViaRelay2 } = await import("../../client-
|
|
6292
|
+
const { requestViaRelay: requestViaRelay2 } = await import("../../client-KL67WZVJ.js");
|
|
6001
6293
|
return requestViaRelay2(relayClient, {
|
|
6002
6294
|
targetOwner: target.owner,
|
|
6003
6295
|
cardId: target.cardId,
|
|
@@ -6016,12 +6308,24 @@ function createRegistryServer(opts) {
|
|
|
6016
6308
|
const ownerApiKey = opts.ownerApiKey;
|
|
6017
6309
|
const ownerName = opts.ownerName;
|
|
6018
6310
|
void api.register(async (ownerRoutes) => {
|
|
6019
|
-
ownerRoutes.addHook("
|
|
6311
|
+
ownerRoutes.addHook("preHandler", async (request, reply) => {
|
|
6020
6312
|
const auth = request.headers.authorization;
|
|
6021
6313
|
const token = auth?.startsWith("Bearer ") ? auth.slice(7).trim() : null;
|
|
6022
|
-
if (
|
|
6023
|
-
|
|
6314
|
+
if (token === ownerApiKey) {
|
|
6315
|
+
request.agentId = ownerName;
|
|
6316
|
+
return;
|
|
6317
|
+
}
|
|
6318
|
+
const didResult = await tryVerifyIdentity(request, {});
|
|
6319
|
+
if (didResult.valid) {
|
|
6320
|
+
const hubIdentity = getHubIdentityByAgentId(db, didResult.agentId);
|
|
6321
|
+
if (!hubIdentity) {
|
|
6322
|
+
return reply.status(401).send({ error: "Agent not registered on this Hub" });
|
|
6323
|
+
}
|
|
6324
|
+
request.agentId = didResult.agentId;
|
|
6325
|
+
request.agentPublicKey = didResult.publicKey;
|
|
6326
|
+
return;
|
|
6024
6327
|
}
|
|
6328
|
+
return reply.status(401).send({ error: "Unauthorized" });
|
|
6025
6329
|
});
|
|
6026
6330
|
ownerRoutes.get("/me", {
|
|
6027
6331
|
schema: {
|
|
@@ -6032,13 +6336,14 @@ function createRegistryServer(opts) {
|
|
|
6032
6336
|
200: { type: "object", properties: { owner: { type: "string" }, balance: { type: "number" } } }
|
|
6033
6337
|
}
|
|
6034
6338
|
}
|
|
6035
|
-
}, async (
|
|
6339
|
+
}, async (request, reply) => {
|
|
6340
|
+
const identity = request.agentId ?? ownerName;
|
|
6036
6341
|
let balance = 0;
|
|
6037
6342
|
if (opts.creditDb) {
|
|
6038
6343
|
const ledger = createLedger({ db: opts.creditDb });
|
|
6039
|
-
balance = await ledger.getBalance(
|
|
6344
|
+
balance = await ledger.getBalance(identity);
|
|
6040
6345
|
}
|
|
6041
|
-
return reply.send({ owner:
|
|
6346
|
+
return reply.send({ owner: identity, balance });
|
|
6042
6347
|
});
|
|
6043
6348
|
ownerRoutes.get("/requests", {
|
|
6044
6349
|
schema: {
|
|
@@ -6225,6 +6530,62 @@ function createRegistryServer(opts) {
|
|
|
6225
6530
|
const items = await ledger.getHistory(ownerName, limit);
|
|
6226
6531
|
return reply.send({ items, limit });
|
|
6227
6532
|
});
|
|
6533
|
+
ownerRoutes.get("/me/events", {
|
|
6534
|
+
schema: {
|
|
6535
|
+
tags: ["owner"],
|
|
6536
|
+
summary: "Provider event stream",
|
|
6537
|
+
security: [{ bearerAuth: [] }],
|
|
6538
|
+
querystring: {
|
|
6539
|
+
type: "object",
|
|
6540
|
+
properties: {
|
|
6541
|
+
limit: { type: "integer", description: "Max entries (default 50)" },
|
|
6542
|
+
since: { type: "string", description: "ISO timestamp for cursor-based polling" },
|
|
6543
|
+
event_type: { type: "string", description: "Filter by event type" }
|
|
6544
|
+
}
|
|
6545
|
+
}
|
|
6546
|
+
}
|
|
6547
|
+
}, async (request, reply) => {
|
|
6548
|
+
const { getProviderEvents: getEvents } = await import("../../provider-events-GTTJPYHS.js");
|
|
6549
|
+
const query = request.query;
|
|
6550
|
+
const limit = query.limit ? parseInt(query.limit, 10) : void 0;
|
|
6551
|
+
const events = getEvents(db, {
|
|
6552
|
+
limit,
|
|
6553
|
+
since: query.since,
|
|
6554
|
+
event_type: query.event_type
|
|
6555
|
+
});
|
|
6556
|
+
return reply.send({ events });
|
|
6557
|
+
});
|
|
6558
|
+
ownerRoutes.get("/me/stats", {
|
|
6559
|
+
schema: {
|
|
6560
|
+
tags: ["owner"],
|
|
6561
|
+
summary: "Aggregated provider stats",
|
|
6562
|
+
security: [{ bearerAuth: [] }],
|
|
6563
|
+
querystring: {
|
|
6564
|
+
type: "object",
|
|
6565
|
+
properties: { period: { type: "string", enum: ["24h", "7d", "30d"] } }
|
|
6566
|
+
}
|
|
6567
|
+
}
|
|
6568
|
+
}, async (request, reply) => {
|
|
6569
|
+
const { getProviderStats: getStats } = await import("../../provider-events-GTTJPYHS.js");
|
|
6570
|
+
const query = request.query;
|
|
6571
|
+
const period = query.period ?? "7d";
|
|
6572
|
+
const stats = getStats(db, period);
|
|
6573
|
+
if (opts.creditDb) {
|
|
6574
|
+
const periodMs = { "24h": 864e5, "7d": 6048e5, "30d": 2592e6 }[period];
|
|
6575
|
+
const cutoff = new Date(Date.now() - periodMs).toISOString();
|
|
6576
|
+
try {
|
|
6577
|
+
const row = opts.creditDb.prepare(`
|
|
6578
|
+
SELECT COALESCE(SUM(CASE WHEN amount < 0 AND reason IN ('escrow_hold', 'voucher_hold', 'network_fee') THEN -amount ELSE 0 END), 0) as spent
|
|
6579
|
+
FROM credit_transactions
|
|
6580
|
+
WHERE owner = ? AND created_at >= ?
|
|
6581
|
+
`).get(ownerName, cutoff);
|
|
6582
|
+
stats.total_spending = row?.spent ?? 0;
|
|
6583
|
+
stats.net_pnl = stats.total_earnings - stats.total_spending;
|
|
6584
|
+
} catch {
|
|
6585
|
+
}
|
|
6586
|
+
}
|
|
6587
|
+
return reply.send(stats);
|
|
6588
|
+
});
|
|
6228
6589
|
});
|
|
6229
6590
|
}
|
|
6230
6591
|
api.get("/api/providers/:owner/reliability", {
|
|
@@ -6469,7 +6830,7 @@ import { execFileSync } from "child_process";
|
|
|
6469
6830
|
import { existsSync as existsSync4, realpathSync } from "fs";
|
|
6470
6831
|
import { createRequire } from "module";
|
|
6471
6832
|
import { homedir as homedir2 } from "os";
|
|
6472
|
-
import { basename, dirname as dirname3, isAbsolute, join as join3, resolve } from "path";
|
|
6833
|
+
import { basename as basename2, dirname as dirname3, isAbsolute, join as join3, resolve } from "path";
|
|
6473
6834
|
function resolveSelfCli() {
|
|
6474
6835
|
const require2 = createRequire(import.meta.url);
|
|
6475
6836
|
return resolveSelfCliWithDeps({
|
|
@@ -6587,7 +6948,7 @@ function getPnpmGlobalCandidates(platform, homeDir) {
|
|
|
6587
6948
|
}
|
|
6588
6949
|
function looksLikeAgentbnbCli(path) {
|
|
6589
6950
|
const normalized = path.replace(/\\/g, "/").toLowerCase();
|
|
6590
|
-
const fileName =
|
|
6951
|
+
const fileName = basename2(normalized);
|
|
6591
6952
|
if (fileName === "agentbnb" || fileName === "agentbnb.cmd" || fileName === "agentbnb.exe") {
|
|
6592
6953
|
return true;
|
|
6593
6954
|
}
|
|
@@ -6600,7 +6961,7 @@ function extractErrorMessage(err) {
|
|
|
6600
6961
|
|
|
6601
6962
|
// src/runtime/service-coordinator.ts
|
|
6602
6963
|
import { spawn as spawn2 } from "child_process";
|
|
6603
|
-
import { existsSync as existsSync5, readFileSync as
|
|
6964
|
+
import { existsSync as existsSync5, readFileSync as readFileSync4 } from "fs";
|
|
6604
6965
|
import { join as join4 } from "path";
|
|
6605
6966
|
import { randomUUID as randomUUID9 } from "crypto";
|
|
6606
6967
|
import { Cron as Cron2 } from "croner";
|
|
@@ -6775,7 +7136,7 @@ var ServiceCoordinator = class {
|
|
|
6775
7136
|
console.log("Conductor mode enabled \u2014 orchestrate/plan skills available via gateway");
|
|
6776
7137
|
}
|
|
6777
7138
|
if (opts.conductorEnabled && this.config.conductor?.public) {
|
|
6778
|
-
const { buildConductorCard } = await import("../../card-
|
|
7139
|
+
const { buildConductorCard } = await import("../../card-U2HQRPYN.js");
|
|
6779
7140
|
const conductorCard = attachCanonicalAgentId(
|
|
6780
7141
|
this.runtime.registryDb,
|
|
6781
7142
|
buildConductorCard(this.config.owner)
|
|
@@ -6852,7 +7213,7 @@ var ServiceCoordinator = class {
|
|
|
6852
7213
|
}
|
|
6853
7214
|
if (opts.registryUrl && opts.relay) {
|
|
6854
7215
|
const { RelayClient: RelayClient2 } = await import("../../websocket-client-RT4KLJL4.js");
|
|
6855
|
-
const { executeCapabilityRequest: executeCapabilityRequest2 } = await import("../../execute-
|
|
7216
|
+
const { executeCapabilityRequest: executeCapabilityRequest2 } = await import("../../execute-YBNCDAOX.js");
|
|
6856
7217
|
const localCards = listCards(this.runtime.registryDb, this.config.owner);
|
|
6857
7218
|
const { primaryCard, additionalCards } = buildRelayRegistrationCards(this.config.owner, localCards);
|
|
6858
7219
|
if (this.config.conductor?.public) {
|
|
@@ -7113,7 +7474,7 @@ function loadPersistedRuntime(configDir) {
|
|
|
7113
7474
|
const runtimePath = join4(configDir, "runtime.json");
|
|
7114
7475
|
if (!existsSync5(runtimePath)) return null;
|
|
7115
7476
|
try {
|
|
7116
|
-
const raw =
|
|
7477
|
+
const raw = readFileSync4(runtimePath, "utf8");
|
|
7117
7478
|
const parsed = JSON.parse(raw);
|
|
7118
7479
|
const nodeExec = parsed["node_exec"];
|
|
7119
7480
|
if (typeof nodeExec !== "string" || nodeExec.trim().length === 0) {
|
|
@@ -7530,7 +7891,7 @@ function isNetworkError(err) {
|
|
|
7530
7891
|
}
|
|
7531
7892
|
|
|
7532
7893
|
// skills/agentbnb/openclaw-tools.ts
|
|
7533
|
-
import { readFileSync as
|
|
7894
|
+
import { readFileSync as readFileSync5, existsSync as existsSync6 } from "fs";
|
|
7534
7895
|
import { join as join5 } from "path";
|
|
7535
7896
|
import { homedir as homedir3 } from "os";
|
|
7536
7897
|
|
|
@@ -8119,7 +8480,7 @@ function buildMcpContext(toolCtx) {
|
|
|
8119
8480
|
`AgentBnB not initialized at ${configDir}. Run \`agentbnb init\` or activate the plugin first.`
|
|
8120
8481
|
);
|
|
8121
8482
|
}
|
|
8122
|
-
const config = JSON.parse(
|
|
8483
|
+
const config = JSON.parse(readFileSync5(configPath, "utf-8"));
|
|
8123
8484
|
const identity = ensureIdentity(configDir, config.owner);
|
|
8124
8485
|
const ctx = { configDir, config, identity };
|
|
8125
8486
|
contextCache.set(configDir, ctx);
|
|
@@ -8358,7 +8719,7 @@ async function runCommand(cmd, env) {
|
|
|
8358
8719
|
return execAsync(cmd, { env });
|
|
8359
8720
|
}
|
|
8360
8721
|
function deriveAgentName(configDir) {
|
|
8361
|
-
const parent =
|
|
8722
|
+
const parent = basename3(dirname4(configDir));
|
|
8362
8723
|
if (parent && parent !== "." && parent !== ".agentbnb" && parent !== homedir4().split("/").pop()) {
|
|
8363
8724
|
return parent;
|
|
8364
8725
|
}
|