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,3 +1,11 @@
|
|
|
1
|
+
import {
|
|
2
|
+
executeCapabilityBatch,
|
|
3
|
+
executeCapabilityRequest,
|
|
4
|
+
notifyProviderEvent
|
|
5
|
+
} from "./chunk-53Q2HHHH.js";
|
|
6
|
+
import {
|
|
7
|
+
StructuredFeedbackSchema
|
|
8
|
+
} from "./chunk-AUBHR7HH.js";
|
|
1
9
|
import {
|
|
2
10
|
ApiSkillConfigSchema,
|
|
3
11
|
parseSkillsFile
|
|
@@ -9,17 +17,13 @@ import {
|
|
|
9
17
|
import {
|
|
10
18
|
interpolateObject
|
|
11
19
|
} from "./chunk-3MJT4PZG.js";
|
|
12
|
-
import {
|
|
13
|
-
executeCapabilityBatch,
|
|
14
|
-
executeCapabilityRequest
|
|
15
|
-
} from "./chunk-3Y76PHEY.js";
|
|
16
|
-
import {
|
|
17
|
-
StructuredFeedbackSchema
|
|
18
|
-
} from "./chunk-AUBHR7HH.js";
|
|
19
20
|
import {
|
|
20
21
|
announceGateway,
|
|
21
22
|
stopAnnouncement
|
|
22
23
|
} from "./chunk-TA73FIZU.js";
|
|
24
|
+
import {
|
|
25
|
+
syncCreditsFromRegistry
|
|
26
|
+
} from "./chunk-KKFP5Y2Z.js";
|
|
23
27
|
import {
|
|
24
28
|
resolveSelfCli
|
|
25
29
|
} from "./chunk-7S4ZLFVI.js";
|
|
@@ -28,34 +32,32 @@ import {
|
|
|
28
32
|
buildDraftCard,
|
|
29
33
|
detectApiKeys,
|
|
30
34
|
getPricingStats
|
|
31
|
-
} from "./chunk-
|
|
35
|
+
} from "./chunk-UPWAXWY2.js";
|
|
36
|
+
import {
|
|
37
|
+
createLedger,
|
|
38
|
+
identityAuthPlugin,
|
|
39
|
+
tryVerifyIdentity
|
|
40
|
+
} from "./chunk-Z7XWQ63B.js";
|
|
41
|
+
import {
|
|
42
|
+
deriveAgentId
|
|
43
|
+
} from "./chunk-AA25Z6FW.js";
|
|
32
44
|
import {
|
|
33
45
|
listPendingRequests,
|
|
34
46
|
resolvePendingRequest
|
|
35
47
|
} from "./chunk-5PV5YCSN.js";
|
|
48
|
+
import "./chunk-FK54LVDR.js";
|
|
49
|
+
import "./chunk-ELFGYC22.js";
|
|
36
50
|
import {
|
|
37
51
|
DEFAULT_AUTONOMY_CONFIG,
|
|
38
52
|
getAutonomyTier,
|
|
39
53
|
insertAuditEvent
|
|
40
54
|
} from "./chunk-G5WKW3ED.js";
|
|
41
|
-
import {
|
|
42
|
-
syncCreditsFromRegistry
|
|
43
|
-
} from "./chunk-ZYOMPJGG.js";
|
|
44
|
-
import {
|
|
45
|
-
createLedger,
|
|
46
|
-
identityAuthPlugin
|
|
47
|
-
} from "./chunk-LENX5NUW.js";
|
|
48
|
-
import {
|
|
49
|
-
deriveAgentId
|
|
50
|
-
} from "./chunk-5CC6O6SO.js";
|
|
51
|
-
import "./chunk-4M6IAIVK.js";
|
|
52
|
-
import "./chunk-ELFGYC22.js";
|
|
53
55
|
import {
|
|
54
56
|
buildReputationMap,
|
|
55
57
|
computeReputation,
|
|
56
58
|
filterCards,
|
|
57
59
|
searchCards
|
|
58
|
-
} from "./chunk-
|
|
60
|
+
} from "./chunk-EC6DIVE5.js";
|
|
59
61
|
import {
|
|
60
62
|
NETWORK_FEE_RATE,
|
|
61
63
|
bootstrapAgent,
|
|
@@ -70,25 +72,6 @@ import {
|
|
|
70
72
|
releaseEscrow,
|
|
71
73
|
settleEscrow
|
|
72
74
|
} from "./chunk-D7NH6YLM.js";
|
|
73
|
-
import {
|
|
74
|
-
RelayMessageSchema,
|
|
75
|
-
SESSION_MESSAGE_TYPES,
|
|
76
|
-
SessionEndMessageSchema,
|
|
77
|
-
SessionMessageMessageSchema,
|
|
78
|
-
SessionOpenMessageSchema,
|
|
79
|
-
loadSessionConfig
|
|
80
|
-
} from "./chunk-Q5OFZ2JR.js";
|
|
81
|
-
import {
|
|
82
|
-
loadCoreConfig
|
|
83
|
-
} from "./chunk-QXRNW4OJ.js";
|
|
84
|
-
import {
|
|
85
|
-
generateKeyPair,
|
|
86
|
-
verifyEscrowReceipt
|
|
87
|
-
} from "./chunk-YNBZLXYS.js";
|
|
88
|
-
import "./chunk-YDGXKH2T.js";
|
|
89
|
-
import {
|
|
90
|
-
getConfigDir
|
|
91
|
-
} from "./chunk-3XPBFF6H.js";
|
|
92
75
|
import {
|
|
93
76
|
attachCanonicalAgentId,
|
|
94
77
|
getCard,
|
|
@@ -105,12 +88,34 @@ import {
|
|
|
105
88
|
updateCard,
|
|
106
89
|
updateSkillAvailability,
|
|
107
90
|
updateSkillIdleRate
|
|
108
|
-
} from "./chunk-
|
|
91
|
+
} from "./chunk-C56X7EFJ.js";
|
|
92
|
+
import {
|
|
93
|
+
emitProviderEvent
|
|
94
|
+
} from "./chunk-GZUTU6IZ.js";
|
|
95
|
+
import {
|
|
96
|
+
RelayMessageSchema,
|
|
97
|
+
SESSION_MESSAGE_TYPES,
|
|
98
|
+
SessionEndMessageSchema,
|
|
99
|
+
SessionMessageMessageSchema,
|
|
100
|
+
SessionOpenMessageSchema,
|
|
101
|
+
loadSessionConfig
|
|
102
|
+
} from "./chunk-Q5OFZ2JR.js";
|
|
103
|
+
import {
|
|
104
|
+
loadCoreConfig
|
|
105
|
+
} from "./chunk-QXRNW4OJ.js";
|
|
106
|
+
import {
|
|
107
|
+
generateKeyPair,
|
|
108
|
+
verifyEscrowReceipt
|
|
109
|
+
} from "./chunk-65GNX2KC.js";
|
|
110
|
+
import "./chunk-YDGXKH2T.js";
|
|
109
111
|
import "./chunk-J4RFJVXI.js";
|
|
110
112
|
import {
|
|
111
113
|
AgentBnBError,
|
|
112
114
|
AnyCardSchema
|
|
113
115
|
} from "./chunk-UVCNMRPS.js";
|
|
116
|
+
import {
|
|
117
|
+
getConfigDir
|
|
118
|
+
} from "./chunk-3XPBFF6H.js";
|
|
114
119
|
import {
|
|
115
120
|
getActivityFeed,
|
|
116
121
|
getRequestLog,
|
|
@@ -120,7 +125,7 @@ import {
|
|
|
120
125
|
import "./chunk-3RG5ZIWI.js";
|
|
121
126
|
|
|
122
127
|
// src/runtime/agent-runtime.ts
|
|
123
|
-
import { readFileSync, existsSync } from "fs";
|
|
128
|
+
import { readFileSync as readFileSync2, existsSync } from "fs";
|
|
124
129
|
|
|
125
130
|
// src/skills/executor.ts
|
|
126
131
|
function buildTimeoutError(skillId, timeoutMs) {
|
|
@@ -775,7 +780,30 @@ var OpenClawBridge = class {
|
|
|
775
780
|
|
|
776
781
|
// src/skills/command-executor.ts
|
|
777
782
|
import { spawn } from "child_process";
|
|
783
|
+
import { readFileSync, statSync } from "fs";
|
|
784
|
+
import { basename, extname } from "path";
|
|
778
785
|
var KILL_GRACE_MS = 5e3;
|
|
786
|
+
var MAX_INLINE_FILE_BYTES = 5 * 1024 * 1024;
|
|
787
|
+
var MIME_TYPES = {
|
|
788
|
+
".mp3": "audio/mpeg",
|
|
789
|
+
".wav": "audio/wav",
|
|
790
|
+
".ogg": "audio/ogg",
|
|
791
|
+
".m4a": "audio/mp4",
|
|
792
|
+
".pdf": "application/pdf",
|
|
793
|
+
".png": "image/png",
|
|
794
|
+
".jpg": "image/jpeg",
|
|
795
|
+
".jpeg": "image/jpeg",
|
|
796
|
+
".gif": "image/gif",
|
|
797
|
+
".webp": "image/webp",
|
|
798
|
+
".svg": "image/svg+xml",
|
|
799
|
+
".json": "application/json",
|
|
800
|
+
".txt": "text/plain",
|
|
801
|
+
".md": "text/markdown",
|
|
802
|
+
".csv": "text/csv"
|
|
803
|
+
};
|
|
804
|
+
function guessMimeType(filePath) {
|
|
805
|
+
return MIME_TYPES[extname(filePath).toLowerCase()] ?? "application/octet-stream";
|
|
806
|
+
}
|
|
779
807
|
function shellEscape2(value) {
|
|
780
808
|
return "'" + value.replace(/'/g, "'\\''") + "'";
|
|
781
809
|
}
|
|
@@ -991,8 +1019,34 @@ var CommandExecutor = class {
|
|
|
991
1019
|
};
|
|
992
1020
|
}
|
|
993
1021
|
}
|
|
994
|
-
case "file":
|
|
995
|
-
|
|
1022
|
+
case "file": {
|
|
1023
|
+
try {
|
|
1024
|
+
const stats = statSync(rawOutput);
|
|
1025
|
+
if (stats.size > MAX_INLINE_FILE_BYTES) {
|
|
1026
|
+
return {
|
|
1027
|
+
success: false,
|
|
1028
|
+
error: `File too large for inline return: ${stats.size} bytes (max ${MAX_INLINE_FILE_BYTES})`
|
|
1029
|
+
};
|
|
1030
|
+
}
|
|
1031
|
+
const buffer = readFileSync(rawOutput);
|
|
1032
|
+
return {
|
|
1033
|
+
success: true,
|
|
1034
|
+
result: {
|
|
1035
|
+
file: {
|
|
1036
|
+
name: basename(rawOutput),
|
|
1037
|
+
mime_type: guessMimeType(rawOutput),
|
|
1038
|
+
size_bytes: stats.size,
|
|
1039
|
+
data_base64: buffer.toString("base64")
|
|
1040
|
+
},
|
|
1041
|
+
// Keep file_path for backward compat (local workflows)
|
|
1042
|
+
file_path: rawOutput
|
|
1043
|
+
}
|
|
1044
|
+
};
|
|
1045
|
+
} catch (err) {
|
|
1046
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
1047
|
+
return { success: false, error: `Failed to read file "${rawOutput}": ${msg}` };
|
|
1048
|
+
}
|
|
1049
|
+
}
|
|
996
1050
|
default:
|
|
997
1051
|
return {
|
|
998
1052
|
success: false,
|
|
@@ -1121,13 +1175,13 @@ var AgentRuntime = class {
|
|
|
1121
1175
|
}
|
|
1122
1176
|
let configs = [];
|
|
1123
1177
|
if (hasSkillsYaml) {
|
|
1124
|
-
const yamlContent =
|
|
1178
|
+
const yamlContent = readFileSync2(this.skillsYamlPath, "utf8");
|
|
1125
1179
|
configs = parseSkillsFile(yamlContent);
|
|
1126
1180
|
}
|
|
1127
1181
|
const modes = /* @__PURE__ */ new Map();
|
|
1128
1182
|
if (this.conductorEnabled) {
|
|
1129
|
-
const { ConductorMode } = await import("./conductor-mode-
|
|
1130
|
-
const { registerConductorCard, CONDUCTOR_OWNER } = await import("./card-
|
|
1183
|
+
const { ConductorMode } = await import("./conductor-mode-PFO2VLH6.js");
|
|
1184
|
+
const { registerConductorCard, CONDUCTOR_OWNER } = await import("./card-VVXNKHDX.js");
|
|
1131
1185
|
const { loadPeers } = await import("./peers-7BMU2775.js");
|
|
1132
1186
|
registerConductorCard(this.registryDb);
|
|
1133
1187
|
const resolveAgentUrl = (owner) => {
|
|
@@ -2006,12 +2060,14 @@ var SessionManager = class {
|
|
|
2006
2060
|
escrow;
|
|
2007
2061
|
config;
|
|
2008
2062
|
sendToAgent;
|
|
2063
|
+
registryDb;
|
|
2009
2064
|
/** Maps agent connection key → set of session IDs they participate in. */
|
|
2010
2065
|
agentSessions = /* @__PURE__ */ new Map();
|
|
2011
2066
|
constructor(opts) {
|
|
2012
2067
|
this.escrow = new SessionEscrow(opts.creditDb);
|
|
2013
2068
|
this.config = opts.config ?? loadSessionConfig();
|
|
2014
2069
|
this.sendToAgent = opts.sendToAgent;
|
|
2070
|
+
this.registryDb = opts.registryDb ?? null;
|
|
2015
2071
|
}
|
|
2016
2072
|
/**
|
|
2017
2073
|
* Open a new session between requester and provider.
|
|
@@ -2070,6 +2126,15 @@ var SessionManager = class {
|
|
|
2070
2126
|
}
|
|
2071
2127
|
this.resetIdleTimer(session.id);
|
|
2072
2128
|
this.startDurationTimer(session.id);
|
|
2129
|
+
this.emitEvent({
|
|
2130
|
+
event_type: "session.opened",
|
|
2131
|
+
skill_id: session.skill_id,
|
|
2132
|
+
session_id: session.id,
|
|
2133
|
+
requester: session.requester_id,
|
|
2134
|
+
credits: session.budget,
|
|
2135
|
+
duration_ms: 0,
|
|
2136
|
+
metadata: { engine: "session", pricing_model: session.pricing_model }
|
|
2137
|
+
});
|
|
2073
2138
|
return session;
|
|
2074
2139
|
}
|
|
2075
2140
|
/**
|
|
@@ -2130,6 +2195,15 @@ var SessionManager = class {
|
|
|
2130
2195
|
content: msg.content,
|
|
2131
2196
|
metadata: msg.metadata
|
|
2132
2197
|
});
|
|
2198
|
+
this.emitEvent({
|
|
2199
|
+
event_type: "session.message",
|
|
2200
|
+
skill_id: session.skill_id,
|
|
2201
|
+
session_id: session.id,
|
|
2202
|
+
requester: session.requester_id,
|
|
2203
|
+
credits: session.spent,
|
|
2204
|
+
duration_ms: Date.now() - new Date(session.created_at).getTime(),
|
|
2205
|
+
metadata: { message_count: session.messages.length, running_cost: session.spent, sender: msg.sender }
|
|
2206
|
+
});
|
|
2133
2207
|
this.resetIdleTimer(session.id);
|
|
2134
2208
|
}
|
|
2135
2209
|
/**
|
|
@@ -2173,6 +2247,19 @@ var SessionManager = class {
|
|
|
2173
2247
|
this.durationTimers.clear();
|
|
2174
2248
|
}
|
|
2175
2249
|
// -------------------------------------------------------------------------
|
|
2250
|
+
// Event emission
|
|
2251
|
+
// -------------------------------------------------------------------------
|
|
2252
|
+
/** Emit a provider event + Telegram notification. Silently no-ops on failure. */
|
|
2253
|
+
emitEvent(event) {
|
|
2254
|
+
if (!this.registryDb) return;
|
|
2255
|
+
try {
|
|
2256
|
+
const emitted = emitProviderEvent(this.registryDb, event);
|
|
2257
|
+
notifyProviderEvent(emitted).catch(() => {
|
|
2258
|
+
});
|
|
2259
|
+
} catch {
|
|
2260
|
+
}
|
|
2261
|
+
}
|
|
2262
|
+
// -------------------------------------------------------------------------
|
|
2176
2263
|
// Internal helpers
|
|
2177
2264
|
// -------------------------------------------------------------------------
|
|
2178
2265
|
endSessionInternal(session, reason) {
|
|
@@ -2196,6 +2283,27 @@ var SessionManager = class {
|
|
|
2196
2283
|
};
|
|
2197
2284
|
session.status = "settled";
|
|
2198
2285
|
session.updated_at = (/* @__PURE__ */ new Date()).toISOString();
|
|
2286
|
+
const isFailed = reason === "error";
|
|
2287
|
+
const eventMetadata = {
|
|
2288
|
+
total_messages: session.messages.length,
|
|
2289
|
+
reason,
|
|
2290
|
+
refunded: session.budget - session.spent
|
|
2291
|
+
};
|
|
2292
|
+
if (isFailed) {
|
|
2293
|
+
eventMetadata["last_messages"] = session.messages.slice(-3).map((m) => ({
|
|
2294
|
+
sender: m.sender,
|
|
2295
|
+
content: m.content.slice(0, 200)
|
|
2296
|
+
}));
|
|
2297
|
+
}
|
|
2298
|
+
this.emitEvent({
|
|
2299
|
+
event_type: isFailed ? "session.failed" : "session.ended",
|
|
2300
|
+
skill_id: session.skill_id,
|
|
2301
|
+
session_id: session.id,
|
|
2302
|
+
requester: session.requester_id,
|
|
2303
|
+
credits: session.spent,
|
|
2304
|
+
duration_ms: durationMs,
|
|
2305
|
+
metadata: eventMetadata
|
|
2306
|
+
});
|
|
2199
2307
|
this.sendToAgent(session.requester_id, settledMsg);
|
|
2200
2308
|
this.sendToAgent(session.provider_id, settledMsg);
|
|
2201
2309
|
session.status = "closed";
|
|
@@ -3158,6 +3266,75 @@ function initiateGithubAuth() {
|
|
|
3158
3266
|
};
|
|
3159
3267
|
}
|
|
3160
3268
|
|
|
3269
|
+
// src/registry/hub-identities.ts
|
|
3270
|
+
import { randomBytes as randomBytes2, createHash } from "crypto";
|
|
3271
|
+
var HUB_IDENTITIES_SCHEMA = `
|
|
3272
|
+
CREATE TABLE IF NOT EXISTS hub_identities (
|
|
3273
|
+
email TEXT PRIMARY KEY,
|
|
3274
|
+
agent_id TEXT NOT NULL UNIQUE,
|
|
3275
|
+
public_key TEXT NOT NULL,
|
|
3276
|
+
encrypted_private_key TEXT NOT NULL,
|
|
3277
|
+
kdf_salt TEXT NOT NULL,
|
|
3278
|
+
display_name TEXT NOT NULL,
|
|
3279
|
+
created_at TEXT NOT NULL
|
|
3280
|
+
);
|
|
3281
|
+
|
|
3282
|
+
CREATE INDEX IF NOT EXISTS idx_hub_identities_agent_id
|
|
3283
|
+
ON hub_identities(agent_id);
|
|
3284
|
+
`;
|
|
3285
|
+
var CHALLENGES_SCHEMA = `
|
|
3286
|
+
CREATE TABLE IF NOT EXISTS hub_challenges (
|
|
3287
|
+
challenge TEXT PRIMARY KEY,
|
|
3288
|
+
expires_at TEXT NOT NULL,
|
|
3289
|
+
consumed_at TEXT
|
|
3290
|
+
);
|
|
3291
|
+
`;
|
|
3292
|
+
function ensureHubIdentitiesTables(db) {
|
|
3293
|
+
db.exec(HUB_IDENTITIES_SCHEMA);
|
|
3294
|
+
db.exec(CHALLENGES_SCHEMA);
|
|
3295
|
+
}
|
|
3296
|
+
function deriveAgentId2(publicKeyHex) {
|
|
3297
|
+
const hash = createHash("sha256").update(publicKeyHex, "hex").digest("hex");
|
|
3298
|
+
return `agent-${hash.slice(0, 16)}`;
|
|
3299
|
+
}
|
|
3300
|
+
var CHALLENGE_TTL_MS = 10 * 60 * 1e3;
|
|
3301
|
+
function createChallenge(db) {
|
|
3302
|
+
const challenge = randomBytes2(32).toString("hex");
|
|
3303
|
+
const expires_at = new Date(Date.now() + CHALLENGE_TTL_MS).toISOString();
|
|
3304
|
+
db.prepare("INSERT INTO hub_challenges (challenge, expires_at) VALUES (?, ?)").run(challenge, expires_at);
|
|
3305
|
+
return { challenge, expires_at };
|
|
3306
|
+
}
|
|
3307
|
+
function consumeChallenge(db, challenge) {
|
|
3308
|
+
const row = db.prepare("SELECT expires_at, consumed_at FROM hub_challenges WHERE challenge = ?").get(challenge);
|
|
3309
|
+
if (!row) return false;
|
|
3310
|
+
if (row.consumed_at) return false;
|
|
3311
|
+
if (new Date(row.expires_at).getTime() < Date.now()) return false;
|
|
3312
|
+
const consumed_at = (/* @__PURE__ */ new Date()).toISOString();
|
|
3313
|
+
db.prepare("UPDATE hub_challenges SET consumed_at = ? WHERE challenge = ?").run(consumed_at, challenge);
|
|
3314
|
+
return true;
|
|
3315
|
+
}
|
|
3316
|
+
function pruneChallenges(db) {
|
|
3317
|
+
const cutoff = new Date(Date.now() - 24 * 60 * 60 * 1e3).toISOString();
|
|
3318
|
+
db.prepare("DELETE FROM hub_challenges WHERE expires_at < ? OR consumed_at IS NOT NULL").run(cutoff);
|
|
3319
|
+
}
|
|
3320
|
+
function registerHubIdentity(db, input) {
|
|
3321
|
+
const agent_id = deriveAgentId2(input.public_key);
|
|
3322
|
+
const created_at = (/* @__PURE__ */ new Date()).toISOString();
|
|
3323
|
+
db.prepare(`
|
|
3324
|
+
INSERT INTO hub_identities (email, agent_id, public_key, encrypted_private_key, kdf_salt, display_name, created_at)
|
|
3325
|
+
VALUES (?, ?, ?, ?, ?, ?, ?)
|
|
3326
|
+
`).run(input.email, agent_id, input.public_key, input.encrypted_private_key, input.kdf_salt, input.display_name, created_at);
|
|
3327
|
+
return { ...input, agent_id, created_at };
|
|
3328
|
+
}
|
|
3329
|
+
function getHubIdentityByEmail(db, email) {
|
|
3330
|
+
const row = db.prepare("SELECT * FROM hub_identities WHERE email = ?").get(email);
|
|
3331
|
+
return row ?? null;
|
|
3332
|
+
}
|
|
3333
|
+
function getHubIdentityByAgentId(db, agent_id) {
|
|
3334
|
+
const row = db.prepare("SELECT * FROM hub_identities WHERE agent_id = ?").get(agent_id);
|
|
3335
|
+
return row ?? null;
|
|
3336
|
+
}
|
|
3337
|
+
|
|
3161
3338
|
// src/registry/free-tier.ts
|
|
3162
3339
|
function initFreeTierTable(db) {
|
|
3163
3340
|
db.exec(`
|
|
@@ -5166,6 +5343,121 @@ function createRegistryServer(opts) {
|
|
|
5166
5343
|
throw err;
|
|
5167
5344
|
}
|
|
5168
5345
|
});
|
|
5346
|
+
ensureHubIdentitiesTables(db);
|
|
5347
|
+
try {
|
|
5348
|
+
pruneChallenges(db);
|
|
5349
|
+
} catch {
|
|
5350
|
+
}
|
|
5351
|
+
api.get("/api/agents/challenge", {
|
|
5352
|
+
schema: {
|
|
5353
|
+
tags: ["hub-auth"],
|
|
5354
|
+
summary: "Get a registration challenge",
|
|
5355
|
+
response: {
|
|
5356
|
+
200: {
|
|
5357
|
+
type: "object",
|
|
5358
|
+
properties: {
|
|
5359
|
+
challenge: { type: "string" },
|
|
5360
|
+
expires_at: { type: "string" }
|
|
5361
|
+
}
|
|
5362
|
+
}
|
|
5363
|
+
}
|
|
5364
|
+
}
|
|
5365
|
+
}, async (_request, reply) => {
|
|
5366
|
+
const { challenge, expires_at } = createChallenge(db);
|
|
5367
|
+
return reply.send({ challenge, expires_at });
|
|
5368
|
+
});
|
|
5369
|
+
api.post("/api/agents/register", {
|
|
5370
|
+
schema: {
|
|
5371
|
+
tags: ["hub-auth"],
|
|
5372
|
+
summary: "Register a new Hub-managed agent identity",
|
|
5373
|
+
body: {
|
|
5374
|
+
type: "object",
|
|
5375
|
+
required: ["email", "public_key", "encrypted_private_key", "kdf_salt", "display_name", "challenge", "signature"],
|
|
5376
|
+
properties: {
|
|
5377
|
+
email: { type: "string", format: "email" },
|
|
5378
|
+
public_key: { type: "string" },
|
|
5379
|
+
encrypted_private_key: { type: "string" },
|
|
5380
|
+
kdf_salt: { type: "string" },
|
|
5381
|
+
display_name: { type: "string" },
|
|
5382
|
+
challenge: { type: "string" },
|
|
5383
|
+
signature: { type: "string" }
|
|
5384
|
+
}
|
|
5385
|
+
},
|
|
5386
|
+
response: {
|
|
5387
|
+
201: { type: "object", additionalProperties: true },
|
|
5388
|
+
400: { type: "object", properties: { error: { type: "string" } } },
|
|
5389
|
+
409: { type: "object", properties: { error: { type: "string" } } }
|
|
5390
|
+
}
|
|
5391
|
+
}
|
|
5392
|
+
}, async (request, reply) => {
|
|
5393
|
+
const body = request.body;
|
|
5394
|
+
if (!consumeChallenge(db, body.challenge)) {
|
|
5395
|
+
return reply.code(400).send({ error: "Invalid or expired challenge" });
|
|
5396
|
+
}
|
|
5397
|
+
if (!/^[0-9a-fA-F]+$/.test(body.public_key) || body.public_key.length % 2 !== 0) {
|
|
5398
|
+
return reply.code(400).send({ error: "Invalid public_key format" });
|
|
5399
|
+
}
|
|
5400
|
+
try {
|
|
5401
|
+
const { verifyEscrowReceipt: verifyEscrowReceipt2 } = await import("./signing-AQTKYJDB.js");
|
|
5402
|
+
const publicKeyBuffer = Buffer.from(body.public_key, "hex");
|
|
5403
|
+
const valid = verifyEscrowReceipt2({ challenge: body.challenge }, body.signature, publicKeyBuffer);
|
|
5404
|
+
if (!valid) {
|
|
5405
|
+
return reply.code(400).send({ error: "Invalid signature" });
|
|
5406
|
+
}
|
|
5407
|
+
} catch (err) {
|
|
5408
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
5409
|
+
return reply.code(400).send({ error: `Signature verification failed: ${msg}` });
|
|
5410
|
+
}
|
|
5411
|
+
const existing = getHubIdentityByEmail(db, body.email.toLowerCase());
|
|
5412
|
+
if (existing) {
|
|
5413
|
+
return reply.code(409).send({ error: "Email already registered" });
|
|
5414
|
+
}
|
|
5415
|
+
const agent_id = deriveAgentId2(body.public_key);
|
|
5416
|
+
const existingByAgentId = getHubIdentityByAgentId(db, agent_id);
|
|
5417
|
+
if (existingByAgentId) {
|
|
5418
|
+
return reply.code(409).send({ error: "Agent already registered" });
|
|
5419
|
+
}
|
|
5420
|
+
const identity = registerHubIdentity(db, {
|
|
5421
|
+
email: body.email.toLowerCase(),
|
|
5422
|
+
public_key: body.public_key,
|
|
5423
|
+
encrypted_private_key: body.encrypted_private_key,
|
|
5424
|
+
kdf_salt: body.kdf_salt,
|
|
5425
|
+
display_name: body.display_name
|
|
5426
|
+
});
|
|
5427
|
+
return reply.code(201).send({
|
|
5428
|
+
agent_id: identity.agent_id,
|
|
5429
|
+
did: `did:agentbnb:${identity.agent_id}`,
|
|
5430
|
+
created_at: identity.created_at
|
|
5431
|
+
});
|
|
5432
|
+
});
|
|
5433
|
+
api.post("/api/agents/login", {
|
|
5434
|
+
schema: {
|
|
5435
|
+
tags: ["hub-auth"],
|
|
5436
|
+
summary: "Fetch encrypted identity blob for login",
|
|
5437
|
+
body: {
|
|
5438
|
+
type: "object",
|
|
5439
|
+
required: ["email"],
|
|
5440
|
+
properties: { email: { type: "string", format: "email" } }
|
|
5441
|
+
},
|
|
5442
|
+
response: {
|
|
5443
|
+
200: { type: "object", additionalProperties: true },
|
|
5444
|
+
404: { type: "object", properties: { error: { type: "string" } } }
|
|
5445
|
+
}
|
|
5446
|
+
}
|
|
5447
|
+
}, async (request, reply) => {
|
|
5448
|
+
const body = request.body;
|
|
5449
|
+
const identity = getHubIdentityByEmail(db, body.email.toLowerCase());
|
|
5450
|
+
if (!identity) {
|
|
5451
|
+
return reply.code(404).send({ error: "Identity not found" });
|
|
5452
|
+
}
|
|
5453
|
+
return reply.send({
|
|
5454
|
+
agent_id: identity.agent_id,
|
|
5455
|
+
public_key: identity.public_key,
|
|
5456
|
+
encrypted_private_key: identity.encrypted_private_key,
|
|
5457
|
+
kdf_salt: identity.kdf_salt,
|
|
5458
|
+
display_name: identity.display_name
|
|
5459
|
+
});
|
|
5460
|
+
});
|
|
5169
5461
|
api.post("/api/identity/link", {
|
|
5170
5462
|
schema: {
|
|
5171
5463
|
tags: ["identity"],
|
|
@@ -5465,7 +5757,7 @@ function createRegistryServer(opts) {
|
|
|
5465
5757
|
});
|
|
5466
5758
|
await relayClient.connect();
|
|
5467
5759
|
}
|
|
5468
|
-
const { requestViaRelay } = await import("./client-
|
|
5760
|
+
const { requestViaRelay } = await import("./client-KL67WZVJ.js");
|
|
5469
5761
|
return requestViaRelay(relayClient, {
|
|
5470
5762
|
targetOwner: target.owner,
|
|
5471
5763
|
cardId: target.cardId,
|
|
@@ -5484,12 +5776,24 @@ function createRegistryServer(opts) {
|
|
|
5484
5776
|
const ownerApiKey = opts.ownerApiKey;
|
|
5485
5777
|
const ownerName = opts.ownerName;
|
|
5486
5778
|
void api.register(async (ownerRoutes) => {
|
|
5487
|
-
ownerRoutes.addHook("
|
|
5779
|
+
ownerRoutes.addHook("preHandler", async (request, reply) => {
|
|
5488
5780
|
const auth = request.headers.authorization;
|
|
5489
5781
|
const token = auth?.startsWith("Bearer ") ? auth.slice(7).trim() : null;
|
|
5490
|
-
if (
|
|
5491
|
-
|
|
5782
|
+
if (token === ownerApiKey) {
|
|
5783
|
+
request.agentId = ownerName;
|
|
5784
|
+
return;
|
|
5785
|
+
}
|
|
5786
|
+
const didResult = await tryVerifyIdentity(request, {});
|
|
5787
|
+
if (didResult.valid) {
|
|
5788
|
+
const hubIdentity = getHubIdentityByAgentId(db, didResult.agentId);
|
|
5789
|
+
if (!hubIdentity) {
|
|
5790
|
+
return reply.status(401).send({ error: "Agent not registered on this Hub" });
|
|
5791
|
+
}
|
|
5792
|
+
request.agentId = didResult.agentId;
|
|
5793
|
+
request.agentPublicKey = didResult.publicKey;
|
|
5794
|
+
return;
|
|
5492
5795
|
}
|
|
5796
|
+
return reply.status(401).send({ error: "Unauthorized" });
|
|
5493
5797
|
});
|
|
5494
5798
|
ownerRoutes.get("/me", {
|
|
5495
5799
|
schema: {
|
|
@@ -5500,13 +5804,14 @@ function createRegistryServer(opts) {
|
|
|
5500
5804
|
200: { type: "object", properties: { owner: { type: "string" }, balance: { type: "number" } } }
|
|
5501
5805
|
}
|
|
5502
5806
|
}
|
|
5503
|
-
}, async (
|
|
5807
|
+
}, async (request, reply) => {
|
|
5808
|
+
const identity = request.agentId ?? ownerName;
|
|
5504
5809
|
let balance = 0;
|
|
5505
5810
|
if (opts.creditDb) {
|
|
5506
5811
|
const ledger = createLedger({ db: opts.creditDb });
|
|
5507
|
-
balance = await ledger.getBalance(
|
|
5812
|
+
balance = await ledger.getBalance(identity);
|
|
5508
5813
|
}
|
|
5509
|
-
return reply.send({ owner:
|
|
5814
|
+
return reply.send({ owner: identity, balance });
|
|
5510
5815
|
});
|
|
5511
5816
|
ownerRoutes.get("/requests", {
|
|
5512
5817
|
schema: {
|
|
@@ -5693,6 +5998,62 @@ function createRegistryServer(opts) {
|
|
|
5693
5998
|
const items = await ledger.getHistory(ownerName, limit);
|
|
5694
5999
|
return reply.send({ items, limit });
|
|
5695
6000
|
});
|
|
6001
|
+
ownerRoutes.get("/me/events", {
|
|
6002
|
+
schema: {
|
|
6003
|
+
tags: ["owner"],
|
|
6004
|
+
summary: "Provider event stream",
|
|
6005
|
+
security: [{ bearerAuth: [] }],
|
|
6006
|
+
querystring: {
|
|
6007
|
+
type: "object",
|
|
6008
|
+
properties: {
|
|
6009
|
+
limit: { type: "integer", description: "Max entries (default 50)" },
|
|
6010
|
+
since: { type: "string", description: "ISO timestamp for cursor-based polling" },
|
|
6011
|
+
event_type: { type: "string", description: "Filter by event type" }
|
|
6012
|
+
}
|
|
6013
|
+
}
|
|
6014
|
+
}
|
|
6015
|
+
}, async (request, reply) => {
|
|
6016
|
+
const { getProviderEvents: getEvents } = await import("./provider-events-GTTJPYHS.js");
|
|
6017
|
+
const query = request.query;
|
|
6018
|
+
const limit = query.limit ? parseInt(query.limit, 10) : void 0;
|
|
6019
|
+
const events = getEvents(db, {
|
|
6020
|
+
limit,
|
|
6021
|
+
since: query.since,
|
|
6022
|
+
event_type: query.event_type
|
|
6023
|
+
});
|
|
6024
|
+
return reply.send({ events });
|
|
6025
|
+
});
|
|
6026
|
+
ownerRoutes.get("/me/stats", {
|
|
6027
|
+
schema: {
|
|
6028
|
+
tags: ["owner"],
|
|
6029
|
+
summary: "Aggregated provider stats",
|
|
6030
|
+
security: [{ bearerAuth: [] }],
|
|
6031
|
+
querystring: {
|
|
6032
|
+
type: "object",
|
|
6033
|
+
properties: { period: { type: "string", enum: ["24h", "7d", "30d"] } }
|
|
6034
|
+
}
|
|
6035
|
+
}
|
|
6036
|
+
}, async (request, reply) => {
|
|
6037
|
+
const { getProviderStats: getStats } = await import("./provider-events-GTTJPYHS.js");
|
|
6038
|
+
const query = request.query;
|
|
6039
|
+
const period = query.period ?? "7d";
|
|
6040
|
+
const stats = getStats(db, period);
|
|
6041
|
+
if (opts.creditDb) {
|
|
6042
|
+
const periodMs = { "24h": 864e5, "7d": 6048e5, "30d": 2592e6 }[period];
|
|
6043
|
+
const cutoff = new Date(Date.now() - periodMs).toISOString();
|
|
6044
|
+
try {
|
|
6045
|
+
const row = opts.creditDb.prepare(`
|
|
6046
|
+
SELECT COALESCE(SUM(CASE WHEN amount < 0 AND reason IN ('escrow_hold', 'voucher_hold', 'network_fee') THEN -amount ELSE 0 END), 0) as spent
|
|
6047
|
+
FROM credit_transactions
|
|
6048
|
+
WHERE owner = ? AND created_at >= ?
|
|
6049
|
+
`).get(ownerName, cutoff);
|
|
6050
|
+
stats.total_spending = row?.spent ?? 0;
|
|
6051
|
+
stats.net_pnl = stats.total_earnings - stats.total_spending;
|
|
6052
|
+
} catch {
|
|
6053
|
+
}
|
|
6054
|
+
}
|
|
6055
|
+
return reply.send(stats);
|
|
6056
|
+
});
|
|
5696
6057
|
});
|
|
5697
6058
|
}
|
|
5698
6059
|
api.get("/api/providers/:owner/reliability", {
|
|
@@ -5897,7 +6258,7 @@ var IdleMonitor = class {
|
|
|
5897
6258
|
|
|
5898
6259
|
// src/runtime/service-coordinator.ts
|
|
5899
6260
|
import { spawn as spawn2 } from "child_process";
|
|
5900
|
-
import { existsSync as existsSync3, readFileSync as
|
|
6261
|
+
import { existsSync as existsSync3, readFileSync as readFileSync3 } from "fs";
|
|
5901
6262
|
import { join as join2 } from "path";
|
|
5902
6263
|
import { randomUUID as randomUUID8 } from "crypto";
|
|
5903
6264
|
import { Cron as Cron2 } from "croner";
|
|
@@ -6072,7 +6433,7 @@ var ServiceCoordinator = class {
|
|
|
6072
6433
|
console.log("Conductor mode enabled \u2014 orchestrate/plan skills available via gateway");
|
|
6073
6434
|
}
|
|
6074
6435
|
if (opts.conductorEnabled && this.config.conductor?.public) {
|
|
6075
|
-
const { buildConductorCard } = await import("./card-
|
|
6436
|
+
const { buildConductorCard } = await import("./card-VVXNKHDX.js");
|
|
6076
6437
|
const conductorCard = attachCanonicalAgentId(
|
|
6077
6438
|
this.runtime.registryDb,
|
|
6078
6439
|
buildConductorCard(this.config.owner)
|
|
@@ -6149,7 +6510,7 @@ var ServiceCoordinator = class {
|
|
|
6149
6510
|
}
|
|
6150
6511
|
if (opts.registryUrl && opts.relay) {
|
|
6151
6512
|
const { RelayClient } = await import("./websocket-client-FCPZOE4S.js");
|
|
6152
|
-
const { executeCapabilityRequest: executeCapabilityRequest2 } = await import("./execute-
|
|
6513
|
+
const { executeCapabilityRequest: executeCapabilityRequest2 } = await import("./execute-NOQVN7ZG.js");
|
|
6153
6514
|
const localCards = listCards(this.runtime.registryDb, this.config.owner);
|
|
6154
6515
|
const { primaryCard, additionalCards } = buildRelayRegistrationCards(this.config.owner, localCards);
|
|
6155
6516
|
if (this.config.conductor?.public) {
|
|
@@ -6410,7 +6771,7 @@ function loadPersistedRuntime(configDir) {
|
|
|
6410
6771
|
const runtimePath = join2(configDir, "runtime.json");
|
|
6411
6772
|
if (!existsSync3(runtimePath)) return null;
|
|
6412
6773
|
try {
|
|
6413
|
-
const raw =
|
|
6774
|
+
const raw = readFileSync3(runtimePath, "utf8");
|
|
6414
6775
|
const parsed = JSON.parse(raw);
|
|
6415
6776
|
const nodeExec = parsed["node_exec"];
|
|
6416
6777
|
if (typeof nodeExec !== "string" || nodeExec.trim().length === 0) {
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import {
|
|
2
2
|
ensureIdentity
|
|
3
|
-
} from "./chunk-
|
|
4
|
-
import "./chunk-
|
|
3
|
+
} from "./chunk-AA25Z6FW.js";
|
|
4
|
+
import "./chunk-65GNX2KC.js";
|
|
5
|
+
import "./chunk-UVCNMRPS.js";
|
|
5
6
|
import {
|
|
6
7
|
getConfigDir,
|
|
7
8
|
loadConfig
|
|
8
9
|
} from "./chunk-3XPBFF6H.js";
|
|
9
|
-
import "./chunk-UVCNMRPS.js";
|
|
10
10
|
import "./chunk-3RG5ZIWI.js";
|
|
11
11
|
|
|
12
12
|
// src/cli/session-action.ts
|