Spaces:
Running
Running
| import type { ChannelId } from "../channels/plugins/types.js"; | |
| import type { OpenClawConfig } from "../config/config.js"; | |
| import type { AgentBinding } from "../config/types.js"; | |
| import { resolveChannelDefaultAccountId } from "../channels/plugins/helpers.js"; | |
| import { | |
| getChannelPlugin, | |
| listChannelPlugins, | |
| normalizeChannelId, | |
| } from "../channels/plugins/index.js"; | |
| import { DEFAULT_ACCOUNT_ID } from "../routing/session-key.js"; | |
| type ProviderAccountStatus = { | |
| provider: ChannelId; | |
| accountId: string; | |
| name?: string; | |
| state: "linked" | "not linked" | "configured" | "not configured" | "enabled" | "disabled"; | |
| enabled?: boolean; | |
| configured?: boolean; | |
| }; | |
| function providerAccountKey(provider: ChannelId, accountId?: string) { | |
| return `${provider}:${accountId ?? DEFAULT_ACCOUNT_ID}`; | |
| } | |
| function formatChannelAccountLabel(params: { | |
| provider: ChannelId; | |
| accountId: string; | |
| name?: string; | |
| }): string { | |
| const label = getChannelPlugin(params.provider)?.meta.label ?? params.provider; | |
| const account = params.name?.trim() | |
| ? `${params.accountId} (${params.name.trim()})` | |
| : params.accountId; | |
| return `${label} ${account}`; | |
| } | |
| function formatProviderState(entry: ProviderAccountStatus): string { | |
| const parts = [entry.state]; | |
| if (entry.enabled === false && entry.state !== "disabled") { | |
| parts.push("disabled"); | |
| } | |
| return parts.join(", "); | |
| } | |
| export async function buildProviderStatusIndex( | |
| cfg: OpenClawConfig, | |
| ): Promise<Map<string, ProviderAccountStatus>> { | |
| const map = new Map<string, ProviderAccountStatus>(); | |
| for (const plugin of listChannelPlugins()) { | |
| const accountIds = plugin.config.listAccountIds(cfg); | |
| for (const accountId of accountIds) { | |
| const account = plugin.config.resolveAccount(cfg, accountId); | |
| const snapshot = plugin.config.describeAccount?.(account, cfg); | |
| const enabled = plugin.config.isEnabled | |
| ? plugin.config.isEnabled(account, cfg) | |
| : typeof snapshot?.enabled === "boolean" | |
| ? snapshot.enabled | |
| : (account as { enabled?: boolean }).enabled; | |
| const configured = plugin.config.isConfigured | |
| ? await plugin.config.isConfigured(account, cfg) | |
| : snapshot?.configured; | |
| const resolvedEnabled = typeof enabled === "boolean" ? enabled : true; | |
| const resolvedConfigured = typeof configured === "boolean" ? configured : true; | |
| const state = | |
| plugin.status?.resolveAccountState?.({ | |
| account, | |
| cfg, | |
| configured: resolvedConfigured, | |
| enabled: resolvedEnabled, | |
| }) ?? | |
| (typeof snapshot?.linked === "boolean" | |
| ? snapshot.linked | |
| ? "linked" | |
| : "not linked" | |
| : resolvedConfigured | |
| ? "configured" | |
| : "not configured"); | |
| const name = snapshot?.name ?? (account as { name?: string }).name; | |
| map.set(providerAccountKey(plugin.id, accountId), { | |
| provider: plugin.id, | |
| accountId, | |
| name, | |
| state, | |
| enabled, | |
| configured, | |
| }); | |
| } | |
| } | |
| return map; | |
| } | |
| function resolveDefaultAccountId(cfg: OpenClawConfig, provider: ChannelId): string { | |
| const plugin = getChannelPlugin(provider); | |
| if (!plugin) { | |
| return DEFAULT_ACCOUNT_ID; | |
| } | |
| return resolveChannelDefaultAccountId({ plugin, cfg }); | |
| } | |
| function shouldShowProviderEntry(entry: ProviderAccountStatus, cfg: OpenClawConfig): boolean { | |
| 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]; | |
| return Boolean(entry.configured) || Boolean(providerConfig); | |
| } | |
| return Boolean(entry.configured); | |
| } | |
| function formatProviderEntry(entry: ProviderAccountStatus): string { | |
| const label = formatChannelAccountLabel({ | |
| provider: entry.provider, | |
| accountId: entry.accountId, | |
| name: entry.name, | |
| }); | |
| return `${label}: ${formatProviderState(entry)}`; | |
| } | |
| export function summarizeBindings(cfg: OpenClawConfig, bindings: AgentBinding[]): string[] { | |
| if (bindings.length === 0) { | |
| return []; | |
| } | |
| const seen = new Map<string, string>(); | |
| for (const binding of bindings) { | |
| const channel = normalizeChannelId(binding.match.channel); | |
| if (!channel) { | |
| continue; | |
| } | |
| const accountId = binding.match.accountId ?? resolveDefaultAccountId(cfg, channel); | |
| const key = providerAccountKey(channel, accountId); | |
| if (!seen.has(key)) { | |
| const label = formatChannelAccountLabel({ | |
| provider: channel, | |
| accountId, | |
| }); | |
| seen.set(key, label); | |
| } | |
| } | |
| return [...seen.values()]; | |
| } | |
| export function listProvidersForAgent(params: { | |
| summaryIsDefault: boolean; | |
| cfg: OpenClawConfig; | |
| bindings: AgentBinding[]; | |
| providerStatus: Map<string, ProviderAccountStatus>; | |
| }): string[] { | |
| const allProviderEntries = [...params.providerStatus.values()]; | |
| const providerLines: string[] = []; | |
| if (params.bindings.length > 0) { | |
| const seen = new Set<string>(); | |
| for (const binding of params.bindings) { | |
| const channel = normalizeChannelId(binding.match.channel); | |
| if (!channel) { | |
| continue; | |
| } | |
| const accountId = binding.match.accountId ?? resolveDefaultAccountId(params.cfg, channel); | |
| const key = providerAccountKey(channel, accountId); | |
| if (seen.has(key)) { | |
| continue; | |
| } | |
| seen.add(key); | |
| const status = params.providerStatus.get(key); | |
| if (status) { | |
| providerLines.push(formatProviderEntry(status)); | |
| } else { | |
| providerLines.push( | |
| `${formatChannelAccountLabel({ provider: channel, accountId })}: unknown`, | |
| ); | |
| } | |
| } | |
| return providerLines; | |
| } | |
| if (params.summaryIsDefault) { | |
| for (const entry of allProviderEntries) { | |
| if (shouldShowProviderEntry(entry, params.cfg)) { | |
| providerLines.push(formatProviderEntry(entry)); | |
| } | |
| } | |
| } | |
| return providerLines; | |
| } | |