@agentvault/agentvault 0.15.3 → 0.16.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.
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
- "sources": ["../src/openclaw-compat.ts", "../src/openclaw-entry.ts", "../src/account-config.ts", "../src/fetch-interceptor.ts", "../src/http-handlers.ts"],
4
- "sourcesContent": ["/**\n * OpenClaw SDK compatibility layer \u2014 dynamic import wrappers with caching.\n *\n * Each wrapper attempts to import a deep SDK module at runtime. If the import\n * fails (older gateway, missing SDK), the function returns a no-op result.\n * Results are cached after the first attempt.\n *\n * IMPORTANT: All imports are guarded by try/catch \u2014 the plugin degrades\n * gracefully on older OpenClaw versions.\n */\n\nimport type { AgentEventPayload, TranscriptUpdatePayload } from \"./openclaw-types.js\";\n\n// ---------------------------------------------------------------------------\n// requestHeartbeatNow \u2014 wake agent proactively before outbound sends\n// ---------------------------------------------------------------------------\n\nlet _heartbeatFn: ((opts?: { reason?: string }) => Promise<void>) | false | null = null;\n\n/**\n * Request an immediate heartbeat wake from the OpenClaw gateway.\n * Returns true if the heartbeat API was available and called, false otherwise.\n * Never throws.\n */\nexport async function requestHeartbeatNow(opts?: { reason?: string }): Promise<boolean> {\n if (_heartbeatFn === null) {\n try {\n // @ts-expect-error \u2014 deep SDK import only available when openclaw is installed\n const mod = await import(\"openclaw/dist/plugin-sdk/infra/heartbeat-wake.js\");\n _heartbeatFn = mod.requestHeartbeatNow ?? mod.default?.requestHeartbeatNow ?? false;\n } catch {\n _heartbeatFn = false;\n }\n }\n if (typeof _heartbeatFn === \"function\") {\n try {\n await _heartbeatFn(opts);\n return true;\n } catch {\n return false;\n }\n }\n return false;\n}\n\n// ---------------------------------------------------------------------------\n// onAgentEvent \u2014 subscribe to agent-level events for trust telemetry\n// ---------------------------------------------------------------------------\n\ntype AgentEventCallback = (event: AgentEventPayload) => void;\nlet _agentEventFn: ((cb: AgentEventCallback) => (() => void)) | false | null = null;\n\n/**\n * Subscribe to agent-level events (tool_use, reasoning_complete, error, etc.).\n * Returns an unsubscribe function, or a no-op if the API is unavailable.\n */\nexport async function onAgentEvent(callback: AgentEventCallback): Promise<() => void> {\n if (_agentEventFn === null) {\n try {\n // @ts-expect-error \u2014 deep SDK import only available when openclaw is installed\n const mod = await import(\"openclaw/dist/plugin-sdk/infra/agent-events.js\");\n _agentEventFn = mod.onAgentEvent ?? mod.default?.onAgentEvent ?? false;\n } catch {\n _agentEventFn = false;\n }\n }\n if (typeof _agentEventFn === \"function\") {\n try {\n return _agentEventFn(callback);\n } catch {\n return () => {};\n }\n }\n return () => {};\n}\n\n// ---------------------------------------------------------------------------\n// onSessionTranscriptUpdate \u2014 subscribe to transcript deltas\n// ---------------------------------------------------------------------------\n\ntype TranscriptCallback = (update: TranscriptUpdatePayload) => void;\nlet _transcriptFn: ((cb: TranscriptCallback) => (() => void)) | false | null = null;\n\n/**\n * Subscribe to session transcript updates for behavioral analysis.\n * Returns an unsubscribe function, or a no-op if the API is unavailable.\n */\nexport async function onSessionTranscriptUpdate(callback: TranscriptCallback): Promise<() => void> {\n if (_transcriptFn === null) {\n try {\n // @ts-expect-error \u2014 deep SDK import only available when openclaw is installed\n const mod = await import(\"openclaw/dist/plugin-sdk/sessions/transcript-events.js\");\n _transcriptFn = mod.onSessionTranscriptUpdate ?? mod.default?.onSessionTranscriptUpdate ?? false;\n } catch {\n _transcriptFn = false;\n }\n }\n if (typeof _transcriptFn === \"function\") {\n try {\n return _transcriptFn(callback);\n } catch {\n return () => {};\n }\n }\n return () => {};\n}\n", "/**\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\";\nimport { listAccountIds, resolveAccount } from \"./account-config.js\";\nimport { installFetchInterceptor, runWithTraceContext } from \"./fetch-interceptor.js\";\nimport { handleSendRequest, handleActionRequest, handleDecisionRequest, handleStatusRequest } from \"./http-handlers.js\";\nimport { requestHeartbeatNow } from \"./openclaw-compat.js\";\nimport type {\n OpenClawPluginApi,\n PluginRuntime,\n ChannelGatewayContext,\n ResolvedAccountBase,\n ChannelOutboundPayloadContext,\n ReplyPayload,\n MessageSentEvent,\n SessionStartEvent,\n SessionEndEvent,\n} from \"./openclaw-types.js\";\n\n// --- Runtime and active channels (set during register) ---\nlet _ocRuntime: PluginRuntime | null = null;\nconst _channels = new Map<string, any>();\nconst _messageQueue: Array<() => Promise<void>> = [];\n\n// --- A2A conversation loop prevention ---\n// Tracks recent A2A reply timestamps per channel to prevent infinite loops.\n// Max replies per channel within the window, then cooldown.\nconst A2A_MAX_REPLIES_PER_WINDOW = 4;\nconst A2A_WINDOW_MS = 60_000; // 1-minute sliding window\nconst A2A_COOLDOWN_MS = 120_000; // 2-minute cooldown after hitting limit\nconst _a2aReplyTimestamps = new Map<string, number[]>();\nconst _a2aCooldownUntil = new Map<string, number>();\n\nfunction _a2aCanReply(channelId: string): boolean {\n const now = Date.now();\n\n // Check cooldown\n const cooldownEnd = _a2aCooldownUntil.get(channelId) ?? 0;\n if (now < cooldownEnd) {\n return false;\n }\n\n // Get timestamps within window\n const timestamps = _a2aReplyTimestamps.get(channelId) ?? [];\n const recent = timestamps.filter((t) => now - t < A2A_WINDOW_MS);\n\n if (recent.length >= A2A_MAX_REPLIES_PER_WINDOW) {\n // Hit limit \u2014 enter cooldown\n _a2aCooldownUntil.set(channelId, now + A2A_COOLDOWN_MS);\n _a2aReplyTimestamps.set(channelId, []);\n console.warn(\n `[AgentVault] A2A rate limit hit for channel ${channelId.slice(0, 8)}... \u2014 ` +\n `${A2A_MAX_REPLIES_PER_WINDOW} replies in ${A2A_WINDOW_MS / 1000}s, cooling down ${A2A_COOLDOWN_MS / 1000}s`,\n );\n return false;\n }\n\n return true;\n}\n\nfunction _a2aRecordReply(channelId: string): void {\n const now = Date.now();\n const timestamps = _a2aReplyTimestamps.get(channelId) ?? [];\n timestamps.push(now);\n // Keep only timestamps within window\n _a2aReplyTimestamps.set(\n channelId,\n timestamps.filter((t) => now - t < A2A_WINDOW_MS),\n );\n}\n\n/** Whether OpenClaw managed HTTP routes are active (vs self-managed server). */\nexport let isUsingManagedRoutes = false;\n\n/**\n * Shared mutable targets array for OpenClaw outbound routing.\n * OpenClaw validates `to` against this list before calling sendText/sendPayload.\n * We mutate it at runtime to add A2A channel targets dynamically.\n */\nconst _outboundTargets: Array<{ id: string; label: string; accountId: string }> = [\n { id: \"owner\", label: \"AgentVault Owner\", accountId: \"default\" },\n { id: \"default\", label: \"AgentVault Owner (default)\", accountId: \"default\" },\n];\n\n/** Register a room as a valid outbound target (idempotent). */\nfunction _registerRoomTarget(roomId: string, roomName: string, accountId: string): void {\n const targetId = `room:${roomId}`;\n if (_outboundTargets.some((t) => t.id === targetId)) return;\n _outboundTargets.push({ id: targetId, label: `Room: ${roomName}`, accountId });\n console.log(`[AgentVault] Registered room target: ${roomName} (${roomId.slice(0, 8)}...)`);\n}\n\n/** Register an A2A peer as a valid outbound target (idempotent). */\nfunction _registerA2ATarget(hubAddress: string, accountId: string): void {\n const targetId = `a2a:${hubAddress}`;\n if (_outboundTargets.some((t) => t.id === targetId)) return;\n _outboundTargets.push({\n id: targetId,\n label: `A2A: ${hubAddress}`,\n accountId,\n });\n console.log(`[AgentVault] Registered A2A target: ${targetId}`);\n}\n\nfunction _setRuntime(rt: PluginRuntime) {\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// --- @mention filtering for multi-agent rooms ---\n\n/** Extract @mention names from plaintext. Returns lowercased names. */\nfunction _parseMentions(text: string): string[] {\n const mentions: string[] = [];\n // Match @word at word boundary \u2014 supports multi-word via sequential matching\n const re = /@(\\w[\\w]*)/gi;\n let match: RegExpExecArray | null;\n while ((match = re.exec(text)) !== null) {\n mentions.push(match[1].toLowerCase());\n }\n return mentions;\n}\n\n/** Determine whether this agent should process a room message based on @mentions. */\nfunction _shouldProcessRoomMessage(\n plaintext: string,\n agentName: string,\n accountId: string,\n): boolean {\n const mentions = _parseMentions(plaintext);\n // No mentions \u2192 broadcast to all agents (current behavior)\n if (mentions.length === 0) return true;\n // @all / @everyone \u2192 all agents process\n if (mentions.includes(\"all\") || mentions.includes(\"everyone\")) return true;\n // Check if this agent is mentioned (by name or accountId)\n const nameLower = agentName.toLowerCase();\n const idLower = accountId.toLowerCase();\n // Match first word of agent name (e.g., \"Cortina\" from \"Cortina (Coder)\")\n const firstWord = nameLower.split(/[\\s(]/)[0];\n return mentions.some(\n (m) => m === nameLower || m === firstWord || m === idLower,\n );\n}\n\n/** Strip the matching @mention prefix from plaintext so the agent sees clean text. */\nfunction _stripMentions(\n text: string,\n agentName: string,\n accountId: string,\n): string {\n const nameLower = agentName.toLowerCase();\n const firstWord = nameLower.split(/[\\s(]/)[0];\n const idLower = accountId.toLowerCase();\n // Remove all @mentions that match this agent (case-insensitive)\n return text\n .replace(/@(\\w[\\w]*)/gi, (full, name) => {\n const lower = name.toLowerCase();\n if (lower === nameLower || lower === firstWord || lower === idLower) {\n return \"\";\n }\n // Also strip @all/@everyone since they're routing directives\n if (lower === \"all\" || lower === \"everyone\") return \"\";\n return full;\n })\n .replace(/^\\s+/, \"\") // trim leading whitespace left by stripped mention\n .trim();\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: rawPlaintext, metadata, channel, account, cfg } = params;\n const isRoomMessage = Boolean(metadata.roomId);\n const isA2AMessage = Boolean(metadata.a2aChannelId);\n\n // @mention filtering: only for room messages\n if (isRoomMessage) {\n if (!_shouldProcessRoomMessage(rawPlaintext, account.agentName ?? \"\", account.accountId ?? \"\")) {\n return; // This agent is not mentioned \u2014 skip silently\n }\n }\n\n // Strip @mentions from plaintext so the agent sees clean text\n const plaintext = isRoomMessage\n ? _stripMentions(rawPlaintext, account.agentName ?? \"\", account.accountId ?? \"\")\n : rawPlaintext;\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 const inferenceSpanId = randomBytes(8).toString(\"hex\");\n // Instrumentation context for agent code to report LLM/tool/error spans\n /** Helper: send an activity span over WS for real-time owner display. */\n const _sendActivity = (spanData: Record<string, unknown>) => {\n try { channel.sendActivitySpan({ ...spanData, trace_id: traceId, parent_span_id: inferenceSpanId }); } catch {}\n };\n\n const _instrument = {\n reportLlm: (opts: any) => {\n const enriched = { ...opts, traceId, parentSpanId: inferenceSpanId };\n if (opts.skillName || _instrument.skillName) enriched.skillName = opts.skillName ?? _instrument.skillName;\n try { channel.telemetry?.reportLlmCall(enriched); } catch {}\n const activityAttrs: Record<string, string> = { \"ai.agent.llm.model\": opts.model ?? \"\" };\n if (enriched.skillName) activityAttrs[\"ai.agent.skill.name\"] = enriched.skillName;\n _sendActivity({\n span_id: randomBytes(8).toString(\"hex\"), span_type: \"llm\", span_name: opts.model ?? \"LLM\",\n status: opts.status === \"error\" ? \"error\" : \"ok\",\n start_time: new Date(Date.now() - (opts.latencyMs ?? 0)).toISOString(),\n end_time: new Date().toISOString(), duration_ms: opts.latencyMs ?? 0,\n attributes: activityAttrs,\n tokens_input: opts.tokensInput, tokens_output: opts.tokensOutput,\n });\n },\n reportTool: (opts: any) => {\n const enriched = { ...opts, traceId, parentSpanId: inferenceSpanId };\n if (opts.skillName || _instrument.skillName) enriched.skillName = opts.skillName ?? _instrument.skillName;\n try { channel.telemetry?.reportToolCall(enriched); } catch {}\n const activityAttrs: Record<string, string> = { \"ai.agent.tool.name\": opts.toolName ?? \"\" };\n if (enriched.skillName) activityAttrs[\"ai.agent.skill.name\"] = enriched.skillName;\n _sendActivity({\n span_id: randomBytes(8).toString(\"hex\"), span_type: \"tool\", span_name: opts.toolName ?? \"tool\",\n status: opts.success === false ? \"error\" : \"ok\",\n start_time: new Date(Date.now() - (opts.latencyMs ?? 0)).toISOString(),\n end_time: new Date().toISOString(), duration_ms: opts.latencyMs ?? 0,\n attributes: activityAttrs,\n tool_success: opts.success,\n });\n },\n reportError: (opts: any) => {\n const enriched = { ...opts, traceId, parentSpanId: inferenceSpanId };\n if (opts.skillName || _instrument.skillName) enriched.skillName = opts.skillName ?? _instrument.skillName;\n try { channel.telemetry?.reportError(enriched); } catch {}\n const activityAttrs: Record<string, string> = { \"ai.agent.error.type\": opts.errorType ?? \"\" };\n if (enriched.skillName) activityAttrs[\"ai.agent.skill.name\"] = enriched.skillName;\n _sendActivity({\n span_id: randomBytes(8).toString(\"hex\"), span_type: \"error\", span_name: opts.errorType ?? \"error\",\n status: \"error\",\n start_time: new Date().toISOString(), end_time: new Date().toISOString(), duration_ms: 0,\n attributes: activityAttrs,\n error_type: opts.errorType, error_message: opts.errorMessage,\n });\n },\n reportHttp: (opts: any) => {\n const enriched = { ...opts, traceId, parentSpanId: inferenceSpanId };\n if (opts.skillName || _instrument.skillName) enriched.skillName = opts.skillName ?? _instrument.skillName;\n try { channel.telemetry?.reportHttpCall(enriched); } catch {}\n const activityAttrs: Record<string, string> = { \"ai.agent.http.method\": opts.method ?? \"\", \"ai.agent.http.url\": opts.url ?? \"\" };\n if (enriched.skillName) activityAttrs[\"ai.agent.skill.name\"] = enriched.skillName;\n _sendActivity({\n span_id: randomBytes(8).toString(\"hex\"), span_type: \"http\",\n span_name: (() => { try { return new URL(opts.url).hostname; } catch { return opts.url?.slice(0, 40) ?? \"http\"; } })(),\n status: (opts.statusCode ?? 200) >= 400 ? \"error\" : \"ok\",\n start_time: new Date(Date.now() - (opts.latencyMs ?? 0)).toISOString(),\n end_time: new Date().toISOString(), duration_ms: opts.latencyMs ?? 0,\n attributes: activityAttrs,\n http_method: opts.method, http_status_code: opts.statusCode, http_url: opts.url,\n });\n },\n reportAction: (opts: any) => {\n const enriched = { ...opts, traceId, parentSpanId: inferenceSpanId };\n if (opts.skillName || _instrument.skillName) enriched.skillName = opts.skillName ?? _instrument.skillName;\n try { channel.telemetry?.reportActionCall(enriched); } catch {}\n const activityAttrs: Record<string, string> = { \"ai.agent.action.type\": opts.actionType ?? \"\", \"ai.agent.action.target\": opts.target ?? \"\" };\n if (enriched.skillName) activityAttrs[\"ai.agent.skill.name\"] = enriched.skillName;\n _sendActivity({\n span_id: randomBytes(8).toString(\"hex\"), span_type: \"action\",\n span_name: `${opts.actionType ?? \"action\"}: ${opts.target ?? \"\"}`,\n status: opts.success === false ? \"error\" : \"ok\",\n start_time: new Date(Date.now() - (opts.latencyMs ?? 0)).toISOString(),\n end_time: new Date().toISOString(), duration_ms: opts.latencyMs ?? 0,\n attributes: activityAttrs,\n action_type: opts.actionType, action_target: opts.target,\n });\n },\n reportNav: (opts: any) => {\n const enriched = { ...opts, traceId, parentSpanId: inferenceSpanId };\n if (opts.skillName || _instrument.skillName) enriched.skillName = opts.skillName ?? _instrument.skillName;\n try { channel.telemetry?.reportNavCall(enriched); } catch {}\n const activityAttrs: Record<string, string> = { \"ai.agent.nav.to_url\": opts.toUrl ?? \"\" };\n if (enriched.skillName) activityAttrs[\"ai.agent.skill.name\"] = enriched.skillName;\n _sendActivity({\n span_id: randomBytes(8).toString(\"hex\"), span_type: \"nav\",\n span_name: opts.toUrl?.slice(0, 40) ?? \"navigate\",\n status: opts.status === \"error\" ? \"error\" : \"ok\",\n start_time: new Date(Date.now() - (opts.latencyMs ?? 0)).toISOString(),\n end_time: new Date().toISOString(), duration_ms: opts.latencyMs ?? 0,\n attributes: activityAttrs,\n });\n },\n skillName: undefined as string | undefined,\n traceId,\n parentSpanId: inferenceSpanId,\n };\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\": isA2AMessage ? \"a2a\" : 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!; // Non-null: caller guards with `if (!_ocRuntime)` check\n\n // Resolve room/sender context for room messages\n let roomName: string | undefined;\n let senderDisplayName: string | undefined;\n if (isRoomMessage && metadata.roomId) {\n roomName = metadata.roomName;\n if (!roomName) {\n const rooms = channel.getRooms?.() ?? [];\n const room = rooms.find((r: any) => r.roomId === metadata.roomId);\n if (room) {\n roomName = room.name;\n if (metadata.senderDeviceId) {\n const member = room.members?.find((m: any) => m.deviceId === metadata.senderDeviceId);\n if (member) senderDisplayName = member.displayName;\n }\n }\n }\n }\n\n const route = core.channel.routing.resolveAgentRoute({\n cfg,\n channel: \"agentvault\",\n accountId: account.accountId,\n peer: {\n kind: isA2AMessage ? \"a2a\" as any : isRoomMessage ? \"group\" as any : \"direct\",\n id: isA2AMessage\n ? `agentvault:a2a:${metadata.fromHubAddress}`\n : isRoomMessage\n ? `agentvault:room:${metadata.roomId}`\n : \"agentvault:owner\",\n },\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: isA2AMessage ? `Agent (${metadata.fromHubAddress})` : isRoomMessage ? (senderDisplayName ?? \"Room Member\") : \"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: isA2AMessage ? `a2a:${metadata.fromHubAddress}` : isRoomMessage ? `agentvault:room:${metadata.roomId}` : \"agentvault:owner\",\n To: `agentvault:agent:${account.accountId}`,\n SessionKey: route.sessionKey,\n AccountId: account.accountId,\n ChatType: isA2AMessage ? \"a2a\" : isRoomMessage ? \"room\" : \"direct\",\n ConversationLabel: isA2AMessage ? `A2A: ${metadata.fromHubAddress}` : isRoomMessage ? (roomName ?? \"AgentVault Room\") : \"AgentVault\",\n SenderName: isA2AMessage ? metadata.fromHubAddress : isRoomMessage ? (senderDisplayName ?? \"Room Member\") : \"Owner\",\n SenderId: isA2AMessage ? `a2a:${metadata.fromHubAddress}` : isRoomMessage ? `agentvault:room:${metadata.senderDeviceId ?? 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 Instrument: _instrument, // OpenClaw ctx convention\n AgentVaultTelemetry: _instrument, // AgentVault-specific accessor\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 runWithTraceContext(\n { traceId, parentSpanId: inferenceSpanId },\n () => 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: A2A \u2192 sendToAgent, room \u2192 sendToRoom, 1:1 \u2192 send\n if (isA2AMessage) {\n // Loop prevention: rate limit A2A replies per channel\n if (!_a2aCanReply(metadata.a2aChannelId)) {\n console.warn(`[AgentVault] A2A reply suppressed (rate limit) for channel ${metadata.a2aChannelId?.slice(0, 8)}...`);\n return;\n }\n await channel.sendToAgent(metadata.fromHubAddress, text, {\n parentSpanId: inferenceSpanId,\n });\n _a2aRecordReply(metadata.a2aChannelId);\n } else if (isRoomMessage) {\n await channel.sendToRoom(metadata.roomId, text, {\n metadata: { content_length: text.length },\n });\n } else {\n await channel.send(text, {\n conversationId: metadata.conversationId,\n topicId: metadata.topicId,\n });\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\n const endTime = Date.now();\n\n // Emit child spans for the completed message lifecycle\n _emitHierarchicalSpans(channel, {\n traceId,\n rootSpanId,\n inferenceSpanId,\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 inferenceSpanId,\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 // Dedicated error span for the Errors tab\n _emitChildSpan(channel, {\n traceId,\n parentSpanId: rootSpanId,\n name: \"error\",\n startTime: endTime,\n endTime: endTime,\n attributes: {\n \"ai.agent.error.type\": (err as any)?.constructor?.name ?? \"Error\",\n \"ai.agent.error.message\": String(err),\n },\n status: \"error\",\n statusMessage: String(err),\n });\n throw err;\n }\n}\n\n/** Infer a span type from the span name for activity stream display. */\nfunction _inferSpanType(name: string): \"llm\" | \"tool\" | \"http\" | \"action\" | \"error\" | \"nav\" {\n if (name === \"error\" || name.includes(\"error\")) return \"error\";\n if (name.startsWith(\"llm.\") || name.includes(\"inference\")) return \"llm\";\n if (name.startsWith(\"tool.\") || name.includes(\"tool\")) return \"tool\";\n if (name.startsWith(\"http.\") || name.includes(\"http\")) return \"http\";\n if (name.startsWith(\"nav.\") || name.includes(\"nav\")) return \"nav\";\n if (name.startsWith(\"action.\") || name.includes(\"action\")) return \"action\";\n return \"action\"; // default fallback\n}\n\n/** Extract a human-readable span name from span attributes. */\nfunction _extractSpanName(name: string, attrs: Record<string, string | number | boolean>): string {\n if (attrs[\"ai.agent.llm.model\"]) return String(attrs[\"ai.agent.llm.model\"]);\n if (attrs[\"ai.agent.tool.name\"]) return String(attrs[\"ai.agent.tool.name\"]);\n if (attrs[\"ai.agent.http.url\"]) {\n try { return new URL(String(attrs[\"ai.agent.http.url\"])).hostname; } catch { /* use raw */ }\n return String(attrs[\"ai.agent.http.url\"]).slice(0, 40);\n }\n if (attrs[\"ai.agent.action.type\"]) return `${attrs[\"ai.agent.action.type\"]}: ${attrs[\"ai.agent.action.target\"] ?? \"\"}`;\n if (attrs[\"ai.agent.nav.to_url\"]) return String(attrs[\"ai.agent.nav.to_url\"]).slice(0, 40);\n if (attrs[\"ai.agent.error.type\"]) return String(attrs[\"ai.agent.error.type\"]);\n return name;\n}\n\n/** Emit a single child span via the channel's telemetry reporter + WS activity stream. */\nfunction _emitChildSpan(channel: any, opts: {\n traceId: string;\n parentSpanId: string;\n spanId?: 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 const spanId = opts.spanId ?? randomBytes(8).toString(\"hex\");\n\n reporter.reportCustomSpan({\n traceId: opts.traceId,\n spanId,\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\n // Dual-path: also send via WS for real-time activity streaming\n try {\n const spanType = _inferSpanType(opts.name);\n const spanName = _extractSpanName(opts.name, opts.attributes);\n const durationMs = opts.endTime - opts.startTime;\n channel.sendActivitySpan({\n trace_id: opts.traceId,\n span_id: spanId,\n parent_span_id: opts.parentSpanId,\n span_type: spanType,\n span_name: spanName,\n status: opts.status,\n start_time: new Date(opts.startTime).toISOString(),\n end_time: new Date(opts.endTime).toISOString(),\n duration_ms: durationMs,\n attributes: opts.attributes,\n ...(spanType === \"llm\" ? {\n tokens_input: opts.attributes[\"ai.agent.llm.tokens_input\"],\n tokens_output: opts.attributes[\"ai.agent.llm.tokens_output\"],\n } : {}),\n ...(spanType === \"http\" ? {\n http_method: opts.attributes[\"ai.agent.http.method\"],\n http_status_code: opts.attributes[\"ai.agent.http.status_code\"],\n http_url: opts.attributes[\"ai.agent.http.url\"],\n } : {}),\n ...(spanType === \"tool\" ? {\n tool_success: opts.attributes[\"ai.agent.tool.success\"],\n } : {}),\n ...(spanType === \"error\" ? {\n error_type: opts.attributes[\"ai.agent.error.type\"],\n error_message: opts.attributes[\"ai.agent.error.message\"],\n } : {}),\n });\n } catch { /* WS activity is best-effort */ }\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 inferenceSpanId?: 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 spanId: opts.inferenceSpanId,\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\", \"room\"] },\n config: { listAccountIds, resolveAccount },\n\n gateway: {\n /** Health probe for `openclaw channels status --probe` */\n probe: async (ctx: any) => {\n const accountId = ctx?.accountId ?? \"default\";\n const ch = _channels.get(accountId);\n if (!ch) return { ok: false, status: \"disconnected\", error: \"Channel not started\" };\n const state = ch.state;\n return {\n ok: state === \"ready\",\n status: state,\n deviceId: ch.deviceId ?? undefined,\n sessions: ch.sessionCount,\n };\n },\n\n /** Status for `openclaw health --json` per-channel summary */\n status: (ctx: any) => {\n const accountId = ctx?.accountId ?? \"default\";\n const ch = _channels.get(accountId);\n if (!ch) return { connected: false, status: \"not_started\" };\n return {\n connected: ch.state === \"ready\",\n status: ch.state,\n deviceId: ch.deviceId ?? undefined,\n sessions: ch.sessionCount,\n encrypted: true,\n };\n },\n\n startAccount: async (ctx: ChannelGatewayContext<ResolvedAccountBase>) => {\n const { account, cfg, log, abortSignal } = ctx;\n const _log: ((msg: string) => void) | undefined = typeof log === \"function\" ? log : log?.info?.bind(log);\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(/^~/, require(\"node:os\").homedir()));\n _log?.(`[AgentVault] starting (dataDir=${dataDir})`);\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?.(\"[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?.(`[AgentVault] inbound error: ${String(err)}`);\n }\n },\n onA2AMessage: async (msg: any) => {\n const a2aMetadata = {\n a2aChannelId: msg.channelId,\n fromHubAddress: msg.fromHubAddress,\n conversationId: msg.conversationId,\n timestamp: msg.timestamp,\n parentSpanId: msg.parentSpanId,\n messageId: `a2a:${msg.channelId}:${Date.now()}`,\n };\n if (!_ocRuntime) {\n _log?.(\"[AgentVault] runtime not ready, queuing A2A message\");\n _messageQueue.push(async () => {\n await handleInbound({ plaintext: msg.text, metadata: a2aMetadata, channel, account, cfg });\n });\n return;\n }\n try {\n await handleInbound({ plaintext: msg.text, metadata: a2aMetadata, channel, account, cfg });\n } catch (err) {\n _log?.(`[AgentVault] A2A inbound error: ${String(err)}`);\n }\n },\n onA2AChannelReady: async (info: {\n channelId: string;\n peerHubAddress: string;\n role: \"initiator\" | \"responder\";\n conversationId: string;\n topic?: string;\n }) => {\n // Register peer as valid outbound target (both roles)\n _registerA2ATarget(info.peerHubAddress, account.accountId);\n\n // Only initiator sends the seed message\n if (info.role !== \"initiator\") {\n _log?.(`[AgentVault] A2A channel ready (responder) \u2014 waiting for initiator: ${info.peerHubAddress}`);\n return;\n }\n _log?.(`[AgentVault] A2A channel ready (initiator) \u2014 sending seed to ${info.peerHubAddress}${info.topic ? ` [topic: ${info.topic}]` : \"\"}`);\n\n const seedText = info.topic\n ? `[System] A new A2A channel has been established with agent ${info.peerHubAddress}. ` +\n `Topic: \"${info.topic}\". ` +\n `Introduce yourself briefly and begin discussing this topic.`\n : `[System] A new A2A channel has been established with agent ${info.peerHubAddress}. ` +\n `Introduce yourself briefly and state what you can help with.`;\n const seedMetadata = {\n a2aChannelId: info.channelId,\n fromHubAddress: info.peerHubAddress,\n conversationId: info.conversationId,\n timestamp: new Date().toISOString(),\n messageId: `a2a-seed:${info.channelId}:${Date.now()}`,\n };\n\n if (!_ocRuntime) {\n _log?.(\"[AgentVault] runtime not ready, queuing A2A seed\");\n _messageQueue.push(async () => {\n await handleInbound({ plaintext: seedText, metadata: seedMetadata, channel, account, cfg });\n });\n return;\n }\n try {\n await handleInbound({ plaintext: seedText, metadata: seedMetadata, channel, account, cfg });\n } catch (err) {\n _log?.(`[AgentVault] A2A seed error: ${String(err)}`);\n }\n },\n onStateChange: (state: string) => {\n _log?.(`[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?.(`[AgentVault] channel error (non-fatal): ${String(err)}`);\n });\n\n // Always start local HTTP server \u2014 managed routes are an overlay, not a replacement\n const httpPort = account.httpPort ?? 18790;\n channel.on(\"ready\", () => {\n channel.startHttpServer(httpPort);\n _log?.(`[AgentVault] HTTP send server listening on http://127.0.0.1:${httpPort}`);\n if (isUsingManagedRoutes) {\n _log?.(`[AgentVault] OpenClaw managed routes also registered`);\n }\n\n // Register persisted A2A peers as valid outbound targets\n for (const peerAddress of channel.a2aPeerAddresses) {\n _registerA2ATarget(peerAddress, account.accountId);\n }\n\n // Register persisted rooms as valid outbound targets\n for (const room of channel.roomIds) {\n _registerRoomTarget(room.roomId, room.name, account.accountId);\n }\n });\n\n // Register new rooms as outbound targets when agent joins\n channel.on(\"room_joined\", (info: { roomId: string; name: string }) => {\n _registerRoomTarget(info.roomId, info.name, account.accountId);\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: _outboundTargets,\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 if (to.startsWith(\"a2a:\")) {\n await ch.sendToAgent(to.slice(4), text);\n } else if (to.startsWith(\"room:\")) {\n await ch.sendToRoom(to.slice(5), text);\n } else {\n // \"owner\"/\"default\" \u2014 auto-route to room if context exists\n const roomId = ch.lastInboundRoomId;\n if (roomId) {\n await ch.sendToRoom(roomId, text);\n } else {\n await ch.send(text);\n }\n }\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 if (to.startsWith(\"a2a:\")) {\n await ch.sendToAgent(to.slice(4), message);\n } else if (to.startsWith(\"room:\")) {\n await ch.sendToRoom(to.slice(5), message);\n } else {\n // \"owner\"/\"default\" \u2014 auto-route to room if context exists\n const roomId = ch.lastInboundRoomId;\n if (roomId) {\n await ch.sendToRoom(roomId, message);\n } else {\n await ch.send(message);\n }\n }\n return { ok: true, queued: !wasReady };\n } catch (err) {\n return { ok: false, error: String(err) };\n }\n },\n\n /** Rich payload delivery \u2014 OpenClaw v2026.3.2+ calls this for structured messages. */\n sendPayload: async (ctx: ChannelOutboundPayloadContext) => {\n const { payload, accountId } = ctx;\n const resolvedId = accountId ?? \"default\";\n const ch = _channels.get(resolvedId);\n if (!ch) return { ok: false, error: \"AgentVault channel not connected\" };\n\n try {\n // Suppress reasoning blocks \u2014 E2E channel should only deliver actual responses\n if (payload.isReasoning) return { ok: true };\n\n // Wake agent proactively before sending (fire-and-forget)\n requestHeartbeatNow({ reason: \"outbound-payload\" }).catch(() => {});\n\n const text = (payload.text ?? \"\").trim();\n if (!text && !payload.mediaUrls?.length) return { ok: true };\n\n // Helper: route through A2A, room, or direct depending on target\n const _send = async (msg: string) => {\n const target = (ctx as any).to;\n if (target && typeof target === \"string\" && target.startsWith(\"a2a:\")) {\n await ch.sendToAgent(target.slice(4), msg);\n } else if (target && typeof target === \"string\" && target.startsWith(\"room:\")) {\n await ch.sendToRoom(target.slice(5), msg);\n } else {\n // \"owner\"/\"default\" \u2014 auto-route to room if context exists\n const roomId = ch.lastInboundRoomId;\n if (roomId) {\n await ch.sendToRoom(roomId, msg);\n } else {\n await ch.send(msg);\n }\n }\n };\n\n // Encrypt and deliver text content\n if (text) {\n await _send(text);\n }\n\n // Deliver media URLs as text messages (E2E encrypted)\n if (payload.mediaUrls?.length) {\n for (const url of payload.mediaUrls) {\n await _send(url);\n }\n }\n\n // Forward suggested actions as a structured message\n if (payload.suggestedActions?.length) {\n const actionsText = payload.suggestedActions\n .map((a: { label: string; action: string }) => `- ${a.label}: ${a.action}`)\n .join(\"\\n\");\n await _send(`Suggested actions:\\n${actionsText}`);\n }\n\n return { ok: true };\n } catch (err) {\n return { ok: false, error: String(err) };\n }\n },\n },\n};\n\n// --- Exported for testing ---\nexport { _parseMentions, _shouldProcessRoomMessage, _stripMentions };\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: OpenClawPluginApi) {\n _setRuntime(api.runtime);\n\n // Install fetch interceptor to capture all outbound HTTP from the gateway process.\n installFetchInterceptor({\n onHttpCall: (report) => {\n // Find an active channel to emit through\n const ch = _channels.values().next().value;\n if (!ch) return;\n\n // Telemetry reporter is optional \u2014 may not be initialized\n if (ch.telemetry) {\n try {\n ch.telemetry.reportHttpCall({\n method: report.method,\n url: report.url,\n statusCode: report.statusCode,\n latencyMs: report.latencyMs,\n ...(report.traceId ? { traceId: report.traceId } : {}),\n ...(report.parentSpanId ? { parentSpanId: report.parentSpanId } : {}),\n });\n } catch { /* best-effort */ }\n }\n\n // Activity span always fires (uses WS, not telemetry reporter)\n try {\n const hostname = (() => { try { return new URL(report.url).hostname; } catch { return report.url.slice(0, 40); } })();\n ch.sendActivitySpan({\n trace_id: report.traceId ?? \"\",\n parent_span_id: report.parentSpanId ?? \"\",\n span_id: randomBytes(8).toString(\"hex\"),\n span_type: \"http\",\n span_name: hostname,\n status: report.statusCode >= 400 || report.statusCode === 0 ? \"error\" : \"ok\",\n start_time: new Date(Date.now() - report.latencyMs).toISOString(),\n end_time: new Date().toISOString(),\n duration_ms: report.latencyMs,\n attributes: {\n \"ai.agent.http.method\": report.method,\n \"ai.agent.http.url\": report.url,\n },\n http_method: report.method,\n http_status_code: report.statusCode,\n http_url: report.url,\n });\n } catch { /* best-effort */ }\n },\n });\n\n api.registerChannel({ plugin: agentVaultPlugin });\n\n // --- Managed HTTP routes (OpenClaw v2026.3.2+) ---\n if (typeof api.registerHttpRoute === \"function\") {\n try {\n api.registerHttpRoute({\n path: \"/agentvault/send\",\n method: \"POST\",\n handler: async (req) => {\n const ch = _channels.values().next().value;\n if (!ch) return { status: 503, body: { ok: false, error: \"Channel not started\" } };\n const parsed = (typeof req.body === \"string\" ? JSON.parse(req.body) : req.body) as Record<string, unknown>;\n const result = await handleSendRequest(parsed, ch);\n return { status: result.status, body: result.body };\n },\n });\n api.registerHttpRoute({\n path: \"/agentvault/action\",\n method: \"POST\",\n handler: async (req) => {\n const ch = _channels.values().next().value;\n if (!ch) return { status: 503, body: { ok: false, error: \"Channel not started\" } };\n const parsed = (typeof req.body === \"string\" ? JSON.parse(req.body) : req.body) as Record<string, unknown>;\n const result = await handleActionRequest(parsed, ch);\n return { status: result.status, body: result.body };\n },\n });\n api.registerHttpRoute({\n path: \"/agentvault/decision\",\n method: \"POST\",\n handler: async (req) => {\n const ch = _channels.values().next().value;\n if (!ch) return { status: 503, body: { ok: false, error: \"Channel not started\" } };\n const parsed = (typeof req.body === \"string\" ? JSON.parse(req.body) : req.body) as Record<string, unknown>;\n const result = await handleDecisionRequest(parsed, ch);\n return { status: result.status, body: result.body };\n },\n });\n api.registerHttpRoute({\n path: \"/agentvault/status\",\n method: \"GET\",\n handler: async () => {\n const ch = _channels.values().next().value;\n if (!ch) return { status: 503, body: { ok: false, error: \"Channel not started\" } };\n const result = handleStatusRequest(ch);\n return { status: result.status, body: result.body };\n },\n });\n isUsingManagedRoutes = true;\n } catch { /* registerHttpRoute failed \u2014 fall back to self-managed server */ }\n }\n\n // --- Event hooks (OpenClaw v2026.3.2+) ---\n if (typeof api.on === \"function\") {\n // Phase 4: message_sent \u2014 delivery confirmation tracking\n api.on(\"message_sent\", async (event: MessageSentEvent) => {\n try {\n const ch = _channels.values().next().value;\n if (!ch?.telemetry) return;\n ch.telemetry.reportCustomSpan({\n traceId: randomBytes(16).toString(\"hex\"),\n spanId: randomBytes(8).toString(\"hex\"),\n name: \"agentvault.message.delivered\",\n kind: \"internal\",\n startTime: event.timestamp,\n endTime: event.timestamp + 1,\n attributes: {\n \"agentvault.message.id\": event.messageId,\n \"agentvault.delivery.status\": event.deliveryStatus,\n \"agentvault.channel.id\": event.channelId,\n },\n status: { code: event.deliveryStatus === \"failed\" ? 2 : 1 },\n });\n } catch { /* best-effort */ }\n });\n\n // Phase 6: session lifecycle hooks\n api.on(\"session_start\", async (event: SessionStartEvent) => {\n try {\n const ch = _channels.values().next().value;\n if (!ch?.telemetry) return;\n ch.telemetry.reportCustomSpan({\n traceId: randomBytes(16).toString(\"hex\"),\n spanId: randomBytes(8).toString(\"hex\"),\n name: \"agentvault.session.start\",\n kind: \"internal\",\n startTime: event.timestamp,\n endTime: event.timestamp + 1,\n attributes: {\n \"agentvault.session.key\": event.sessionKey,\n \"agentvault.agent.id\": event.agentId,\n },\n status: { code: 1 },\n });\n } catch { /* best-effort */ }\n });\n\n api.on(\"session_end\", async (event: SessionEndEvent) => {\n try {\n const ch = _channels.values().next().value;\n if (!ch?.telemetry) return;\n ch.telemetry.reportCustomSpan({\n traceId: randomBytes(16).toString(\"hex\"),\n spanId: randomBytes(8).toString(\"hex\"),\n name: \"agentvault.session.end\",\n kind: \"internal\",\n startTime: event.timestamp,\n endTime: event.timestamp + 1,\n attributes: {\n \"agentvault.session.key\": event.sessionKey,\n \"agentvault.agent.id\": event.agentId,\n ...(event.reason ? { \"agentvault.session.end_reason\": event.reason } : {}),\n },\n status: { code: 1 },\n });\n } catch { /* best-effort */ }\n });\n }\n\n // --- Phase 7: Agent events for trust telemetry ---\n import(\"./openclaw-compat.js\").then(async ({ onAgentEvent, onSessionTranscriptUpdate }) => {\n onAgentEvent((event) => {\n try {\n const ch = _channels.values().next().value;\n if (!ch?.telemetry) return;\n ch.telemetry.reportCustomSpan({\n traceId: randomBytes(16).toString(\"hex\"),\n spanId: randomBytes(8).toString(\"hex\"),\n name: `ai.agent.event.${event.type}`,\n kind: \"internal\",\n startTime: event.timestamp,\n endTime: event.timestamp + 1,\n attributes: {\n \"ai.agent.event.type\": event.type,\n \"ai.agent.id\": event.agentId,\n ...(event.data ? Object.fromEntries(\n Object.entries(event.data).map(([k, v]) => [`ai.agent.event.${k}`, String(v)])\n ) : {}),\n },\n status: { code: 1 },\n });\n } catch { /* best-effort */ }\n }).catch(() => {});\n\n onSessionTranscriptUpdate((update) => {\n try {\n const ch = _channels.values().next().value;\n if (!ch?.telemetry) return;\n ch.telemetry.reportCustomSpan({\n traceId: randomBytes(16).toString(\"hex\"),\n spanId: randomBytes(8).toString(\"hex\"),\n name: \"ai.agent.transcript.update\",\n kind: \"internal\",\n startTime: update.timestamp,\n endTime: update.timestamp + 1,\n attributes: {\n \"agentvault.session.key\": update.sessionKey,\n \"ai.agent.transcript.role\": update.role ?? \"unknown\",\n \"ai.agent.transcript.delta_chars\": update.delta.length,\n },\n status: { code: 1 },\n });\n } catch { /* best-effort */ }\n }).catch(() => {});\n }).catch(() => { /* openclaw-compat import failed \u2014 older SDK */ });\n\n // --- Agent tool: agentvault_status ---\n // Lets the agent check its own encrypted channel status\n try {\n api.registerTool?.({\n name: \"agentvault_status\",\n description: \"Check the AgentVault encrypted channel status, connection state, and session count.\",\n parameters: {\n type: \"object\",\n properties: {\n accountId: {\n type: \"string\",\n description: \"Account ID to check (default: 'default')\",\n },\n },\n },\n execute: async (_id: string, params: { accountId?: string }) => {\n const id = params.accountId ?? \"default\";\n const ch = _channels.get(id);\n if (!ch) {\n return { content: [{ type: \"text\", text: JSON.stringify({ connected: false, error: \"Channel not started\" }) }] };\n }\n return {\n content: [{\n type: \"text\",\n text: JSON.stringify({\n connected: ch.state === \"ready\",\n state: ch.state,\n deviceId: ch.deviceId,\n sessions: ch.sessionCount,\n encrypted: true,\n }),\n }],\n };\n },\n }, { optional: true });\n } catch { /* registerTool may not be available in older OpenClaw versions */ }\n\n // --- Auto-reply command: /agentvault ---\n // Quick status check without AI involvement\n try {\n api.registerCommand?.({\n name: \"agentvault\",\n description: \"Show AgentVault encrypted channel status\",\n handler: () => {\n const statuses: string[] = [];\n if (_channels.size === 0) {\n statuses.push(\"AgentVault: no active channels\");\n } else {\n for (const [id, ch] of _channels) {\n statuses.push(`AgentVault [${id}]: ${ch.state} | sessions: ${ch.sessionCount} | encrypted: yes`);\n }\n }\n return { text: statuses.join(\"\\n\") };\n },\n });\n } catch { /* registerCommand may not be available in older OpenClaw versions */ }\n },\n};\n", "/**\n * Shared multi-account config resolution for AgentVault OpenClaw plugin.\n *\n * Supports two config shapes:\n * 1. Legacy single-agent: channels.agentvault.dataDir (returns [\"default\"])\n * 2. Multi-agent: channels.agentvault.accounts.{id}.dataDir (returns account keys)\n *\n * When `accounts` key is present, it takes precedence over top-level dataDir.\n */\n\nconst DEFAULT_API_URL = \"https://api.agentvault.chat\";\nconst DEFAULT_HTTP_PORT = 18790;\n\nexport interface ResolvedAccount {\n accountId: string;\n dataDir: string;\n apiUrl: string;\n agentName: string;\n httpPort: number;\n configured: boolean;\n}\n\nexport function listAccountIds(cfg: any): string[] {\n const av = cfg?.channels?.agentvault;\n if (!av) return [];\n if (av.accounts && typeof av.accounts === \"object\") {\n return Object.keys(av.accounts);\n }\n return av.dataDir ? [\"default\"] : [];\n}\n\nexport function resolveAccount(cfg: any, accountId?: string): ResolvedAccount {\n const av = cfg?.channels?.agentvault ?? {};\n const id = accountId ?? \"default\";\n\n if (av.accounts && typeof av.accounts === \"object\") {\n const acct = av.accounts[id];\n if (!acct) {\n return {\n accountId: id,\n dataDir: \"\",\n apiUrl: av.apiUrl ?? DEFAULT_API_URL,\n agentName: id,\n httpPort: DEFAULT_HTTP_PORT,\n configured: false,\n };\n }\n\n let httpPort = acct.httpPort;\n if (httpPort == null) {\n const keys = Object.keys(av.accounts);\n const index = keys.indexOf(id);\n httpPort = DEFAULT_HTTP_PORT + (index >= 0 ? index : 0);\n }\n\n return {\n accountId: id,\n dataDir: acct.dataDir ?? \"\",\n apiUrl: acct.apiUrl ?? av.apiUrl ?? DEFAULT_API_URL,\n agentName: acct.agentName ?? id,\n httpPort,\n configured: Boolean(acct.dataDir),\n };\n }\n\n return {\n accountId: id,\n dataDir: av.dataDir ?? \"~/.openclaw/agentvault\",\n apiUrl: av.apiUrl ?? DEFAULT_API_URL,\n agentName: av.agentName ?? \"OpenClaw Agent\",\n httpPort: av.httpPort ?? DEFAULT_HTTP_PORT,\n configured: Boolean(av.dataDir),\n };\n}\n", "/**\n * HTTP interceptor for capturing outbound HTTP calls during message handling.\n *\n * Uses Node.js diagnostics_channel to subscribe to undici request events,\n * capturing ALL outbound HTTP from the process (including LLM SDKs, Playwright\n * navigations, and any library that uses undici under the hood).\n *\n * Also monkey-patches globalThis.fetch as a fallback for non-undici HTTP.\n *\n * Uses AsyncLocalStorage to associate intercepted calls with the active\n * message's traceId/parentSpanId.\n *\n * Built-in skip patterns prevent capturing internal infrastructure requests\n * (localhost, AgentVault API, Clerk auth).\n */\nimport { AsyncLocalStorage } from \"node:async_hooks\";\nimport diagnosticsChannel from \"node:diagnostics_channel\";\n\n// \u2500\u2500 Public types \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nexport interface HttpCallReport {\n method: string;\n url: string;\n statusCode: number;\n latencyMs: number;\n traceId?: string;\n parentSpanId?: string;\n}\n\nexport interface TraceContext {\n traceId: string;\n parentSpanId: string;\n}\n\nexport interface FetchInterceptorOptions {\n onHttpCall: (report: HttpCallReport) => void;\n skipPatterns?: RegExp[];\n}\n\n// \u2500\u2500 Internal state \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nconst traceStore = new AsyncLocalStorage<TraceContext>();\n\nconst DEFAULT_SKIP_PATTERNS: RegExp[] = [\n /^https?:\\/\\/localhost(:\\d+)?/,\n /^https?:\\/\\/127\\.0\\.0\\.1(:\\d+)?/,\n /\\.agentvault\\.chat/,\n /\\.agentvault\\.dev/,\n /\\.clerk\\./,\n];\n\nlet installed = false;\nlet originalFetch: typeof globalThis.fetch | undefined;\n\n// Track in-flight undici requests: request \u2192 { url, method, startTime }\nconst inflightRequests = new WeakMap<\n object,\n { url: string; method: string; startTime: number }\n>();\n\n// Diagnostics channel subscriptions\nlet unsubCreate: (() => void) | undefined;\nlet unsubHeaders: (() => void) | undefined;\nlet unsubError: (() => void) | undefined;\n\n// \u2500\u2500 Helpers \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nfunction shouldSkip(url: string, extraPatterns: RegExp[]): boolean {\n const allPatterns = [...DEFAULT_SKIP_PATTERNS, ...extraPatterns];\n return allPatterns.some((p) => p.test(url));\n}\n\nfunction extractUrl(origin: string, path: string): string {\n // undici gives us origin (e.g., \"https://api.openai.com\") and path (e.g., \"/v1/chat/completions\")\n return `${origin}${path}`;\n}\n\n// \u2500\u2500 Public API \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n/**\n * Install HTTP interceptor using both undici diagnostics channels and\n * globalThis.fetch monkey-patching. Idempotent.\n */\nexport function installFetchInterceptor(opts: FetchInterceptorOptions): void {\n if (installed) return;\n installed = true;\n\n const skipPatterns = [\n ...DEFAULT_SKIP_PATTERNS,\n ...(opts.skipPatterns ?? []),\n ];\n\n // \u2500\u2500 1. Undici diagnostics channel \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n // undici publishes events for every HTTP request it makes.\n // This captures LLM SDK calls, playwright navigations, etc.\n\n try {\n const createChannel = diagnosticsChannel.channel(\"undici:request:create\");\n const headersChannel = diagnosticsChannel.channel(\"undici:request:headers\");\n const errorChannel = diagnosticsChannel.channel(\"undici:request:error\");\n\n const onRequestCreate = (message: unknown) => {\n try {\n const msg = message as {\n request: {\n method?: string;\n origin?: string;\n path?: string;\n };\n };\n const req = msg.request;\n if (!req) return;\n\n const origin = String(req.origin ?? \"\");\n const path = String(req.path ?? \"/\");\n const url = extractUrl(origin, path);\n\n if (shouldSkip(url, skipPatterns)) return;\n\n inflightRequests.set(req, {\n url,\n method: String(req.method ?? \"GET\").toUpperCase(),\n startTime: Date.now(),\n });\n } catch { /* best-effort */ }\n };\n\n const onRequestHeaders = (message: unknown) => {\n try {\n const msg = message as {\n request: object;\n response: { statusCode?: number };\n };\n const tracked = inflightRequests.get(msg.request);\n if (!tracked) return;\n inflightRequests.delete(msg.request);\n\n const latencyMs = Date.now() - tracked.startTime;\n const ctx = traceStore.getStore();\n\n opts.onHttpCall({\n method: tracked.method,\n url: tracked.url,\n statusCode: msg.response?.statusCode ?? 0,\n latencyMs,\n traceId: ctx?.traceId,\n parentSpanId: ctx?.parentSpanId,\n });\n } catch { /* best-effort */ }\n };\n\n const onRequestError = (message: unknown) => {\n try {\n const msg = message as { request: object; error?: Error };\n const tracked = inflightRequests.get(msg.request);\n if (!tracked) return;\n inflightRequests.delete(msg.request);\n\n const latencyMs = Date.now() - tracked.startTime;\n const ctx = traceStore.getStore();\n\n opts.onHttpCall({\n method: tracked.method,\n url: tracked.url,\n statusCode: 0,\n latencyMs,\n traceId: ctx?.traceId,\n parentSpanId: ctx?.parentSpanId,\n });\n } catch { /* best-effort */ }\n };\n\n createChannel.subscribe(onRequestCreate);\n headersChannel.subscribe(onRequestHeaders);\n errorChannel.subscribe(onRequestError);\n\n unsubCreate = () => createChannel.unsubscribe(onRequestCreate);\n unsubHeaders = () => headersChannel.unsubscribe(onRequestHeaders);\n unsubError = () => errorChannel.unsubscribe(onRequestError);\n } catch {\n // diagnostics_channel not available or undici not loaded \u2014 fall through to fetch-only\n }\n\n // \u2500\u2500 2. globalThis.fetch monkey-patch (fallback) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n // Catches any HTTP that doesn't go through undici (e.g., native fetch\n // in newer Node.js, or custom HTTP implementations).\n\n originalFetch = globalThis.fetch;\n const savedOriginal = originalFetch;\n\n globalThis.fetch = async (\n input: RequestInfo | URL,\n init?: RequestInit,\n ): Promise<Response> => {\n const url =\n input instanceof Request\n ? input.url\n : input instanceof URL\n ? input.href\n : String(input);\n\n if (shouldSkip(url, skipPatterns)) {\n return savedOriginal(input, init);\n }\n\n const method =\n input instanceof Request\n ? input.method\n : init?.method ?? \"GET\";\n\n const ctx = traceStore.getStore();\n const start = Date.now();\n\n try {\n const response = await savedOriginal(input, init);\n const latencyMs = Date.now() - start;\n\n try {\n opts.onHttpCall({\n method,\n url,\n statusCode: response.status,\n latencyMs,\n traceId: ctx?.traceId,\n parentSpanId: ctx?.parentSpanId,\n });\n } catch { /* best-effort */ }\n\n return response;\n } catch (err) {\n const latencyMs = Date.now() - start;\n\n try {\n opts.onHttpCall({\n method,\n url,\n statusCode: 0,\n latencyMs,\n traceId: ctx?.traceId,\n parentSpanId: ctx?.parentSpanId,\n });\n } catch { /* best-effort */ }\n\n throw err;\n }\n };\n}\n\n/**\n * Uninstall all interceptors. Safe to call even if not installed.\n */\nexport function uninstallFetchInterceptor(): void {\n if (!installed) return;\n\n // Restore fetch\n if (originalFetch) {\n globalThis.fetch = originalFetch;\n originalFetch = undefined;\n }\n\n // Unsubscribe from diagnostics channels\n unsubCreate?.();\n unsubHeaders?.();\n unsubError?.();\n unsubCreate = undefined;\n unsubHeaders = undefined;\n unsubError = undefined;\n\n installed = false;\n}\n\n/**\n * Run an async function with trace context attached via AsyncLocalStorage.\n * Any HTTP calls made within `fn` (via undici or fetch) will include\n * traceId/parentSpanId in their HttpCallReport.\n */\nexport function runWithTraceContext<T>(\n ctx: TraceContext,\n fn: () => T | Promise<T>,\n): Promise<T> {\n return traceStore.run(ctx, fn) as Promise<T>;\n}\n", "/**\n * Extracted HTTP handler logic for the AgentVault plugin.\n *\n * These handlers are shared between:\n * 1. The self-managed HTTP server in channel.ts (legacy/fallback path)\n * 2. OpenClaw's registerHttpRoute() managed routes (new path)\n *\n * Both entry points call the same handler functions, ensuring consistent\n * behavior regardless of how the route is served.\n */\n\nimport type { SecureChannel } from \"./channel.js\";\n\nexport interface HandlerResult {\n status: number;\n body: Record<string, unknown>;\n}\n\n/**\n * Handle POST /send \u2014 send a message (text, file, or room).\n */\nexport async function handleSendRequest(\n parsed: Record<string, unknown>,\n channel: SecureChannel,\n): Promise<HandlerResult> {\n const text = parsed.text;\n if (!text || typeof text !== \"string\") {\n return { status: 400, body: { ok: false, error: \"Missing 'text' field\" } };\n }\n\n try {\n // A2A send: accept hub_address, a2a_address, a2aAddress, or channel_id\n let a2aTarget = (parsed.hub_address ?? parsed.a2a_address ?? parsed.a2aAddress) as string | undefined;\n\n // Resolve channel_id to hub address if provided\n if (!a2aTarget && parsed.channel_id && typeof parsed.channel_id === \"string\") {\n const hubAddr = channel.resolveA2AChannelHub(parsed.channel_id as string);\n if (hubAddr) a2aTarget = hubAddr;\n }\n\n // Resolve room_id: explicit in body, or fallback to last inbound room context\n const roomId = (typeof parsed.room_id === \"string\" ? parsed.room_id : undefined) ?? channel.lastInboundRoomId;\n\n if (a2aTarget && typeof a2aTarget === \"string\") {\n await channel.sendToAgent(a2aTarget, text as string);\n } else if (roomId) {\n await channel.sendToRoom(roomId, text as string, {\n messageType: parsed.message_type as string | undefined,\n priority: parsed.priority as string | undefined,\n metadata: parsed.metadata as Record<string, unknown> | undefined,\n });\n } else if (parsed.file_path && typeof parsed.file_path === \"string\") {\n await channel.sendWithAttachment(text as string, parsed.file_path as string, {\n topicId: parsed.topicId as string | undefined,\n });\n } else {\n await channel.send(text as string, {\n topicId: parsed.topicId as string | undefined,\n messageType: parsed.message_type as string | undefined,\n metadata: parsed.metadata as Record<string, unknown> | undefined,\n });\n }\n return { status: 200, body: { ok: true } };\n } catch (err) {\n return { status: 500, body: { ok: false, error: String(err) } };\n }\n}\n\n/**\n * Handle POST /action \u2014 send an action confirmation.\n */\nexport async function handleActionRequest(\n parsed: Record<string, unknown>,\n channel: SecureChannel,\n): Promise<HandlerResult> {\n if (!parsed.action || typeof parsed.action !== \"string\") {\n return { status: 400, body: { ok: false, error: \"Missing 'action' field\" } };\n }\n\n try {\n const confirmation = {\n action: parsed.action as string,\n status: (parsed.status ?? \"completed\") as \"completed\" | \"failed\" | \"partial\",\n decisionId: parsed.decision_id as string | undefined,\n detail: parsed.detail as string | undefined,\n estimated_cost: parsed.estimated_cost as number | undefined,\n };\n\n if (parsed.room_id && typeof parsed.room_id === \"string\") {\n await channel.sendActionConfirmationToRoom(parsed.room_id, confirmation);\n } else {\n await channel.sendActionConfirmation(confirmation);\n }\n return { status: 200, body: { ok: true } };\n } catch (err) {\n return { status: 500, body: { ok: false, error: String(err) } };\n }\n}\n\n/**\n * Handle POST /decision \u2014 send a decision request to the owner.\n */\nexport async function handleDecisionRequest(\n parsed: Record<string, unknown>,\n channel: SecureChannel,\n): Promise<HandlerResult> {\n const title = parsed.title;\n if (!title || typeof title !== \"string\") {\n return { status: 400, body: { ok: false, error: \"Missing 'title' field\" } };\n }\n\n const options = parsed.options;\n if (!Array.isArray(options) || options.length < 2) {\n return { status: 400, body: { ok: false, error: \"'options' must be an array with at least 2 items\" } };\n }\n\n for (const opt of options) {\n if (!opt || typeof opt !== \"object\" || !opt.option_id || !opt.label) {\n return { status: 400, body: { ok: false, error: \"Each option must have 'option_id' and 'label'\" } };\n }\n }\n\n try {\n const decision_id = await channel.sendDecisionRequest({\n title: title as string,\n description: parsed.description as string | undefined,\n options: options as Array<{ option_id: string; label: string; risk_level: \"low\" | \"medium\" | \"high\" | \"critical\"; is_default?: boolean }>,\n context_refs: parsed.context_refs as Array<{ type: string; uri: string; label: string }> | undefined,\n deadline: parsed.deadline as string | undefined,\n auto_action: parsed.auto_action as { option_id: string; trigger: string; description?: string } | undefined,\n });\n return { status: 200, body: { ok: true, decision_id } };\n } catch (err) {\n return { status: 500, body: { ok: false, error: String(err) } };\n }\n}\n\n/**\n * Handle GET /status \u2014 return channel health info.\n */\nexport function handleStatusRequest(channel: SecureChannel): HandlerResult {\n return {\n status: 200,\n body: {\n ok: true,\n state: channel.state,\n deviceId: channel.deviceId ?? undefined,\n sessions: channel.sessionCount,\n },\n };\n}\n"],
5
- "mappings": "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",
6
- "names": ["resolve", "onAgentEvent", "onSessionTranscriptUpdate"]
3
+ "sources": ["../src/openclaw-compat.ts", "../src/openclaw-entry.ts", "../src/account-config.ts", "../src/fetch-interceptor.ts", "../src/http-handlers.ts", "../src/types.ts"],
4
+ "sourcesContent": ["/**\n * OpenClaw SDK compatibility layer \u2014 dynamic import wrappers with caching.\n *\n * Each wrapper attempts to import a deep SDK module at runtime. If the import\n * fails (older gateway, missing SDK), the function returns a no-op result.\n * Results are cached after the first attempt.\n *\n * IMPORTANT: All imports are guarded by try/catch \u2014 the plugin degrades\n * gracefully on older OpenClaw versions.\n */\n\nimport type { AgentEventPayload, TranscriptUpdatePayload } from \"./openclaw-types.js\";\n\n// ---------------------------------------------------------------------------\n// requestHeartbeatNow \u2014 wake agent proactively before outbound sends\n// ---------------------------------------------------------------------------\n\nlet _heartbeatFn: ((opts?: { reason?: string }) => Promise<void>) | false | null = null;\n\n/**\n * Request an immediate heartbeat wake from the OpenClaw gateway.\n * Returns true if the heartbeat API was available and called, false otherwise.\n * Never throws.\n */\nexport async function requestHeartbeatNow(opts?: { reason?: string }): Promise<boolean> {\n if (_heartbeatFn === null) {\n try {\n // @ts-expect-error \u2014 deep SDK import only available when openclaw is installed\n const mod = await import(\"openclaw/dist/plugin-sdk/infra/heartbeat-wake.js\");\n _heartbeatFn = mod.requestHeartbeatNow ?? mod.default?.requestHeartbeatNow ?? false;\n } catch {\n _heartbeatFn = false;\n }\n }\n if (typeof _heartbeatFn === \"function\") {\n try {\n await _heartbeatFn(opts);\n return true;\n } catch {\n return false;\n }\n }\n return false;\n}\n\n// ---------------------------------------------------------------------------\n// onAgentEvent \u2014 subscribe to agent-level events for trust telemetry\n// ---------------------------------------------------------------------------\n\ntype AgentEventCallback = (event: AgentEventPayload) => void;\nlet _agentEventFn: ((cb: AgentEventCallback) => (() => void)) | false | null = null;\n\n/**\n * Subscribe to agent-level events (tool_use, reasoning_complete, error, etc.).\n * Returns an unsubscribe function, or a no-op if the API is unavailable.\n */\nexport async function onAgentEvent(callback: AgentEventCallback): Promise<() => void> {\n if (_agentEventFn === null) {\n try {\n // @ts-expect-error \u2014 deep SDK import only available when openclaw is installed\n const mod = await import(\"openclaw/dist/plugin-sdk/infra/agent-events.js\");\n _agentEventFn = mod.onAgentEvent ?? mod.default?.onAgentEvent ?? false;\n } catch {\n _agentEventFn = false;\n }\n }\n if (typeof _agentEventFn === \"function\") {\n try {\n return _agentEventFn(callback);\n } catch {\n return () => {};\n }\n }\n return () => {};\n}\n\n// ---------------------------------------------------------------------------\n// onSessionTranscriptUpdate \u2014 subscribe to transcript deltas\n// ---------------------------------------------------------------------------\n\ntype TranscriptCallback = (update: TranscriptUpdatePayload) => void;\nlet _transcriptFn: ((cb: TranscriptCallback) => (() => void)) | false | null = null;\n\n/**\n * Subscribe to session transcript updates for behavioral analysis.\n * Returns an unsubscribe function, or a no-op if the API is unavailable.\n */\nexport async function onSessionTranscriptUpdate(callback: TranscriptCallback): Promise<() => void> {\n if (_transcriptFn === null) {\n try {\n // @ts-expect-error \u2014 deep SDK import only available when openclaw is installed\n const mod = await import(\"openclaw/dist/plugin-sdk/sessions/transcript-events.js\");\n _transcriptFn = mod.onSessionTranscriptUpdate ?? mod.default?.onSessionTranscriptUpdate ?? false;\n } catch {\n _transcriptFn = false;\n }\n }\n if (typeof _transcriptFn === \"function\") {\n try {\n return _transcriptFn(callback);\n } catch {\n return () => {};\n }\n }\n return () => {};\n}\n", "/**\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\";\nimport { listAccountIds, resolveAccount } from \"./account-config.js\";\nimport { installFetchInterceptor, runWithTraceContext } from \"./fetch-interceptor.js\";\nimport { handleSendRequest, handleActionRequest, handleDecisionRequest, handleStatusRequest, handleTargetsRequest } from \"./http-handlers.js\";\nimport { requestHeartbeatNow } from \"./openclaw-compat.js\";\nimport { parseTarget } from \"./types.js\";\nimport type { DeliveryTarget } from \"./types.js\";\nimport type {\n OpenClawPluginApi,\n PluginRuntime,\n ChannelGatewayContext,\n ResolvedAccountBase,\n ChannelOutboundPayloadContext,\n ReplyPayload,\n MessageSentEvent,\n SessionStartEvent,\n SessionEndEvent,\n} from \"./openclaw-types.js\";\n\n// --- Runtime and active channels (set during register) ---\nlet _ocRuntime: PluginRuntime | null = null;\nconst _channels = new Map<string, any>();\nconst _messageQueue: Array<() => Promise<void>> = [];\n\n// --- A2A conversation loop prevention ---\n// Tracks recent A2A reply timestamps per channel to prevent infinite loops.\n// Max replies per channel within the window, then cooldown.\nconst A2A_MAX_REPLIES_PER_WINDOW = 4;\nconst A2A_WINDOW_MS = 60_000; // 1-minute sliding window\nconst A2A_COOLDOWN_MS = 120_000; // 2-minute cooldown after hitting limit\nconst _a2aReplyTimestamps = new Map<string, number[]>();\nconst _a2aCooldownUntil = new Map<string, number>();\n\nfunction _a2aCanReply(channelId: string): boolean {\n const now = Date.now();\n\n // Check cooldown\n const cooldownEnd = _a2aCooldownUntil.get(channelId) ?? 0;\n if (now < cooldownEnd) {\n return false;\n }\n\n // Get timestamps within window\n const timestamps = _a2aReplyTimestamps.get(channelId) ?? [];\n const recent = timestamps.filter((t) => now - t < A2A_WINDOW_MS);\n\n if (recent.length >= A2A_MAX_REPLIES_PER_WINDOW) {\n // Hit limit \u2014 enter cooldown\n _a2aCooldownUntil.set(channelId, now + A2A_COOLDOWN_MS);\n _a2aReplyTimestamps.set(channelId, []);\n console.warn(\n `[AgentVault] A2A rate limit hit for channel ${channelId.slice(0, 8)}... \u2014 ` +\n `${A2A_MAX_REPLIES_PER_WINDOW} replies in ${A2A_WINDOW_MS / 1000}s, cooling down ${A2A_COOLDOWN_MS / 1000}s`,\n );\n return false;\n }\n\n return true;\n}\n\nfunction _a2aRecordReply(channelId: string): void {\n const now = Date.now();\n const timestamps = _a2aReplyTimestamps.get(channelId) ?? [];\n timestamps.push(now);\n // Keep only timestamps within window\n _a2aReplyTimestamps.set(\n channelId,\n timestamps.filter((t) => now - t < A2A_WINDOW_MS),\n );\n}\n\n/** Whether OpenClaw managed HTTP routes are active (vs self-managed server). */\nexport let isUsingManagedRoutes = false;\n\n/**\n * Shared mutable targets array for OpenClaw outbound routing.\n * OpenClaw validates `to` against this list before calling sendText/sendPayload.\n * We mutate it at runtime to add A2A channel targets dynamically.\n */\nconst _outboundTargets: Array<{ id: string; label: string; accountId: string }> = [\n { id: \"owner\", label: \"AgentVault Owner\", accountId: \"default\" },\n { id: \"default\", label: \"AgentVault Owner (default)\", accountId: \"default\" },\n];\n\n// _normalizeTarget removed \u2014 replaced by parseTarget() from types.ts\n\n/** Register a room as a valid outbound target (idempotent). */\nfunction _registerRoomTarget(roomId: string, roomName: string, accountId: string): void {\n const targetId = `room:${roomId}`;\n if (_outboundTargets.some((t) => t.id === targetId)) return;\n _outboundTargets.push({ id: targetId, label: `Room: ${roomName}`, accountId });\n console.log(`[AgentVault] Registered room target: ${roomName} (${roomId.slice(0, 8)}...)`);\n}\n\n/** Register an A2A peer as a valid outbound target (idempotent). */\nfunction _registerA2ATarget(hubAddress: string, accountId: string): void {\n const targetId = `a2a:${hubAddress}`;\n if (_outboundTargets.some((t) => t.id === targetId)) return;\n _outboundTargets.push({\n id: targetId,\n label: `A2A: ${hubAddress}`,\n accountId,\n });\n console.log(`[AgentVault] Registered A2A target: ${targetId}`);\n}\n\nfunction _setRuntime(rt: PluginRuntime) {\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// --- @mention filtering for multi-agent rooms ---\n\n/** Extract @mention names from plaintext. Returns lowercased names. */\nfunction _parseMentions(text: string): string[] {\n const mentions: string[] = [];\n // Match @word at word boundary \u2014 supports multi-word via sequential matching\n const re = /@(\\w[\\w]*)/gi;\n let match: RegExpExecArray | null;\n while ((match = re.exec(text)) !== null) {\n mentions.push(match[1].toLowerCase());\n }\n return mentions;\n}\n\n/** Determine whether this agent should process a room message based on @mentions. */\nfunction _shouldProcessRoomMessage(\n plaintext: string,\n agentName: string,\n accountId: string,\n): boolean {\n const mentions = _parseMentions(plaintext);\n // No mentions \u2192 broadcast to all agents (current behavior)\n if (mentions.length === 0) return true;\n // @all / @everyone \u2192 all agents process\n if (mentions.includes(\"all\") || mentions.includes(\"everyone\")) return true;\n // Check if this agent is mentioned (by name or accountId)\n const nameLower = agentName.toLowerCase();\n const idLower = accountId.toLowerCase();\n // Match first word of agent name (e.g., \"Cortina\" from \"Cortina (Coder)\")\n const firstWord = nameLower.split(/[\\s(]/)[0];\n return mentions.some(\n (m) => m === nameLower || m === firstWord || m === idLower,\n );\n}\n\n/** Strip the matching @mention prefix from plaintext so the agent sees clean text. */\nfunction _stripMentions(\n text: string,\n agentName: string,\n accountId: string,\n): string {\n const nameLower = agentName.toLowerCase();\n const firstWord = nameLower.split(/[\\s(]/)[0];\n const idLower = accountId.toLowerCase();\n // Remove all @mentions that match this agent (case-insensitive)\n return text\n .replace(/@(\\w[\\w]*)/gi, (full, name) => {\n const lower = name.toLowerCase();\n if (lower === nameLower || lower === firstWord || lower === idLower) {\n return \"\";\n }\n // Also strip @all/@everyone since they're routing directives\n if (lower === \"all\" || lower === \"everyone\") return \"\";\n return full;\n })\n .replace(/^\\s+/, \"\") // trim leading whitespace left by stripped mention\n .trim();\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: rawPlaintext, metadata, channel, account, cfg } = params;\n const isRoomMessage = Boolean(metadata.roomId);\n const isA2AMessage = Boolean(metadata.a2aChannelId);\n\n // @mention filtering: only for room messages\n if (isRoomMessage) {\n if (!_shouldProcessRoomMessage(rawPlaintext, account.agentName ?? \"\", account.accountId ?? \"\")) {\n return; // This agent is not mentioned \u2014 skip silently\n }\n }\n\n // Strip @mentions from plaintext so the agent sees clean text\n const plaintext = isRoomMessage\n ? _stripMentions(rawPlaintext, account.agentName ?? \"\", account.accountId ?? \"\")\n : rawPlaintext;\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 const inferenceSpanId = randomBytes(8).toString(\"hex\");\n // Instrumentation context for agent code to report LLM/tool/error spans\n /** Helper: send an activity span over WS for real-time owner display. */\n const _sendActivity = (spanData: Record<string, unknown>) => {\n try { channel.sendActivitySpan({ ...spanData, trace_id: traceId, parent_span_id: inferenceSpanId }); } catch {}\n };\n\n const _instrument = {\n reportLlm: (opts: any) => {\n const enriched = { ...opts, traceId, parentSpanId: inferenceSpanId };\n if (opts.skillName || _instrument.skillName) enriched.skillName = opts.skillName ?? _instrument.skillName;\n try { channel.telemetry?.reportLlmCall(enriched); } catch {}\n const activityAttrs: Record<string, string> = { \"ai.agent.llm.model\": opts.model ?? \"\" };\n if (enriched.skillName) activityAttrs[\"ai.agent.skill.name\"] = enriched.skillName;\n _sendActivity({\n span_id: randomBytes(8).toString(\"hex\"), span_type: \"llm\", span_name: opts.model ?? \"LLM\",\n status: opts.status === \"error\" ? \"error\" : \"ok\",\n start_time: new Date(Date.now() - (opts.latencyMs ?? 0)).toISOString(),\n end_time: new Date().toISOString(), duration_ms: opts.latencyMs ?? 0,\n attributes: activityAttrs,\n tokens_input: opts.tokensInput, tokens_output: opts.tokensOutput,\n });\n },\n reportTool: (opts: any) => {\n const enriched = { ...opts, traceId, parentSpanId: inferenceSpanId };\n if (opts.skillName || _instrument.skillName) enriched.skillName = opts.skillName ?? _instrument.skillName;\n try { channel.telemetry?.reportToolCall(enriched); } catch {}\n const activityAttrs: Record<string, string> = { \"ai.agent.tool.name\": opts.toolName ?? \"\" };\n if (enriched.skillName) activityAttrs[\"ai.agent.skill.name\"] = enriched.skillName;\n _sendActivity({\n span_id: randomBytes(8).toString(\"hex\"), span_type: \"tool\", span_name: opts.toolName ?? \"tool\",\n status: opts.success === false ? \"error\" : \"ok\",\n start_time: new Date(Date.now() - (opts.latencyMs ?? 0)).toISOString(),\n end_time: new Date().toISOString(), duration_ms: opts.latencyMs ?? 0,\n attributes: activityAttrs,\n tool_success: opts.success,\n });\n },\n reportError: (opts: any) => {\n const enriched = { ...opts, traceId, parentSpanId: inferenceSpanId };\n if (opts.skillName || _instrument.skillName) enriched.skillName = opts.skillName ?? _instrument.skillName;\n try { channel.telemetry?.reportError(enriched); } catch {}\n const activityAttrs: Record<string, string> = { \"ai.agent.error.type\": opts.errorType ?? \"\" };\n if (enriched.skillName) activityAttrs[\"ai.agent.skill.name\"] = enriched.skillName;\n _sendActivity({\n span_id: randomBytes(8).toString(\"hex\"), span_type: \"error\", span_name: opts.errorType ?? \"error\",\n status: \"error\",\n start_time: new Date().toISOString(), end_time: new Date().toISOString(), duration_ms: 0,\n attributes: activityAttrs,\n error_type: opts.errorType, error_message: opts.errorMessage,\n });\n },\n reportHttp: (opts: any) => {\n const enriched = { ...opts, traceId, parentSpanId: inferenceSpanId };\n if (opts.skillName || _instrument.skillName) enriched.skillName = opts.skillName ?? _instrument.skillName;\n try { channel.telemetry?.reportHttpCall(enriched); } catch {}\n const activityAttrs: Record<string, string> = { \"ai.agent.http.method\": opts.method ?? \"\", \"ai.agent.http.url\": opts.url ?? \"\" };\n if (enriched.skillName) activityAttrs[\"ai.agent.skill.name\"] = enriched.skillName;\n _sendActivity({\n span_id: randomBytes(8).toString(\"hex\"), span_type: \"http\",\n span_name: (() => { try { return new URL(opts.url).hostname; } catch { return opts.url?.slice(0, 40) ?? \"http\"; } })(),\n status: (opts.statusCode ?? 200) >= 400 ? \"error\" : \"ok\",\n start_time: new Date(Date.now() - (opts.latencyMs ?? 0)).toISOString(),\n end_time: new Date().toISOString(), duration_ms: opts.latencyMs ?? 0,\n attributes: activityAttrs,\n http_method: opts.method, http_status_code: opts.statusCode, http_url: opts.url,\n });\n },\n reportAction: (opts: any) => {\n const enriched = { ...opts, traceId, parentSpanId: inferenceSpanId };\n if (opts.skillName || _instrument.skillName) enriched.skillName = opts.skillName ?? _instrument.skillName;\n try { channel.telemetry?.reportActionCall(enriched); } catch {}\n const activityAttrs: Record<string, string> = { \"ai.agent.action.type\": opts.actionType ?? \"\", \"ai.agent.action.target\": opts.target ?? \"\" };\n if (enriched.skillName) activityAttrs[\"ai.agent.skill.name\"] = enriched.skillName;\n _sendActivity({\n span_id: randomBytes(8).toString(\"hex\"), span_type: \"action\",\n span_name: `${opts.actionType ?? \"action\"}: ${opts.target ?? \"\"}`,\n status: opts.success === false ? \"error\" : \"ok\",\n start_time: new Date(Date.now() - (opts.latencyMs ?? 0)).toISOString(),\n end_time: new Date().toISOString(), duration_ms: opts.latencyMs ?? 0,\n attributes: activityAttrs,\n action_type: opts.actionType, action_target: opts.target,\n });\n },\n reportNav: (opts: any) => {\n const enriched = { ...opts, traceId, parentSpanId: inferenceSpanId };\n if (opts.skillName || _instrument.skillName) enriched.skillName = opts.skillName ?? _instrument.skillName;\n try { channel.telemetry?.reportNavCall(enriched); } catch {}\n const activityAttrs: Record<string, string> = { \"ai.agent.nav.to_url\": opts.toUrl ?? \"\" };\n if (enriched.skillName) activityAttrs[\"ai.agent.skill.name\"] = enriched.skillName;\n _sendActivity({\n span_id: randomBytes(8).toString(\"hex\"), span_type: \"nav\",\n span_name: opts.toUrl?.slice(0, 40) ?? \"navigate\",\n status: opts.status === \"error\" ? \"error\" : \"ok\",\n start_time: new Date(Date.now() - (opts.latencyMs ?? 0)).toISOString(),\n end_time: new Date().toISOString(), duration_ms: opts.latencyMs ?? 0,\n attributes: activityAttrs,\n });\n },\n skillName: undefined as string | undefined,\n traceId,\n parentSpanId: inferenceSpanId,\n };\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\": isA2AMessage ? \"a2a\" : 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!; // Non-null: caller guards with `if (!_ocRuntime)` check\n\n // Resolve room/sender context for room messages\n let roomName: string | undefined;\n let senderDisplayName: string | undefined;\n if (isRoomMessage && metadata.roomId) {\n roomName = metadata.roomName;\n if (!roomName) {\n const rooms = channel.getRooms?.() ?? [];\n const room = rooms.find((r: any) => r.roomId === metadata.roomId);\n if (room) {\n roomName = room.name;\n if (metadata.senderDeviceId) {\n const member = room.members?.find((m: any) => m.deviceId === metadata.senderDeviceId);\n if (member) senderDisplayName = member.displayName;\n }\n }\n }\n }\n\n const route = core.channel.routing.resolveAgentRoute({\n cfg,\n channel: \"agentvault\",\n accountId: account.accountId,\n peer: {\n kind: isA2AMessage ? \"a2a\" as any : isRoomMessage ? \"group\" as any : \"direct\",\n id: isA2AMessage\n ? `agentvault:a2a:${metadata.fromHubAddress}`\n : isRoomMessage\n ? `agentvault:room:${metadata.roomId}`\n : \"agentvault:owner\",\n },\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: isA2AMessage ? `Agent (${metadata.fromHubAddress})` : isRoomMessage ? (senderDisplayName ?? \"Room Member\") : \"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: isA2AMessage ? `a2a:${metadata.fromHubAddress}` : isRoomMessage ? `agentvault:room:${metadata.roomId}` : \"agentvault:owner\",\n To: `agentvault:agent:${account.accountId}`,\n SessionKey: route.sessionKey,\n AccountId: account.accountId,\n ChatType: isA2AMessage ? \"a2a\" : isRoomMessage ? \"room\" : \"direct\",\n ConversationLabel: isA2AMessage ? `A2A: ${metadata.fromHubAddress}` : isRoomMessage ? (roomName ?? \"AgentVault Room\") : \"AgentVault\",\n SenderName: isA2AMessage ? metadata.fromHubAddress : isRoomMessage ? (senderDisplayName ?? \"Room Member\") : \"Owner\",\n SenderId: isA2AMessage ? `a2a:${metadata.fromHubAddress}` : isRoomMessage ? `agentvault:room:${metadata.senderDeviceId ?? 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 Instrument: _instrument, // OpenClaw ctx convention\n AgentVaultTelemetry: _instrument, // AgentVault-specific accessor\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 runWithTraceContext(\n { traceId, parentSpanId: inferenceSpanId },\n () => 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 via deliver() \u2014 explicit target, no silent fallback\n let replyTarget: DeliveryTarget;\n if (isA2AMessage) {\n // Loop prevention: rate limit A2A replies per channel\n if (!_a2aCanReply(metadata.a2aChannelId)) {\n console.warn(`[AgentVault] A2A reply suppressed (rate limit) for channel ${metadata.a2aChannelId?.slice(0, 8)}...`);\n return;\n }\n replyTarget = { kind: \"a2a\", hubAddress: metadata.fromHubAddress };\n } else if (isRoomMessage) {\n replyTarget = { kind: \"room\", roomId: metadata.roomId };\n } else {\n replyTarget = { kind: \"owner\" };\n }\n await channel.deliver(replyTarget, { type: \"text\", text }, {\n conversationId: metadata.conversationId,\n topicId: metadata.topicId,\n parentSpanId: inferenceSpanId,\n metadata: isRoomMessage ? { content_length: text.length } : undefined,\n });\n if (isA2AMessage) {\n _a2aRecordReply(metadata.a2aChannelId);\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\n const endTime = Date.now();\n\n // Emit child spans for the completed message lifecycle\n _emitHierarchicalSpans(channel, {\n traceId,\n rootSpanId,\n inferenceSpanId,\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 inferenceSpanId,\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 // Dedicated error span for the Errors tab\n _emitChildSpan(channel, {\n traceId,\n parentSpanId: rootSpanId,\n name: \"error\",\n startTime: endTime,\n endTime: endTime,\n attributes: {\n \"ai.agent.error.type\": (err as any)?.constructor?.name ?? \"Error\",\n \"ai.agent.error.message\": String(err),\n },\n status: \"error\",\n statusMessage: String(err),\n });\n throw err;\n }\n}\n\n/** Infer a span type from the span name for activity stream display. */\nfunction _inferSpanType(name: string): \"llm\" | \"tool\" | \"http\" | \"action\" | \"error\" | \"nav\" {\n if (name === \"error\" || name.includes(\"error\")) return \"error\";\n if (name.startsWith(\"llm.\") || name.includes(\"inference\")) return \"llm\";\n if (name.startsWith(\"tool.\") || name.includes(\"tool\")) return \"tool\";\n if (name.startsWith(\"http.\") || name.includes(\"http\")) return \"http\";\n if (name.startsWith(\"nav.\") || name.includes(\"nav\")) return \"nav\";\n if (name.startsWith(\"action.\") || name.includes(\"action\")) return \"action\";\n return \"action\"; // default fallback\n}\n\n/** Extract a human-readable span name from span attributes. */\nfunction _extractSpanName(name: string, attrs: Record<string, string | number | boolean>): string {\n if (attrs[\"ai.agent.llm.model\"]) return String(attrs[\"ai.agent.llm.model\"]);\n if (attrs[\"ai.agent.tool.name\"]) return String(attrs[\"ai.agent.tool.name\"]);\n if (attrs[\"ai.agent.http.url\"]) {\n try { return new URL(String(attrs[\"ai.agent.http.url\"])).hostname; } catch { /* use raw */ }\n return String(attrs[\"ai.agent.http.url\"]).slice(0, 40);\n }\n if (attrs[\"ai.agent.action.type\"]) return `${attrs[\"ai.agent.action.type\"]}: ${attrs[\"ai.agent.action.target\"] ?? \"\"}`;\n if (attrs[\"ai.agent.nav.to_url\"]) return String(attrs[\"ai.agent.nav.to_url\"]).slice(0, 40);\n if (attrs[\"ai.agent.error.type\"]) return String(attrs[\"ai.agent.error.type\"]);\n return name;\n}\n\n/** Emit a single child span via the channel's telemetry reporter + WS activity stream. */\nfunction _emitChildSpan(channel: any, opts: {\n traceId: string;\n parentSpanId: string;\n spanId?: 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 const spanId = opts.spanId ?? randomBytes(8).toString(\"hex\");\n\n reporter.reportCustomSpan({\n traceId: opts.traceId,\n spanId,\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\n // Dual-path: also send via WS for real-time activity streaming\n try {\n const spanType = _inferSpanType(opts.name);\n const spanName = _extractSpanName(opts.name, opts.attributes);\n const durationMs = opts.endTime - opts.startTime;\n channel.sendActivitySpan({\n trace_id: opts.traceId,\n span_id: spanId,\n parent_span_id: opts.parentSpanId,\n span_type: spanType,\n span_name: spanName,\n status: opts.status,\n start_time: new Date(opts.startTime).toISOString(),\n end_time: new Date(opts.endTime).toISOString(),\n duration_ms: durationMs,\n attributes: opts.attributes,\n ...(spanType === \"llm\" ? {\n tokens_input: opts.attributes[\"ai.agent.llm.tokens_input\"],\n tokens_output: opts.attributes[\"ai.agent.llm.tokens_output\"],\n } : {}),\n ...(spanType === \"http\" ? {\n http_method: opts.attributes[\"ai.agent.http.method\"],\n http_status_code: opts.attributes[\"ai.agent.http.status_code\"],\n http_url: opts.attributes[\"ai.agent.http.url\"],\n } : {}),\n ...(spanType === \"tool\" ? {\n tool_success: opts.attributes[\"ai.agent.tool.success\"],\n } : {}),\n ...(spanType === \"error\" ? {\n error_type: opts.attributes[\"ai.agent.error.type\"],\n error_message: opts.attributes[\"ai.agent.error.message\"],\n } : {}),\n });\n } catch { /* WS activity is best-effort */ }\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 inferenceSpanId?: 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 spanId: opts.inferenceSpanId,\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\", \"room\"] },\n config: { listAccountIds, resolveAccount },\n\n gateway: {\n /** Health probe for `openclaw channels status --probe` */\n probe: async (ctx: any) => {\n const accountId = ctx?.accountId ?? \"default\";\n const ch = _channels.get(accountId);\n if (!ch) return { ok: false, status: \"disconnected\", error: \"Channel not started\" };\n const state = ch.state;\n return {\n ok: state === \"ready\",\n status: state,\n deviceId: ch.deviceId ?? undefined,\n sessions: ch.sessionCount,\n };\n },\n\n /** Status for `openclaw health --json` per-channel summary */\n status: (ctx: any) => {\n const accountId = ctx?.accountId ?? \"default\";\n const ch = _channels.get(accountId);\n if (!ch) return { connected: false, status: \"not_started\" };\n return {\n connected: ch.state === \"ready\",\n status: ch.state,\n deviceId: ch.deviceId ?? undefined,\n sessions: ch.sessionCount,\n encrypted: true,\n };\n },\n\n startAccount: async (ctx: ChannelGatewayContext<ResolvedAccountBase>) => {\n const { account, cfg, log, abortSignal } = ctx;\n const _log: ((msg: string) => void) | undefined = typeof log === \"function\" ? log : log?.info?.bind(log);\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(/^~/, require(\"node:os\").homedir()));\n _log?.(`[AgentVault] starting (dataDir=${dataDir})`);\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?.(\"[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?.(`[AgentVault] inbound error: ${String(err)}`);\n }\n },\n onA2AMessage: async (msg: any) => {\n const a2aMetadata = {\n a2aChannelId: msg.channelId,\n fromHubAddress: msg.fromHubAddress,\n conversationId: msg.conversationId,\n timestamp: msg.timestamp,\n parentSpanId: msg.parentSpanId,\n messageId: `a2a:${msg.channelId}:${Date.now()}`,\n };\n if (!_ocRuntime) {\n _log?.(\"[AgentVault] runtime not ready, queuing A2A message\");\n _messageQueue.push(async () => {\n await handleInbound({ plaintext: msg.text, metadata: a2aMetadata, channel, account, cfg });\n });\n return;\n }\n try {\n await handleInbound({ plaintext: msg.text, metadata: a2aMetadata, channel, account, cfg });\n } catch (err) {\n _log?.(`[AgentVault] A2A inbound error: ${String(err)}`);\n }\n },\n onA2AChannelReady: async (info: {\n channelId: string;\n peerHubAddress: string;\n role: \"initiator\" | \"responder\";\n conversationId: string;\n topic?: string;\n }) => {\n // Register peer as valid outbound target (both roles)\n _registerA2ATarget(info.peerHubAddress, account.accountId);\n\n // Only initiator sends the seed message\n if (info.role !== \"initiator\") {\n _log?.(`[AgentVault] A2A channel ready (responder) \u2014 waiting for initiator: ${info.peerHubAddress}`);\n return;\n }\n _log?.(`[AgentVault] A2A channel ready (initiator) \u2014 sending seed to ${info.peerHubAddress}${info.topic ? ` [topic: ${info.topic}]` : \"\"}`);\n\n const seedText = info.topic\n ? `[System] A new A2A channel has been established with agent ${info.peerHubAddress}. ` +\n `Topic: \"${info.topic}\". ` +\n `Introduce yourself briefly and begin discussing this topic.`\n : `[System] A new A2A channel has been established with agent ${info.peerHubAddress}. ` +\n `Introduce yourself briefly and state what you can help with.`;\n const seedMetadata = {\n a2aChannelId: info.channelId,\n fromHubAddress: info.peerHubAddress,\n conversationId: info.conversationId,\n timestamp: new Date().toISOString(),\n messageId: `a2a-seed:${info.channelId}:${Date.now()}`,\n };\n\n if (!_ocRuntime) {\n _log?.(\"[AgentVault] runtime not ready, queuing A2A seed\");\n _messageQueue.push(async () => {\n await handleInbound({ plaintext: seedText, metadata: seedMetadata, channel, account, cfg });\n });\n return;\n }\n try {\n await handleInbound({ plaintext: seedText, metadata: seedMetadata, channel, account, cfg });\n } catch (err) {\n _log?.(`[AgentVault] A2A seed error: ${String(err)}`);\n }\n },\n onStateChange: (state: string) => {\n _log?.(`[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?.(`[AgentVault] channel error (non-fatal): ${String(err)}`);\n });\n\n // Always start local HTTP server \u2014 managed routes are an overlay, not a replacement\n const httpPort = account.httpPort ?? 18790;\n channel.on(\"ready\", () => {\n channel.startHttpServer(httpPort);\n _log?.(`[AgentVault] HTTP send server listening on http://127.0.0.1:${httpPort}`);\n if (isUsingManagedRoutes) {\n _log?.(`[AgentVault] OpenClaw managed routes also registered`);\n }\n\n // Register persisted A2A peers as valid outbound targets\n for (const peerAddress of channel.a2aPeerAddresses) {\n _registerA2ATarget(peerAddress, account.accountId);\n }\n\n // Register persisted rooms as valid outbound targets\n for (const room of channel.roomIds) {\n _registerRoomTarget(room.roomId, room.name, account.accountId);\n }\n });\n\n // Register new rooms as outbound targets when agent joins\n channel.on(\"room_joined\", (info: { roomId: string; name: string }) => {\n _registerRoomTarget(info.roomId, info.name, account.accountId);\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: _outboundTargets,\n\n sendText: async ({ to: rawTo, 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 target = parseTarget(rawTo);\n const receipt = await ch.deliver(target, { type: \"text\", text });\n return { ok: receipt.ok, queued: receipt.queued, error: receipt.error };\n } catch (err) {\n return { ok: false, error: String(err) };\n }\n },\n\n sendMedia: async ({ to: rawTo, 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 target = parseTarget(rawTo);\n const receipt = await ch.deliver(target, { type: \"text\", text: message });\n return { ok: receipt.ok, queued: receipt.queued, error: receipt.error };\n } catch (err) {\n return { ok: false, error: String(err) };\n }\n },\n\n /** Rich payload delivery \u2014 OpenClaw v2026.3.2+ calls this for structured messages. */\n sendPayload: async (ctx: ChannelOutboundPayloadContext) => {\n const { payload, accountId } = ctx;\n const resolvedId = accountId ?? \"default\";\n const ch = _channels.get(resolvedId);\n if (!ch) return { ok: false, error: \"AgentVault channel not connected\" };\n\n try {\n // Suppress reasoning blocks \u2014 E2E channel should only deliver actual responses\n if (payload.isReasoning) return { ok: true };\n\n // Wake agent proactively before sending (fire-and-forget)\n requestHeartbeatNow({ reason: \"outbound-payload\" }).catch(() => {});\n\n const text = (payload.text ?? \"\").trim();\n if (!text && !payload.mediaUrls?.length) return { ok: true };\n\n // Resolve target via parseTarget \u2014 owner if no explicit target\n const rawTarget = (ctx as any).to;\n let target: DeliveryTarget;\n if (rawTarget && typeof rawTarget === \"string\") {\n target = parseTarget(rawTarget);\n } else {\n target = { kind: \"owner\" };\n }\n\n // Helper: deliver text via unified deliver()\n const _send = async (msg: string) => {\n await ch.deliver(target, { type: \"text\", text: msg });\n };\n\n // Encrypt and deliver text content\n if (text) {\n await _send(text);\n }\n\n // Deliver media URLs as text messages (E2E encrypted)\n if (payload.mediaUrls?.length) {\n for (const url of payload.mediaUrls) {\n await _send(url);\n }\n }\n\n // Forward suggested actions as a structured message\n if (payload.suggestedActions?.length) {\n const actionsText = payload.suggestedActions\n .map((a: { label: string; action: string }) => `- ${a.label}: ${a.action}`)\n .join(\"\\n\");\n await _send(`Suggested actions:\\n${actionsText}`);\n }\n\n return { ok: true };\n } catch (err) {\n return { ok: false, error: String(err) };\n }\n },\n },\n};\n\n// --- Exported for testing ---\nexport { _parseMentions, _shouldProcessRoomMessage, _stripMentions };\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: OpenClawPluginApi) {\n _setRuntime(api.runtime);\n\n // Install fetch interceptor to capture all outbound HTTP from the gateway process.\n installFetchInterceptor({\n onHttpCall: (report) => {\n // Find an active channel to emit through\n const ch = _channels.values().next().value;\n if (!ch) return;\n\n // Telemetry reporter is optional \u2014 may not be initialized\n if (ch.telemetry) {\n try {\n ch.telemetry.reportHttpCall({\n method: report.method,\n url: report.url,\n statusCode: report.statusCode,\n latencyMs: report.latencyMs,\n ...(report.traceId ? { traceId: report.traceId } : {}),\n ...(report.parentSpanId ? { parentSpanId: report.parentSpanId } : {}),\n });\n } catch { /* best-effort */ }\n }\n\n // Activity span always fires (uses WS, not telemetry reporter)\n try {\n const hostname = (() => { try { return new URL(report.url).hostname; } catch { return report.url.slice(0, 40); } })();\n ch.sendActivitySpan({\n trace_id: report.traceId ?? \"\",\n parent_span_id: report.parentSpanId ?? \"\",\n span_id: randomBytes(8).toString(\"hex\"),\n span_type: \"http\",\n span_name: hostname,\n status: report.statusCode >= 400 || report.statusCode === 0 ? \"error\" : \"ok\",\n start_time: new Date(Date.now() - report.latencyMs).toISOString(),\n end_time: new Date().toISOString(),\n duration_ms: report.latencyMs,\n attributes: {\n \"ai.agent.http.method\": report.method,\n \"ai.agent.http.url\": report.url,\n },\n http_method: report.method,\n http_status_code: report.statusCode,\n http_url: report.url,\n });\n } catch { /* best-effort */ }\n },\n });\n\n api.registerChannel({ plugin: agentVaultPlugin });\n\n // --- Managed HTTP routes (OpenClaw v2026.3.2+) ---\n if (typeof api.registerHttpRoute === \"function\") {\n try {\n api.registerHttpRoute({\n path: \"/agentvault/send\",\n method: \"POST\",\n handler: async (req) => {\n const ch = _channels.values().next().value;\n if (!ch) return { status: 503, body: { ok: false, error: \"Channel not started\" } };\n const parsed = (typeof req.body === \"string\" ? JSON.parse(req.body) : req.body) as Record<string, unknown>;\n const result = await handleSendRequest(parsed, ch);\n return { status: result.status, body: result.body };\n },\n });\n api.registerHttpRoute({\n path: \"/agentvault/action\",\n method: \"POST\",\n handler: async (req) => {\n const ch = _channels.values().next().value;\n if (!ch) return { status: 503, body: { ok: false, error: \"Channel not started\" } };\n const parsed = (typeof req.body === \"string\" ? JSON.parse(req.body) : req.body) as Record<string, unknown>;\n const result = await handleActionRequest(parsed, ch);\n return { status: result.status, body: result.body };\n },\n });\n api.registerHttpRoute({\n path: \"/agentvault/decision\",\n method: \"POST\",\n handler: async (req) => {\n const ch = _channels.values().next().value;\n if (!ch) return { status: 503, body: { ok: false, error: \"Channel not started\" } };\n const parsed = (typeof req.body === \"string\" ? JSON.parse(req.body) : req.body) as Record<string, unknown>;\n const result = await handleDecisionRequest(parsed, ch);\n return { status: result.status, body: result.body };\n },\n });\n api.registerHttpRoute({\n path: \"/agentvault/status\",\n method: \"GET\",\n handler: async () => {\n const ch = _channels.values().next().value;\n if (!ch) return { status: 503, body: { ok: false, error: \"Channel not started\" } };\n const result = handleStatusRequest(ch);\n return { status: result.status, body: result.body };\n },\n });\n api.registerHttpRoute({\n path: \"/agentvault/targets\",\n method: \"GET\",\n handler: async () => {\n const ch = _channels.values().next().value;\n if (!ch) return { status: 503, body: { ok: false, error: \"Channel not started\" } };\n const result = handleTargetsRequest(ch);\n return { status: result.status, body: result.body };\n },\n });\n isUsingManagedRoutes = true;\n } catch { /* registerHttpRoute failed \u2014 fall back to self-managed server */ }\n }\n\n // --- Event hooks (OpenClaw v2026.3.2+) ---\n if (typeof api.on === \"function\") {\n // Phase 4: message_sent \u2014 delivery confirmation tracking\n api.on(\"message_sent\", async (event: MessageSentEvent) => {\n try {\n const ch = _channels.values().next().value;\n if (!ch?.telemetry) return;\n ch.telemetry.reportCustomSpan({\n traceId: randomBytes(16).toString(\"hex\"),\n spanId: randomBytes(8).toString(\"hex\"),\n name: \"agentvault.message.delivered\",\n kind: \"internal\",\n startTime: event.timestamp,\n endTime: event.timestamp + 1,\n attributes: {\n \"agentvault.message.id\": event.messageId,\n \"agentvault.delivery.status\": event.deliveryStatus,\n \"agentvault.channel.id\": event.channelId,\n },\n status: { code: event.deliveryStatus === \"failed\" ? 2 : 1 },\n });\n } catch { /* best-effort */ }\n });\n\n // Phase 6: session lifecycle hooks\n api.on(\"session_start\", async (event: SessionStartEvent) => {\n try {\n const ch = _channels.values().next().value;\n if (!ch?.telemetry) return;\n ch.telemetry.reportCustomSpan({\n traceId: randomBytes(16).toString(\"hex\"),\n spanId: randomBytes(8).toString(\"hex\"),\n name: \"agentvault.session.start\",\n kind: \"internal\",\n startTime: event.timestamp,\n endTime: event.timestamp + 1,\n attributes: {\n \"agentvault.session.key\": event.sessionKey,\n \"agentvault.agent.id\": event.agentId,\n },\n status: { code: 1 },\n });\n } catch { /* best-effort */ }\n });\n\n api.on(\"session_end\", async (event: SessionEndEvent) => {\n try {\n const ch = _channels.values().next().value;\n if (!ch?.telemetry) return;\n ch.telemetry.reportCustomSpan({\n traceId: randomBytes(16).toString(\"hex\"),\n spanId: randomBytes(8).toString(\"hex\"),\n name: \"agentvault.session.end\",\n kind: \"internal\",\n startTime: event.timestamp,\n endTime: event.timestamp + 1,\n attributes: {\n \"agentvault.session.key\": event.sessionKey,\n \"agentvault.agent.id\": event.agentId,\n ...(event.reason ? { \"agentvault.session.end_reason\": event.reason } : {}),\n },\n status: { code: 1 },\n });\n } catch { /* best-effort */ }\n });\n }\n\n // --- Phase 7: Agent events for trust telemetry ---\n import(\"./openclaw-compat.js\").then(async ({ onAgentEvent, onSessionTranscriptUpdate }) => {\n onAgentEvent((event) => {\n try {\n const ch = _channels.values().next().value;\n if (!ch?.telemetry) return;\n ch.telemetry.reportCustomSpan({\n traceId: randomBytes(16).toString(\"hex\"),\n spanId: randomBytes(8).toString(\"hex\"),\n name: `ai.agent.event.${event.type}`,\n kind: \"internal\",\n startTime: event.timestamp,\n endTime: event.timestamp + 1,\n attributes: {\n \"ai.agent.event.type\": event.type,\n \"ai.agent.id\": event.agentId,\n ...(event.data ? Object.fromEntries(\n Object.entries(event.data).map(([k, v]) => [`ai.agent.event.${k}`, String(v)])\n ) : {}),\n },\n status: { code: 1 },\n });\n } catch { /* best-effort */ }\n }).catch(() => {});\n\n onSessionTranscriptUpdate((update) => {\n try {\n const ch = _channels.values().next().value;\n if (!ch?.telemetry) return;\n ch.telemetry.reportCustomSpan({\n traceId: randomBytes(16).toString(\"hex\"),\n spanId: randomBytes(8).toString(\"hex\"),\n name: \"ai.agent.transcript.update\",\n kind: \"internal\",\n startTime: update.timestamp,\n endTime: update.timestamp + 1,\n attributes: {\n \"agentvault.session.key\": update.sessionKey,\n \"ai.agent.transcript.role\": update.role ?? \"unknown\",\n \"ai.agent.transcript.delta_chars\": update.delta.length,\n },\n status: { code: 1 },\n });\n } catch { /* best-effort */ }\n }).catch(() => {});\n }).catch(() => { /* openclaw-compat import failed \u2014 older SDK */ });\n\n // --- Agent tool: agentvault_status ---\n // Lets the agent check its own encrypted channel status\n try {\n api.registerTool?.({\n name: \"agentvault_status\",\n description: \"Check the AgentVault encrypted channel status, connection state, and session count.\",\n parameters: {\n type: \"object\",\n properties: {\n accountId: {\n type: \"string\",\n description: \"Account ID to check (default: 'default')\",\n },\n },\n },\n execute: async (_id: string, params: { accountId?: string }) => {\n const id = params.accountId ?? \"default\";\n const ch = _channels.get(id);\n if (!ch) {\n return { content: [{ type: \"text\", text: JSON.stringify({ connected: false, error: \"Channel not started\" }) }] };\n }\n return {\n content: [{\n type: \"text\",\n text: JSON.stringify({\n connected: ch.state === \"ready\",\n state: ch.state,\n deviceId: ch.deviceId,\n sessions: ch.sessionCount,\n encrypted: true,\n }),\n }],\n };\n },\n }, { optional: true });\n } catch { /* registerTool may not be available in older OpenClaw versions */ }\n\n // --- Auto-reply command: /agentvault ---\n // Quick status check without AI involvement\n try {\n api.registerCommand?.({\n name: \"agentvault\",\n description: \"Show AgentVault encrypted channel status\",\n handler: () => {\n const statuses: string[] = [];\n if (_channels.size === 0) {\n statuses.push(\"AgentVault: no active channels\");\n } else {\n for (const [id, ch] of _channels) {\n statuses.push(`AgentVault [${id}]: ${ch.state} | sessions: ${ch.sessionCount} | encrypted: yes`);\n }\n }\n return { text: statuses.join(\"\\n\") };\n },\n });\n } catch { /* registerCommand may not be available in older OpenClaw versions */ }\n },\n};\n", "/**\n * Shared multi-account config resolution for AgentVault OpenClaw plugin.\n *\n * Supports two config shapes:\n * 1. Legacy single-agent: channels.agentvault.dataDir (returns [\"default\"])\n * 2. Multi-agent: channels.agentvault.accounts.{id}.dataDir (returns account keys)\n *\n * When `accounts` key is present, it takes precedence over top-level dataDir.\n */\n\nconst DEFAULT_API_URL = \"https://api.agentvault.chat\";\nconst DEFAULT_HTTP_PORT = 18790;\n\nexport interface ResolvedAccount {\n accountId: string;\n dataDir: string;\n apiUrl: string;\n agentName: string;\n httpPort: number;\n configured: boolean;\n}\n\nexport function listAccountIds(cfg: any): string[] {\n const av = cfg?.channels?.agentvault;\n if (!av) return [];\n if (av.accounts && typeof av.accounts === \"object\") {\n return Object.keys(av.accounts);\n }\n return av.dataDir ? [\"default\"] : [];\n}\n\nexport function resolveAccount(cfg: any, accountId?: string): ResolvedAccount {\n const av = cfg?.channels?.agentvault ?? {};\n const id = accountId ?? \"default\";\n\n if (av.accounts && typeof av.accounts === \"object\") {\n const acct = av.accounts[id];\n if (!acct) {\n return {\n accountId: id,\n dataDir: \"\",\n apiUrl: av.apiUrl ?? DEFAULT_API_URL,\n agentName: id,\n httpPort: DEFAULT_HTTP_PORT,\n configured: false,\n };\n }\n\n let httpPort = acct.httpPort;\n if (httpPort == null) {\n const keys = Object.keys(av.accounts);\n const index = keys.indexOf(id);\n httpPort = DEFAULT_HTTP_PORT + (index >= 0 ? index : 0);\n }\n\n return {\n accountId: id,\n dataDir: acct.dataDir ?? \"\",\n apiUrl: acct.apiUrl ?? av.apiUrl ?? DEFAULT_API_URL,\n agentName: acct.agentName ?? id,\n httpPort,\n configured: Boolean(acct.dataDir),\n };\n }\n\n return {\n accountId: id,\n dataDir: av.dataDir ?? \"~/.openclaw/agentvault\",\n apiUrl: av.apiUrl ?? DEFAULT_API_URL,\n agentName: av.agentName ?? \"OpenClaw Agent\",\n httpPort: av.httpPort ?? DEFAULT_HTTP_PORT,\n configured: Boolean(av.dataDir),\n };\n}\n", "/**\n * HTTP interceptor for capturing outbound HTTP calls during message handling.\n *\n * Uses Node.js diagnostics_channel to subscribe to undici request events,\n * capturing ALL outbound HTTP from the process (including LLM SDKs, Playwright\n * navigations, and any library that uses undici under the hood).\n *\n * Also monkey-patches globalThis.fetch as a fallback for non-undici HTTP.\n *\n * Uses AsyncLocalStorage to associate intercepted calls with the active\n * message's traceId/parentSpanId.\n *\n * Built-in skip patterns prevent capturing internal infrastructure requests\n * (localhost, AgentVault API, Clerk auth).\n */\nimport { AsyncLocalStorage } from \"node:async_hooks\";\nimport diagnosticsChannel from \"node:diagnostics_channel\";\n\n// \u2500\u2500 Public types \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nexport interface HttpCallReport {\n method: string;\n url: string;\n statusCode: number;\n latencyMs: number;\n traceId?: string;\n parentSpanId?: string;\n}\n\nexport interface TraceContext {\n traceId: string;\n parentSpanId: string;\n}\n\nexport interface FetchInterceptorOptions {\n onHttpCall: (report: HttpCallReport) => void;\n skipPatterns?: RegExp[];\n}\n\n// \u2500\u2500 Internal state \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nconst traceStore = new AsyncLocalStorage<TraceContext>();\n\nconst DEFAULT_SKIP_PATTERNS: RegExp[] = [\n /^https?:\\/\\/localhost(:\\d+)?/,\n /^https?:\\/\\/127\\.0\\.0\\.1(:\\d+)?/,\n /\\.agentvault\\.chat/,\n /\\.agentvault\\.dev/,\n /\\.clerk\\./,\n];\n\nlet installed = false;\nlet originalFetch: typeof globalThis.fetch | undefined;\n\n// Track in-flight undici requests: request \u2192 { url, method, startTime }\nconst inflightRequests = new WeakMap<\n object,\n { url: string; method: string; startTime: number }\n>();\n\n// Diagnostics channel subscriptions\nlet unsubCreate: (() => void) | undefined;\nlet unsubHeaders: (() => void) | undefined;\nlet unsubError: (() => void) | undefined;\n\n// \u2500\u2500 Helpers \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nfunction shouldSkip(url: string, extraPatterns: RegExp[]): boolean {\n const allPatterns = [...DEFAULT_SKIP_PATTERNS, ...extraPatterns];\n return allPatterns.some((p) => p.test(url));\n}\n\nfunction extractUrl(origin: string, path: string): string {\n // undici gives us origin (e.g., \"https://api.openai.com\") and path (e.g., \"/v1/chat/completions\")\n return `${origin}${path}`;\n}\n\n// \u2500\u2500 Public API \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n/**\n * Install HTTP interceptor using both undici diagnostics channels and\n * globalThis.fetch monkey-patching. Idempotent.\n */\nexport function installFetchInterceptor(opts: FetchInterceptorOptions): void {\n if (installed) return;\n installed = true;\n\n const skipPatterns = [\n ...DEFAULT_SKIP_PATTERNS,\n ...(opts.skipPatterns ?? []),\n ];\n\n // \u2500\u2500 1. Undici diagnostics channel \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n // undici publishes events for every HTTP request it makes.\n // This captures LLM SDK calls, playwright navigations, etc.\n\n try {\n const createChannel = diagnosticsChannel.channel(\"undici:request:create\");\n const headersChannel = diagnosticsChannel.channel(\"undici:request:headers\");\n const errorChannel = diagnosticsChannel.channel(\"undici:request:error\");\n\n const onRequestCreate = (message: unknown) => {\n try {\n const msg = message as {\n request: {\n method?: string;\n origin?: string;\n path?: string;\n };\n };\n const req = msg.request;\n if (!req) return;\n\n const origin = String(req.origin ?? \"\");\n const path = String(req.path ?? \"/\");\n const url = extractUrl(origin, path);\n\n if (shouldSkip(url, skipPatterns)) return;\n\n inflightRequests.set(req, {\n url,\n method: String(req.method ?? \"GET\").toUpperCase(),\n startTime: Date.now(),\n });\n } catch { /* best-effort */ }\n };\n\n const onRequestHeaders = (message: unknown) => {\n try {\n const msg = message as {\n request: object;\n response: { statusCode?: number };\n };\n const tracked = inflightRequests.get(msg.request);\n if (!tracked) return;\n inflightRequests.delete(msg.request);\n\n const latencyMs = Date.now() - tracked.startTime;\n const ctx = traceStore.getStore();\n\n opts.onHttpCall({\n method: tracked.method,\n url: tracked.url,\n statusCode: msg.response?.statusCode ?? 0,\n latencyMs,\n traceId: ctx?.traceId,\n parentSpanId: ctx?.parentSpanId,\n });\n } catch { /* best-effort */ }\n };\n\n const onRequestError = (message: unknown) => {\n try {\n const msg = message as { request: object; error?: Error };\n const tracked = inflightRequests.get(msg.request);\n if (!tracked) return;\n inflightRequests.delete(msg.request);\n\n const latencyMs = Date.now() - tracked.startTime;\n const ctx = traceStore.getStore();\n\n opts.onHttpCall({\n method: tracked.method,\n url: tracked.url,\n statusCode: 0,\n latencyMs,\n traceId: ctx?.traceId,\n parentSpanId: ctx?.parentSpanId,\n });\n } catch { /* best-effort */ }\n };\n\n createChannel.subscribe(onRequestCreate);\n headersChannel.subscribe(onRequestHeaders);\n errorChannel.subscribe(onRequestError);\n\n unsubCreate = () => createChannel.unsubscribe(onRequestCreate);\n unsubHeaders = () => headersChannel.unsubscribe(onRequestHeaders);\n unsubError = () => errorChannel.unsubscribe(onRequestError);\n } catch {\n // diagnostics_channel not available or undici not loaded \u2014 fall through to fetch-only\n }\n\n // \u2500\u2500 2. globalThis.fetch monkey-patch (fallback) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n // Catches any HTTP that doesn't go through undici (e.g., native fetch\n // in newer Node.js, or custom HTTP implementations).\n\n originalFetch = globalThis.fetch;\n const savedOriginal = originalFetch;\n\n globalThis.fetch = async (\n input: RequestInfo | URL,\n init?: RequestInit,\n ): Promise<Response> => {\n const url =\n input instanceof Request\n ? input.url\n : input instanceof URL\n ? input.href\n : String(input);\n\n if (shouldSkip(url, skipPatterns)) {\n return savedOriginal(input, init);\n }\n\n const method =\n input instanceof Request\n ? input.method\n : init?.method ?? \"GET\";\n\n const ctx = traceStore.getStore();\n const start = Date.now();\n\n try {\n const response = await savedOriginal(input, init);\n const latencyMs = Date.now() - start;\n\n try {\n opts.onHttpCall({\n method,\n url,\n statusCode: response.status,\n latencyMs,\n traceId: ctx?.traceId,\n parentSpanId: ctx?.parentSpanId,\n });\n } catch { /* best-effort */ }\n\n return response;\n } catch (err) {\n const latencyMs = Date.now() - start;\n\n try {\n opts.onHttpCall({\n method,\n url,\n statusCode: 0,\n latencyMs,\n traceId: ctx?.traceId,\n parentSpanId: ctx?.parentSpanId,\n });\n } catch { /* best-effort */ }\n\n throw err;\n }\n };\n}\n\n/**\n * Uninstall all interceptors. Safe to call even if not installed.\n */\nexport function uninstallFetchInterceptor(): void {\n if (!installed) return;\n\n // Restore fetch\n if (originalFetch) {\n globalThis.fetch = originalFetch;\n originalFetch = undefined;\n }\n\n // Unsubscribe from diagnostics channels\n unsubCreate?.();\n unsubHeaders?.();\n unsubError?.();\n unsubCreate = undefined;\n unsubHeaders = undefined;\n unsubError = undefined;\n\n installed = false;\n}\n\n/**\n * Run an async function with trace context attached via AsyncLocalStorage.\n * Any HTTP calls made within `fn` (via undici or fetch) will include\n * traceId/parentSpanId in their HttpCallReport.\n */\nexport function runWithTraceContext<T>(\n ctx: TraceContext,\n fn: () => T | Promise<T>,\n): Promise<T> {\n return traceStore.run(ctx, fn) as Promise<T>;\n}\n", "/**\n * Extracted HTTP handler logic for the AgentVault plugin.\n *\n * These handlers are shared between:\n * 1. The self-managed HTTP server in channel.ts (legacy/fallback path)\n * 2. OpenClaw's registerHttpRoute() managed routes (new path)\n *\n * Both entry points call the same handler functions, ensuring consistent\n * behavior regardless of how the route is served.\n */\n\nimport type { SecureChannel } from \"./channel.js\";\nimport type { DeliveryTarget } from \"./types.js\";\n\nexport interface HandlerResult {\n status: number;\n body: Record<string, unknown>;\n}\n\n/**\n * Handle POST /send \u2014 send a message (text, file, or room).\n *\n * Routing: explicit target fields only \u2014 no silent lastInboundRoomId fallback.\n * - hub_address / a2a_address / channel_id \u2192 A2A\n * - room_id \u2192 room\n * - target: \"context\" \u2192 resolve from lastInboundRoomId (opt-in)\n * - No target fields \u2192 owner (the breaking fix)\n */\nexport async function handleSendRequest(\n parsed: Record<string, unknown>,\n channel: SecureChannel,\n): Promise<HandlerResult> {\n const text = parsed.text;\n if (!text || typeof text !== \"string\") {\n return { status: 400, body: { ok: false, error: \"Missing 'text' field\" } };\n }\n\n try {\n // Build DeliveryTarget from request fields\n let target: DeliveryTarget;\n\n // A2A send: accept hub_address, a2a_address, a2aAddress, or channel_id\n let a2aTarget = (parsed.hub_address ?? parsed.a2a_address ?? parsed.a2aAddress) as string | undefined;\n\n // Resolve channel_id to hub address if provided\n if (!a2aTarget && parsed.channel_id && typeof parsed.channel_id === \"string\") {\n const hubAddr = channel.resolveA2AChannelHub(parsed.channel_id as string);\n if (hubAddr) a2aTarget = hubAddr;\n }\n\n if (a2aTarget && typeof a2aTarget === \"string\") {\n target = { kind: \"a2a\", hubAddress: a2aTarget };\n } else if (typeof parsed.room_id === \"string\") {\n target = { kind: \"room\", roomId: parsed.room_id };\n } else if (parsed.target === \"context\") {\n target = { kind: \"context\" };\n } else if (parsed.file_path && typeof parsed.file_path === \"string\") {\n // Attachment \u2014 goes to owner\n const receipt = await channel.deliver(\n { kind: \"owner\" },\n { type: \"attachment\", text: text as string, filePath: parsed.file_path as string },\n { topicId: parsed.topicId as string | undefined },\n );\n return {\n status: receipt.ok ? 200 : 500,\n body: {\n ok: receipt.ok,\n destination: receipt.destination,\n ...(receipt.error ? { error: receipt.error } : {}),\n },\n };\n } else {\n // Default: owner (NOT context \u2014 this is the breaking fix)\n target = { kind: \"owner\" };\n }\n\n const receipt = await channel.deliver(\n target,\n { type: \"text\", text: text as string },\n {\n topicId: parsed.topicId as string | undefined,\n priority: parsed.priority as string | undefined,\n metadata: {\n ...(parsed.metadata as Record<string, unknown> | undefined),\n ...(parsed.message_type ? { message_type: parsed.message_type } : {}),\n },\n },\n );\n\n return {\n status: receipt.ok ? 200 : 500,\n body: {\n ok: receipt.ok,\n destination: receipt.destination,\n ...(receipt.error ? { error: receipt.error } : {}),\n },\n };\n } catch (err) {\n return { status: 500, body: { ok: false, error: String(err) } };\n }\n}\n\n/**\n * Handle POST /action \u2014 send an action confirmation.\n */\nexport async function handleActionRequest(\n parsed: Record<string, unknown>,\n channel: SecureChannel,\n): Promise<HandlerResult> {\n if (!parsed.action || typeof parsed.action !== \"string\") {\n return { status: 400, body: { ok: false, error: \"Missing 'action' field\" } };\n }\n\n try {\n const confirmation = {\n action: parsed.action as string,\n status: (parsed.status ?? \"completed\") as \"completed\" | \"failed\" | \"partial\",\n decisionId: parsed.decision_id as string | undefined,\n detail: parsed.detail as string | undefined,\n estimated_cost: parsed.estimated_cost as number | undefined,\n };\n\n // Build target from room_id field\n const target: DeliveryTarget = (parsed.room_id && typeof parsed.room_id === \"string\")\n ? { kind: \"room\", roomId: parsed.room_id }\n : { kind: \"owner\" };\n\n const receipt = await channel.deliver(\n target,\n { type: \"action_confirmation\", confirmation },\n );\n\n return {\n status: receipt.ok ? 200 : 500,\n body: {\n ok: receipt.ok,\n destination: receipt.destination,\n ...(receipt.error ? { error: receipt.error } : {}),\n },\n };\n } catch (err) {\n return { status: 500, body: { ok: false, error: String(err) } };\n }\n}\n\n/**\n * Handle POST /decision \u2014 send a decision request to the owner.\n */\nexport async function handleDecisionRequest(\n parsed: Record<string, unknown>,\n channel: SecureChannel,\n): Promise<HandlerResult> {\n const title = parsed.title;\n if (!title || typeof title !== \"string\") {\n return { status: 400, body: { ok: false, error: \"Missing 'title' field\" } };\n }\n\n const options = parsed.options;\n if (!Array.isArray(options) || options.length < 2) {\n return { status: 400, body: { ok: false, error: \"'options' must be an array with at least 2 items\" } };\n }\n\n for (const opt of options) {\n if (!opt || typeof opt !== \"object\" || !opt.option_id || !opt.label) {\n return { status: 400, body: { ok: false, error: \"Each option must have 'option_id' and 'label'\" } };\n }\n }\n\n try {\n const decision_id = await channel.sendDecisionRequest({\n title: title as string,\n description: parsed.description as string | undefined,\n options: options as Array<{ option_id: string; label: string; risk_level: \"low\" | \"medium\" | \"high\" | \"critical\"; is_default?: boolean }>,\n context_refs: parsed.context_refs as Array<{ type: string; uri: string; label: string }> | undefined,\n deadline: parsed.deadline as string | undefined,\n auto_action: parsed.auto_action as { option_id: string; trigger: string; description?: string } | undefined,\n });\n return { status: 200, body: { ok: true, decision_id } };\n } catch (err) {\n return { status: 500, body: { ok: false, error: String(err) } };\n }\n}\n\n/**\n * Handle GET /status \u2014 return channel health info.\n */\nexport function handleStatusRequest(channel: SecureChannel): HandlerResult {\n return {\n status: 200,\n body: {\n ok: true,\n state: channel.state,\n deviceId: channel.deviceId ?? undefined,\n sessions: channel.sessionCount,\n },\n };\n}\n\n/**\n * Handle GET /targets \u2014 return available delivery destinations.\n */\nexport function handleTargetsRequest(channel: SecureChannel): HandlerResult {\n return {\n status: 200,\n body: {\n ok: true,\n targets: channel.listTargets(),\n context: channel.lastInboundRoomId\n ? { kind: \"room\", roomId: channel.lastInboundRoomId }\n : { kind: \"owner\" },\n },\n };\n}\n", "export interface SecureChannelConfig {\n inviteToken: string;\n dataDir: string;\n apiUrl: string;\n agentName?: string;\n agentVersion?: string;\n platform?: string;\n maxHistorySize?: number; // max stored messages for cross-device replay (default 500)\n webhookUrl?: string; // URL to register for webhook notifications from backend\n httpPort?: number; // Local HTTP port for proactive sends (default: none)\n onMessage?: (plaintext: string, metadata: MessageMetadata) => void;\n onStateChange?: (state: ChannelState) => void;\n onA2AMessage?: (msg: A2AMessage) => void;\n /** Called when an A2A channel becomes ready (approved or activated). */\n onA2AChannelReady?: (info: {\n channelId: string;\n peerHubAddress: string;\n role: \"initiator\" | \"responder\";\n conversationId: string;\n topic?: string;\n }) => void;\n /** Enable client-side policy scanning. If true, rules are fetched on connect. */\n enableScanning?: boolean;\n /** If set, auto-backup encrypted state to server after state changes. */\n backupCode?: string;\n}\n\nexport type ChannelState =\n | \"idle\"\n | \"enrolling\"\n | \"polling\"\n | \"activating\"\n | \"connecting\"\n | \"ready\"\n | \"disconnected\"\n | \"error\";\n\nexport interface AttachmentData {\n filename: string;\n mime: string;\n size: number;\n filePath: string;\n /** Base64-encoded decrypted content (for images passed to LLM vision) */\n base64?: string;\n /** Extracted text content (for text-based files) */\n textContent?: string;\n}\n\nexport interface MessageMetadata {\n messageId: string;\n conversationId: string;\n timestamp: string;\n topicId?: string;\n attachment?: AttachmentData;\n spanId?: string;\n parentSpanId?: string;\n messageType?: string;\n priority?: string;\n envelopeVersion?: string;\n /** Set when the message originated from a multi-agent room */\n roomId?: string;\n /** Device ID of the sender (room messages only) */\n senderDeviceId?: string;\n /** Human-readable room name (room messages only) */\n roomName?: string;\n}\n\nexport interface SendOptions {\n /** Target a specific conversation instead of broadcasting to all sessions */\n conversationId?: string;\n topicId?: string;\n messageType?: string;\n priority?: string;\n parentSpanId?: string;\n metadata?: Record<string, unknown>;\n}\n\nexport interface DecisionOption {\n option_id: string;\n label: string;\n risk_level: \"low\" | \"medium\" | \"high\" | \"critical\";\n is_default?: boolean;\n}\n\nexport interface ContextRef {\n type: string;\n uri: string;\n label: string;\n}\n\nexport interface DecisionRequest {\n title: string;\n description?: string;\n options: DecisionOption[];\n context_refs?: ContextRef[];\n deadline?: string; // ISO 8601\n auto_action?: {\n option_id: string;\n trigger: string;\n description?: string;\n };\n}\n\nexport interface DecisionResponse {\n decision_id: string;\n selected_option_id?: string;\n resolved_at?: string; // ISO 8601\n action?: \"approve\" | \"deny\" | \"defer\";\n defer_until?: string;\n defer_reason?: string;\n}\n\nexport interface HistoryEntry {\n sender: \"owner\" | \"agent\";\n text: string;\n ts: string; // ISO 8601\n topicId?: string; // topic this message belongs to\n}\n\nexport interface DeviceSession {\n ownerDeviceId: string;\n ratchetState: string; // serialized DoubleRatchet\n activated?: boolean; // true after first owner message received\n}\n\nexport interface PersistedState {\n deviceId: string;\n deviceJwt: string;\n primaryConversationId: string;\n sessions: Record<string, DeviceSession>; // conversationId -> session\n identityKeypair: { publicKey: string; privateKey: string }; // hex\n ephemeralKeypair: { publicKey: string; privateKey: string }; // hex\n fingerprint: string;\n lastMessageTimestamp?: string; // ISO timestamp of last received message\n messageHistory?: HistoryEntry[]; // stored messages for cross-device replay\n topics?: Array<{ id: string; name: string; isDefault: boolean }>;\n defaultTopicId?: string;\n groupId?: string;\n hubAddress?: string;\n hubId?: string; // hub UUID \u2014 used for telemetry ingestion\n agentHubId?: string; // agent's hub_id (alias of hubId for routing clarity)\n ownerHubId?: string; // owner's hub_id (populated from device_linked or enrollment)\n /** A2A channel state (agent-to-agent communication) */\n a2aChannels?: Record<string, {\n channelId: string;\n hubAddress: string; // the other agent's hub address\n conversationId: string;\n role?: \"initiator\" | \"responder\";\n session?: DeviceSession; // ratchet state (populated after X3DH)\n pendingEphemeralPrivateKey?: string; // hex, temporary until activated\n /** Observer session (agent \u2192 owner ratchet for A2A observation) */\n observerSession?: {\n ratchetState: string; // serialized DoubleRatchet\n };\n pendingObserverEphemeralPrivateKey?: string; // hex, temporary until observer key accepted\n }>;\n /** Outbound messages queued while disconnected */\n outboundQueue?: Array<{\n convId: string;\n headerBlob: string;\n ciphertext: string;\n messageGroupId: string;\n topicId?: string;\n }>;\n /** Multi-agent room state */\n rooms?: Record<string, RoomState>;\n /** Last inbound room ID for sticky room routing across restarts */\n lastInboundRoomId?: string;\n}\n\n/** Legacy state format for backward compatibility */\nexport interface LegacyPersistedState {\n deviceId: string;\n deviceJwt: string;\n conversationId: string;\n identityKeypair: { publicKey: string; privateKey: string }; // hex\n ephemeralKeypair: { publicKey: string; privateKey: string }; // hex\n fingerprint: string;\n ratchetState: string; // serialized DoubleRatchet\n lastMessageTimestamp?: string;\n}\n\n// --- Room types (multi-agent rooms) ---\n\nexport interface RoomMemberInfo {\n deviceId: string;\n entityType: string;\n displayName: string;\n identityPublicKey?: string;\n ephemeralPublicKey?: string;\n}\n\nexport interface RoomConversationInfo {\n id: string;\n participantA: string;\n participantB: string;\n}\n\nexport interface RoomInfo {\n roomId: string;\n name: string;\n members: RoomMemberInfo[];\n conversationIds: string[];\n}\n\nexport interface RoomState {\n roomId: string;\n name: string;\n conversationIds: string[];\n members: RoomMemberInfo[];\n /** Encryption mode \u2014 null/undefined = pairwise, \"sender_key\" = O(1) Sender Key */\n encryptionMode?: \"pairwise\" | \"sender_key\";\n /** Serialized SenderKeyChain (own chain for this room) */\n ownSenderKeyChain?: string;\n /** Serialized SenderKeyState (peer chains for this room) */\n peerSenderKeyState?: string;\n /** Set of device IDs we've distributed our sender key to */\n distributedTo?: string[];\n}\n\nexport interface HeartbeatStatus {\n agent_status: string;\n current_task: string;\n}\n\nexport interface StatusAlert {\n title: string;\n message: string;\n severity: \"info\" | \"warning\" | \"error\" | \"critical\";\n detail?: string;\n detailFormat?: \"markdown\" | \"json\" | \"text\";\n category?: \"performance\" | \"security\" | \"error\" | \"info\";\n}\n\n// --- Room participant event types (team room join/leave) ---\n\nexport interface RoomParticipantEvent {\n roomId: string;\n participant: {\n deviceId: string;\n participantType: \"human\" | \"agent\";\n displayName?: string;\n };\n}\n\n// --- A2A Channel types (agent-to-agent communication) ---\n\nexport interface A2AChannel {\n channelId: string;\n initiatorHubAddress: string;\n responderHubAddress: string;\n conversationId: string | null;\n status: \"pending\" | \"approved\" | \"active\" | \"rejected\" | \"revoked\";\n createdAt: string;\n}\n\nexport interface A2AMessage {\n text: string;\n fromHubAddress: string;\n channelId: string;\n conversationId: string;\n parentSpanId?: string;\n timestamp: string;\n}\n\n// --- Unified Delivery Protocol types ---\n\n/** Explicit routing target for outbound messages. */\nexport type DeliveryTarget =\n | { kind: \"owner\" }\n | { kind: \"room\"; roomId: string }\n | { kind: \"a2a\"; hubAddress: string }\n | { kind: \"context\" }; // Resolve from _lastInboundRoomId (opt-in only)\n\n/** Structured message content for the deliver() dispatcher. */\nexport type DeliveryContent =\n | { type: \"text\"; text: string }\n | { type: \"decision_request\"; request: DecisionRequest }\n | { type: \"status_alert\"; alert: StatusAlert }\n | { type: \"action_confirmation\"; confirmation: ActionConfirmation }\n | { type: \"artifact\"; artifact: ArtifactPayload }\n | { type: \"attachment\"; text: string; filePath: string };\n\nexport interface ActionConfirmation {\n action: string;\n status: \"completed\" | \"failed\" | \"partial\";\n decisionId?: string;\n detail?: string;\n estimated_cost?: number;\n}\n\nexport interface ArtifactPayload {\n filePath: string;\n filename: string;\n mimeType: string;\n description?: string;\n}\n\nexport interface DeliveryOptions {\n conversationId?: string;\n topicId?: string;\n priority?: string;\n parentSpanId?: string;\n metadata?: Record<string, unknown>;\n}\n\nexport interface DeliveryReceipt {\n ok: boolean;\n destination: { kind: \"owner\" | \"room\" | \"a2a\"; id?: string };\n error?: string;\n queued?: boolean;\n decisionId?: string;\n timestamp: string;\n}\n\nexport interface TargetInfo {\n kind: \"owner\" | \"room\" | \"a2a\";\n id: string;\n label: string;\n available: boolean;\n}\n\n/**\n * Parse a string target into a DeliveryTarget.\n * Handles: \"owner\", \"default\", \"room:<uuid>\", \"a2a:<hubAddr>\", \"context\",\n * \"agentvault:room:<uuid>\" (channel-prefixed), \"agent:<name>\" (\u2192 a2a).\n */\nexport function parseTarget(raw: string): DeliveryTarget {\n // Strip channel prefix: \"agentvault:room:X\" \u2192 \"room:X\"\n let target = raw;\n if (target.startsWith(\"agentvault:\")) {\n target = target.slice(\"agentvault:\".length);\n }\n\n // Map \"agent:X\" \u2192 \"a2a:X\" (OpenClaw uses \"agent:\", plugin uses \"a2a:\")\n if (target.startsWith(\"agent:\")) {\n target = \"a2a:\" + target.slice(\"agent:\".length);\n }\n\n if (target === \"owner\" || target === \"default\") {\n return { kind: \"owner\" };\n }\n if (target === \"context\") {\n return { kind: \"context\" };\n }\n if (target.startsWith(\"room:\")) {\n const roomId = target.slice(\"room:\".length);\n if (!roomId) throw new Error(`Invalid room target: \"${raw}\" \u2014 missing room ID`);\n return { kind: \"room\", roomId };\n }\n if (target.startsWith(\"a2a:\")) {\n const hubAddress = target.slice(\"a2a:\".length);\n if (!hubAddress) throw new Error(`Invalid A2A target: \"${raw}\" \u2014 missing hub address`);\n return { kind: \"a2a\", hubAddress };\n }\n\n throw new Error(`Unrecognized delivery target: \"${raw}\". Use \"owner\", \"room:<id>\", \"a2a:<addr>\", or \"context\".`);\n}\n"],
5
+ "mappings": "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",
6
+ "names": ["receipt", "resolve", "onAgentEvent", "onSessionTranscriptUpdate"]
7
7
  }