fix(plugin-sdk): avoid recursive bundled facade loads

This commit is contained in:
Peter Steinberger
2026-03-29 14:59:32 +01:00
parent 24d16c39ad
commit 8109195ad8
17 changed files with 76 additions and 24 deletions

View File

@@ -8,7 +8,7 @@ import {
hasConfiguredSecretInput,
normalizeSecretInputString,
} from "openclaw/plugin-sdk/secret-input";
import type { TelegramAccountConfig } from "../runtime-api.js";
import type { TelegramAccountConfig } from "openclaw/plugin-sdk/telegram-core";
import {
mergeTelegramAccountConfig,
resolveDefaultTelegramAccountId,

View File

@@ -16,7 +16,10 @@ import {
} from "openclaw/plugin-sdk/routing";
import { formatSetExplicitDefaultInstruction } from "openclaw/plugin-sdk/routing";
import { createSubsystemLogger, isTruthyEnvValue } from "openclaw/plugin-sdk/runtime-env";
import type { TelegramAccountConfig, TelegramActionConfig } from "../runtime-api.js";
import type {
TelegramAccountConfig,
TelegramActionConfig,
} from "openclaw/plugin-sdk/telegram-core";
import { resolveTelegramToken } from "./token.js";
let log: ReturnType<typeof createSubsystemLogger> | null = null;

View File

@@ -1,4 +1,4 @@
import type { TelegramNetworkConfig } from "../runtime-api.js";
import type { TelegramNetworkConfig } from "openclaw/plugin-sdk/telegram-core";
import { resolveTelegramApiBase, resolveTelegramFetch } from "./fetch.js";
import { makeProxyFetch } from "./proxy.js";

View File

@@ -1,4 +1,4 @@
import { type ChannelPlugin } from "../runtime-api.js";
import type { ChannelPlugin } from "openclaw/plugin-sdk/telegram-core";
import { type ResolvedTelegramAccount } from "./accounts.js";
import type { TelegramProbe } from "./probe.js";
import { telegramSetupAdapter } from "./setup-core.js";

View File

@@ -1,6 +1,6 @@
import type { BaseProbeResult } from "openclaw/plugin-sdk/channel-contract";
import type { TelegramNetworkConfig } from "openclaw/plugin-sdk/telegram-core";
import { fetchWithTimeout } from "openclaw/plugin-sdk/text-runtime";
import type { TelegramNetworkConfig } from "../runtime-api.js";
import { resolveTelegramApiBase, resolveTelegramFetch } from "./fetch.js";
import { makeProxyFetch } from "./proxy.js";

View File

@@ -9,7 +9,7 @@ import {
} from "openclaw/plugin-sdk/setup";
import type { ChannelSetupAdapter, ChannelSetupDmPolicy } from "openclaw/plugin-sdk/setup";
import { formatCliCommand, formatDocsLink } from "openclaw/plugin-sdk/setup-tools";
import type { TelegramNetworkConfig } from "../runtime-api.js";
import type { TelegramNetworkConfig } from "openclaw/plugin-sdk/telegram-core";
import { resolveDefaultTelegramAccountId, resolveTelegramAccount } from "./accounts.js";
import { lookupTelegramChatId } from "./api-fetch.js";

View File

@@ -4,7 +4,7 @@ import type { OpenClawConfig } from "openclaw/plugin-sdk/config-runtime";
import { tryReadSecretFileSync } from "openclaw/plugin-sdk/core";
import { DEFAULT_ACCOUNT_ID, normalizeAccountId } from "openclaw/plugin-sdk/routing";
import { normalizeResolvedSecretInputString } from "openclaw/plugin-sdk/secret-input";
import type { TelegramAccountConfig } from "../runtime-api.js";
import type { TelegramAccountConfig } from "openclaw/plugin-sdk/telegram-core";
export type TelegramTokenSource = "env" | "tokenFile" | "config" | "none";

View File

@@ -1,5 +1,5 @@
import { normalizeXaiModelId } from "openclaw/plugin-sdk/provider-models";
import { postTrustedWebToolsJson } from "openclaw/plugin-sdk/provider-web-search";
import { normalizeXaiModelId } from "../model-id.js";
import { extractXaiWebSearchContent, type XaiWebSearchResponse } from "./web-search-shared.js";
export const XAI_CODE_EXECUTION_ENDPOINT = "https://api.x.ai/v1/responses";

View File

@@ -1,5 +1,5 @@
import { postTrustedWebToolsJson, wrapWebContent } from "openclaw/plugin-sdk/provider-web-search";
import { normalizeXaiModelId } from "../api.js";
import { normalizeXaiModelId } from "../model-id.js";
export const XAI_WEB_SEARCH_ENDPOINT = "https://api.x.ai/v1/responses";
export const XAI_DEFAULT_WEB_SEARCH_MODEL = "grok-4-1-fast";

View File

@@ -1,5 +1,5 @@
import { normalizeXaiModelId } from "openclaw/plugin-sdk/provider-models";
import { postTrustedWebToolsJson, wrapWebContent } from "openclaw/plugin-sdk/provider-web-search";
import { normalizeXaiModelId } from "../model-id.js";
import { extractXaiWebSearchContent, type XaiWebSearchResponse } from "./web-search-shared.js";
export const XAI_X_SEARCH_ENDPOINT = "https://api.x.ai/v1/responses";

View File

@@ -16,12 +16,12 @@ export * from "../agents/pi-embedded-utils.js";
export * from "../agents/provider-id.js";
export * from "../agents/sandbox-paths.js";
export * from "../agents/schema/typebox.js";
export * from "./sglang.js";
export * from "../../extensions/sglang/api.js";
export * from "../agents/tools/common.js";
export * from "../agents/tools/web-guarded-fetch.js";
export * from "../agents/tools/web-shared.js";
export * from "../agents/tools/web-fetch-utils.js";
export * from "./vllm.js";
export * from "../../extensions/vllm/api.js";
// Intentional public runtime surface: channel plugins use ingress agent helpers directly.
export * from "../agents/agent-command.js";
export * from "../tts/tts.js";

View File

@@ -75,6 +75,34 @@ const SAME_CHANNEL_SDK_GUARDS: GuardedSource[] = [
path: bundledPluginFile("telegram", "src/action-runtime.ts"),
forbiddenPatterns: [/["']\.\.\/runtime-api\.js["']/],
},
{
path: bundledPluginFile("telegram", "src/accounts.ts"),
forbiddenPatterns: [/["']\.\.\/runtime-api\.js["']/],
},
{
path: bundledPluginFile("telegram", "src/account-inspect.ts"),
forbiddenPatterns: [/["']\.\.\/runtime-api\.js["']/],
},
{
path: bundledPluginFile("telegram", "src/api-fetch.ts"),
forbiddenPatterns: [/["']\.\.\/runtime-api\.js["']/],
},
{
path: bundledPluginFile("telegram", "src/channel.setup.ts"),
forbiddenPatterns: [/["']\.\.\/runtime-api\.js["']/],
},
{
path: bundledPluginFile("telegram", "src/probe.ts"),
forbiddenPatterns: [/["']\.\.\/runtime-api\.js["']/],
},
{
path: bundledPluginFile("telegram", "src/setup-core.ts"),
forbiddenPatterns: [/["']\.\.\/runtime-api\.js["']/],
},
{
path: bundledPluginFile("telegram", "src/token.ts"),
forbiddenPatterns: [/["']\.\.\/runtime-api\.js["']/],
},
{
path: bundledPluginFile("imessage", "src/shared.ts"),
forbiddenPatterns: [/["']openclaw\/plugin-sdk\/imessage["']/, /plugin-sdk-internal\/imessage/],
@@ -160,9 +188,11 @@ const LOCAL_EXTENSION_API_BARREL_GUARDS = [
"msteams",
"nextcloud-talk",
"nostr",
"ollama",
"open-prose",
"phone-control",
"copilot-proxy",
"sglang",
"zai",
"signal",
"synology-chat",
@@ -171,8 +201,10 @@ const LOCAL_EXTENSION_API_BARREL_GUARDS = [
"thread-ownership",
"tlon",
"voice-call",
"vllm",
"whatsapp",
"twitch",
"xai",
"zalo",
"zalouser",
] as const;

View File

@@ -28,7 +28,7 @@ export {
HTML_ENTITY_TOOL_CALL_ARGUMENTS_ENCODING,
normalizeXaiModelId,
XAI_TOOL_SCHEMA_PROFILE,
} from "./xai.js";
} from "../../extensions/xai/api.js";
export {
isMiniMaxModernModelId,
MINIMAX_DEFAULT_MODEL_ID,
@@ -87,7 +87,7 @@ export {
type OllamaModelWithContext,
type OllamaTagModel,
type OllamaTagsResponse,
} from "./ollama-surface.js";
} from "../../extensions/ollama/api.js";
export {
buildSyntheticModelDefinition,
SYNTHETIC_BASE_URL,
@@ -130,9 +130,9 @@ export {
OLLAMA_DEFAULT_CONTEXT_WINDOW,
OLLAMA_DEFAULT_COST,
OLLAMA_DEFAULT_MAX_TOKENS,
} from "./ollama-surface.js";
export { VLLM_DEFAULT_BASE_URL } from "./vllm.js";
export { SGLANG_DEFAULT_BASE_URL } from "./sglang.js";
} from "../../extensions/ollama/api.js";
export { VLLM_DEFAULT_BASE_URL } from "../../extensions/vllm/api.js";
export { SGLANG_DEFAULT_BASE_URL } from "../../extensions/sglang/api.js";
export {
buildKilocodeModelDefinition,
KILOCODE_BASE_URL,

View File

@@ -18,13 +18,16 @@ export {
SELF_HOSTED_DEFAULT_COST,
SELF_HOSTED_DEFAULT_MAX_TOKENS,
} from "../plugins/provider-self-hosted-setup.js";
export { OLLAMA_DEFAULT_BASE_URL, OLLAMA_DEFAULT_MODEL } from "./ollama-surface.js";
// Keep shared setup barrels off the generated plugin facades. Source-first
// facade loading can otherwise recurse back into the same plugin while its
// public surface is still evaluating.
export { OLLAMA_DEFAULT_BASE_URL, OLLAMA_DEFAULT_MODEL } from "../../extensions/ollama/api.js";
export {
buildOllamaProvider,
configureOllamaNonInteractive,
ensureOllamaModelPulled,
promptAndConfigureOllama,
} from "./ollama-surface.js";
} from "../../extensions/ollama/api.js";
export {
VLLM_DEFAULT_BASE_URL,
VLLM_DEFAULT_CONTEXT_WINDOW,
@@ -32,5 +35,5 @@ export {
VLLM_DEFAULT_MAX_TOKENS,
promptAndConfigureVllm,
} from "../plugins/provider-vllm-setup.js";
export { buildVllmProvider } from "./vllm.js";
export { buildSglangProvider } from "./sglang.js";
export { buildVllmProvider } from "../../extensions/vllm/api.js";
export { buildSglangProvider } from "../../extensions/sglang/api.js";

View File

@@ -19,5 +19,5 @@ export {
SELF_HOSTED_DEFAULT_MAX_TOKENS,
} from "../plugins/provider-self-hosted-setup.js";
export { buildVllmProvider } from "./vllm.js";
export { buildSglangProvider } from "./sglang.js";
export { buildVllmProvider } from "../../extensions/vllm/api.js";
export { buildSglangProvider } from "../../extensions/sglang/api.js";

View File

@@ -117,6 +117,10 @@ function expectSourceContains(subpath: string, snippet: string) {
expect(readPluginSdkSource(subpath)).toContain(snippet);
}
function expectSourceOmitsSnippet(subpath: string, snippet: string) {
expect(readPluginSdkSource(subpath)).not.toContain(snippet);
}
describe("plugin-sdk subpath exports", () => {
it("keeps the curated public list free of internal implementation subpaths", () => {
for (const deniedSubpath of [
@@ -593,6 +597,9 @@ describe("plugin-sdk subpath exports", () => {
"buildVllmProvider",
"discoverOpenAICompatibleSelfHostedProvider",
]);
expectSourceOmitsSnippet("provider-setup", "./ollama-surface.js");
expectSourceOmitsSnippet("provider-setup", "./vllm.js");
expectSourceOmitsSnippet("provider-setup", "./sglang.js");
expectSourceMentions("provider-auth", [
"buildOauthProviderAuthResult",
"generatePkceVerifierChallenge",
@@ -609,6 +616,8 @@ describe("plugin-sdk subpath exports", () => {
"resolveZaiBaseUrl",
],
});
expectSourceOmitsSnippet("provider-models", "./xai.js");
expectSourceOmitsSnippet("provider-models", "./ollama-surface.js");
expectSourceContract("provider-model-shared", {
mentions: ["DEFAULT_CONTEXT_TOKENS", "normalizeModelCompat", "cloneFirstTemplateModel"],
omits: ["applyOpenAIConfig", "buildKilocodeModelDefinition", "discoverHuggingfaceModels"],
@@ -637,6 +646,11 @@ describe("plugin-sdk subpath exports", () => {
"buildSglangProvider",
"configureOpenAICompatibleSelfHostedProviderNonInteractive",
]);
expectSourceOmitsSnippet("self-hosted-provider-setup", "./vllm.js");
expectSourceOmitsSnippet("self-hosted-provider-setup", "./sglang.js");
expectSourceOmitsSnippet("agent-runtime", "./sglang.js");
expectSourceOmitsSnippet("agent-runtime", "./vllm.js");
expectSourceOmitsSnippet("xai-model-id", "./xai.js");
expectSourceMentions("sandbox", ["registerSandboxBackend", "runPluginCommandWithTimeout"]);
expectSourceMentions("secret-input", [

View File

@@ -1 +1 @@
export { normalizeXaiModelId } from "./xai.js";
export { normalizeXaiModelId } from "../../extensions/xai/model-id.js";