mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-08 13:01:25 +00:00
refactor!: rename chat providers to channels
This commit is contained in:
@@ -7,6 +7,16 @@ import {
|
||||
} from "../agents/agent-scope.js";
|
||||
import { ensureAuthProfileStore } from "../agents/auth-profiles.js";
|
||||
import { DEFAULT_IDENTITY_FILENAME } from "../agents/workspace.js";
|
||||
import { resolveChannelDefaultAccountId } from "../channels/plugins/helpers.js";
|
||||
import {
|
||||
getChannelPlugin,
|
||||
listChannelPlugins,
|
||||
} from "../channels/plugins/index.js";
|
||||
import {
|
||||
type ChatChannelId,
|
||||
getChatChannelMeta,
|
||||
normalizeChatChannelId,
|
||||
} from "../channels/registry.js";
|
||||
import type { ClawdbotConfig } from "../config/config.js";
|
||||
import {
|
||||
CONFIG_PATH_CLAWDBOT,
|
||||
@@ -14,16 +24,7 @@ import {
|
||||
writeConfigFile,
|
||||
} from "../config/config.js";
|
||||
import { resolveSessionTranscriptsDirForAgent } from "../config/sessions.js";
|
||||
import { resolveProviderDefaultAccountId } from "../providers/plugins/helpers.js";
|
||||
import {
|
||||
getProviderPlugin,
|
||||
listProviderPlugins,
|
||||
} from "../providers/plugins/index.js";
|
||||
import {
|
||||
type ChatProviderId,
|
||||
getChatProviderMeta,
|
||||
normalizeChatProviderId,
|
||||
} from "../providers/registry.js";
|
||||
import type { AgentBinding } from "../config/types.js";
|
||||
import {
|
||||
DEFAULT_ACCOUNT_ID,
|
||||
DEFAULT_AGENT_ID,
|
||||
@@ -36,9 +37,9 @@ import { createClackPrompter } from "../wizard/clack-prompter.js";
|
||||
import { WizardCancelledError } from "../wizard/prompts.js";
|
||||
import { applyAuthChoice, warnIfModelConfigLooksOff } from "./auth-choice.js";
|
||||
import { promptAuthChoiceGrouped } from "./auth-choice-prompt.js";
|
||||
import { setupChannels } from "./onboard-channels.js";
|
||||
import { ensureWorkspaceAndSessions, moveToTrash } from "./onboard-helpers.js";
|
||||
import { setupProviders } from "./onboard-providers.js";
|
||||
import type { ProviderChoice } from "./onboard-types.js";
|
||||
import type { ChannelChoice } from "./onboard-types.js";
|
||||
|
||||
type AgentsListOptions = {
|
||||
json?: boolean;
|
||||
@@ -77,17 +78,6 @@ export type AgentSummary = {
|
||||
isDefault: boolean;
|
||||
};
|
||||
|
||||
type AgentBinding = {
|
||||
agentId: string;
|
||||
match: {
|
||||
provider: string;
|
||||
accountId?: string;
|
||||
peer?: { kind: "dm" | "group" | "channel"; id: string };
|
||||
guildId?: string;
|
||||
teamId?: string;
|
||||
};
|
||||
};
|
||||
|
||||
type AgentEntry = NonNullable<
|
||||
NonNullable<ClawdbotConfig["agents"]>["list"]
|
||||
>[number];
|
||||
@@ -100,7 +90,7 @@ type AgentIdentity = {
|
||||
};
|
||||
|
||||
type ProviderAccountStatus = {
|
||||
provider: ChatProviderId;
|
||||
provider: ChatChannelId;
|
||||
accountId: string;
|
||||
name?: string;
|
||||
state:
|
||||
@@ -276,7 +266,7 @@ export function applyAgentConfig(
|
||||
function bindingMatchKey(match: AgentBinding["match"]) {
|
||||
const accountId = match.accountId?.trim() || DEFAULT_ACCOUNT_ID;
|
||||
return [
|
||||
match.provider,
|
||||
match.channel,
|
||||
accountId,
|
||||
match.peer?.kind ?? "",
|
||||
match.peer?.id ?? "",
|
||||
@@ -438,16 +428,16 @@ function formatSummary(summary: AgentSummary) {
|
||||
return lines.join("\n");
|
||||
}
|
||||
|
||||
function providerAccountKey(provider: ChatProviderId, accountId?: string) {
|
||||
function providerAccountKey(provider: ChatChannelId, accountId?: string) {
|
||||
return `${provider}:${accountId ?? DEFAULT_ACCOUNT_ID}`;
|
||||
}
|
||||
|
||||
function formatProviderAccountLabel(params: {
|
||||
provider: ChatProviderId;
|
||||
function formatChannelAccountLabel(params: {
|
||||
provider: ChatChannelId;
|
||||
accountId: string;
|
||||
name?: string;
|
||||
}): string {
|
||||
const label = getChatProviderMeta(params.provider).label;
|
||||
const label = getChatChannelMeta(params.provider).label;
|
||||
const account = params.name?.trim()
|
||||
? `${params.accountId} (${params.name.trim()})`
|
||||
: params.accountId;
|
||||
@@ -467,7 +457,7 @@ async function buildProviderStatusIndex(
|
||||
): Promise<Map<string, ProviderAccountStatus>> {
|
||||
const map = new Map<string, ProviderAccountStatus>();
|
||||
|
||||
for (const plugin of listProviderPlugins()) {
|
||||
for (const plugin of listChannelPlugins()) {
|
||||
const accountIds = plugin.config.listAccountIds(cfg);
|
||||
for (const accountId of accountIds) {
|
||||
const account = plugin.config.resolveAccount(cfg, accountId);
|
||||
@@ -514,18 +504,18 @@ async function buildProviderStatusIndex(
|
||||
|
||||
function resolveDefaultAccountId(
|
||||
cfg: ClawdbotConfig,
|
||||
provider: ChatProviderId,
|
||||
provider: ChatChannelId,
|
||||
): string {
|
||||
const plugin = getProviderPlugin(provider);
|
||||
const plugin = getChannelPlugin(provider);
|
||||
if (!plugin) return DEFAULT_ACCOUNT_ID;
|
||||
return resolveProviderDefaultAccountId({ plugin, cfg });
|
||||
return resolveChannelDefaultAccountId({ plugin, cfg });
|
||||
}
|
||||
|
||||
function shouldShowProviderEntry(
|
||||
entry: ProviderAccountStatus,
|
||||
cfg: ClawdbotConfig,
|
||||
): boolean {
|
||||
const plugin = getProviderPlugin(entry.provider);
|
||||
const plugin = getChannelPlugin(entry.provider);
|
||||
if (!plugin) return Boolean(entry.configured);
|
||||
if (plugin.meta.showConfigured === false) {
|
||||
const providerConfig = (cfg as Record<string, unknown>)[plugin.id];
|
||||
@@ -535,7 +525,7 @@ function shouldShowProviderEntry(
|
||||
}
|
||||
|
||||
function formatProviderEntry(entry: ProviderAccountStatus): string {
|
||||
const label = formatProviderAccountLabel({
|
||||
const label = formatChannelAccountLabel({
|
||||
provider: entry.provider,
|
||||
accountId: entry.accountId,
|
||||
name: entry.name,
|
||||
@@ -550,14 +540,14 @@ function summarizeBindings(
|
||||
if (bindings.length === 0) return [];
|
||||
const seen = new Map<string, string>();
|
||||
for (const binding of bindings) {
|
||||
const provider = normalizeChatProviderId(binding.match.provider);
|
||||
if (!provider) continue;
|
||||
const channel = normalizeChatChannelId(binding.match.channel);
|
||||
if (!channel) continue;
|
||||
const accountId =
|
||||
binding.match.accountId ?? resolveDefaultAccountId(cfg, provider);
|
||||
const key = providerAccountKey(provider, accountId);
|
||||
binding.match.accountId ?? resolveDefaultAccountId(cfg, channel);
|
||||
const key = providerAccountKey(channel, accountId);
|
||||
if (!seen.has(key)) {
|
||||
const label = formatProviderAccountLabel({
|
||||
provider,
|
||||
const label = formatChannelAccountLabel({
|
||||
provider: channel,
|
||||
accountId,
|
||||
});
|
||||
seen.set(key, label);
|
||||
@@ -628,11 +618,11 @@ export async function agentsListCommand(
|
||||
if (bindings.length > 0) {
|
||||
const seen = new Set<string>();
|
||||
for (const binding of bindings) {
|
||||
const provider = normalizeChatProviderId(binding.match.provider);
|
||||
if (!provider) continue;
|
||||
const channel = normalizeChatChannelId(binding.match.channel);
|
||||
if (!channel) continue;
|
||||
const accountId =
|
||||
binding.match.accountId ?? resolveDefaultAccountId(cfg, provider);
|
||||
const key = providerAccountKey(provider, accountId);
|
||||
binding.match.accountId ?? resolveDefaultAccountId(cfg, channel);
|
||||
const key = providerAccountKey(channel, accountId);
|
||||
if (seen.has(key)) continue;
|
||||
seen.add(key);
|
||||
const status = providerStatus.get(key);
|
||||
@@ -640,7 +630,7 @@ export async function agentsListCommand(
|
||||
providerLines.push(formatProviderEntry(status));
|
||||
} else {
|
||||
providerLines.push(
|
||||
`${formatProviderAccountLabel({ provider, accountId })}: unknown`,
|
||||
`${formatChannelAccountLabel({ provider: channel, accountId })}: unknown`,
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -663,17 +653,17 @@ export async function agentsListCommand(
|
||||
|
||||
const lines = ["Agents:", ...summaries.map(formatSummary)];
|
||||
lines.push(
|
||||
"Routing rules map provider/account/peer to an agent. Use --bindings for full rules.",
|
||||
"Routing rules map channel/account/peer to an agent. Use --bindings for full rules.",
|
||||
);
|
||||
lines.push(
|
||||
"Provider status reflects local config/creds. For live health: clawdbot providers status --probe.",
|
||||
"Channel status reflects local config/creds. For live health: clawdbot channels status --probe.",
|
||||
);
|
||||
runtime.log(lines.join("\n"));
|
||||
}
|
||||
|
||||
function describeBinding(binding: AgentBinding) {
|
||||
const match = binding.match;
|
||||
const parts = [match.provider];
|
||||
const parts = [match.channel];
|
||||
if (match.accountId) parts.push(`accountId=${match.accountId}`);
|
||||
if (match.peer) parts.push(`peer=${match.peer.kind}:${match.peer.id}`);
|
||||
if (match.guildId) parts.push(`guild=${match.guildId}`);
|
||||
@@ -681,23 +671,23 @@ function describeBinding(binding: AgentBinding) {
|
||||
return parts.join(" ");
|
||||
}
|
||||
|
||||
function buildProviderBindings(params: {
|
||||
function buildChannelBindings(params: {
|
||||
agentId: string;
|
||||
selection: ProviderChoice[];
|
||||
selection: ChannelChoice[];
|
||||
config: ClawdbotConfig;
|
||||
accountIds?: Partial<Record<ProviderChoice, string>>;
|
||||
accountIds?: Partial<Record<ChannelChoice, string>>;
|
||||
}): AgentBinding[] {
|
||||
const bindings: AgentBinding[] = [];
|
||||
const agentId = normalizeAgentId(params.agentId);
|
||||
for (const provider of params.selection) {
|
||||
const match: AgentBinding["match"] = { provider };
|
||||
const accountId = params.accountIds?.[provider]?.trim();
|
||||
for (const channel of params.selection) {
|
||||
const match: AgentBinding["match"] = { channel };
|
||||
const accountId = params.accountIds?.[channel]?.trim();
|
||||
if (accountId) {
|
||||
match.accountId = accountId;
|
||||
} else {
|
||||
const plugin = getProviderPlugin(provider);
|
||||
const plugin = getChannelPlugin(channel);
|
||||
if (plugin?.meta.forceAccountBinding) {
|
||||
match.accountId = resolveDefaultAccountId(params.config, provider);
|
||||
match.accountId = resolveDefaultAccountId(params.config, channel);
|
||||
}
|
||||
}
|
||||
bindings.push({ agentId, match });
|
||||
@@ -717,10 +707,10 @@ function parseBindingSpecs(params: {
|
||||
for (const raw of specs) {
|
||||
const trimmed = raw?.trim();
|
||||
if (!trimmed) continue;
|
||||
const [providerRaw, accountRaw] = trimmed.split(":", 2);
|
||||
const provider = normalizeChatProviderId(providerRaw);
|
||||
if (!provider) {
|
||||
errors.push(`Unknown provider "${providerRaw}".`);
|
||||
const [channelRaw, accountRaw] = trimmed.split(":", 2);
|
||||
const channel = normalizeChatChannelId(channelRaw);
|
||||
if (!channel) {
|
||||
errors.push(`Unknown channel "${channelRaw}".`);
|
||||
continue;
|
||||
}
|
||||
let accountId = accountRaw?.trim();
|
||||
@@ -729,12 +719,12 @@ function parseBindingSpecs(params: {
|
||||
continue;
|
||||
}
|
||||
if (!accountId) {
|
||||
const plugin = getProviderPlugin(provider);
|
||||
const plugin = getChannelPlugin(channel);
|
||||
if (plugin?.meta.forceAccountBinding) {
|
||||
accountId = resolveDefaultAccountId(params.config, provider);
|
||||
accountId = resolveDefaultAccountId(params.config, channel);
|
||||
}
|
||||
}
|
||||
const match: AgentBinding["match"] = { provider };
|
||||
const match: AgentBinding["match"] = { channel };
|
||||
if (accountId) match.accountId = accountId;
|
||||
bindings.push({ agentId, match });
|
||||
}
|
||||
@@ -958,30 +948,30 @@ export async function agentsAddCommand(
|
||||
agentDir,
|
||||
});
|
||||
|
||||
let selection: ProviderChoice[] = [];
|
||||
const providerAccountIds: Partial<Record<ProviderChoice, string>> = {};
|
||||
nextConfig = await setupProviders(nextConfig, runtime, prompter, {
|
||||
let selection: ChannelChoice[] = [];
|
||||
const channelAccountIds: Partial<Record<ChannelChoice, string>> = {};
|
||||
nextConfig = await setupChannels(nextConfig, runtime, prompter, {
|
||||
allowSignalInstall: true,
|
||||
onSelection: (value) => {
|
||||
selection = value;
|
||||
},
|
||||
promptAccountIds: true,
|
||||
onAccountId: (provider, accountId) => {
|
||||
providerAccountIds[provider] = accountId;
|
||||
onAccountId: (channel, accountId) => {
|
||||
channelAccountIds[channel] = accountId;
|
||||
},
|
||||
});
|
||||
|
||||
if (selection.length > 0) {
|
||||
const wantsBindings = await prompter.confirm({
|
||||
message: "Route selected providers to this agent now? (bindings)",
|
||||
message: "Route selected channels to this agent now? (bindings)",
|
||||
initialValue: false,
|
||||
});
|
||||
if (wantsBindings) {
|
||||
const desiredBindings = buildProviderBindings({
|
||||
const desiredBindings = buildChannelBindings({
|
||||
agentId,
|
||||
selection,
|
||||
config: nextConfig,
|
||||
accountIds: providerAccountIds,
|
||||
accountIds: channelAccountIds,
|
||||
});
|
||||
const result = applyAgentBindings(nextConfig, desiredBindings);
|
||||
nextConfig = result.config;
|
||||
|
||||
Reference in New Issue
Block a user