From 76c4ecd651e9480c856fd3213fece6bcc1ef8fb8 Mon Sep 17 00:00:00 2001 From: Vincent Koc Date: Wed, 1 Apr 2026 23:14:40 +0900 Subject: [PATCH] perf(test): narrow sdk seams for channel hotspots --- .../src/monitor/message-handler.preflight.ts | 6 ++-- .../src/monitor/model-picker.test-utils.ts | 2 +- .../discord/src/monitor/model-picker.test.ts | 2 +- .../discord/src/monitor/model-picker.ts | 5 ++- .../telegram/src/bot-message-context.body.ts | 4 +-- .../src/bot-message-context.session.ts | 2 +- .../telegram/src/bot-native-commands.ts | 6 ++-- extensions/whatsapp/src/account-config.ts | 32 +++++++++++++++++++ extensions/whatsapp/src/accounts.ts | 23 ++++--------- extensions/whatsapp/src/auto-reply/monitor.ts | 2 +- .../src/auto-reply/monitor/group-gating.ts | 2 +- .../src/auto-reply/monitor/process-message.ts | 4 +-- extensions/whatsapp/src/reaction-level.ts | 4 +-- package.json | 24 ++++++++++++++ scripts/lib/plugin-sdk-entrypoints.json | 6 ++++ src/plugin-sdk/command-detection.ts | 6 ++++ src/plugin-sdk/command-surface.ts | 4 +++ src/plugin-sdk/markdown-table-runtime.ts | 2 ++ src/plugin-sdk/models-provider-runtime.ts | 6 ++++ src/plugin-sdk/runtime-config-snapshot.ts | 2 ++ src/plugin-sdk/telegram-command-config.ts | 5 +++ 21 files changed, 114 insertions(+), 35 deletions(-) create mode 100644 extensions/whatsapp/src/account-config.ts create mode 100644 src/plugin-sdk/command-detection.ts create mode 100644 src/plugin-sdk/command-surface.ts create mode 100644 src/plugin-sdk/markdown-table-runtime.ts create mode 100644 src/plugin-sdk/models-provider-runtime.ts create mode 100644 src/plugin-sdk/runtime-config-snapshot.ts create mode 100644 src/plugin-sdk/telegram-command-config.ts diff --git a/extensions/discord/src/monitor/message-handler.preflight.ts b/extensions/discord/src/monitor/message-handler.preflight.ts index 39bfbde3554..9abfd9c2e37 100644 --- a/extensions/discord/src/monitor/message-handler.preflight.ts +++ b/extensions/discord/src/monitor/message-handler.preflight.ts @@ -8,9 +8,9 @@ import { resolveMentionGatingWithBypass, } from "openclaw/plugin-sdk/channel-inbound"; import { enqueueSystemEvent, recordChannelActivity } from "openclaw/plugin-sdk/channel-runtime"; -import { resolveControlCommandGate } from "openclaw/plugin-sdk/command-auth"; -import { hasControlCommand } from "openclaw/plugin-sdk/command-auth"; -import { shouldHandleTextCommands } from "openclaw/plugin-sdk/command-auth"; +import { resolveControlCommandGate } from "openclaw/plugin-sdk/command-auth-native"; +import { hasControlCommand } from "openclaw/plugin-sdk/command-detection"; +import { shouldHandleTextCommands } from "openclaw/plugin-sdk/command-surface"; import { loadConfig } from "openclaw/plugin-sdk/config-runtime"; import { isDangerousNameMatchingEnabled } from "openclaw/plugin-sdk/config-runtime"; import type { SessionBindingRecord } from "openclaw/plugin-sdk/conversation-runtime"; diff --git a/extensions/discord/src/monitor/model-picker.test-utils.ts b/extensions/discord/src/monitor/model-picker.test-utils.ts index f0e60eb112e..c8779150b6c 100644 --- a/extensions/discord/src/monitor/model-picker.test-utils.ts +++ b/extensions/discord/src/monitor/model-picker.test-utils.ts @@ -1,4 +1,4 @@ -import type { ModelsProviderData } from "openclaw/plugin-sdk/command-auth"; +import type { ModelsProviderData } from "openclaw/plugin-sdk/models-provider-runtime"; export function createModelsProviderData( entries: Record, diff --git a/extensions/discord/src/monitor/model-picker.test.ts b/extensions/discord/src/monitor/model-picker.test.ts index 5bd1f7cb882..de915be66bd 100644 --- a/extensions/discord/src/monitor/model-picker.test.ts +++ b/extensions/discord/src/monitor/model-picker.test.ts @@ -1,6 +1,6 @@ import { serializePayload } from "@buape/carbon"; import { ComponentType } from "discord-api-types/v10"; -import * as modelsCommandModule from "openclaw/plugin-sdk/command-auth"; +import * as modelsCommandModule from "openclaw/plugin-sdk/models-provider-runtime"; import type { OpenClawConfig } from "openclaw/plugin-sdk/config-runtime"; import { describe, expect, it, vi } from "vitest"; import { diff --git a/extensions/discord/src/monitor/model-picker.ts b/extensions/discord/src/monitor/model-picker.ts index 47313af5801..4a467eedfcd 100644 --- a/extensions/discord/src/monitor/model-picker.ts +++ b/extensions/discord/src/monitor/model-picker.ts @@ -12,7 +12,10 @@ import { import type { APISelectMenuOption } from "discord-api-types/v10"; import { ButtonStyle } from "discord-api-types/v10"; import { normalizeProviderId } from "openclaw/plugin-sdk/agent-runtime"; -import { buildModelsProviderData, type ModelsProviderData } from "openclaw/plugin-sdk/command-auth"; +import { + buildModelsProviderData, + type ModelsProviderData, +} from "openclaw/plugin-sdk/models-provider-runtime"; import type { OpenClawConfig } from "openclaw/plugin-sdk/config-runtime"; export const DISCORD_MODEL_PICKER_CUSTOM_ID_KEY = "mdlpk"; diff --git a/extensions/telegram/src/bot-message-context.body.ts b/extensions/telegram/src/bot-message-context.body.ts index 382db32447e..cb9ad7bbb48 100644 --- a/extensions/telegram/src/bot-message-context.body.ts +++ b/extensions/telegram/src/bot-message-context.body.ts @@ -6,8 +6,8 @@ import { resolveMentionGatingWithBypass, type NormalizedLocation, } from "openclaw/plugin-sdk/channel-inbound"; -import { resolveControlCommandGate } from "openclaw/plugin-sdk/command-auth"; -import { hasControlCommand } from "openclaw/plugin-sdk/command-auth"; +import { resolveControlCommandGate } from "openclaw/plugin-sdk/command-auth-native"; +import { hasControlCommand } from "openclaw/plugin-sdk/command-detection"; import type { OpenClawConfig } from "openclaw/plugin-sdk/config-runtime"; import type { TelegramDirectConfig, diff --git a/extensions/telegram/src/bot-message-context.session.ts b/extensions/telegram/src/bot-message-context.session.ts index fe251e2c601..6a7685cf90f 100644 --- a/extensions/telegram/src/bot-message-context.session.ts +++ b/extensions/telegram/src/bot-message-context.session.ts @@ -4,7 +4,7 @@ import { toLocationContext, type NormalizedLocation, } from "openclaw/plugin-sdk/channel-inbound"; -import { normalizeCommandBody } from "openclaw/plugin-sdk/command-auth"; +import { normalizeCommandBody } from "openclaw/plugin-sdk/command-surface"; import type { OpenClawConfig } from "openclaw/plugin-sdk/config-runtime"; import { readSessionUpdatedAt, resolveStorePath } from "openclaw/plugin-sdk/config-runtime"; import type { diff --git a/extensions/telegram/src/bot-native-commands.ts b/extensions/telegram/src/bot-native-commands.ts index b123c535e86..73baf121c27 100644 --- a/extensions/telegram/src/bot-native-commands.ts +++ b/extensions/telegram/src/bot-native-commands.ts @@ -15,13 +15,13 @@ import { } from "openclaw/plugin-sdk/command-auth-native"; import type { OpenClawConfig } from "openclaw/plugin-sdk/config-runtime"; import type { ChannelGroupPolicy } from "openclaw/plugin-sdk/config-runtime"; -import { getRuntimeConfigSnapshot } from "openclaw/plugin-sdk/config-runtime"; -import { resolveMarkdownTableMode } from "openclaw/plugin-sdk/config-runtime"; +import { resolveMarkdownTableMode } from "openclaw/plugin-sdk/markdown-table-runtime"; +import { getRuntimeConfigSnapshot } from "openclaw/plugin-sdk/runtime-config-snapshot"; import { normalizeTelegramCommandName, resolveTelegramCustomCommands, TELEGRAM_COMMAND_NAME_PATTERN, -} from "openclaw/plugin-sdk/config-runtime"; +} from "openclaw/plugin-sdk/telegram-command-config"; import type { ReplyToMode, TelegramAccountConfig, diff --git a/extensions/whatsapp/src/account-config.ts b/extensions/whatsapp/src/account-config.ts new file mode 100644 index 00000000000..74bd6c5c89a --- /dev/null +++ b/extensions/whatsapp/src/account-config.ts @@ -0,0 +1,32 @@ +import { + DEFAULT_ACCOUNT_ID, + resolveAccountEntry, + resolveMergedAccountConfig, + type OpenClawConfig, +} from "openclaw/plugin-sdk/account-core"; +import type { WhatsAppAccountConfig } from "./runtime-api.js"; + +function resolveWhatsAppAccountConfig( + cfg: OpenClawConfig, + accountId: string, +): WhatsAppAccountConfig | undefined { + return resolveAccountEntry(cfg.channels?.whatsapp?.accounts, accountId); +} + +export function resolveMergedWhatsAppAccountConfig(params: { + cfg: OpenClawConfig; + accountId?: string | null; +}): WhatsAppAccountConfig & { accountId: string } { + const rootCfg = params.cfg.channels?.whatsapp; + const accountId = params.accountId?.trim() || rootCfg?.defaultAccount || DEFAULT_ACCOUNT_ID; + const merged = resolveMergedAccountConfig({ + channelConfig: rootCfg as WhatsAppAccountConfig | undefined, + accounts: rootCfg?.accounts as Record> | undefined, + accountId, + omitKeys: ["defaultAccount"], + }); + return { + accountId, + ...merged, + }; +} diff --git a/extensions/whatsapp/src/accounts.ts b/extensions/whatsapp/src/accounts.ts index a85108ac43c..085eade655f 100644 --- a/extensions/whatsapp/src/accounts.ts +++ b/extensions/whatsapp/src/accounts.ts @@ -4,12 +4,11 @@ import { createAccountListHelpers, DEFAULT_ACCOUNT_ID, normalizeAccountId, - resolveAccountEntry, - resolveMergedAccountConfig, resolveUserPath, type OpenClawConfig, } from "openclaw/plugin-sdk/account-core"; import { resolveOAuthDir } from "openclaw/plugin-sdk/state-paths"; +import { resolveMergedWhatsAppAccountConfig } from "./account-config.js"; import { hasWebCredsSync } from "./creds-files.js"; import type { DmPolicy, GroupPolicy, WhatsAppAccountConfig } from "./runtime-api.js"; @@ -73,13 +72,6 @@ export function hasAnyWhatsAppAuth(cfg: OpenClawConfig): boolean { return listWhatsAppAuthDirs(cfg).some((authDir) => hasWebCredsSync(authDir)); } -function resolveAccountConfig( - cfg: OpenClawConfig, - accountId: string, -): WhatsAppAccountConfig | undefined { - return resolveAccountEntry(cfg.channels?.whatsapp?.accounts, accountId); -} - function resolveDefaultAuthDir(accountId: string): string { return path.join(resolveOAuthDir(), "whatsapp", normalizeAccountId(accountId)); } @@ -102,7 +94,7 @@ export function resolveWhatsAppAuthDir(params: { cfg: OpenClawConfig; accountId: isLegacy: boolean; } { const accountId = params.accountId.trim() || DEFAULT_ACCOUNT_ID; - const account = resolveAccountConfig(params.cfg, accountId); + const account = resolveMergedWhatsAppAccountConfig({ cfg: params.cfg, accountId }); const configured = account?.authDir?.trim(); if (configured) { return { authDir: resolveUserPath(configured), isLegacy: false }; @@ -123,14 +115,11 @@ export function resolveWhatsAppAccount(params: { cfg: OpenClawConfig; accountId?: string | null; }): ResolvedWhatsAppAccount { - const rootCfg = params.cfg.channels?.whatsapp; - const accountId = params.accountId?.trim() || resolveDefaultWhatsAppAccountId(params.cfg); - const merged = resolveMergedAccountConfig({ - channelConfig: rootCfg as WhatsAppAccountConfig | undefined, - accounts: rootCfg?.accounts as Record> | undefined, - accountId, - omitKeys: ["defaultAccount"], + const merged = resolveMergedWhatsAppAccountConfig({ + cfg: params.cfg, + accountId: params.accountId?.trim() || resolveDefaultWhatsAppAccountId(params.cfg), }); + const accountId = merged.accountId; const enabled = merged.enabled !== false; const { authDir, isLegacy } = resolveWhatsAppAuthDir({ cfg: params.cfg, diff --git a/extensions/whatsapp/src/auto-reply/monitor.ts b/extensions/whatsapp/src/auto-reply/monitor.ts index 5a586946d13..0d114f1cbae 100644 --- a/extensions/whatsapp/src/auto-reply/monitor.ts +++ b/extensions/whatsapp/src/auto-reply/monitor.ts @@ -2,7 +2,7 @@ import { resolveInboundDebounceMs } from "openclaw/plugin-sdk/channel-inbound"; import { enqueueSystemEvent } from "openclaw/plugin-sdk/channel-runtime"; import { formatCliCommand } from "openclaw/plugin-sdk/cli-runtime"; import { waitForever } from "openclaw/plugin-sdk/cli-runtime"; -import { hasControlCommand } from "openclaw/plugin-sdk/command-auth"; +import { hasControlCommand } from "openclaw/plugin-sdk/command-detection"; import { loadConfig } from "openclaw/plugin-sdk/config-runtime"; import { DEFAULT_GROUP_HISTORY_LIMIT } from "openclaw/plugin-sdk/reply-history"; import { getReplyFromConfig } from "openclaw/plugin-sdk/reply-runtime"; diff --git a/extensions/whatsapp/src/auto-reply/monitor/group-gating.ts b/extensions/whatsapp/src/auto-reply/monitor/group-gating.ts index 62ecc7bbe5f..1b7f4aea99b 100644 --- a/extensions/whatsapp/src/auto-reply/monitor/group-gating.ts +++ b/extensions/whatsapp/src/auto-reply/monitor/group-gating.ts @@ -1,5 +1,5 @@ import { resolveMentionGating } from "openclaw/plugin-sdk/channel-inbound"; -import { hasControlCommand } from "openclaw/plugin-sdk/command-auth"; +import { hasControlCommand } from "openclaw/plugin-sdk/command-detection"; import type { loadConfig } from "openclaw/plugin-sdk/config-runtime"; import { recordPendingHistoryEntryIfEnabled } from "openclaw/plugin-sdk/reply-history"; import { parseActivationCommand } from "openclaw/plugin-sdk/reply-runtime"; diff --git a/extensions/whatsapp/src/auto-reply/monitor/process-message.ts b/extensions/whatsapp/src/auto-reply/monitor/process-message.ts index 5e6ea614b43..01ddbdc83d3 100644 --- a/extensions/whatsapp/src/auto-reply/monitor/process-message.ts +++ b/extensions/whatsapp/src/auto-reply/monitor/process-message.ts @@ -5,9 +5,9 @@ import { } from "openclaw/plugin-sdk/channel-inbound"; import { formatInboundEnvelope } from "openclaw/plugin-sdk/channel-inbound"; import { createChannelReplyPipeline } from "openclaw/plugin-sdk/channel-reply-pipeline"; -import { shouldComputeCommandAuthorized } from "openclaw/plugin-sdk/command-auth"; +import { shouldComputeCommandAuthorized } from "openclaw/plugin-sdk/command-detection"; import type { loadConfig } from "openclaw/plugin-sdk/config-runtime"; -import { resolveMarkdownTableMode } from "openclaw/plugin-sdk/config-runtime"; +import { resolveMarkdownTableMode } from "openclaw/plugin-sdk/markdown-table-runtime"; import { recordSessionMetaFromInbound } from "openclaw/plugin-sdk/config-runtime"; import { getAgentScopedMediaLocalRoots } from "openclaw/plugin-sdk/media-runtime"; import { diff --git a/extensions/whatsapp/src/reaction-level.ts b/extensions/whatsapp/src/reaction-level.ts index e9bcaf51425..35a395b096a 100644 --- a/extensions/whatsapp/src/reaction-level.ts +++ b/extensions/whatsapp/src/reaction-level.ts @@ -4,7 +4,7 @@ import { type ReactionLevel, type ResolvedReactionLevel, } from "openclaw/plugin-sdk/text-runtime"; -import { resolveWhatsAppAccount } from "./accounts.js"; +import { resolveMergedWhatsAppAccountConfig } from "./account-config.js"; export type WhatsAppReactionLevel = ReactionLevel; export type ResolvedWhatsAppReactionLevel = ResolvedReactionLevel; @@ -14,7 +14,7 @@ export function resolveWhatsAppReactionLevel(params: { cfg: OpenClawConfig; accountId?: string; }): ResolvedWhatsAppReactionLevel { - const account = resolveWhatsAppAccount({ + const account = resolveMergedWhatsAppAccountConfig({ cfg: params.cfg, accountId: params.accountId, }); diff --git a/package.json b/package.json index 1e34a587398..e6fac10310e 100644 --- a/package.json +++ b/package.json @@ -135,6 +135,10 @@ "types": "./dist/plugin-sdk/infra-runtime.d.ts", "default": "./dist/plugin-sdk/infra-runtime.js" }, + "./plugin-sdk/runtime-config-snapshot": { + "types": "./dist/plugin-sdk/runtime-config-snapshot.d.ts", + "default": "./dist/plugin-sdk/runtime-config-snapshot.js" + }, "./plugin-sdk/ssrf-runtime": { "types": "./dist/plugin-sdk/ssrf-runtime.d.ts", "default": "./dist/plugin-sdk/ssrf-runtime.js" @@ -247,6 +251,10 @@ "types": "./dist/plugin-sdk/logging-core.d.ts", "default": "./dist/plugin-sdk/logging-core.js" }, + "./plugin-sdk/markdown-table-runtime": { + "types": "./dist/plugin-sdk/markdown-table-runtime.d.ts", + "default": "./dist/plugin-sdk/markdown-table-runtime.js" + }, "./plugin-sdk/account-helpers": { "types": "./dist/plugin-sdk/account-helpers.d.ts", "default": "./dist/plugin-sdk/account-helpers.js" @@ -327,6 +335,14 @@ "types": "./dist/plugin-sdk/command-auth-native.d.ts", "default": "./dist/plugin-sdk/command-auth-native.js" }, + "./plugin-sdk/command-detection": { + "types": "./dist/plugin-sdk/command-detection.d.ts", + "default": "./dist/plugin-sdk/command-detection.js" + }, + "./plugin-sdk/command-surface": { + "types": "./dist/plugin-sdk/command-surface.d.ts", + "default": "./dist/plugin-sdk/command-surface.js" + }, "./plugin-sdk/collection-runtime": { "types": "./dist/plugin-sdk/collection-runtime.d.ts", "default": "./dist/plugin-sdk/collection-runtime.js" @@ -671,6 +687,10 @@ "types": "./dist/plugin-sdk/msteams.d.ts", "default": "./dist/plugin-sdk/msteams.js" }, + "./plugin-sdk/models-provider-runtime": { + "types": "./dist/plugin-sdk/models-provider-runtime.d.ts", + "default": "./dist/plugin-sdk/models-provider-runtime.js" + }, "./plugin-sdk/nextcloud-talk": { "types": "./dist/plugin-sdk/nextcloud-talk.d.ts", "default": "./dist/plugin-sdk/nextcloud-talk.js" @@ -859,6 +879,10 @@ "types": "./dist/plugin-sdk/telegram-account.d.ts", "default": "./dist/plugin-sdk/telegram-account.js" }, + "./plugin-sdk/telegram-command-config": { + "types": "./dist/plugin-sdk/telegram-command-config.d.ts", + "default": "./dist/plugin-sdk/telegram-command-config.js" + }, "./plugin-sdk/telegram-allow-from": { "types": "./dist/plugin-sdk/telegram-allow-from.d.ts", "default": "./dist/plugin-sdk/telegram-allow-from.js" diff --git a/scripts/lib/plugin-sdk-entrypoints.json b/scripts/lib/plugin-sdk-entrypoints.json index 1085535796d..804db0e26b6 100644 --- a/scripts/lib/plugin-sdk-entrypoints.json +++ b/scripts/lib/plugin-sdk-entrypoints.json @@ -23,6 +23,7 @@ "interactive-runtime", "outbound-runtime", "infra-runtime", + "runtime-config-snapshot", "ssrf-runtime", "media-runtime", "media-understanding-runtime", @@ -51,6 +52,7 @@ "testing", "temp-path", "logging-core", + "markdown-table-runtime", "account-helpers", "account-core", "account-id", @@ -71,6 +73,8 @@ "chutes", "command-auth", "command-auth-native", + "command-detection", + "command-surface", "collection-runtime", "compat", "direct-dm", @@ -157,6 +161,7 @@ "moonshot", "mistral", "msteams", + "models-provider-runtime", "nextcloud-talk", "nvidia", "nostr", @@ -204,6 +209,7 @@ "state-paths", "synthetic", "telegram-account", + "telegram-command-config", "telegram-allow-from", "telegram-core", "telegram-surface", diff --git a/src/plugin-sdk/command-detection.ts b/src/plugin-sdk/command-detection.ts new file mode 100644 index 00000000000..e6b8ef64bed --- /dev/null +++ b/src/plugin-sdk/command-detection.ts @@ -0,0 +1,6 @@ +export { + hasControlCommand, + hasInlineCommandTokens, + isControlCommandMessage, + shouldComputeCommandAuthorized, +} from "../auto-reply/command-detection.js"; diff --git a/src/plugin-sdk/command-surface.ts b/src/plugin-sdk/command-surface.ts new file mode 100644 index 00000000000..3ef363ed430 --- /dev/null +++ b/src/plugin-sdk/command-surface.ts @@ -0,0 +1,4 @@ +export { + normalizeCommandBody, + shouldHandleTextCommands, +} from "../auto-reply/commands-registry.js"; diff --git a/src/plugin-sdk/markdown-table-runtime.ts b/src/plugin-sdk/markdown-table-runtime.ts new file mode 100644 index 00000000000..62e2848512f --- /dev/null +++ b/src/plugin-sdk/markdown-table-runtime.ts @@ -0,0 +1,2 @@ +export { resolveMarkdownTableMode } from "../config/markdown-tables.js"; +export type { MarkdownTableMode } from "../config/types.base.js"; diff --git a/src/plugin-sdk/models-provider-runtime.ts b/src/plugin-sdk/models-provider-runtime.ts new file mode 100644 index 00000000000..8c0204d48db --- /dev/null +++ b/src/plugin-sdk/models-provider-runtime.ts @@ -0,0 +1,6 @@ +export { + buildModelsProviderData, + formatModelsAvailableHeader, + resolveModelsCommandReply, +} from "../auto-reply/reply/commands-models.js"; +export type { ModelsProviderData } from "../auto-reply/reply/commands-models.js"; diff --git a/src/plugin-sdk/runtime-config-snapshot.ts b/src/plugin-sdk/runtime-config-snapshot.ts new file mode 100644 index 00000000000..a00e7de1e85 --- /dev/null +++ b/src/plugin-sdk/runtime-config-snapshot.ts @@ -0,0 +1,2 @@ +export { getRuntimeConfigSnapshot } from "../config/io.js"; +export type { OpenClawConfig } from "../config/types.js"; diff --git a/src/plugin-sdk/telegram-command-config.ts b/src/plugin-sdk/telegram-command-config.ts new file mode 100644 index 00000000000..8c327f94af4 --- /dev/null +++ b/src/plugin-sdk/telegram-command-config.ts @@ -0,0 +1,5 @@ +export { + TELEGRAM_COMMAND_NAME_PATTERN, + normalizeTelegramCommandName, + resolveTelegramCustomCommands, +} from "../config/telegram-custom-commands.js";