@agentvault/agentvault 0.9.9 → 0.10.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/__tests__/install-plugin.test.d.ts +2 -0
- package/dist/__tests__/install-plugin.test.d.ts.map +1 -0
- package/dist/openclaw-entry.d.ts.map +1 -1
- package/dist/openclaw-entry.js +154 -18
- package/dist/openclaw-entry.js.map +2 -2
- package/package.json +1 -1
- package/dist/channel.js +0 -2257
- package/dist/channel.js.map +0 -1
- package/dist/crypto-helpers.js +0 -4
- package/dist/crypto-helpers.js.map +0 -1
- package/dist/openclaw-plugin.js +0 -222
- package/dist/openclaw-plugin.js.map +0 -1
- package/dist/setup.js +0 -329
- package/dist/setup.js.map +0 -1
- package/dist/state.js +0 -61
- package/dist/state.js.map +0 -1
- package/dist/transport.js +0 -43
- package/dist/transport.js.map +0 -1
- package/dist/types.js +0 -2
- package/dist/types.js.map +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"install-plugin.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/install-plugin.test.ts"],"names":[],"mappings":""}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"openclaw-entry.d.ts","sourceRoot":"","sources":["../src/openclaw-entry.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;;;;;
|
|
1
|
+
{"version":3,"file":"openclaw-entry.d.ts","sourceRoot":"","sources":["../src/openclaw-entry.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;;;;;kBAoea,GAAG;;AAJnB,wBAQE"}
|
package/dist/openclaw-entry.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
// src/openclaw-entry.ts
|
|
2
2
|
import { resolve } from "node:path";
|
|
3
|
+
import { randomBytes } from "node:crypto";
|
|
3
4
|
var _ocRuntime = null;
|
|
4
5
|
var _channels = /* @__PURE__ */ new Map();
|
|
5
6
|
var _messageQueue = [];
|
|
@@ -29,6 +30,26 @@ function resolveAccount(cfg, accountId) {
|
|
|
29
30
|
}
|
|
30
31
|
async function handleInbound(params) {
|
|
31
32
|
const { plaintext, metadata, channel, account, cfg } = params;
|
|
33
|
+
const startTime = Date.now();
|
|
34
|
+
const traceId = randomBytes(16).toString("hex");
|
|
35
|
+
const rootSpanId = randomBytes(8).toString("hex");
|
|
36
|
+
let replyCount = 0;
|
|
37
|
+
let totalReplyChars = 0;
|
|
38
|
+
let firstReplyTime = null;
|
|
39
|
+
const replySpans = [];
|
|
40
|
+
_emitChildSpan(channel, {
|
|
41
|
+
traceId,
|
|
42
|
+
parentSpanId: rootSpanId,
|
|
43
|
+
name: "ai.agent.message.receive",
|
|
44
|
+
startTime,
|
|
45
|
+
endTime: startTime + 1,
|
|
46
|
+
// instant
|
|
47
|
+
attributes: {
|
|
48
|
+
"ai.agent.message.input_chars": plaintext.length,
|
|
49
|
+
"ai.agent.message.type": metadata.roomId ? "room" : "direct"
|
|
50
|
+
},
|
|
51
|
+
status: "ok"
|
|
52
|
+
});
|
|
32
53
|
try {
|
|
33
54
|
channel.sendTyping();
|
|
34
55
|
} catch {
|
|
@@ -96,27 +117,142 @@ async function handleInbound(params) {
|
|
|
96
117
|
core.error?.(`[AgentVault] session record failed: ${String(err)}`);
|
|
97
118
|
}
|
|
98
119
|
});
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
120
|
+
try {
|
|
121
|
+
await core.channel.reply.dispatchReplyWithBufferedBlockDispatcher({
|
|
122
|
+
ctx: ctxPayload,
|
|
123
|
+
cfg,
|
|
124
|
+
dispatcherOptions: {
|
|
125
|
+
deliver: async (payload) => {
|
|
126
|
+
if (payload.kind === "thinking" || payload.kind === "reasoning") return;
|
|
127
|
+
const text = (payload.text ?? "").trim();
|
|
128
|
+
if (!text) return;
|
|
129
|
+
if (/^(Reasoning|Thinking|Let me think|I need to|Let me check):/i.test(text)) return;
|
|
130
|
+
const replyStart = Date.now();
|
|
131
|
+
replyCount++;
|
|
132
|
+
totalReplyChars += text.length;
|
|
133
|
+
if (!firstReplyTime) firstReplyTime = replyStart;
|
|
134
|
+
if (isRoomMessage) {
|
|
135
|
+
await channel.sendToRoom(metadata.roomId, text);
|
|
136
|
+
} else {
|
|
137
|
+
await channel.send(text, { topicId: metadata.topicId });
|
|
138
|
+
}
|
|
139
|
+
const replyEnd = Date.now();
|
|
140
|
+
replySpans.push({ startTime: replyStart, endTime: replyEnd, chars: text.length, index: replyCount });
|
|
141
|
+
},
|
|
142
|
+
onError: (err, info) => {
|
|
143
|
+
core.error?.(`[AgentVault] ${info?.kind ?? "reply"} error: ${String(err)}`);
|
|
112
144
|
}
|
|
113
145
|
},
|
|
114
|
-
|
|
115
|
-
|
|
146
|
+
replyOptions: {}
|
|
147
|
+
});
|
|
148
|
+
const endTime = Date.now();
|
|
149
|
+
_emitHierarchicalSpans(channel, {
|
|
150
|
+
traceId,
|
|
151
|
+
rootSpanId,
|
|
152
|
+
startTime,
|
|
153
|
+
endTime,
|
|
154
|
+
firstReplyTime,
|
|
155
|
+
replySpans,
|
|
156
|
+
inputChars: plaintext.length,
|
|
157
|
+
replyCount,
|
|
158
|
+
totalReplyChars,
|
|
159
|
+
isRoom: isRoomMessage,
|
|
160
|
+
status: "ok"
|
|
161
|
+
});
|
|
162
|
+
} catch (err) {
|
|
163
|
+
const endTime = Date.now();
|
|
164
|
+
_emitHierarchicalSpans(channel, {
|
|
165
|
+
traceId,
|
|
166
|
+
rootSpanId,
|
|
167
|
+
startTime,
|
|
168
|
+
endTime,
|
|
169
|
+
firstReplyTime,
|
|
170
|
+
replySpans,
|
|
171
|
+
inputChars: plaintext.length,
|
|
172
|
+
replyCount,
|
|
173
|
+
totalReplyChars,
|
|
174
|
+
isRoom: isRoomMessage,
|
|
175
|
+
status: "error",
|
|
176
|
+
statusMessage: String(err)
|
|
177
|
+
});
|
|
178
|
+
throw err;
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
function _emitChildSpan(channel, opts) {
|
|
182
|
+
try {
|
|
183
|
+
const reporter = channel.telemetry;
|
|
184
|
+
if (!reporter) return;
|
|
185
|
+
reporter.reportCustomSpan({
|
|
186
|
+
traceId: opts.traceId,
|
|
187
|
+
spanId: randomBytes(8).toString("hex"),
|
|
188
|
+
parentSpanId: opts.parentSpanId,
|
|
189
|
+
name: opts.name,
|
|
190
|
+
kind: "internal",
|
|
191
|
+
startTime: opts.startTime,
|
|
192
|
+
endTime: opts.endTime,
|
|
193
|
+
attributes: opts.attributes,
|
|
194
|
+
status: {
|
|
195
|
+
code: opts.status === "ok" ? 1 : 2,
|
|
196
|
+
message: opts.statusMessage
|
|
116
197
|
}
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
}
|
|
198
|
+
});
|
|
199
|
+
} catch {
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
function _emitHierarchicalSpans(channel, opts) {
|
|
203
|
+
try {
|
|
204
|
+
const reporter = channel.telemetry;
|
|
205
|
+
if (!reporter) return;
|
|
206
|
+
const inferenceEnd = opts.firstReplyTime ?? opts.endTime;
|
|
207
|
+
_emitChildSpan(channel, {
|
|
208
|
+
traceId: opts.traceId,
|
|
209
|
+
parentSpanId: opts.rootSpanId,
|
|
210
|
+
name: "ai.agent.inference",
|
|
211
|
+
startTime: opts.startTime + 1,
|
|
212
|
+
// just after receive
|
|
213
|
+
endTime: inferenceEnd,
|
|
214
|
+
attributes: {
|
|
215
|
+
"ai.agent.inference.latency_ms": inferenceEnd - opts.startTime,
|
|
216
|
+
"ai.agent.message.input_chars": opts.inputChars
|
|
217
|
+
},
|
|
218
|
+
status: opts.status,
|
|
219
|
+
statusMessage: opts.status === "error" ? opts.statusMessage : void 0
|
|
220
|
+
});
|
|
221
|
+
for (const reply of opts.replySpans) {
|
|
222
|
+
_emitChildSpan(channel, {
|
|
223
|
+
traceId: opts.traceId,
|
|
224
|
+
parentSpanId: opts.rootSpanId,
|
|
225
|
+
name: "ai.agent.reply",
|
|
226
|
+
startTime: reply.startTime,
|
|
227
|
+
endTime: reply.endTime,
|
|
228
|
+
attributes: {
|
|
229
|
+
"ai.agent.reply.index": reply.index,
|
|
230
|
+
"ai.agent.reply.chars": reply.chars
|
|
231
|
+
},
|
|
232
|
+
status: "ok"
|
|
233
|
+
});
|
|
234
|
+
}
|
|
235
|
+
reporter.reportCustomSpan({
|
|
236
|
+
traceId: opts.traceId,
|
|
237
|
+
spanId: opts.rootSpanId,
|
|
238
|
+
name: "ai.agent.message",
|
|
239
|
+
kind: "server",
|
|
240
|
+
startTime: opts.startTime,
|
|
241
|
+
endTime: opts.endTime,
|
|
242
|
+
attributes: {
|
|
243
|
+
"ai.agent.message.input_chars": opts.inputChars,
|
|
244
|
+
"ai.agent.message.reply_count": opts.replyCount,
|
|
245
|
+
"ai.agent.message.reply_chars": opts.totalReplyChars,
|
|
246
|
+
"ai.agent.message.latency_ms": opts.endTime - opts.startTime,
|
|
247
|
+
"ai.agent.message.type": opts.isRoom ? "room" : "direct"
|
|
248
|
+
},
|
|
249
|
+
status: {
|
|
250
|
+
code: opts.status === "ok" ? 1 : 2,
|
|
251
|
+
message: opts.statusMessage
|
|
252
|
+
}
|
|
253
|
+
});
|
|
254
|
+
} catch {
|
|
255
|
+
}
|
|
120
256
|
}
|
|
121
257
|
var agentVaultPlugin = {
|
|
122
258
|
id: "agentvault",
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../src/openclaw-entry.ts"],
|
|
4
|
-
"sourcesContent": ["/**\n * OpenClaw channel plugin entry point.\n *\n * Intentionally thin \u2014 no heavy imports (libsodium etc.) at module load time.\n * SecureChannel is dynamically imported inside gateway.startAccount (already async)\n * so libsodium's top-level await never runs during plugin registration.\n *\n * Loaded by OpenClaw via the `openclaw.extensions` field in package.json.\n */\n\nimport { resolve } from \"node:path\";\n\n// --- Runtime and active channels (set during register) ---\nlet _ocRuntime: any = null;\nconst _channels = new Map<string, any>();\nconst _messageQueue: Array<() => Promise<void>> = [];\n\nfunction _setRuntime(rt: any) {\n _ocRuntime = rt;\n // Flush any messages that arrived before runtime was ready\n if (_messageQueue.length > 0) {\n const pending = _messageQueue.splice(0);\n for (const fn of pending) {\n fn().catch(() => {});\n }\n }\n}\n\n// --- Channel config helpers ---\n\nfunction listAccountIds(cfg: any): string[] {\n return cfg?.channels?.agentvault?.dataDir ? [\"default\"] : [];\n}\n\nfunction resolveAccount(cfg: any, accountId?: string) {\n const av = cfg?.channels?.agentvault ?? {};\n return {\n accountId: accountId ?? \"default\",\n dataDir: av.dataDir ?? \"~/.openclaw/agentvault\",\n apiUrl: av.apiUrl ?? \"https://api.agentvault.chat\",\n agentName: av.agentName ?? \"OpenClaw Agent\",\n httpPort: av.httpPort ?? 18790,\n configured: Boolean(av.dataDir),\n };\n}\n\n// --- Inbound message dispatch ---\n\nasync function handleInbound(params: {\n plaintext: string;\n metadata: any;\n channel: any;\n account: any;\n cfg: any;\n}): Promise<void> {\n const { plaintext, metadata, channel, account, cfg } = params;\n\n // Send typing indicator to owner (non-critical, best-effort)\n try { channel.sendTyping(); } catch { /* ignore */ }\n\n const core = _ocRuntime;\n const isRoomMessage = Boolean(metadata.roomId);\n\n const route = core.channel.routing.resolveAgentRoute({\n cfg,\n channel: \"agentvault\",\n accountId: account.accountId,\n peer: { kind: \"direct\", id: isRoomMessage ? `agentvault:room:${metadata.roomId}` : \"agentvault:owner\" },\n });\n\n const storePath = core.channel.session.resolveStorePath(cfg?.session?.store, {\n agentId: route.agentId,\n });\n\n const envelopeOptions = core.channel.reply.resolveEnvelopeFormatOptions(cfg);\n const previousTimestamp = core.channel.session.readSessionUpdatedAt({\n storePath,\n sessionKey: route.sessionKey,\n });\n\n const body = core.channel.reply.formatAgentEnvelope({\n channel: \"AgentVault\",\n from: isRoomMessage ? \"Room\" : \"Owner\",\n timestamp: new Date(metadata.timestamp).getTime(),\n previousTimestamp,\n envelope: envelopeOptions,\n body: plaintext,\n });\n\n // Build attachment fields for the context payload\n const attachmentFields: Record<string, any> = {};\n if (metadata.attachment) {\n attachmentFields.AttachmentPath = metadata.attachment.filePath;\n attachmentFields.AttachmentFilename = metadata.attachment.filename;\n attachmentFields.AttachmentMime = metadata.attachment.mime;\n\n // For images: include as MediaUrl so the LLM can see the visual content\n if (metadata.attachment.base64) {\n attachmentFields.MediaUrl = metadata.attachment.base64;\n attachmentFields.NumMedia = \"1\";\n }\n\n // For text files: content is already inlined in plaintext body\n }\n\n const ctxPayload = core.channel.reply.finalizeInboundContext({\n Body: body,\n RawBody: plaintext,\n CommandBody: plaintext,\n From: isRoomMessage ? `agentvault:room:${metadata.roomId}` : \"agentvault:owner\",\n To: `agentvault:agent:${account.accountId}`,\n SessionKey: route.sessionKey,\n AccountId: account.accountId,\n ChatType: isRoomMessage ? \"room\" : \"direct\",\n ConversationLabel: isRoomMessage ? \"AgentVault Room\" : \"AgentVault\",\n SenderName: isRoomMessage ? \"Room\" : \"Owner\",\n SenderId: isRoomMessage ? `agentvault:room:${metadata.roomId}` : \"agentvault:owner\",\n Provider: \"agentvault\",\n Surface: \"agentvault\",\n MessageSid: metadata.messageId,\n Timestamp: new Date(metadata.timestamp).getTime(),\n OriginatingChannel: \"agentvault\",\n OriginatingTo: `agentvault:agent:${account.accountId}`,\n CommandAuthorized: true,\n ...attachmentFields,\n });\n\n await core.channel.session.recordInboundSession({\n storePath,\n sessionKey: ctxPayload.SessionKey ?? route.sessionKey,\n ctx: ctxPayload,\n onRecordError: (err: Error) => {\n core.error?.(`[AgentVault] session record failed: ${String(err)}`);\n },\n });\n\n await core.channel.reply.dispatchReplyWithBufferedBlockDispatcher({\n ctx: ctxPayload,\n cfg,\n dispatcherOptions: {\n deliver: async (payload: { text?: string; kind?: string }) => {\n // Filter out thinking/reasoning blocks \u2014 only deliver actual responses\n if (payload.kind === \"thinking\" || payload.kind === \"reasoning\") return;\n const text = (payload.text ?? \"\").trim();\n if (!text) return;\n // Heuristic: skip blocks that look like leaked chain-of-thought\n if (/^(Reasoning|Thinking|Let me think|I need to|Let me check):/i.test(text)) return;\n\n // Route reply: room messages go back to the room, 1:1 goes to owner\n if (isRoomMessage) {\n await channel.sendToRoom(metadata.roomId, text);\n } else {\n await channel.send(text, { topicId: metadata.topicId });\n }\n },\n onError: (err: Error, info?: { kind?: string }) => {\n core.error?.(`[AgentVault] ${info?.kind ?? \"reply\"} error: ${String(err)}`);\n },\n },\n replyOptions: {},\n });\n}\n\n// --- Channel plugin definition ---\n\nconst agentVaultPlugin = {\n id: \"agentvault\",\n meta: {\n id: \"agentvault\",\n label: \"AgentVault\",\n selectionLabel: \"AgentVault (E2E Encrypted)\",\n docsPath: \"https://agentvault.chat/docs\",\n blurb: \"Zero-knowledge, end-to-end encrypted messaging between owners and their AI agents.\",\n aliases: [\"av\", \"agent-vault\"],\n },\n capabilities: { chatTypes: [\"direct\"] },\n config: { listAccountIds, resolveAccount },\n\n gateway: {\n startAccount: async (ctx: any) => {\n const { account, cfg, log, abortSignal } = ctx;\n\n if (!account.configured) {\n throw new Error(\n \"AgentVault channel not configured. Run: npx @agentvault/agentvault setup --token=av_tok_...\\nThen restart OpenClaw.\",\n );\n }\n\n const dataDir = resolve(account.dataDir.replace(/^~/, process.env.HOME ?? \"~\"));\n log?.info(`[AgentVault] starting (dataDir=${dataDir})`);\n\n // Lazy import \u2014 defers libsodium initialization until channel actually starts\n const { SecureChannel } = await import(\"./index.js\");\n\n // startAccount must STAY PENDING while the channel is running.\n // Resolving signals \"channel stopped\" to the gateway health monitor,\n // which triggers auto-restart. We block here until the abortSignal\n // fires (gateway shutdown / config reload), then clean up.\n await new Promise<void>((resolve, reject) => {\n let channel: any;\n\n const onAbort = async () => {\n await channel?.stop();\n _channels.delete(account.accountId);\n resolve();\n };\n\n abortSignal?.addEventListener(\"abort\", () => void onAbort());\n\n // Lazy import \u2014 defers libsodium initialization until channel starts\n import(\"./index.js\").then(({ SecureChannel }) => {\n channel = new SecureChannel({\n inviteToken: \"\",\n dataDir,\n apiUrl: account.apiUrl,\n agentName: account.agentName,\n onMessage: async (plaintext: string, metadata: any) => {\n if (!_ocRuntime) {\n log?.info(\"[AgentVault] runtime not ready, queuing message\");\n _messageQueue.push(async () => {\n await handleInbound({ plaintext, metadata, channel, account, cfg });\n });\n return;\n }\n try {\n await handleInbound({ plaintext, metadata, channel, account, cfg });\n } catch (err) {\n log?.info(`[AgentVault] inbound error: ${String(err)}`);\n }\n },\n onStateChange: (state: string) => {\n log?.info(`[AgentVault] \u2192 ${state}`);\n // \"error\" is a permanent failure \u2014 reject so gateway can restart\n if (state === \"error\") reject(new Error(\"AgentVault channel permanent error\"));\n // All other states (connecting/ready/disconnected) are handled\n // internally by SecureChannel's reconnect logic \u2014 do NOT resolve.\n },\n });\n\n _channels.set(account.accountId, channel);\n\n // Prevent unhandled \"error\" events from crashing the process.\n // Without this handler, Node.js EventEmitter throws on emit(\"error\").\n channel.on(\"error\", (err: any) => {\n log?.info(`[AgentVault] channel error (non-fatal): ${String(err)}`);\n });\n\n // Start local HTTP server for proactive sends\n const httpPort = account.httpPort ?? 18790;\n channel.on(\"ready\", () => {\n channel.startHttpServer(httpPort);\n log?.info(`[AgentVault] HTTP send server listening on http://127.0.0.1:${httpPort}`);\n });\n\n channel.start().catch(reject);\n }).catch(reject);\n });\n\n return { stop: async () => {} }; // Channel already stopped via abortSignal by this point\n },\n },\n\n outbound: {\n deliveryMode: \"direct\" as const,\n\n // Register valid send targets so OpenClaw's `message` tool can route\n // proactive (agent-initiated) sends \u2014 not just replies to inbound messages.\n targets: [\n {\n id: \"owner\",\n label: \"AgentVault Owner\",\n accountId: \"default\",\n },\n {\n id: \"default\",\n label: \"AgentVault Owner (default)\",\n accountId: \"default\",\n },\n ],\n\n sendText: async ({ to, text, accountId }: { to: string; text: string; accountId?: string }) => {\n const resolvedId = accountId ?? \"default\";\n const ch = _channels.get(resolvedId);\n if (!ch) return { ok: false, error: \"AgentVault channel not connected\" };\n try {\n const wasReady = ch.state === \"ready\";\n await ch.send(text);\n return { ok: true, queued: !wasReady };\n } catch (err) {\n return { ok: false, error: String(err) };\n }\n },\n\n sendMedia: async ({ to, text, mediaUrl, accountId }: { to: string; text?: string; mediaUrl: string; accountId?: string }) => {\n const resolvedId = accountId ?? \"default\";\n const ch = _channels.get(resolvedId);\n if (!ch) return { ok: false, error: \"AgentVault channel not connected\" };\n try {\n // For now, send media URL as text \u2014 AgentVault handles attachments separately\n const message = text ? `${text}\\n${mediaUrl}` : mediaUrl;\n const wasReady = ch.state === \"ready\";\n await ch.send(message);\n return { ok: true, queued: !wasReady };\n } catch (err) {\n return { ok: false, error: String(err) };\n }\n },\n },\n};\n\n// --- Plugin export ---\n\nexport default {\n id: \"agentvault\",\n name: \"AgentVault\",\n description: \"End-to-end encrypted, zero-knowledge messaging between AI agent owners and their agents.\",\n register(api: any) {\n _setRuntime(api.runtime);\n api.registerChannel({ plugin: agentVaultPlugin });\n },\n};\n"],
|
|
5
|
-
"mappings": ";AAUA,SAAS,eAAe;
|
|
4
|
+
"sourcesContent": ["/**\n * OpenClaw channel plugin entry point.\n *\n * Intentionally thin \u2014 no heavy imports (libsodium etc.) at module load time.\n * SecureChannel is dynamically imported inside gateway.startAccount (already async)\n * so libsodium's top-level await never runs during plugin registration.\n *\n * Loaded by OpenClaw via the `openclaw.extensions` field in package.json.\n */\n\nimport { resolve } from \"node:path\";\nimport { randomBytes } from \"node:crypto\";\n\n// --- Runtime and active channels (set during register) ---\nlet _ocRuntime: any = null;\nconst _channels = new Map<string, any>();\nconst _messageQueue: Array<() => Promise<void>> = [];\n\nfunction _setRuntime(rt: any) {\n _ocRuntime = rt;\n // Flush any messages that arrived before runtime was ready\n if (_messageQueue.length > 0) {\n const pending = _messageQueue.splice(0);\n for (const fn of pending) {\n fn().catch(() => {});\n }\n }\n}\n\n// --- Channel config helpers ---\n\nfunction listAccountIds(cfg: any): string[] {\n return cfg?.channels?.agentvault?.dataDir ? [\"default\"] : [];\n}\n\nfunction resolveAccount(cfg: any, accountId?: string) {\n const av = cfg?.channels?.agentvault ?? {};\n return {\n accountId: accountId ?? \"default\",\n dataDir: av.dataDir ?? \"~/.openclaw/agentvault\",\n apiUrl: av.apiUrl ?? \"https://api.agentvault.chat\",\n agentName: av.agentName ?? \"OpenClaw Agent\",\n httpPort: av.httpPort ?? 18790,\n configured: Boolean(av.dataDir),\n };\n}\n\n// --- Inbound message dispatch ---\n\nasync function handleInbound(params: {\n plaintext: string;\n metadata: any;\n channel: any;\n account: any;\n cfg: any;\n}): Promise<void> {\n const { plaintext, metadata, channel, account, cfg } = params;\n\n // Telemetry: hierarchical spans for the full message lifecycle\n const startTime = Date.now();\n const traceId = randomBytes(16).toString(\"hex\");\n const rootSpanId = randomBytes(8).toString(\"hex\");\n let replyCount = 0;\n let totalReplyChars = 0;\n let firstReplyTime: number | null = null;\n const replySpans: Array<{ startTime: number; endTime: number; chars: number; index: number }> = [];\n\n // Emit \"receive\" child span immediately \u2014 marks inbound arrival\n _emitChildSpan(channel, {\n traceId,\n parentSpanId: rootSpanId,\n name: \"ai.agent.message.receive\",\n startTime,\n endTime: startTime + 1, // instant\n attributes: {\n \"ai.agent.message.input_chars\": plaintext.length,\n \"ai.agent.message.type\": metadata.roomId ? \"room\" : \"direct\",\n },\n status: \"ok\",\n });\n\n // Send typing indicator to owner (non-critical, best-effort)\n try { channel.sendTyping(); } catch { /* ignore */ }\n\n const core = _ocRuntime;\n const isRoomMessage = Boolean(metadata.roomId);\n\n const route = core.channel.routing.resolveAgentRoute({\n cfg,\n channel: \"agentvault\",\n accountId: account.accountId,\n peer: { kind: \"direct\", id: isRoomMessage ? `agentvault:room:${metadata.roomId}` : \"agentvault:owner\" },\n });\n\n const storePath = core.channel.session.resolveStorePath(cfg?.session?.store, {\n agentId: route.agentId,\n });\n\n const envelopeOptions = core.channel.reply.resolveEnvelopeFormatOptions(cfg);\n const previousTimestamp = core.channel.session.readSessionUpdatedAt({\n storePath,\n sessionKey: route.sessionKey,\n });\n\n const body = core.channel.reply.formatAgentEnvelope({\n channel: \"AgentVault\",\n from: isRoomMessage ? \"Room\" : \"Owner\",\n timestamp: new Date(metadata.timestamp).getTime(),\n previousTimestamp,\n envelope: envelopeOptions,\n body: plaintext,\n });\n\n // Build attachment fields for the context payload\n const attachmentFields: Record<string, any> = {};\n if (metadata.attachment) {\n attachmentFields.AttachmentPath = metadata.attachment.filePath;\n attachmentFields.AttachmentFilename = metadata.attachment.filename;\n attachmentFields.AttachmentMime = metadata.attachment.mime;\n\n // For images: include as MediaUrl so the LLM can see the visual content\n if (metadata.attachment.base64) {\n attachmentFields.MediaUrl = metadata.attachment.base64;\n attachmentFields.NumMedia = \"1\";\n }\n\n // For text files: content is already inlined in plaintext body\n }\n\n const ctxPayload = core.channel.reply.finalizeInboundContext({\n Body: body,\n RawBody: plaintext,\n CommandBody: plaintext,\n From: isRoomMessage ? `agentvault:room:${metadata.roomId}` : \"agentvault:owner\",\n To: `agentvault:agent:${account.accountId}`,\n SessionKey: route.sessionKey,\n AccountId: account.accountId,\n ChatType: isRoomMessage ? \"room\" : \"direct\",\n ConversationLabel: isRoomMessage ? \"AgentVault Room\" : \"AgentVault\",\n SenderName: isRoomMessage ? \"Room\" : \"Owner\",\n SenderId: isRoomMessage ? `agentvault:room:${metadata.roomId}` : \"agentvault:owner\",\n Provider: \"agentvault\",\n Surface: \"agentvault\",\n MessageSid: metadata.messageId,\n Timestamp: new Date(metadata.timestamp).getTime(),\n OriginatingChannel: \"agentvault\",\n OriginatingTo: `agentvault:agent:${account.accountId}`,\n CommandAuthorized: true,\n ...attachmentFields,\n });\n\n await core.channel.session.recordInboundSession({\n storePath,\n sessionKey: ctxPayload.SessionKey ?? route.sessionKey,\n ctx: ctxPayload,\n onRecordError: (err: Error) => {\n core.error?.(`[AgentVault] session record failed: ${String(err)}`);\n },\n });\n\n try {\n await core.channel.reply.dispatchReplyWithBufferedBlockDispatcher({\n ctx: ctxPayload,\n cfg,\n dispatcherOptions: {\n deliver: async (payload: { text?: string; kind?: string }) => {\n // Filter out thinking/reasoning blocks \u2014 only deliver actual responses\n if (payload.kind === \"thinking\" || payload.kind === \"reasoning\") return;\n const text = (payload.text ?? \"\").trim();\n if (!text) return;\n // Heuristic: skip blocks that look like leaked chain-of-thought\n if (/^(Reasoning|Thinking|Let me think|I need to|Let me check):/i.test(text)) return;\n\n const replyStart = Date.now();\n replyCount++;\n totalReplyChars += text.length;\n if (!firstReplyTime) firstReplyTime = replyStart;\n\n // Route reply: room messages go back to the room, 1:1 goes to owner\n if (isRoomMessage) {\n await channel.sendToRoom(metadata.roomId, text);\n } else {\n await channel.send(text, { topicId: metadata.topicId });\n }\n\n const replyEnd = Date.now();\n replySpans.push({ startTime: replyStart, endTime: replyEnd, chars: text.length, index: replyCount });\n },\n onError: (err: Error, info?: { kind?: string }) => {\n core.error?.(`[AgentVault] ${info?.kind ?? \"reply\"} error: ${String(err)}`);\n },\n },\n replyOptions: {},\n });\n\n const endTime = Date.now();\n\n // Emit child spans for the completed message lifecycle\n _emitHierarchicalSpans(channel, {\n traceId,\n rootSpanId,\n startTime,\n endTime,\n firstReplyTime,\n replySpans,\n inputChars: plaintext.length,\n replyCount,\n totalReplyChars,\n isRoom: isRoomMessage,\n status: \"ok\",\n });\n } catch (err) {\n const endTime = Date.now();\n\n // Emit spans even on error \u2014 shows where failure occurred\n _emitHierarchicalSpans(channel, {\n traceId,\n rootSpanId,\n startTime,\n endTime,\n firstReplyTime,\n replySpans,\n inputChars: plaintext.length,\n replyCount,\n totalReplyChars,\n isRoom: isRoomMessage,\n status: \"error\",\n statusMessage: String(err),\n });\n throw err;\n }\n}\n\n/** Emit a single child span via the channel's telemetry reporter. */\nfunction _emitChildSpan(channel: any, opts: {\n traceId: string;\n parentSpanId: string;\n name: string;\n startTime: number;\n endTime: number;\n attributes: Record<string, string | number | boolean>;\n status: \"ok\" | \"error\";\n statusMessage?: string;\n}): void {\n try {\n const reporter = channel.telemetry;\n if (!reporter) return;\n\n reporter.reportCustomSpan({\n traceId: opts.traceId,\n spanId: randomBytes(8).toString(\"hex\"),\n parentSpanId: opts.parentSpanId,\n name: opts.name,\n kind: \"internal\" as const,\n startTime: opts.startTime,\n endTime: opts.endTime,\n attributes: opts.attributes,\n status: {\n code: opts.status === \"ok\" ? 1 : 2,\n message: opts.statusMessage,\n },\n });\n } catch { /* telemetry is best-effort */ }\n}\n\n/** Emit the full hierarchical span tree for a message lifecycle. */\nfunction _emitHierarchicalSpans(channel: any, opts: {\n traceId: string;\n rootSpanId: string;\n startTime: number;\n endTime: number;\n firstReplyTime: number | null;\n replySpans: Array<{ startTime: number; endTime: number; chars: number; index: number }>;\n inputChars: number;\n replyCount: number;\n totalReplyChars: number;\n isRoom: boolean;\n status: \"ok\" | \"error\";\n statusMessage?: string;\n}): void {\n try {\n const reporter = channel.telemetry;\n if (!reporter) return;\n\n // 1. Inference span: from message arrival to first reply (or end if no replies)\n const inferenceEnd = opts.firstReplyTime ?? opts.endTime;\n _emitChildSpan(channel, {\n traceId: opts.traceId,\n parentSpanId: opts.rootSpanId,\n name: \"ai.agent.inference\",\n startTime: opts.startTime + 1, // just after receive\n endTime: inferenceEnd,\n attributes: {\n \"ai.agent.inference.latency_ms\": inferenceEnd - opts.startTime,\n \"ai.agent.message.input_chars\": opts.inputChars,\n },\n status: opts.status,\n statusMessage: opts.status === \"error\" ? opts.statusMessage : undefined,\n });\n\n // 2. Individual reply spans\n for (const reply of opts.replySpans) {\n _emitChildSpan(channel, {\n traceId: opts.traceId,\n parentSpanId: opts.rootSpanId,\n name: \"ai.agent.reply\",\n startTime: reply.startTime,\n endTime: reply.endTime,\n attributes: {\n \"ai.agent.reply.index\": reply.index,\n \"ai.agent.reply.chars\": reply.chars,\n },\n status: \"ok\",\n });\n }\n\n // 3. Root span (wraps everything) \u2014 emitted last\n reporter.reportCustomSpan({\n traceId: opts.traceId,\n spanId: opts.rootSpanId,\n name: \"ai.agent.message\",\n kind: \"server\" as const,\n startTime: opts.startTime,\n endTime: opts.endTime,\n attributes: {\n \"ai.agent.message.input_chars\": opts.inputChars,\n \"ai.agent.message.reply_count\": opts.replyCount,\n \"ai.agent.message.reply_chars\": opts.totalReplyChars,\n \"ai.agent.message.latency_ms\": opts.endTime - opts.startTime,\n \"ai.agent.message.type\": opts.isRoom ? \"room\" : \"direct\",\n },\n status: {\n code: opts.status === \"ok\" ? 1 : 2,\n message: opts.statusMessage,\n },\n });\n } catch { /* telemetry is best-effort */ }\n}\n\n// --- Channel plugin definition ---\n\nconst agentVaultPlugin = {\n id: \"agentvault\",\n meta: {\n id: \"agentvault\",\n label: \"AgentVault\",\n selectionLabel: \"AgentVault (E2E Encrypted)\",\n docsPath: \"https://agentvault.chat/docs\",\n blurb: \"Zero-knowledge, end-to-end encrypted messaging between owners and their AI agents.\",\n aliases: [\"av\", \"agent-vault\"],\n },\n capabilities: { chatTypes: [\"direct\"] },\n config: { listAccountIds, resolveAccount },\n\n gateway: {\n startAccount: async (ctx: any) => {\n const { account, cfg, log, abortSignal } = ctx;\n\n if (!account.configured) {\n throw new Error(\n \"AgentVault channel not configured. Run: npx @agentvault/agentvault setup --token=av_tok_...\\nThen restart OpenClaw.\",\n );\n }\n\n const dataDir = resolve(account.dataDir.replace(/^~/, process.env.HOME ?? \"~\"));\n log?.info(`[AgentVault] starting (dataDir=${dataDir})`);\n\n // Lazy import \u2014 defers libsodium initialization until channel actually starts\n const { SecureChannel } = await import(\"./index.js\");\n\n // startAccount must STAY PENDING while the channel is running.\n // Resolving signals \"channel stopped\" to the gateway health monitor,\n // which triggers auto-restart. We block here until the abortSignal\n // fires (gateway shutdown / config reload), then clean up.\n await new Promise<void>((resolve, reject) => {\n let channel: any;\n\n const onAbort = async () => {\n await channel?.stop();\n _channels.delete(account.accountId);\n resolve();\n };\n\n abortSignal?.addEventListener(\"abort\", () => void onAbort());\n\n // Lazy import \u2014 defers libsodium initialization until channel starts\n import(\"./index.js\").then(({ SecureChannel }) => {\n channel = new SecureChannel({\n inviteToken: \"\",\n dataDir,\n apiUrl: account.apiUrl,\n agentName: account.agentName,\n onMessage: async (plaintext: string, metadata: any) => {\n if (!_ocRuntime) {\n log?.info(\"[AgentVault] runtime not ready, queuing message\");\n _messageQueue.push(async () => {\n await handleInbound({ plaintext, metadata, channel, account, cfg });\n });\n return;\n }\n try {\n await handleInbound({ plaintext, metadata, channel, account, cfg });\n } catch (err) {\n log?.info(`[AgentVault] inbound error: ${String(err)}`);\n }\n },\n onStateChange: (state: string) => {\n log?.info(`[AgentVault] \u2192 ${state}`);\n // \"error\" is a permanent failure \u2014 reject so gateway can restart\n if (state === \"error\") reject(new Error(\"AgentVault channel permanent error\"));\n // All other states (connecting/ready/disconnected) are handled\n // internally by SecureChannel's reconnect logic \u2014 do NOT resolve.\n },\n });\n\n _channels.set(account.accountId, channel);\n\n // Prevent unhandled \"error\" events from crashing the process.\n // Without this handler, Node.js EventEmitter throws on emit(\"error\").\n channel.on(\"error\", (err: any) => {\n log?.info(`[AgentVault] channel error (non-fatal): ${String(err)}`);\n });\n\n // Start local HTTP server for proactive sends\n const httpPort = account.httpPort ?? 18790;\n channel.on(\"ready\", () => {\n channel.startHttpServer(httpPort);\n log?.info(`[AgentVault] HTTP send server listening on http://127.0.0.1:${httpPort}`);\n });\n\n channel.start().catch(reject);\n }).catch(reject);\n });\n\n return { stop: async () => {} }; // Channel already stopped via abortSignal by this point\n },\n },\n\n outbound: {\n deliveryMode: \"direct\" as const,\n\n // Register valid send targets so OpenClaw's `message` tool can route\n // proactive (agent-initiated) sends \u2014 not just replies to inbound messages.\n targets: [\n {\n id: \"owner\",\n label: \"AgentVault Owner\",\n accountId: \"default\",\n },\n {\n id: \"default\",\n label: \"AgentVault Owner (default)\",\n accountId: \"default\",\n },\n ],\n\n sendText: async ({ to, text, accountId }: { to: string; text: string; accountId?: string }) => {\n const resolvedId = accountId ?? \"default\";\n const ch = _channels.get(resolvedId);\n if (!ch) return { ok: false, error: \"AgentVault channel not connected\" };\n try {\n const wasReady = ch.state === \"ready\";\n await ch.send(text);\n return { ok: true, queued: !wasReady };\n } catch (err) {\n return { ok: false, error: String(err) };\n }\n },\n\n sendMedia: async ({ to, text, mediaUrl, accountId }: { to: string; text?: string; mediaUrl: string; accountId?: string }) => {\n const resolvedId = accountId ?? \"default\";\n const ch = _channels.get(resolvedId);\n if (!ch) return { ok: false, error: \"AgentVault channel not connected\" };\n try {\n // For now, send media URL as text \u2014 AgentVault handles attachments separately\n const message = text ? `${text}\\n${mediaUrl}` : mediaUrl;\n const wasReady = ch.state === \"ready\";\n await ch.send(message);\n return { ok: true, queued: !wasReady };\n } catch (err) {\n return { ok: false, error: String(err) };\n }\n },\n },\n};\n\n// --- Plugin export ---\n\nexport default {\n id: \"agentvault\",\n name: \"AgentVault\",\n description: \"End-to-end encrypted, zero-knowledge messaging between AI agent owners and their agents.\",\n register(api: any) {\n _setRuntime(api.runtime);\n api.registerChannel({ plugin: agentVaultPlugin });\n },\n};\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": ["resolve", "SecureChannel"]
|
|
7
7
|
}
|