diff --git a/src/channels/plugins/status.ts b/src/channels/plugins/status.ts index 689c50c6710..983ba23be33 100644 --- a/src/channels/plugins/status.ts +++ b/src/channels/plugins/status.ts @@ -41,17 +41,17 @@ async function buildSnapshotFromAccount(params: { }; } -function inspectChannelAccount(params: { +async function inspectChannelAccount(params: { plugin: ChannelPlugin; cfg: OpenClawConfig; accountId: string; -}): ResolvedAccount | null { +}): Promise { return (params.plugin.config.inspectAccount?.(params.cfg, params.accountId) ?? - inspectReadOnlyChannelAccount({ + (await inspectReadOnlyChannelAccount({ channelId: params.plugin.id, cfg: params.cfg, accountId: params.accountId, - })) as ResolvedAccount | null; + }))) as ResolvedAccount | null; } export async function buildReadOnlySourceChannelAccountSnapshot(params: { @@ -62,7 +62,7 @@ export async function buildReadOnlySourceChannelAccountSnapshot probe?: unknown; audit?: unknown; }): Promise { - const inspectedAccount = inspectChannelAccount(params); + const inspectedAccount = await inspectChannelAccount(params); if (!inspectedAccount) { return null; } @@ -80,7 +80,7 @@ export async function buildChannelAccountSnapshot(params: { probe?: unknown; audit?: unknown; }): Promise { - const inspectedAccount = inspectChannelAccount(params); + const inspectedAccount = await inspectChannelAccount(params); const account = inspectedAccount ?? params.plugin.config.resolveAccount(params.cfg, params.accountId); return await buildSnapshotFromAccount({ diff --git a/src/channels/read-only-account-inspect.discord.runtime.ts b/src/channels/read-only-account-inspect.discord.runtime.ts new file mode 100644 index 00000000000..aed3283b7a2 --- /dev/null +++ b/src/channels/read-only-account-inspect.discord.runtime.ts @@ -0,0 +1,4 @@ +export { + inspectDiscordAccount, + type InspectedDiscordAccount, +} from "../../extensions/discord/src/account-inspect.js"; diff --git a/src/channels/read-only-account-inspect.slack.runtime.ts b/src/channels/read-only-account-inspect.slack.runtime.ts new file mode 100644 index 00000000000..6d0e0a10b29 --- /dev/null +++ b/src/channels/read-only-account-inspect.slack.runtime.ts @@ -0,0 +1,4 @@ +export { + inspectSlackAccount, + type InspectedSlackAccount, +} from "../../extensions/slack/src/account-inspect.js"; diff --git a/src/channels/read-only-account-inspect.telegram.runtime.ts b/src/channels/read-only-account-inspect.telegram.runtime.ts new file mode 100644 index 00000000000..07866b9d450 --- /dev/null +++ b/src/channels/read-only-account-inspect.telegram.runtime.ts @@ -0,0 +1,4 @@ +export { + inspectTelegramAccount, + type InspectedTelegramAccount, +} from "../../extensions/telegram/src/account-inspect.js"; diff --git a/src/channels/read-only-account-inspect.ts b/src/channels/read-only-account-inspect.ts index c8d99a3a42e..d26c1c77f55 100644 --- a/src/channels/read-only-account-inspect.ts +++ b/src/channels/read-only-account-inspect.ts @@ -1,41 +1,55 @@ -import { - inspectDiscordAccount, - type InspectedDiscordAccount, -} from "../../extensions/discord/src/account-inspect.js"; -import { - inspectSlackAccount, - type InspectedSlackAccount, -} from "../../extensions/slack/src/account-inspect.js"; -import { - inspectTelegramAccount, - type InspectedTelegramAccount, -} from "../../extensions/telegram/src/account-inspect.js"; import type { OpenClawConfig } from "../config/config.js"; import type { ChannelId } from "./plugins/types.js"; -export type ReadOnlyInspectedAccount = - | InspectedDiscordAccount - | InspectedSlackAccount - | InspectedTelegramAccount; +type DiscordInspectModule = typeof import("./read-only-account-inspect.discord.runtime.js"); +type SlackInspectModule = typeof import("./read-only-account-inspect.slack.runtime.js"); +type TelegramInspectModule = typeof import("./read-only-account-inspect.telegram.runtime.js"); -export function inspectReadOnlyChannelAccount(params: { +let discordInspectModulePromise: Promise | undefined; +let slackInspectModulePromise: Promise | undefined; +let telegramInspectModulePromise: Promise | undefined; + +function loadDiscordInspectModule() { + discordInspectModulePromise ??= import("./read-only-account-inspect.discord.runtime.js"); + return discordInspectModulePromise; +} + +function loadSlackInspectModule() { + slackInspectModulePromise ??= import("./read-only-account-inspect.slack.runtime.js"); + return slackInspectModulePromise; +} + +function loadTelegramInspectModule() { + telegramInspectModulePromise ??= import("./read-only-account-inspect.telegram.runtime.js"); + return telegramInspectModulePromise; +} + +export type ReadOnlyInspectedAccount = + | Awaited> + | Awaited> + | Awaited>; + +export async function inspectReadOnlyChannelAccount(params: { channelId: ChannelId; cfg: OpenClawConfig; accountId?: string | null; -}): ReadOnlyInspectedAccount | null { +}): Promise { if (params.channelId === "discord") { + const { inspectDiscordAccount } = await loadDiscordInspectModule(); return inspectDiscordAccount({ cfg: params.cfg, accountId: params.accountId, }); } if (params.channelId === "slack") { + const { inspectSlackAccount } = await loadSlackInspectModule(); return inspectSlackAccount({ cfg: params.cfg, accountId: params.accountId, }); } if (params.channelId === "telegram") { + const { inspectTelegramAccount } = await loadTelegramInspectModule(); return inspectTelegramAccount({ cfg: params.cfg, accountId: params.accountId, diff --git a/src/commands/channel-account-context.ts b/src/commands/channel-account-context.ts index c997ec3e18a..a9f12974b06 100644 --- a/src/commands/channel-account-context.ts +++ b/src/commands/channel-account-context.ts @@ -79,11 +79,11 @@ export async function resolveDefaultChannelAccountContext( const inspected = plugin.config.inspectAccount?.(cfg, defaultAccountId) ?? - inspectReadOnlyChannelAccount({ + (await inspectReadOnlyChannelAccount({ channelId: plugin.id, cfg, accountId: defaultAccountId, - }); + })); let account = inspected; if (!account) { diff --git a/src/commands/health.ts b/src/commands/health.ts index 0e54eebadc7..ddfc308bda4 100644 --- a/src/commands/health.ts +++ b/src/commands/health.ts @@ -165,18 +165,14 @@ const buildSessionSummary = (storePath: string) => { const asRecord = (value: unknown): Record | null => value && typeof value === "object" ? (value as Record) : null; -function inspectHealthAccount( - plugin: ChannelPlugin, - cfg: OpenClawConfig, - accountId: string, -): unknown { +async function inspectHealthAccount(plugin: ChannelPlugin, cfg: OpenClawConfig, accountId: string) { return ( plugin.config.inspectAccount?.(cfg, accountId) ?? - inspectReadOnlyChannelAccount({ + (await inspectReadOnlyChannelAccount({ channelId: plugin.id, cfg, accountId, - }) + })) ); } @@ -206,7 +202,7 @@ async function resolveHealthAccountContext(params: { diagnostics.push( `${params.plugin.id}:${params.accountId}: failed to resolve account (${formatErrorMessage(error)}).`, ); - account = inspectHealthAccount(params.plugin, params.cfg, params.accountId); + account = await inspectHealthAccount(params.plugin, params.cfg, params.accountId); } if (!account) { diff --git a/src/commands/status-all/channels.ts b/src/commands/status-all/channels.ts index cf3a67a99b5..27e0eff43c6 100644 --- a/src/commands/status-all/channels.ts +++ b/src/commands/status-all/channels.ts @@ -91,14 +91,18 @@ function formatTokenHint(token: string, opts: { showSecrets: boolean }): string return `${head}…${tail} · len ${t.length}`; } -function inspectChannelAccount(plugin: ChannelPlugin, cfg: OpenClawConfig, accountId: string) { +async function inspectChannelAccount( + plugin: ChannelPlugin, + cfg: OpenClawConfig, + accountId: string, +) { return ( plugin.config.inspectAccount?.(cfg, accountId) ?? - inspectReadOnlyChannelAccount({ + (await inspectReadOnlyChannelAccount({ channelId: plugin.id, cfg, accountId, - }) + })) ); } @@ -106,8 +110,8 @@ async function resolveChannelAccountRow( params: ResolvedChannelAccountRowParams, ): Promise { const { plugin, cfg, sourceConfig, accountId } = params; - const sourceInspectedAccount = inspectChannelAccount(plugin, sourceConfig, accountId); - const resolvedInspectedAccount = inspectChannelAccount(plugin, cfg, accountId); + const sourceInspectedAccount = await inspectChannelAccount(plugin, sourceConfig, accountId); + const resolvedInspectedAccount = await inspectChannelAccount(plugin, cfg, accountId); const resolvedInspection = resolvedInspectedAccount as { enabled?: boolean; configured?: boolean; diff --git a/src/infra/channel-summary.ts b/src/infra/channel-summary.ts index 08fd35d9327..d537b5eb317 100644 --- a/src/infra/channel-summary.ts +++ b/src/infra/channel-summary.ts @@ -105,14 +105,18 @@ const buildAccountDetails = (params: { return details; }; -function inspectChannelAccount(plugin: ChannelPlugin, cfg: OpenClawConfig, accountId: string) { +async function inspectChannelAccount( + plugin: ChannelPlugin, + cfg: OpenClawConfig, + accountId: string, +) { return ( plugin.config.inspectAccount?.(cfg, accountId) ?? - inspectReadOnlyChannelAccount({ + (await inspectReadOnlyChannelAccount({ channelId: plugin.id, cfg, accountId, - }) + })) ); } @@ -135,8 +139,8 @@ export async function buildChannelSummary( const entries: ChannelAccountEntry[] = []; for (const accountId of resolvedAccountIds) { - const sourceInspectedAccount = inspectChannelAccount(plugin, sourceConfig, accountId); - const resolvedInspectedAccount = inspectChannelAccount(plugin, effective, accountId); + const sourceInspectedAccount = await inspectChannelAccount(plugin, sourceConfig, accountId); + const resolvedInspectedAccount = await inspectChannelAccount(plugin, effective, accountId); const resolvedInspection = resolvedInspectedAccount as { enabled?: boolean; configured?: boolean; diff --git a/src/security/audit-channel.ts b/src/security/audit-channel.ts index bf501cf659b..ce1484f6513 100644 --- a/src/security/audit-channel.ts +++ b/src/security/audit-channel.ts @@ -144,17 +144,17 @@ export async function collectChannelSecurityFindings(params: { const findings: SecurityAuditFinding[] = []; const sourceConfig = params.sourceConfig ?? params.cfg; - const inspectChannelAccount = ( + const inspectChannelAccount = async ( plugin: (typeof params.plugins)[number], cfg: OpenClawConfig, accountId: string, ) => plugin.config.inspectAccount?.(cfg, accountId) ?? - inspectReadOnlyChannelAccount({ + (await inspectReadOnlyChannelAccount({ channelId: plugin.id, cfg, accountId, - }); + })); const asAccountRecord = (value: unknown): Record | null => value && typeof value === "object" && !Array.isArray(value) @@ -166,8 +166,8 @@ export async function collectChannelSecurityFindings(params: { accountId: string, ) => { const diagnostics: string[] = []; - const sourceInspectedAccount = inspectChannelAccount(plugin, sourceConfig, accountId); - const resolvedInspectedAccount = inspectChannelAccount(plugin, params.cfg, accountId); + const sourceInspectedAccount = await inspectChannelAccount(plugin, sourceConfig, accountId); + const resolvedInspectedAccount = await inspectChannelAccount(plugin, params.cfg, accountId); const sourceInspection = sourceInspectedAccount as { enabled?: boolean; configured?: boolean;