perf(plugins): skip registry expansion for explicit document extractor allowlists

This commit is contained in:
Peter Steinberger
2026-04-25 03:41:08 +01:00
parent 28de3e1e5c
commit a6d16a2153
2 changed files with 83 additions and 7 deletions

View File

@@ -1,6 +1,51 @@
import { describe, expect, it } from "vitest";
import { describe, expect, it, vi } from "vitest";
import { resolvePluginDocumentExtractors } from "./document-extractors.runtime.js";
vi.mock("./document-extractor-public-artifacts.js", () => ({
loadBundledDocumentExtractorEntriesFromDir: vi.fn(
({ dirName }: { dirName: string; pluginId: string }) =>
dirName === "document-extract"
? [
{
id: "pdf",
label: "PDF",
mimeTypes: ["application/pdf"],
pluginId: "document-extract",
extract: vi.fn(),
},
]
: null,
),
}));
vi.mock("./manifest-registry.js", () => ({
loadPluginManifestRegistry: vi.fn(() => ({
plugins: [
{
id: "document-extract",
origin: "bundled",
enabledByDefault: true,
channels: [],
cliBackends: [],
providers: [],
legacyPluginIds: [],
contracts: { documentExtractors: ["pdf"] },
},
{
id: "openai",
origin: "bundled",
enabledByDefault: true,
channels: [],
cliBackends: [],
providers: ["openai", "openai-codex"],
legacyPluginIds: [],
contracts: {},
},
],
})),
resolveManifestContractOwnerPluginId: vi.fn(() => undefined),
}));
describe("resolvePluginDocumentExtractors", () => {
it("respects global plugin disablement", () => {
expect(

View File

@@ -97,6 +97,30 @@ function resolveEnabledBundledDocumentExtractorPlugins(params: {
});
}
function resolveExplicitAllowedDocumentExtractorPluginIds(params: {
config?: OpenClawConfig;
onlyPluginIds?: readonly string[];
}): string[] | null {
const allow = params.config?.plugins?.allow;
if (!Array.isArray(allow) || allow.length === 0) {
return null;
}
const onlyPluginIdSet =
params.onlyPluginIds && params.onlyPluginIds.length > 0 ? new Set(params.onlyPluginIds) : null;
const deniedPluginIds = new Set(params.config?.plugins?.deny ?? []);
const entries = params.config?.plugins?.entries ?? {};
return [
...new Set(
allow
.map((pluginId) => pluginId.trim())
.filter(Boolean)
.filter((pluginId) => !onlyPluginIdSet || onlyPluginIdSet.has(pluginId))
.filter((pluginId) => !deniedPluginIds.has(pluginId))
.filter((pluginId) => entries[pluginId]?.enabled !== false),
),
].toSorted((left, right) => left.localeCompare(right));
}
export function resolvePluginDocumentExtractors(params?: {
config?: OpenClawConfig;
workspaceDir?: string;
@@ -105,17 +129,24 @@ export function resolvePluginDocumentExtractors(params?: {
}): PluginDocumentExtractorEntry[] {
const extractors: PluginDocumentExtractorEntry[] = [];
const loadErrors: unknown[] = [];
for (const plugin of resolveEnabledBundledDocumentExtractorPlugins({
const explicitAllowedPluginIds = resolveExplicitAllowedDocumentExtractorPluginIds({
config: params?.config,
workspaceDir: params?.workspaceDir,
env: params?.env,
onlyPluginIds: params?.onlyPluginIds,
})) {
});
const pluginIds =
explicitAllowedPluginIds ??
resolveEnabledBundledDocumentExtractorPlugins({
config: params?.config,
workspaceDir: params?.workspaceDir,
env: params?.env,
onlyPluginIds: params?.onlyPluginIds,
}).map((plugin) => plugin.id);
for (const pluginId of pluginIds) {
let loaded: PluginDocumentExtractorEntry[] | null;
try {
loaded = loadBundledDocumentExtractorEntriesFromDir({
dirName: plugin.id,
pluginId: plugin.id,
dirName: pluginId,
pluginId,
});
} catch (error) {
loadErrors.push(error);