@agentvault/agentvault 0.8.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 +250 -0
- package/dist/__tests__/crypto-helpers.test.d.ts +2 -0
- package/dist/__tests__/crypto-helpers.test.d.ts.map +1 -0
- package/dist/__tests__/functional.test.d.ts +21 -0
- package/dist/__tests__/functional.test.d.ts.map +1 -0
- package/dist/__tests__/multi-session.test.d.ts +2 -0
- package/dist/__tests__/multi-session.test.d.ts.map +1 -0
- package/dist/__tests__/state.test.d.ts +2 -0
- package/dist/__tests__/state.test.d.ts.map +1 -0
- package/dist/__tests__/transport.test.d.ts +2 -0
- package/dist/__tests__/transport.test.d.ts.map +1 -0
- package/dist/channel.d.ts +249 -0
- package/dist/channel.d.ts.map +1 -0
- package/dist/cli.d.ts +2 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +48036 -0
- package/dist/cli.js.map +7 -0
- package/dist/crypto-helpers.d.ts +12 -0
- package/dist/crypto-helpers.d.ts.map +1 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +47609 -0
- package/dist/index.js.map +7 -0
- package/dist/openclaw-entry.d.ts +17 -0
- package/dist/openclaw-entry.d.ts.map +1 -0
- package/dist/openclaw-entry.js +241 -0
- package/dist/openclaw-entry.js.map +7 -0
- package/dist/openclaw-plugin.d.ts +64 -0
- package/dist/openclaw-plugin.d.ts.map +1 -0
- package/dist/setup.d.ts +25 -0
- package/dist/setup.d.ts.map +1 -0
- package/dist/state.d.ts +13 -0
- package/dist/state.d.ts.map +1 -0
- package/dist/transport.d.ts +24 -0
- package/dist/transport.d.ts.map +1 -0
- package/dist/types.d.ts +209 -0
- package/dist/types.d.ts.map +1 -0
- package/openclaw.plugin.json +28 -0
- package/package.json +65 -0
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OpenClaw channel plugin entry point.
|
|
3
|
+
*
|
|
4
|
+
* Intentionally thin — no heavy imports (libsodium etc.) at module load time.
|
|
5
|
+
* SecureChannel is dynamically imported inside gateway.startAccount (already async)
|
|
6
|
+
* so libsodium's top-level await never runs during plugin registration.
|
|
7
|
+
*
|
|
8
|
+
* Loaded by OpenClaw via the `openclaw.extensions` field in package.json.
|
|
9
|
+
*/
|
|
10
|
+
declare const _default: {
|
|
11
|
+
id: string;
|
|
12
|
+
name: string;
|
|
13
|
+
description: string;
|
|
14
|
+
register(api: any): void;
|
|
15
|
+
};
|
|
16
|
+
export default _default;
|
|
17
|
+
//# sourceMappingURL=openclaw-entry.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"openclaw-entry.d.ts","sourceRoot":"","sources":["../src/openclaw-entry.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;;;;;kBAuSa,GAAG;;AAJnB,wBAQE"}
|
|
@@ -0,0 +1,241 @@
|
|
|
1
|
+
// src/openclaw-entry.ts
|
|
2
|
+
import { resolve } from "node:path";
|
|
3
|
+
var _ocRuntime = null;
|
|
4
|
+
var _channels = /* @__PURE__ */ new Map();
|
|
5
|
+
var _messageQueue = [];
|
|
6
|
+
function _setRuntime(rt) {
|
|
7
|
+
_ocRuntime = rt;
|
|
8
|
+
if (_messageQueue.length > 0) {
|
|
9
|
+
const pending = _messageQueue.splice(0);
|
|
10
|
+
for (const fn of pending) {
|
|
11
|
+
fn().catch(() => {
|
|
12
|
+
});
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
function listAccountIds(cfg) {
|
|
17
|
+
return cfg?.channels?.agentvault?.dataDir ? ["default"] : [];
|
|
18
|
+
}
|
|
19
|
+
function resolveAccount(cfg, accountId) {
|
|
20
|
+
const av = cfg?.channels?.agentvault ?? {};
|
|
21
|
+
return {
|
|
22
|
+
accountId: accountId ?? "default",
|
|
23
|
+
dataDir: av.dataDir ?? "~/.openclaw/agentvault",
|
|
24
|
+
apiUrl: av.apiUrl ?? "https://api.agentvault.chat",
|
|
25
|
+
agentName: av.agentName ?? "OpenClaw Agent",
|
|
26
|
+
httpPort: av.httpPort ?? 18790,
|
|
27
|
+
configured: Boolean(av.dataDir)
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
async function handleInbound(params) {
|
|
31
|
+
const { plaintext, metadata, channel, account, cfg } = params;
|
|
32
|
+
try {
|
|
33
|
+
channel.sendTyping();
|
|
34
|
+
} catch {
|
|
35
|
+
}
|
|
36
|
+
const core = _ocRuntime;
|
|
37
|
+
const route = core.channel.routing.resolveAgentRoute({
|
|
38
|
+
cfg,
|
|
39
|
+
channel: "agentvault",
|
|
40
|
+
accountId: account.accountId,
|
|
41
|
+
peer: { kind: "direct", id: "agentvault:owner" }
|
|
42
|
+
});
|
|
43
|
+
const storePath = core.channel.session.resolveStorePath(cfg?.session?.store, {
|
|
44
|
+
agentId: route.agentId
|
|
45
|
+
});
|
|
46
|
+
const envelopeOptions = core.channel.reply.resolveEnvelopeFormatOptions(cfg);
|
|
47
|
+
const previousTimestamp = core.channel.session.readSessionUpdatedAt({
|
|
48
|
+
storePath,
|
|
49
|
+
sessionKey: route.sessionKey
|
|
50
|
+
});
|
|
51
|
+
const body = core.channel.reply.formatAgentEnvelope({
|
|
52
|
+
channel: "AgentVault",
|
|
53
|
+
from: "Owner",
|
|
54
|
+
timestamp: new Date(metadata.timestamp).getTime(),
|
|
55
|
+
previousTimestamp,
|
|
56
|
+
envelope: envelopeOptions,
|
|
57
|
+
body: plaintext
|
|
58
|
+
});
|
|
59
|
+
const attachmentFields = {};
|
|
60
|
+
if (metadata.attachment) {
|
|
61
|
+
attachmentFields.AttachmentPath = metadata.attachment.filePath;
|
|
62
|
+
attachmentFields.AttachmentFilename = metadata.attachment.filename;
|
|
63
|
+
attachmentFields.AttachmentMime = metadata.attachment.mime;
|
|
64
|
+
if (metadata.attachment.base64) {
|
|
65
|
+
attachmentFields.MediaUrl = metadata.attachment.base64;
|
|
66
|
+
attachmentFields.NumMedia = "1";
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
const ctxPayload = core.channel.reply.finalizeInboundContext({
|
|
70
|
+
Body: body,
|
|
71
|
+
RawBody: plaintext,
|
|
72
|
+
CommandBody: plaintext,
|
|
73
|
+
From: "agentvault:owner",
|
|
74
|
+
To: `agentvault:agent:${account.accountId}`,
|
|
75
|
+
SessionKey: route.sessionKey,
|
|
76
|
+
AccountId: account.accountId,
|
|
77
|
+
ChatType: "direct",
|
|
78
|
+
ConversationLabel: "AgentVault",
|
|
79
|
+
SenderName: "Owner",
|
|
80
|
+
SenderId: "agentvault:owner",
|
|
81
|
+
Provider: "agentvault",
|
|
82
|
+
Surface: "agentvault",
|
|
83
|
+
MessageSid: metadata.messageId,
|
|
84
|
+
Timestamp: new Date(metadata.timestamp).getTime(),
|
|
85
|
+
OriginatingChannel: "agentvault",
|
|
86
|
+
OriginatingTo: `agentvault:agent:${account.accountId}`,
|
|
87
|
+
CommandAuthorized: true,
|
|
88
|
+
...attachmentFields
|
|
89
|
+
});
|
|
90
|
+
await core.channel.session.recordInboundSession({
|
|
91
|
+
storePath,
|
|
92
|
+
sessionKey: ctxPayload.SessionKey ?? route.sessionKey,
|
|
93
|
+
ctx: ctxPayload,
|
|
94
|
+
onRecordError: (err) => {
|
|
95
|
+
core.error?.(`[AgentVault] session record failed: ${String(err)}`);
|
|
96
|
+
}
|
|
97
|
+
});
|
|
98
|
+
await core.channel.reply.dispatchReplyWithBufferedBlockDispatcher({
|
|
99
|
+
ctx: ctxPayload,
|
|
100
|
+
cfg,
|
|
101
|
+
dispatcherOptions: {
|
|
102
|
+
deliver: async (payload) => {
|
|
103
|
+
if (payload.kind === "thinking" || payload.kind === "reasoning") return;
|
|
104
|
+
const text = (payload.text ?? "").trim();
|
|
105
|
+
if (!text) return;
|
|
106
|
+
if (/^(Reasoning|Thinking|Let me think|I need to|Let me check):/i.test(text)) return;
|
|
107
|
+
await channel.send(text);
|
|
108
|
+
},
|
|
109
|
+
onError: (err, info) => {
|
|
110
|
+
core.error?.(`[AgentVault] ${info?.kind ?? "reply"} error: ${String(err)}`);
|
|
111
|
+
}
|
|
112
|
+
},
|
|
113
|
+
replyOptions: {}
|
|
114
|
+
});
|
|
115
|
+
}
|
|
116
|
+
var agentVaultPlugin = {
|
|
117
|
+
id: "agentvault",
|
|
118
|
+
meta: {
|
|
119
|
+
id: "agentvault",
|
|
120
|
+
label: "AgentVault",
|
|
121
|
+
selectionLabel: "AgentVault (E2E Encrypted)",
|
|
122
|
+
docsPath: "https://agentvault.chat/docs",
|
|
123
|
+
blurb: "Zero-knowledge, end-to-end encrypted messaging between owners and their AI agents.",
|
|
124
|
+
aliases: ["av", "agent-vault"]
|
|
125
|
+
},
|
|
126
|
+
capabilities: { chatTypes: ["direct"] },
|
|
127
|
+
config: { listAccountIds, resolveAccount },
|
|
128
|
+
gateway: {
|
|
129
|
+
startAccount: async (ctx) => {
|
|
130
|
+
const { account, cfg, log, abortSignal } = ctx;
|
|
131
|
+
if (!account.configured) {
|
|
132
|
+
throw new Error(
|
|
133
|
+
"AgentVault channel not configured. Run: npx @agentvault/agentvault setup --token=av_tok_...\nThen restart OpenClaw."
|
|
134
|
+
);
|
|
135
|
+
}
|
|
136
|
+
const dataDir = resolve(account.dataDir.replace(/^~/, process.env.HOME ?? "~"));
|
|
137
|
+
log?.info(`[AgentVault] starting (dataDir=${dataDir})`);
|
|
138
|
+
const { SecureChannel } = await import("./index.js");
|
|
139
|
+
await new Promise((resolve2, reject) => {
|
|
140
|
+
let channel;
|
|
141
|
+
const onAbort = async () => {
|
|
142
|
+
await channel?.stop();
|
|
143
|
+
_channels.delete(account.accountId);
|
|
144
|
+
resolve2();
|
|
145
|
+
};
|
|
146
|
+
abortSignal?.addEventListener("abort", () => void onAbort());
|
|
147
|
+
import("./index.js").then(({ SecureChannel: SecureChannel2 }) => {
|
|
148
|
+
channel = new SecureChannel2({
|
|
149
|
+
inviteToken: "",
|
|
150
|
+
dataDir,
|
|
151
|
+
apiUrl: account.apiUrl,
|
|
152
|
+
agentName: account.agentName,
|
|
153
|
+
onMessage: async (plaintext, metadata) => {
|
|
154
|
+
if (!_ocRuntime) {
|
|
155
|
+
log?.info("[AgentVault] runtime not ready, queuing message");
|
|
156
|
+
_messageQueue.push(async () => {
|
|
157
|
+
await handleInbound({ plaintext, metadata, channel, account, cfg });
|
|
158
|
+
});
|
|
159
|
+
return;
|
|
160
|
+
}
|
|
161
|
+
try {
|
|
162
|
+
await handleInbound({ plaintext, metadata, channel, account, cfg });
|
|
163
|
+
} catch (err) {
|
|
164
|
+
log?.info(`[AgentVault] inbound error: ${String(err)}`);
|
|
165
|
+
}
|
|
166
|
+
},
|
|
167
|
+
onStateChange: (state) => {
|
|
168
|
+
log?.info(`[AgentVault] \u2192 ${state}`);
|
|
169
|
+
if (state === "error") reject(new Error("AgentVault channel permanent error"));
|
|
170
|
+
}
|
|
171
|
+
});
|
|
172
|
+
_channels.set(account.accountId, channel);
|
|
173
|
+
const httpPort = account.httpPort ?? 18790;
|
|
174
|
+
channel.on("ready", () => {
|
|
175
|
+
channel.startHttpServer(httpPort);
|
|
176
|
+
log?.info(`[AgentVault] HTTP send server listening on http://127.0.0.1:${httpPort}`);
|
|
177
|
+
});
|
|
178
|
+
channel.start().catch(reject);
|
|
179
|
+
}).catch(reject);
|
|
180
|
+
});
|
|
181
|
+
return { stop: async () => {
|
|
182
|
+
} };
|
|
183
|
+
}
|
|
184
|
+
},
|
|
185
|
+
outbound: {
|
|
186
|
+
deliveryMode: "direct",
|
|
187
|
+
// Register valid send targets so OpenClaw's `message` tool can route
|
|
188
|
+
// proactive (agent-initiated) sends — not just replies to inbound messages.
|
|
189
|
+
targets: [
|
|
190
|
+
{
|
|
191
|
+
id: "owner",
|
|
192
|
+
label: "AgentVault Owner",
|
|
193
|
+
accountId: "default"
|
|
194
|
+
},
|
|
195
|
+
{
|
|
196
|
+
id: "default",
|
|
197
|
+
label: "AgentVault Owner (default)",
|
|
198
|
+
accountId: "default"
|
|
199
|
+
}
|
|
200
|
+
],
|
|
201
|
+
sendText: async ({ to, text, accountId }) => {
|
|
202
|
+
const resolvedId = accountId ?? "default";
|
|
203
|
+
const ch = _channels.get(resolvedId);
|
|
204
|
+
if (!ch) return { ok: false, error: "AgentVault channel not connected" };
|
|
205
|
+
try {
|
|
206
|
+
const wasReady = ch.state === "ready";
|
|
207
|
+
await ch.send(text);
|
|
208
|
+
return { ok: true, queued: !wasReady };
|
|
209
|
+
} catch (err) {
|
|
210
|
+
return { ok: false, error: String(err) };
|
|
211
|
+
}
|
|
212
|
+
},
|
|
213
|
+
sendMedia: async ({ to, text, mediaUrl, accountId }) => {
|
|
214
|
+
const resolvedId = accountId ?? "default";
|
|
215
|
+
const ch = _channels.get(resolvedId);
|
|
216
|
+
if (!ch) return { ok: false, error: "AgentVault channel not connected" };
|
|
217
|
+
try {
|
|
218
|
+
const message = text ? `${text}
|
|
219
|
+
${mediaUrl}` : mediaUrl;
|
|
220
|
+
const wasReady = ch.state === "ready";
|
|
221
|
+
await ch.send(message);
|
|
222
|
+
return { ok: true, queued: !wasReady };
|
|
223
|
+
} catch (err) {
|
|
224
|
+
return { ok: false, error: String(err) };
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
};
|
|
229
|
+
var openclaw_entry_default = {
|
|
230
|
+
id: "agentvault",
|
|
231
|
+
name: "AgentVault",
|
|
232
|
+
description: "End-to-end encrypted, zero-knowledge messaging between AI agent owners and their agents.",
|
|
233
|
+
register(api) {
|
|
234
|
+
_setRuntime(api.runtime);
|
|
235
|
+
api.registerChannel({ plugin: agentVaultPlugin });
|
|
236
|
+
}
|
|
237
|
+
};
|
|
238
|
+
export {
|
|
239
|
+
openclaw_entry_default as default
|
|
240
|
+
};
|
|
241
|
+
//# sourceMappingURL=openclaw-entry.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 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\n const route = core.channel.routing.resolveAgentRoute({\n cfg,\n channel: \"agentvault\",\n accountId: account.accountId,\n peer: { kind: \"direct\", id: \"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: \"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: \"agentvault:owner\",\n To: `agentvault:agent:${account.accountId}`,\n SessionKey: route.sessionKey,\n AccountId: account.accountId,\n ChatType: \"direct\",\n ConversationLabel: \"AgentVault\",\n SenderName: \"Owner\",\n SenderId: \"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 await channel.send(text);\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 // 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
|
+
"names": ["resolve", "SecureChannel"]
|
|
7
|
+
}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AgentVault OpenClaw Channel Plugin
|
|
3
|
+
*
|
|
4
|
+
* Registers AgentVault as a first-class OpenClaw messaging channel.
|
|
5
|
+
* Messages from the AgentVault UI are decrypted and routed into the
|
|
6
|
+
* OpenClaw agent loop; agent replies are encrypted and sent back.
|
|
7
|
+
*
|
|
8
|
+
* Installation (one-time):
|
|
9
|
+
* npx @agentvault/agentvault setup --token=av_tok_...
|
|
10
|
+
*
|
|
11
|
+
* After setup, restart OpenClaw — no further configuration needed.
|
|
12
|
+
*/
|
|
13
|
+
import { SecureChannel } from "./channel.js";
|
|
14
|
+
export declare function setOcRuntime(runtime: any): void;
|
|
15
|
+
export declare function getActiveChannel(accountId?: string): SecureChannel | undefined;
|
|
16
|
+
interface AgentVaultAccount {
|
|
17
|
+
accountId: string;
|
|
18
|
+
dataDir: string;
|
|
19
|
+
apiUrl: string;
|
|
20
|
+
agentName: string;
|
|
21
|
+
httpPort: number;
|
|
22
|
+
configured: boolean;
|
|
23
|
+
}
|
|
24
|
+
export declare const agentVaultPlugin: {
|
|
25
|
+
id: string;
|
|
26
|
+
meta: {
|
|
27
|
+
id: string;
|
|
28
|
+
label: string;
|
|
29
|
+
selectionLabel: string;
|
|
30
|
+
docsPath: string;
|
|
31
|
+
blurb: string;
|
|
32
|
+
aliases: string[];
|
|
33
|
+
};
|
|
34
|
+
capabilities: {
|
|
35
|
+
chatTypes: string[];
|
|
36
|
+
};
|
|
37
|
+
config: {
|
|
38
|
+
listAccountIds: (cfg: any) => string[];
|
|
39
|
+
resolveAccount: (cfg: any, accountId?: string) => AgentVaultAccount;
|
|
40
|
+
};
|
|
41
|
+
gateway: {
|
|
42
|
+
startAccount: (ctx: any) => Promise<{
|
|
43
|
+
stop: () => Promise<void>;
|
|
44
|
+
}>;
|
|
45
|
+
};
|
|
46
|
+
outbound: {
|
|
47
|
+
deliveryMode: "direct";
|
|
48
|
+
targets: {
|
|
49
|
+
id: string;
|
|
50
|
+
label: string;
|
|
51
|
+
accountId: string;
|
|
52
|
+
}[];
|
|
53
|
+
sendText: ({ text, accountId, targetId, }: {
|
|
54
|
+
text: string;
|
|
55
|
+
accountId?: string;
|
|
56
|
+
targetId?: string;
|
|
57
|
+
}) => Promise<{
|
|
58
|
+
ok: boolean;
|
|
59
|
+
error?: string;
|
|
60
|
+
}>;
|
|
61
|
+
};
|
|
62
|
+
};
|
|
63
|
+
export {};
|
|
64
|
+
//# sourceMappingURL=openclaw-plugin.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"openclaw-plugin.d.ts","sourceRoot":"","sources":["../src/openclaw-plugin.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAGH,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAQ7C,wBAAgB,YAAY,CAAC,OAAO,EAAE,GAAG,GAAG,IAAI,CAE/C;AAED,wBAAgB,gBAAgB,CAAC,SAAS,SAAY,GAAG,aAAa,GAAG,SAAS,CAEjF;AAMD,UAAU,iBAAiB;IACzB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,OAAO,CAAC;CACrB;AAMD,eAAO,MAAM,gBAAgB;;;;;;;;;;;;;;8BAcH,GAAG,KAAG,MAAM,EAAE;8BAId,GAAG,cAAc,MAAM,KAAG,iBAAiB;;;4BAavC,GAAG;;;;;;;;;;;mDAsF1B;YACD,IAAI,EAAE,MAAM,CAAC;YACb,SAAS,CAAC,EAAE,MAAM,CAAC;YACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;SACnB,KAAG,OAAO,CAAC;YAAE,EAAE,EAAE,OAAO,CAAC;YAAC,KAAK,CAAC,EAAE,MAAM,CAAA;SAAE,CAAC;;CAc/C,CAAC"}
|
package/dist/setup.d.ts
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AgentVault one-time setup command.
|
|
3
|
+
*
|
|
4
|
+
* Runs enrollment + waits for owner approval + persists state,
|
|
5
|
+
* then auto-registers the agentvault channel in openclaw config.
|
|
6
|
+
*
|
|
7
|
+
* Usage: npx @agentvault/agentvault setup --token=av_tok_...
|
|
8
|
+
*/
|
|
9
|
+
export declare function runSetupCommand(options: {
|
|
10
|
+
token: string;
|
|
11
|
+
name: string;
|
|
12
|
+
apiUrl: string;
|
|
13
|
+
dataDir: string;
|
|
14
|
+
}): Promise<void>;
|
|
15
|
+
/**
|
|
16
|
+
* Install/update the plugin in OpenClaw's extensions directory.
|
|
17
|
+
* Returns true if the plugin is installed (or was already up-to-date).
|
|
18
|
+
*/
|
|
19
|
+
export declare function installPlugin(env: NodeJS.ProcessEnv): boolean;
|
|
20
|
+
/**
|
|
21
|
+
* Configure pm2 to manage the OpenClaw gateway process.
|
|
22
|
+
* Returns true if pm2 was configured (or already configured).
|
|
23
|
+
*/
|
|
24
|
+
export declare function configurePm2(env: NodeJS.ProcessEnv): boolean;
|
|
25
|
+
//# sourceMappingURL=setup.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"setup.d.ts","sourceRoot":"","sources":["../src/setup.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAQH,wBAAsB,eAAe,CAAC,OAAO,EAAE;IAC7C,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;CACjB,GAAG,OAAO,CAAC,IAAI,CAAC,CAkKhB;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,CAAC,UAAU,GAAG,OAAO,CAyC7D;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,CAAC,UAAU,GAAG,OAAO,CA4D5D"}
|
package/dist/state.d.ts
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { PersistedState } from "./types.js";
|
|
2
|
+
export declare function saveState(dataDir: string, state: PersistedState): Promise<void>;
|
|
3
|
+
/**
|
|
4
|
+
* Load raw persisted state from disk.
|
|
5
|
+
* Returns the raw parsed JSON — caller is responsible for migration
|
|
6
|
+
* from legacy format to current PersistedState.
|
|
7
|
+
*
|
|
8
|
+
* Checks agentvault.json first, falls back to secure-channel.json
|
|
9
|
+
* for backward compatibility. Auto-migrates on first legacy load.
|
|
10
|
+
*/
|
|
11
|
+
export declare function loadState(dataDir: string): Promise<any | null>;
|
|
12
|
+
export declare function clearState(dataDir: string): Promise<void>;
|
|
13
|
+
//# sourceMappingURL=state.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"state.d.ts","sourceRoot":"","sources":["../src/state.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAKjD,wBAAsB,SAAS,CAC7B,OAAO,EAAE,MAAM,EACf,KAAK,EAAE,cAAc,GACpB,OAAO,CAAC,IAAI,CAAC,CAWf;AAED;;;;;;;GAOG;AACH,wBAAsB,SAAS,CAC7B,OAAO,EAAE,MAAM,GAEd,OAAO,CAAC,GAAG,GAAG,IAAI,CAAC,CAuBrB;AAED,wBAAsB,UAAU,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAS/D"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
export interface EnrollResponse {
|
|
2
|
+
device_id: string;
|
|
3
|
+
fingerprint: string;
|
|
4
|
+
status: string;
|
|
5
|
+
}
|
|
6
|
+
export interface StatusResponse {
|
|
7
|
+
device_id: string;
|
|
8
|
+
status: string;
|
|
9
|
+
fingerprint: string;
|
|
10
|
+
}
|
|
11
|
+
export interface ActivateResponse {
|
|
12
|
+
device_id: string;
|
|
13
|
+
conversation_id: string;
|
|
14
|
+
status: string;
|
|
15
|
+
device_jwt: string;
|
|
16
|
+
owner_identity_public_key: string;
|
|
17
|
+
owner_ephemeral_public_key: string | null;
|
|
18
|
+
}
|
|
19
|
+
export declare function enrollDevice(apiUrl: string, inviteToken: string, identityPkHex: string, ephemeralPkHex: string, proofHex: string, platform?: string): Promise<EnrollResponse>;
|
|
20
|
+
export declare function pollDeviceStatus(apiUrl: string, deviceId: string): Promise<StatusResponse & {
|
|
21
|
+
rateLimited?: boolean;
|
|
22
|
+
}>;
|
|
23
|
+
export declare function activateDevice(apiUrl: string, deviceId: string): Promise<ActivateResponse>;
|
|
24
|
+
//# sourceMappingURL=transport.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"transport.d.ts","sourceRoot":"","sources":["../src/transport.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,cAAc;IAC7B,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,cAAc;IAC7B,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,gBAAgB;IAC/B,SAAS,EAAE,MAAM,CAAC;IAClB,eAAe,EAAE,MAAM,CAAC;IACxB,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;IACnB,yBAAyB,EAAE,MAAM,CAAC;IAClC,0BAA0B,EAAE,MAAM,GAAG,IAAI,CAAC;CAC3C;AAED,wBAAsB,YAAY,CAChC,MAAM,EAAE,MAAM,EACd,WAAW,EAAE,MAAM,EACnB,aAAa,EAAE,MAAM,EACrB,cAAc,EAAE,MAAM,EACtB,QAAQ,EAAE,MAAM,EAChB,QAAQ,CAAC,EAAE,MAAM,GAChB,OAAO,CAAC,cAAc,CAAC,CAiBzB;AAED,wBAAsB,gBAAgB,CACpC,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,cAAc,GAAG;IAAE,WAAW,CAAC,EAAE,OAAO,CAAA;CAAE,CAAC,CAWrD;AAED,wBAAsB,cAAc,CAClC,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,gBAAgB,CAAC,CAW3B"}
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,209 @@
|
|
|
1
|
+
export interface SecureChannelConfig {
|
|
2
|
+
inviteToken: string;
|
|
3
|
+
dataDir: string;
|
|
4
|
+
apiUrl: string;
|
|
5
|
+
agentName?: string;
|
|
6
|
+
platform?: string;
|
|
7
|
+
maxHistorySize?: number;
|
|
8
|
+
webhookUrl?: string;
|
|
9
|
+
httpPort?: number;
|
|
10
|
+
onMessage?: (plaintext: string, metadata: MessageMetadata) => void;
|
|
11
|
+
onStateChange?: (state: ChannelState) => void;
|
|
12
|
+
onA2AMessage?: (msg: A2AMessage) => void;
|
|
13
|
+
/** Enable client-side policy scanning. If true, rules are fetched on connect. */
|
|
14
|
+
enableScanning?: boolean;
|
|
15
|
+
}
|
|
16
|
+
export type ChannelState = "idle" | "enrolling" | "polling" | "activating" | "connecting" | "ready" | "disconnected" | "error";
|
|
17
|
+
export interface AttachmentData {
|
|
18
|
+
filename: string;
|
|
19
|
+
mime: string;
|
|
20
|
+
size: number;
|
|
21
|
+
filePath: string;
|
|
22
|
+
/** Base64-encoded decrypted content (for images passed to LLM vision) */
|
|
23
|
+
base64?: string;
|
|
24
|
+
/** Extracted text content (for text-based files) */
|
|
25
|
+
textContent?: string;
|
|
26
|
+
}
|
|
27
|
+
export interface MessageMetadata {
|
|
28
|
+
messageId: string;
|
|
29
|
+
conversationId: string;
|
|
30
|
+
timestamp: string;
|
|
31
|
+
topicId?: string;
|
|
32
|
+
attachment?: AttachmentData;
|
|
33
|
+
spanId?: string;
|
|
34
|
+
parentSpanId?: string;
|
|
35
|
+
messageType?: string;
|
|
36
|
+
priority?: string;
|
|
37
|
+
envelopeVersion?: string;
|
|
38
|
+
}
|
|
39
|
+
export interface SendOptions {
|
|
40
|
+
topicId?: string;
|
|
41
|
+
messageType?: string;
|
|
42
|
+
priority?: string;
|
|
43
|
+
parentSpanId?: string;
|
|
44
|
+
metadata?: Record<string, unknown>;
|
|
45
|
+
}
|
|
46
|
+
export interface DecisionOption {
|
|
47
|
+
option_id: string;
|
|
48
|
+
label: string;
|
|
49
|
+
risk_level: "low" | "medium" | "high" | "critical";
|
|
50
|
+
is_default?: boolean;
|
|
51
|
+
}
|
|
52
|
+
export interface ContextRef {
|
|
53
|
+
type: string;
|
|
54
|
+
uri: string;
|
|
55
|
+
label: string;
|
|
56
|
+
}
|
|
57
|
+
export interface DecisionRequest {
|
|
58
|
+
title: string;
|
|
59
|
+
description?: string;
|
|
60
|
+
options: DecisionOption[];
|
|
61
|
+
context_refs?: ContextRef[];
|
|
62
|
+
deadline?: string;
|
|
63
|
+
auto_action?: {
|
|
64
|
+
option_id: string;
|
|
65
|
+
trigger: string;
|
|
66
|
+
description?: string;
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
export interface DecisionResponse {
|
|
70
|
+
decision_id: string;
|
|
71
|
+
selected_option_id?: string;
|
|
72
|
+
resolved_at?: string;
|
|
73
|
+
action?: "approve" | "deny" | "defer";
|
|
74
|
+
defer_until?: string;
|
|
75
|
+
defer_reason?: string;
|
|
76
|
+
}
|
|
77
|
+
export interface HistoryEntry {
|
|
78
|
+
sender: "owner" | "agent";
|
|
79
|
+
text: string;
|
|
80
|
+
ts: string;
|
|
81
|
+
topicId?: string;
|
|
82
|
+
}
|
|
83
|
+
export interface DeviceSession {
|
|
84
|
+
ownerDeviceId: string;
|
|
85
|
+
ratchetState: string;
|
|
86
|
+
activated?: boolean;
|
|
87
|
+
}
|
|
88
|
+
export interface PersistedState {
|
|
89
|
+
deviceId: string;
|
|
90
|
+
deviceJwt: string;
|
|
91
|
+
primaryConversationId: string;
|
|
92
|
+
sessions: Record<string, DeviceSession>;
|
|
93
|
+
identityKeypair: {
|
|
94
|
+
publicKey: string;
|
|
95
|
+
privateKey: string;
|
|
96
|
+
};
|
|
97
|
+
ephemeralKeypair: {
|
|
98
|
+
publicKey: string;
|
|
99
|
+
privateKey: string;
|
|
100
|
+
};
|
|
101
|
+
fingerprint: string;
|
|
102
|
+
lastMessageTimestamp?: string;
|
|
103
|
+
messageHistory?: HistoryEntry[];
|
|
104
|
+
topics?: Array<{
|
|
105
|
+
id: string;
|
|
106
|
+
name: string;
|
|
107
|
+
isDefault: boolean;
|
|
108
|
+
}>;
|
|
109
|
+
defaultTopicId?: string;
|
|
110
|
+
groupId?: string;
|
|
111
|
+
hubAddress?: string;
|
|
112
|
+
/** A2A channel state (agent-to-agent communication) */
|
|
113
|
+
a2aChannels?: Record<string, {
|
|
114
|
+
channelId: string;
|
|
115
|
+
hubAddress: string;
|
|
116
|
+
conversationId: string;
|
|
117
|
+
role?: "initiator" | "responder";
|
|
118
|
+
session?: DeviceSession;
|
|
119
|
+
pendingEphemeralPrivateKey?: string;
|
|
120
|
+
}>;
|
|
121
|
+
/** Outbound messages queued while disconnected */
|
|
122
|
+
outboundQueue?: Array<{
|
|
123
|
+
convId: string;
|
|
124
|
+
headerBlob: string;
|
|
125
|
+
ciphertext: string;
|
|
126
|
+
messageGroupId: string;
|
|
127
|
+
topicId?: string;
|
|
128
|
+
}>;
|
|
129
|
+
/** Multi-agent room state */
|
|
130
|
+
rooms?: Record<string, RoomState>;
|
|
131
|
+
}
|
|
132
|
+
/** Legacy state format for backward compatibility */
|
|
133
|
+
export interface LegacyPersistedState {
|
|
134
|
+
deviceId: string;
|
|
135
|
+
deviceJwt: string;
|
|
136
|
+
conversationId: string;
|
|
137
|
+
identityKeypair: {
|
|
138
|
+
publicKey: string;
|
|
139
|
+
privateKey: string;
|
|
140
|
+
};
|
|
141
|
+
ephemeralKeypair: {
|
|
142
|
+
publicKey: string;
|
|
143
|
+
privateKey: string;
|
|
144
|
+
};
|
|
145
|
+
fingerprint: string;
|
|
146
|
+
ratchetState: string;
|
|
147
|
+
lastMessageTimestamp?: string;
|
|
148
|
+
}
|
|
149
|
+
export interface RoomMemberInfo {
|
|
150
|
+
deviceId: string;
|
|
151
|
+
entityType: string;
|
|
152
|
+
displayName: string;
|
|
153
|
+
identityPublicKey?: string;
|
|
154
|
+
ephemeralPublicKey?: string;
|
|
155
|
+
}
|
|
156
|
+
export interface RoomConversationInfo {
|
|
157
|
+
id: string;
|
|
158
|
+
participantA: string;
|
|
159
|
+
participantB: string;
|
|
160
|
+
}
|
|
161
|
+
export interface RoomInfo {
|
|
162
|
+
roomId: string;
|
|
163
|
+
name: string;
|
|
164
|
+
members: RoomMemberInfo[];
|
|
165
|
+
conversationIds: string[];
|
|
166
|
+
}
|
|
167
|
+
export interface RoomState {
|
|
168
|
+
roomId: string;
|
|
169
|
+
name: string;
|
|
170
|
+
conversationIds: string[];
|
|
171
|
+
members: RoomMemberInfo[];
|
|
172
|
+
}
|
|
173
|
+
export interface HeartbeatStatus {
|
|
174
|
+
agent_status: string;
|
|
175
|
+
current_task: string;
|
|
176
|
+
}
|
|
177
|
+
export interface StatusAlert {
|
|
178
|
+
title: string;
|
|
179
|
+
message: string;
|
|
180
|
+
severity: "info" | "warning" | "error" | "critical";
|
|
181
|
+
detail?: string;
|
|
182
|
+
detailFormat?: "markdown" | "json" | "text";
|
|
183
|
+
category?: "performance" | "security" | "error" | "info";
|
|
184
|
+
}
|
|
185
|
+
export interface RoomParticipantEvent {
|
|
186
|
+
roomId: string;
|
|
187
|
+
participant: {
|
|
188
|
+
deviceId: string;
|
|
189
|
+
participantType: "human" | "agent";
|
|
190
|
+
displayName?: string;
|
|
191
|
+
};
|
|
192
|
+
}
|
|
193
|
+
export interface A2AChannel {
|
|
194
|
+
channelId: string;
|
|
195
|
+
initiatorHubAddress: string;
|
|
196
|
+
responderHubAddress: string;
|
|
197
|
+
conversationId: string | null;
|
|
198
|
+
status: "pending" | "approved" | "active" | "rejected" | "revoked";
|
|
199
|
+
createdAt: string;
|
|
200
|
+
}
|
|
201
|
+
export interface A2AMessage {
|
|
202
|
+
text: string;
|
|
203
|
+
fromHubAddress: string;
|
|
204
|
+
channelId: string;
|
|
205
|
+
conversationId: string;
|
|
206
|
+
parentSpanId?: string;
|
|
207
|
+
timestamp: string;
|
|
208
|
+
}
|
|
209
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
|