"use strict";Object.defineProperty(exports, "__esModule", { value: true });exports.adpOpenclawPlugin = void 0; var _pluginSdk = require("openclaw/plugin-sdk"); var _onboarding = require("./onboarding.js"); var _runtime = require("./runtime.js");function _interopRequireWildcard(e, t) {if ("function" == typeof WeakMap) var r = new WeakMap(),n = new WeakMap();return (_interopRequireWildcard = function (e, t) {if (!t && e && e.__esModule) return e;var o,i,f = { __proto__: null, default: e };if (null === e || "object" != typeof e && "function" != typeof e) return f;if (o = t ? n : r) {if (o.has(e)) return o.get(e);o.set(e, f);}for (const t in e) "default" !== t && {}.hasOwnProperty.call(e, t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, t)) && (i.get || i.set) ? o(f, t, i) : f[t] = e[t]);return f;})(e, t);} // ADP OpenClaw channel plugin for OpenClaw // Supports: API Token auth, multiple clients, multi-turn conversations // Default WebSocket URL for ADP OpenClaw const DEFAULT_WS_URL = "wss://wss.lke.cloud.tencent.com/bot/gateway/conn"; // Channel-level config type (from channels["adp-openclaw"]) function resolveAdpOpenclawCredentials(channelCfg) { // Get wsUrl from config or env (has default value) let wsUrl = channelCfg?.wsUrl?.trim(); if (!wsUrl) { wsUrl = process.env.ADP_OPENCLAW_WS_URL || DEFAULT_WS_URL; } // Get clientToken from config or env let clientToken = channelCfg?.clientToken?.trim(); if (!clientToken) { clientToken = process.env.ADP_OPENCLAW_CLIENT_TOKEN || ""; } // Get signKey from config or env (default: ADPOpenClaw) let signKey = channelCfg?.signKey?.trim(); if (!signKey) { signKey = process.env.ADP_OPENCLAW_SIGN_KEY || "ADPOpenClaw"; } // clientToken is required for configured status (wsUrl has default) if (!clientToken) { return null; } return { wsUrl, clientToken, signKey }; } function resolveAccount(cfg, accountId) { const channelCfg = cfg.channels?.["adp-openclaw"]; const enabled = channelCfg?.enabled !== false; const creds = resolveAdpOpenclawCredentials(channelCfg); return { accountId: accountId?.trim() || _pluginSdk.DEFAULT_ACCOUNT_ID, name: "ADP OpenClaw", enabled, configured: Boolean(creds), wsUrl: creds?.wsUrl || DEFAULT_WS_URL, clientToken: creds?.clientToken || "", signKey: creds?.signKey || "ADPOpenClaw" }; } const adpOpenclawPlugin = exports.adpOpenclawPlugin = { id: "adp-openclaw", meta: { id: "adp-openclaw", label: "ADP OpenClaw", selectionLabel: "ADP OpenClaw", docsPath: "/channels/adp-openclaw", blurb: "ADP channel backed by a Go WebSocket server.", order: 999 }, onboarding: _onboarding.adpOpenclawOnboardingAdapter, capabilities: { chatTypes: ["direct"], polls: false, reactions: false, threads: false, media: true, // 启用文件/媒体支持 /** * blockStreaming: true 启用 SDK 的块流式功能 * SDK 会通过 deliver 回调的 info.kind="block" 传递流式块 */ blockStreaming: true }, reload: { configPrefixes: ["channels.adp-openclaw"] }, configSchema: { schema: { type: "object", additionalProperties: false, properties: { enabled: { type: "boolean" }, wsUrl: { type: "string" }, // WebSocket URL (optional, default: wss://wss.lke.cloud.tencent.com/bot/gateway/conn) clientToken: { type: "string" }, signKey: { type: "string" } } } }, config: { listAccountIds: () => [_pluginSdk.DEFAULT_ACCOUNT_ID], resolveAccount: (cfg) => resolveAccount(cfg), defaultAccountId: () => _pluginSdk.DEFAULT_ACCOUNT_ID, setAccountEnabled: ({ cfg, enabled }) => ({ ...cfg, channels: { ...cfg.channels, "adp-openclaw": { ...cfg.channels?.["adp-openclaw"], enabled } } }), deleteAccount: ({ cfg }) => { const next = { ...cfg }; const nextChannels = { ...cfg.channels }; delete nextChannels["adp-openclaw"]; if (Object.keys(nextChannels).length > 0) { next.channels = nextChannels; } else { delete next.channels; } return next; }, isConfigured: (_account, cfg) => Boolean(resolveAdpOpenclawCredentials(cfg.channels?.["adp-openclaw"])), describeAccount: (account) => ({ accountId: account.accountId, name: account.name, enabled: account.enabled, configured: account.configured, wsUrl: account.wsUrl }), resolveAllowFrom: () => [], formatAllowFrom: ({ allowFrom }) => allowFrom }, setup: { resolveAccountId: () => _pluginSdk.DEFAULT_ACCOUNT_ID, applyAccountConfig: ({ cfg }) => ({ ...cfg, channels: { ...cfg.channels, "adp-openclaw": { ...cfg.channels?.["adp-openclaw"], enabled: true } } }) }, status: { defaultRuntime: { accountId: _pluginSdk.DEFAULT_ACCOUNT_ID, running: false, lastStartAt: null, lastStopAt: null, lastError: null }, collectStatusIssues: () => [], buildChannelSummary: ({ snapshot }) => ({ configured: snapshot.configured ?? false, wsUrl: snapshot.wsUrl ?? null, running: snapshot.running ?? false, lastStartAt: snapshot.lastStartAt ?? null, lastStopAt: snapshot.lastStopAt ?? null, lastError: snapshot.lastError ?? null }), probeAccount: async ({ cfg }) => { // For WebSocket-only architecture, we just check if config is valid const account = resolveAccount(cfg); const start = Date.now(); return { ok: account.configured && Boolean(account.clientToken), elapsedMs: Date.now() - start }; }, buildAccountSnapshot: ({ account, runtime, probe }) => ({ accountId: account.accountId, name: account.name, enabled: account.enabled, configured: account.configured, wsUrl: account.wsUrl, running: runtime?.running ?? false, lastStartAt: runtime?.lastStartAt ?? null, lastStopAt: runtime?.lastStopAt ?? null, lastError: runtime?.lastError ?? null, probe }) }, gateway: { startAccount: async (ctx) => { const account = ctx.account; ctx.setStatus({ accountId: account.accountId, wsUrl: account.wsUrl }); ctx.log?.info(`[adp-openclaw] starting WebSocket connection → ${account.wsUrl}`); const { monitorAdpOpenclaw } = await Promise.resolve().then(() => jitiImport("./monitor.js").then((m) => _interopRequireWildcard(m))); return monitorAdpOpenclaw({ wsUrl: account.wsUrl, clientToken: account.clientToken, signKey: account.signKey, abortSignal: ctx.abortSignal, log: ctx.log, cfg: ctx.cfg, setStatus: ctx.setStatus }); } }, // Outbound message support for the "message" tool and cron tasks outbound: { deliveryMode: "direct", // Send text message sendText: async (ctx) => { const { to, text } = ctx; const ws = (0, _runtime.getActiveWebSocket)(); if (!ws) { console.error("[adp-openclaw] No active WebSocket connection for outbound message"); throw new Error("No active WebSocket connection"); } // Parse target: expected format is "adp-openclaw:{userId}" or just "{userId}" const targetParts = to.split(":"); const targetUserId = targetParts.length > 1 ? targetParts.slice(1).join(":") : to; console.log(`[adp-openclaw] Sending outbound text to ${targetUserId}: ${text.slice(0, 50)}...`); // Generate unique request ID const requestId = `outbound-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`; const outMsg = { type: "outbound", requestId, payload: { to: targetUserId, text: text }, timestamp: Date.now() }; ws.send(JSON.stringify(outMsg)); return { channel: "adp-openclaw", messageId: requestId }; }, // Send media message (text with optional media URL) sendMedia: async (ctx) => { const { to, text, mediaUrl } = ctx; const ws = (0, _runtime.getActiveWebSocket)(); if (!ws) { console.error("[adp-openclaw] No active WebSocket connection for outbound media"); throw new Error("No active WebSocket connection"); } // Parse target const targetParts = to.split(":"); const targetUserId = targetParts.length > 1 ? targetParts.slice(1).join(":") : to; console.log(`[adp-openclaw] Sending outbound media to ${targetUserId}: ${text.slice(0, 50)}... (media: ${mediaUrl || "none"})`); // Generate unique request ID const requestId = `outbound-media-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`; // Combine text and media URL if present const finalText = mediaUrl ? `${text}\n\n📎 ${mediaUrl}` : text; const outMsg = { type: "outbound", requestId, payload: { to: targetUserId, text: finalText, mediaUrl: mediaUrl }, timestamp: Date.now() }; ws.send(JSON.stringify(outMsg)); return { channel: "adp-openclaw", messageId: requestId }; } } }; /* v9-e16571f2c5c0712d */