UNPKG

openclaw

Version:

Multi-channel AI gateway with extensible messaging integrations

209 lines (208 loc) 8.41 kB
import { t as formatDocsLink } from "./links-CsLBrRff.js"; import { r as theme } from "./theme-vjDs9tao.js"; import { n as defaultRuntime, r as writeRuntimeJson } from "./runtime-B4lgFmsS.js"; import "./agent-scope-MrLta7Pq.js"; import { c as resolveDefaultAgentId, o as resolveAgentWorkspaceDir } from "./agent-scope-config-CgCYpZfK.js"; import { o as callGateway } from "./call-B5-GYOlf.js"; import { n as isChannelVisibleInConfiguredLists } from "./channel-meta-Dop_ckTT.js"; import { t as resolveMissingOfficialExternalChannelPluginRepairHint } from "./official-external-plugin-repair-hints-C_AGrH5r.js"; import { n as listReadOnlyChannelPluginsForConfig } from "./read-only-7UA2_pQ4.js"; import { r as listTrustedChannelPluginCatalogEntries } from "./trusted-catalog-LdIzL72U.js"; import { t as isCatalogChannelInstalled } from "./discovery-BFtmInPU.js"; import { o as formatChannelAccountLabel, s as requireValidConfig } from "./shared-vtv0TMAo.js"; import { t as buildChannelAccountSnapshot } from "./status-W16cTRep.js"; import { a as resolveChannelAccountStatusRows, i as normalizeRuntimeChannelAccountSnapshots } from "./read-model-BmEjOuR_.js"; //#region src/commands/channels/list.ts async function readGatewayChannelStatus() { try { return await callGateway({ method: "channels.status", params: { probe: false, timeoutMs: 5e3 }, timeoutMs: 5e3 }); } catch { return null; } } const colorValue = (value) => { if (value === "none") return theme.error(value); if (value === "env") return theme.accent(value); return theme.success(value); }; function formatEnabled(value) { return value === false ? theme.error("disabled") : theme.success("enabled"); } function formatConfigured(value) { return value ? theme.success("configured") : theme.warn("not configured"); } function formatInstalled(value) { return value ? theme.success("installed") : theme.warn("not installed"); } function formatCredentialSource(source, status) { const value = source || "none"; if (status === "configured_unavailable" && value !== "none") return theme.warn(`${value}-unavailable`); return colorValue(value); } function formatTokenSource(source, status) { return `token=${formatCredentialSource(source, status)}`; } function formatSource(label, source, status) { return `${label}=${formatCredentialSource(source, status)}`; } function formatLinked(value) { return value ? theme.success("linked") : theme.warn("not linked"); } function shouldShowConfigured(channel) { return isChannelVisibleInConfiguredLists(channel.meta); } function formatAccountLine(params) { const { channel, snapshot, installed } = params; const label = formatChannelAccountLabel({ channel: channel.id, accountId: snapshot.accountId, name: snapshot.name, channelLabel: channel.meta.label ?? channel.id, channelStyle: theme.accent, accountStyle: theme.heading }); const bits = []; bits.push(formatInstalled(installed)); if (shouldShowConfigured(channel) && typeof snapshot.configured === "boolean") bits.push(formatConfigured(snapshot.configured)); if (typeof snapshot.enabled === "boolean") bits.push(formatEnabled(snapshot.enabled)); if (snapshot.linked !== void 0) bits.push(formatLinked(snapshot.linked)); if (snapshot.tokenSource) bits.push(formatTokenSource(snapshot.tokenSource, snapshot.tokenStatus)); if (snapshot.botTokenSource) bits.push(formatSource("bot", snapshot.botTokenSource, snapshot.botTokenStatus)); if (snapshot.appTokenSource) bits.push(formatSource("app", snapshot.appTokenSource, snapshot.appTokenStatus)); if (snapshot.baseUrl) bits.push(`base=${theme.muted(snapshot.baseUrl)}`); return `- ${label}: ${bits.join(", ")}`; } function formatCatalogOnlyLine(params) { const { entry, installed, configured, repairHint } = params; const channelText = theme.accent(entry.meta.label ?? entry.id); const bits = [ formatInstalled(installed), formatConfigured(configured), formatEnabled(false) ]; if (repairHint) bits.push(repairHint); return `- ${channelText}: ${bits.join(", ")}`; } /** Print or serialize configured, available, and installable chat channel accounts. */ async function channelsListCommand(opts, runtime = defaultRuntime) { const cfg = await requireValidConfig(runtime); if (!cfg) return; const showAll = opts.all === true; const plugins = listReadOnlyChannelPluginsForConfig(cfg, { includeSetupFallbackPlugins: true }); const workspaceDir = resolveAgentWorkspaceDir(cfg, resolveDefaultAgentId(cfg)); const catalogEntries = listTrustedChannelPluginCatalogEntries({ cfg, ...workspaceDir ? { workspaceDir } : {} }); const runtimeAccountsByChannel = opts.json === true ? /* @__PURE__ */ new Map() : normalizeRuntimeChannelAccountSnapshots(await readGatewayChannelStatus()); const installedByChannelId = /* @__PURE__ */ new Map(); for (const entry of catalogEntries) installedByChannelId.set(entry.id, isCatalogChannelInstalled({ cfg, entry, ...workspaceDir ? { workspaceDir } : {} })); const isInstalled = (channelId) => installedByChannelId.get(channelId) ?? true; const accountLines = []; const renderedChannelIds = /* @__PURE__ */ new Set(); for (const plugin of plugins) { const accountIds = plugin.config.listAccountIds(cfg); if (accountIds && accountIds.length > 0) { renderedChannelIds.add(plugin.id); const rows = await resolveChannelAccountStatusRows({ localAccountIds: accountIds, runtimeAccounts: runtimeAccountsByChannel.get(plugin.id) ?? [], resolveLocalSnapshot: (accountId) => buildChannelAccountSnapshot({ plugin, cfg, accountId }) }); for (const row of rows) accountLines.push({ plugin, snapshot: row.snapshot, installed: isInstalled(plugin.id) }); continue; } if (!showAll) continue; if (!shouldShowConfigured(plugin)) continue; const snapshot = await buildChannelAccountSnapshot({ plugin, cfg, accountId: "default" }); const runtimeSnapshot = runtimeAccountsByChannel.get(plugin.id)?.find((account) => account.accountId === "default"); renderedChannelIds.add(plugin.id); accountLines.push({ plugin, snapshot: runtimeSnapshot ?? snapshot, installed: isInstalled(plugin.id) }); } const catalogOnlyLines = catalogEntries.filter((entry) => !renderedChannelIds.has(entry.id)).map((entry) => { const hint = resolveMissingOfficialExternalChannelPluginRepairHint({ config: cfg, channelId: entry.id, ...workspaceDir ? { workspaceDir } : {} }); return { entry, installed: isInstalled(entry.id), configured: Boolean(hint), repairHint: hint ? `run ${hint.installCommand} or ${hint.doctorFixCommand}` : void 0 }; }).filter((line) => showAll || line.configured); if (opts.json) { const chat = {}; for (const plugin of plugins) { const accountIds = plugin.config.listAccountIds(cfg); const installed = isInstalled(plugin.id); if (accountIds && accountIds.length > 0) chat[plugin.id] = { accounts: accountIds, installed, origin: "configured" }; else if (showAll && shouldShowConfigured(plugin)) chat[plugin.id] = { accounts: [], installed, origin: "available" }; } for (const line of catalogOnlyLines) chat[line.entry.id] = { accounts: [], installed: line.installed, origin: line.configured ? "configured" : line.installed ? "available" : "installable" }; writeRuntimeJson(runtime, { chat }); return; } const lines = []; lines.push(theme.heading("Chat channels:")); if (accountLines.length === 0 && catalogOnlyLines.length === 0) lines.push(theme.muted(showAll ? "- no chat channels found" : "- no configured chat channels (run `openclaw channels list --all` to see installable channels)")); else { for (const line of accountLines) lines.push(formatAccountLine({ channel: line.plugin, snapshot: line.snapshot, installed: line.installed })); for (const line of catalogOnlyLines) lines.push(formatCatalogOnlyLine({ entry: line.entry, installed: line.installed, configured: line.configured, ...line.repairHint ? { repairHint: line.repairHint } : {} })); } runtime.log(lines.join("\n")); runtime.log(""); runtime.log(theme.muted("Model provider usage moved out of `channels list` — see `openclaw status` or `openclaw models list`.")); runtime.log(`Docs: ${formatDocsLink("/gateway/configuration", "gateway/configuration")}`); } //#endregion export { channelsListCommand as t };