feat: load channel plugins
This commit is contained in:
@@ -1,7 +1,6 @@
|
||||
import { resolveChannelDefaultAccountId } from "../channels/plugins/helpers.js";
|
||||
import { getChannelPlugin } from "../channels/plugins/index.js";
|
||||
import type { ChatChannelId } from "../channels/registry.js";
|
||||
import { normalizeChatChannelId } from "../channels/registry.js";
|
||||
import { getChannelPlugin, normalizeChannelId } from "../channels/plugins/index.js";
|
||||
import type { ChannelId } from "../channels/plugins/types.js";
|
||||
import type { ClawdbotConfig } from "../config/config.js";
|
||||
import type { AgentBinding } from "../config/types.js";
|
||||
import { DEFAULT_ACCOUNT_ID, normalizeAgentId } from "../routing/session-key.js";
|
||||
@@ -82,7 +81,7 @@ export function applyAgentBindings(
|
||||
};
|
||||
}
|
||||
|
||||
function resolveDefaultAccountId(cfg: ClawdbotConfig, provider: ChatChannelId): string {
|
||||
function resolveDefaultAccountId(cfg: ClawdbotConfig, provider: ChannelId): string {
|
||||
const plugin = getChannelPlugin(provider);
|
||||
if (!plugin) return DEFAULT_ACCOUNT_ID;
|
||||
return resolveChannelDefaultAccountId({ plugin, cfg });
|
||||
@@ -125,7 +124,7 @@ export function parseBindingSpecs(params: {
|
||||
const trimmed = raw?.trim();
|
||||
if (!trimmed) continue;
|
||||
const [channelRaw, accountRaw] = trimmed.split(":", 2);
|
||||
const channel = normalizeChatChannelId(channelRaw);
|
||||
const channel = normalizeChannelId(channelRaw);
|
||||
if (!channel) {
|
||||
errors.push(`Unknown channel "${channelRaw}".`);
|
||||
continue;
|
||||
|
||||
@@ -1,13 +1,12 @@
|
||||
import { resolveChannelDefaultAccountId } from "../channels/plugins/helpers.js";
|
||||
import { getChannelPlugin, listChannelPlugins } from "../channels/plugins/index.js";
|
||||
import type { ChatChannelId } from "../channels/registry.js";
|
||||
import { getChatChannelMeta, normalizeChatChannelId } from "../channels/registry.js";
|
||||
import { getChannelPlugin, listChannelPlugins, normalizeChannelId } from "../channels/plugins/index.js";
|
||||
import type { ChannelId } from "../channels/plugins/types.js";
|
||||
import type { ClawdbotConfig } from "../config/config.js";
|
||||
import type { AgentBinding } from "../config/types.js";
|
||||
import { DEFAULT_ACCOUNT_ID } from "../routing/session-key.js";
|
||||
|
||||
type ProviderAccountStatus = {
|
||||
provider: ChatChannelId;
|
||||
provider: ChannelId;
|
||||
accountId: string;
|
||||
name?: string;
|
||||
state: "linked" | "not linked" | "configured" | "not configured" | "enabled" | "disabled";
|
||||
@@ -15,16 +14,16 @@ type ProviderAccountStatus = {
|
||||
configured?: boolean;
|
||||
};
|
||||
|
||||
function providerAccountKey(provider: ChatChannelId, accountId?: string) {
|
||||
function providerAccountKey(provider: ChannelId, accountId?: string) {
|
||||
return `${provider}:${accountId ?? DEFAULT_ACCOUNT_ID}`;
|
||||
}
|
||||
|
||||
function formatChannelAccountLabel(params: {
|
||||
provider: ChatChannelId;
|
||||
provider: ChannelId;
|
||||
accountId: string;
|
||||
name?: string;
|
||||
}): string {
|
||||
const label = getChatChannelMeta(params.provider).label;
|
||||
const label = getChannelPlugin(params.provider)?.meta.label ?? params.provider;
|
||||
const account = params.name?.trim()
|
||||
? `${params.accountId} (${params.name.trim()})`
|
||||
: params.accountId;
|
||||
@@ -88,7 +87,7 @@ export async function buildProviderStatusIndex(
|
||||
return map;
|
||||
}
|
||||
|
||||
function resolveDefaultAccountId(cfg: ClawdbotConfig, provider: ChatChannelId): string {
|
||||
function resolveDefaultAccountId(cfg: ClawdbotConfig, provider: ChannelId): string {
|
||||
const plugin = getChannelPlugin(provider);
|
||||
if (!plugin) return DEFAULT_ACCOUNT_ID;
|
||||
return resolveChannelDefaultAccountId({ plugin, cfg });
|
||||
@@ -117,7 +116,7 @@ export function summarizeBindings(cfg: ClawdbotConfig, bindings: AgentBinding[])
|
||||
if (bindings.length === 0) return [];
|
||||
const seen = new Map<string, string>();
|
||||
for (const binding of bindings) {
|
||||
const channel = normalizeChatChannelId(binding.match.channel);
|
||||
const channel = normalizeChannelId(binding.match.channel);
|
||||
if (!channel) continue;
|
||||
const accountId = binding.match.accountId ?? resolveDefaultAccountId(cfg, channel);
|
||||
const key = providerAccountKey(channel, accountId);
|
||||
@@ -143,7 +142,7 @@ export function listProvidersForAgent(params: {
|
||||
if (params.bindings.length > 0) {
|
||||
const seen = new Set<string>();
|
||||
for (const binding of params.bindings) {
|
||||
const channel = normalizeChatChannelId(binding.match.channel);
|
||||
const channel = normalizeChannelId(binding.match.channel);
|
||||
if (!channel) continue;
|
||||
const accountId = binding.match.accountId ?? resolveDefaultAccountId(params.cfg, channel);
|
||||
const key = providerAccountKey(channel, accountId);
|
||||
|
||||
@@ -15,12 +15,14 @@ type LogLine = ReturnType<typeof parseLogLine>;
|
||||
|
||||
const DEFAULT_LIMIT = 200;
|
||||
const MAX_BYTES = 1_000_000;
|
||||
const CHANNELS = new Set<string>([...listChannelPlugins().map((plugin) => plugin.id), "all"]);
|
||||
|
||||
const getChannelSet = () =>
|
||||
new Set<string>([...listChannelPlugins().map((plugin) => plugin.id), "all"]);
|
||||
|
||||
function parseChannelFilter(raw?: string) {
|
||||
const trimmed = raw?.trim().toLowerCase();
|
||||
if (!trimmed) return "all";
|
||||
return CHANNELS.has(trimmed) ? trimmed : "all";
|
||||
return getChannelSet().has(trimmed) ? trimmed : "all";
|
||||
}
|
||||
|
||||
function matchesChannel(line: NonNullable<LogLine>, channel: string) {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { listChatChannels } from "../channels/registry.js";
|
||||
import { getChannelPlugin, listChannelPlugins } from "../channels/plugins/index.js";
|
||||
import type { ClawdbotConfig } from "../config/config.js";
|
||||
import { CONFIG_PATH_CLAWDBOT } from "../config/config.js";
|
||||
import type { RuntimeEnv } from "../runtime.js";
|
||||
@@ -13,7 +13,9 @@ export async function removeChannelConfigWizard(
|
||||
let next = { ...cfg };
|
||||
|
||||
const listConfiguredChannels = () =>
|
||||
listChatChannels().filter((meta) => next.channels?.[meta.id] !== undefined);
|
||||
listChannelPlugins()
|
||||
.map((plugin) => plugin.meta)
|
||||
.filter((meta) => next.channels?.[meta.id] !== undefined);
|
||||
|
||||
while (true) {
|
||||
const configured = listConfiguredChannels();
|
||||
@@ -45,7 +47,7 @@ export async function removeChannelConfigWizard(
|
||||
|
||||
if (channel === "done") return next;
|
||||
|
||||
const label = listChatChannels().find((meta) => meta.id === channel)?.label ?? channel;
|
||||
const label = getChannelPlugin(channel)?.meta.label ?? channel;
|
||||
const confirmed = guardCancel(
|
||||
await confirm({
|
||||
message: `Delete ${label} configuration from ${CONFIG_PATH_CLAWDBOT}?`,
|
||||
|
||||
@@ -1,9 +1,5 @@
|
||||
import {
|
||||
formatChannelPrimerLine,
|
||||
formatChannelSelectionLine,
|
||||
getChatChannelMeta,
|
||||
listChatChannels,
|
||||
} from "../channels/registry.js";
|
||||
import { listChannelPlugins, getChannelPlugin } from "../channels/plugins/index.js";
|
||||
import { formatChannelPrimerLine, formatChannelSelectionLine } from "../channels/registry.js";
|
||||
import type { ClawdbotConfig } from "../config/config.js";
|
||||
import type { DmPolicy } from "../config/types.js";
|
||||
import type { RuntimeEnv } from "../runtime.js";
|
||||
@@ -17,7 +13,7 @@ import {
|
||||
import type { ChannelOnboardingDmPolicy, SetupChannelsOptions } from "./onboarding/types.js";
|
||||
|
||||
async function noteChannelPrimer(prompter: WizardPrompter): Promise<void> {
|
||||
const channelLines = listChatChannels().map((meta) => formatChannelPrimerLine(meta));
|
||||
const channelLines = listChannelPlugins().map((plugin) => formatChannelPrimerLine(plugin.meta));
|
||||
await prompter.note(
|
||||
[
|
||||
"DM security: default is pairing; unknown DMs get a pairing code.",
|
||||
@@ -130,11 +126,12 @@ export async function setupChannels(
|
||||
|
||||
await noteChannelPrimer(prompter);
|
||||
|
||||
const selectionOptions = listChatChannels().map((meta) => {
|
||||
const selectionOptions = listChannelPlugins().map((plugin) => {
|
||||
const meta = plugin.meta;
|
||||
const status = statusByChannel.get(meta.id as ChannelChoice);
|
||||
return {
|
||||
value: meta.id,
|
||||
label: meta.selectionLabel,
|
||||
label: meta.selectionLabel ?? meta.label,
|
||||
...(status?.selectionHint ? { hint: status.selectionHint } : {}),
|
||||
};
|
||||
});
|
||||
@@ -169,7 +166,10 @@ export async function setupChannels(
|
||||
options?.onSelection?.(selection);
|
||||
|
||||
const selectionNotes = new Map(
|
||||
listChatChannels().map((meta) => [meta.id, formatChannelSelectionLine(meta, formatDocsLink)]),
|
||||
listChannelPlugins().map((plugin) => [
|
||||
plugin.id,
|
||||
formatChannelSelectionLine(plugin.meta, formatDocsLink),
|
||||
]),
|
||||
);
|
||||
const selectedLines = selection
|
||||
.map((channel) => selectionNotes.get(channel))
|
||||
@@ -214,9 +214,9 @@ export async function setupChannels(
|
||||
if (!status.configured) continue;
|
||||
const adapter = getChannelOnboardingAdapter(channelId);
|
||||
if (!adapter?.disable) continue;
|
||||
const meta = getChatChannelMeta(channelId);
|
||||
const meta = getChannelPlugin(channelId)?.meta;
|
||||
const disable = await prompter.confirm({
|
||||
message: `Disable ${meta.label} channel?`,
|
||||
message: `Disable ${meta?.label ?? channelId} channel?`,
|
||||
initialValue: false,
|
||||
});
|
||||
if (disable) {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import type { ChatChannelId } from "../channels/registry.js";
|
||||
import type { ChannelId } from "../channels/plugins/types.js";
|
||||
import type { GatewayDaemonRuntime } from "./daemon-runtime.js";
|
||||
|
||||
export type OnboardMode = "local" | "remote";
|
||||
@@ -31,7 +31,7 @@ export type ResetScope = "config" | "config+creds+sessions" | "full";
|
||||
export type GatewayBind = "loopback" | "lan" | "auto" | "custom";
|
||||
export type TailscaleMode = "off" | "serve" | "funnel";
|
||||
export type NodeManagerChoice = "npm" | "pnpm" | "bun";
|
||||
export type ChannelChoice = ChatChannelId;
|
||||
export type ChannelChoice = ChannelId;
|
||||
// Legacy alias (pre-rename).
|
||||
export type ProviderChoice = ChannelChoice;
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ import {
|
||||
resolveSandboxConfigForAgent,
|
||||
resolveSandboxToolPolicyForAgent,
|
||||
} from "../agents/sandbox.js";
|
||||
import { normalizeChannelId } from "../channels/registry.js";
|
||||
import { normalizeChannelId } from "../channels/plugins/index.js";
|
||||
import type { ClawdbotConfig } from "../config/config.js";
|
||||
import { loadConfig } from "../config/config.js";
|
||||
import {
|
||||
|
||||
Reference in New Issue
Block a user