mirror of
https://github.com/openclaw/openclaw.git
synced 2026-04-24 23:51:48 +00:00
Providers: scope compat resolution to owning plugins
This commit is contained in:
@@ -1,2 +1,5 @@
|
||||
export { resolveProviderPluginChoice } from "../../../plugins/provider-wizard.js";
|
||||
export { resolvePluginProviders } from "../../../plugins/providers.js";
|
||||
export {
|
||||
resolveOwningPluginIdsForProvider,
|
||||
resolvePluginProviders,
|
||||
} from "../../../plugins/providers.js";
|
||||
|
||||
@@ -7,9 +7,11 @@ vi.mock("../../auth-choice.preferred-provider.js", () => ({
|
||||
resolvePreferredProviderForAuthChoice,
|
||||
}));
|
||||
|
||||
const resolveOwningPluginIdsForProvider = vi.hoisted(() => vi.fn(() => undefined));
|
||||
const resolveProviderPluginChoice = vi.hoisted(() => vi.fn());
|
||||
const resolvePluginProviders = vi.hoisted(() => vi.fn(() => []));
|
||||
vi.mock("./auth-choice.plugin-providers.runtime.js", () => ({
|
||||
resolveOwningPluginIdsForProvider,
|
||||
resolveProviderPluginChoice,
|
||||
resolvePluginProviders,
|
||||
PROVIDER_PLUGIN_CHOICE_PREFIX: "provider-plugin:",
|
||||
@@ -30,6 +32,7 @@ describe("applyNonInteractivePluginProviderChoice", () => {
|
||||
it("loads plugin providers for provider-plugin auth choices", async () => {
|
||||
const runtime = createRuntime();
|
||||
const runNonInteractive = vi.fn(async () => ({ plugins: { allow: ["vllm"] } }));
|
||||
resolveOwningPluginIdsForProvider.mockReturnValue(["vllm"] as never);
|
||||
resolvePluginProviders.mockReturnValue([{ id: "vllm", pluginId: "vllm" }] as never);
|
||||
resolveProviderPluginChoice.mockReturnValue({
|
||||
provider: { id: "vllm", pluginId: "vllm", label: "vLLM" },
|
||||
@@ -46,7 +49,18 @@ describe("applyNonInteractivePluginProviderChoice", () => {
|
||||
toApiKeyCredential: vi.fn(),
|
||||
});
|
||||
|
||||
expect(resolveOwningPluginIdsForProvider).toHaveBeenCalledOnce();
|
||||
expect(resolveOwningPluginIdsForProvider).toHaveBeenCalledWith(
|
||||
expect.objectContaining({
|
||||
provider: "vllm",
|
||||
}),
|
||||
);
|
||||
expect(resolvePluginProviders).toHaveBeenCalledOnce();
|
||||
expect(resolvePluginProviders).toHaveBeenCalledWith(
|
||||
expect.objectContaining({
|
||||
onlyPluginIds: ["vllm"],
|
||||
}),
|
||||
);
|
||||
expect(resolveProviderPluginChoice).toHaveBeenCalledOnce();
|
||||
expect(runNonInteractive).toHaveBeenCalledOnce();
|
||||
expect(result).toEqual({ plugins: { allow: ["vllm"] } });
|
||||
|
||||
@@ -79,11 +79,20 @@ export async function applyNonInteractivePluginProviderChoice(params: {
|
||||
params.nextConfig,
|
||||
preferredProviderId,
|
||||
);
|
||||
const { resolveProviderPluginChoice, resolvePluginProviders } = await loadPluginProviderRuntime();
|
||||
const { resolveOwningPluginIdsForProvider, resolveProviderPluginChoice, resolvePluginProviders } =
|
||||
await loadPluginProviderRuntime();
|
||||
const owningPluginIds = preferredProviderId
|
||||
? resolveOwningPluginIdsForProvider({
|
||||
provider: preferredProviderId,
|
||||
config: resolutionConfig,
|
||||
workspaceDir,
|
||||
})
|
||||
: undefined;
|
||||
const providerChoice = resolveProviderPluginChoice({
|
||||
providers: resolvePluginProviders({
|
||||
config: resolutionConfig,
|
||||
workspaceDir,
|
||||
onlyPluginIds: owningPluginIds,
|
||||
bundledProviderAllowlistCompat: true,
|
||||
bundledProviderVitestCompat: true,
|
||||
}),
|
||||
|
||||
@@ -125,6 +125,34 @@ describe("resolvePluginProviders", () => {
|
||||
expect(allow).not.toContain("workspace-provider");
|
||||
});
|
||||
|
||||
it("scopes bundled provider compat expansion to the requested plugin ids", () => {
|
||||
resolvePluginProviders({
|
||||
config: {
|
||||
plugins: {
|
||||
allow: ["openrouter"],
|
||||
},
|
||||
},
|
||||
bundledProviderAllowlistCompat: true,
|
||||
onlyPluginIds: ["moonshot"],
|
||||
});
|
||||
|
||||
expect(loadOpenClawPluginsMock).toHaveBeenCalledWith(
|
||||
expect.objectContaining({
|
||||
onlyPluginIds: ["moonshot"],
|
||||
config: expect.objectContaining({
|
||||
plugins: expect.objectContaining({
|
||||
allow: expect.arrayContaining(["openrouter", "moonshot"]),
|
||||
}),
|
||||
}),
|
||||
}),
|
||||
);
|
||||
|
||||
const call = loadOpenClawPluginsMock.mock.calls.at(-1)?.[0];
|
||||
const allow = call?.config?.plugins?.allow;
|
||||
expect(allow).not.toContain("google");
|
||||
expect(allow).not.toContain("kilocode");
|
||||
});
|
||||
|
||||
it("maps provider ids to owning plugin ids via manifests", () => {
|
||||
loadPluginManifestRegistryMock.mockReturnValue({
|
||||
plugins: [
|
||||
|
||||
@@ -62,14 +62,21 @@ function resolveBundledProviderCompatPluginIds(params: {
|
||||
config?: PluginLoadOptions["config"];
|
||||
workspaceDir?: string;
|
||||
env?: PluginLoadOptions["env"];
|
||||
onlyPluginIds?: string[];
|
||||
}): string[] {
|
||||
const onlyPluginIdSet = params.onlyPluginIds ? new Set(params.onlyPluginIds) : null;
|
||||
const registry = loadPluginManifestRegistry({
|
||||
config: params.config,
|
||||
workspaceDir: params.workspaceDir,
|
||||
env: params.env,
|
||||
});
|
||||
return registry.plugins
|
||||
.filter((plugin) => plugin.origin === "bundled" && plugin.providers.length > 0)
|
||||
.filter(
|
||||
(plugin) =>
|
||||
plugin.origin === "bundled" &&
|
||||
plugin.providers.length > 0 &&
|
||||
(!onlyPluginIdSet || onlyPluginIdSet.has(plugin.id)),
|
||||
)
|
||||
.map((plugin) => plugin.id)
|
||||
.toSorted((left, right) => left.localeCompare(right));
|
||||
}
|
||||
@@ -116,6 +123,7 @@ export function resolvePluginProviders(params: {
|
||||
config: params.config,
|
||||
workspaceDir: params.workspaceDir,
|
||||
env: params.env,
|
||||
onlyPluginIds: params.onlyPluginIds,
|
||||
})
|
||||
: [];
|
||||
const maybeAllowlistCompat = params.bundledProviderAllowlistCompat
|
||||
|
||||
Reference in New Issue
Block a user