mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-02 08:10:22 +00:00
Revert "feat: add video generation core infrastructure and extend image generation parameters (#53681)" (#54943)
This reverts commit 4cb8dde894.
This commit is contained in:
@@ -5,7 +5,6 @@ import type {
|
||||
OpenClawPluginApi,
|
||||
ProviderPlugin,
|
||||
SpeechProviderPlugin,
|
||||
VideoGenerationProviderPlugin,
|
||||
WebSearchProviderPlugin,
|
||||
} from "./types.js";
|
||||
|
||||
@@ -15,7 +14,6 @@ export type CapturedPluginRegistration = {
|
||||
speechProviders: SpeechProviderPlugin[];
|
||||
mediaUnderstandingProviders: MediaUnderstandingProviderPlugin[];
|
||||
imageGenerationProviders: ImageGenerationProviderPlugin[];
|
||||
videoGenerationProviders: VideoGenerationProviderPlugin[];
|
||||
webSearchProviders: WebSearchProviderPlugin[];
|
||||
tools: AnyAgentTool[];
|
||||
};
|
||||
@@ -25,7 +23,6 @@ export function createCapturedPluginRegistration(): CapturedPluginRegistration {
|
||||
const speechProviders: SpeechProviderPlugin[] = [];
|
||||
const mediaUnderstandingProviders: MediaUnderstandingProviderPlugin[] = [];
|
||||
const imageGenerationProviders: ImageGenerationProviderPlugin[] = [];
|
||||
const videoGenerationProviders: VideoGenerationProviderPlugin[] = [];
|
||||
const webSearchProviders: WebSearchProviderPlugin[] = [];
|
||||
const tools: AnyAgentTool[] = [];
|
||||
|
||||
@@ -34,7 +31,6 @@ export function createCapturedPluginRegistration(): CapturedPluginRegistration {
|
||||
speechProviders,
|
||||
mediaUnderstandingProviders,
|
||||
imageGenerationProviders,
|
||||
videoGenerationProviders,
|
||||
webSearchProviders,
|
||||
tools,
|
||||
api: {
|
||||
@@ -50,9 +46,6 @@ export function createCapturedPluginRegistration(): CapturedPluginRegistration {
|
||||
registerImageGenerationProvider(provider: ImageGenerationProviderPlugin) {
|
||||
imageGenerationProviders.push(provider);
|
||||
},
|
||||
registerVideoGenerationProvider(provider: VideoGenerationProviderPlugin) {
|
||||
videoGenerationProviders.push(provider);
|
||||
},
|
||||
registerWebSearchProvider(provider: WebSearchProviderPlugin) {
|
||||
webSearchProviders.push(provider);
|
||||
},
|
||||
|
||||
@@ -203,7 +203,6 @@ describe("plugin contract registry", () => {
|
||||
speechProviderIds: [],
|
||||
mediaUnderstandingProviderIds: [],
|
||||
imageGenerationProviderIds: [],
|
||||
videoGenerationProviderIds: [],
|
||||
webSearchProviderIds: ["exa"],
|
||||
toolNames: [],
|
||||
});
|
||||
@@ -212,7 +211,6 @@ describe("plugin contract registry", () => {
|
||||
speechProviderIds: [],
|
||||
mediaUnderstandingProviderIds: [],
|
||||
imageGenerationProviderIds: [],
|
||||
videoGenerationProviderIds: [],
|
||||
webSearchProviderIds: ["firecrawl"],
|
||||
toolNames: ["firecrawl_search", "firecrawl_scrape"],
|
||||
});
|
||||
@@ -221,7 +219,6 @@ describe("plugin contract registry", () => {
|
||||
speechProviderIds: [],
|
||||
mediaUnderstandingProviderIds: [],
|
||||
imageGenerationProviderIds: [],
|
||||
videoGenerationProviderIds: [],
|
||||
webSearchProviderIds: ["tavily"],
|
||||
toolNames: ["tavily_search", "tavily_extract"],
|
||||
});
|
||||
@@ -233,7 +230,6 @@ describe("plugin contract registry", () => {
|
||||
speechProviderIds: [],
|
||||
mediaUnderstandingProviderIds: [],
|
||||
imageGenerationProviderIds: ["fal"],
|
||||
videoGenerationProviderIds: [],
|
||||
webSearchProviderIds: [],
|
||||
});
|
||||
expect(findRegistrationForPlugin("google")).toMatchObject({
|
||||
@@ -241,7 +237,6 @@ describe("plugin contract registry", () => {
|
||||
speechProviderIds: [],
|
||||
mediaUnderstandingProviderIds: ["google"],
|
||||
imageGenerationProviderIds: ["google"],
|
||||
videoGenerationProviderIds: [],
|
||||
webSearchProviderIds: ["gemini"],
|
||||
});
|
||||
expect(findRegistrationForPlugin("openai")).toMatchObject({
|
||||
@@ -249,21 +244,18 @@ describe("plugin contract registry", () => {
|
||||
speechProviderIds: ["openai"],
|
||||
mediaUnderstandingProviderIds: ["openai", "openai-codex"],
|
||||
imageGenerationProviderIds: ["openai"],
|
||||
videoGenerationProviderIds: [],
|
||||
});
|
||||
expect(findRegistrationForPlugin("elevenlabs")).toMatchObject({
|
||||
providerIds: [],
|
||||
speechProviderIds: ["elevenlabs"],
|
||||
mediaUnderstandingProviderIds: [],
|
||||
imageGenerationProviderIds: [],
|
||||
videoGenerationProviderIds: [],
|
||||
});
|
||||
expect(findRegistrationForPlugin("microsoft")).toMatchObject({
|
||||
providerIds: [],
|
||||
speechProviderIds: ["microsoft"],
|
||||
mediaUnderstandingProviderIds: [],
|
||||
imageGenerationProviderIds: [],
|
||||
videoGenerationProviderIds: [],
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@@ -75,7 +75,6 @@ type PluginRegistrationContractEntry = {
|
||||
speechProviderIds: string[];
|
||||
mediaUnderstandingProviderIds: string[];
|
||||
imageGenerationProviderIds: string[];
|
||||
videoGenerationProviderIds: string[];
|
||||
webSearchProviderIds: string[];
|
||||
toolNames: string[];
|
||||
};
|
||||
@@ -420,10 +419,6 @@ function upsertPluginRegistrationContractEntry(
|
||||
existing.imageGenerationProviderIds,
|
||||
next.imageGenerationProviderIds,
|
||||
);
|
||||
existing.videoGenerationProviderIds = mergeIds(
|
||||
existing.videoGenerationProviderIds,
|
||||
next.videoGenerationProviderIds,
|
||||
);
|
||||
existing.webSearchProviderIds = mergeIds(
|
||||
existing.webSearchProviderIds,
|
||||
next.webSearchProviderIds,
|
||||
@@ -448,7 +443,6 @@ function mergeProviderContractRegistrations(
|
||||
speechProviderIds: [],
|
||||
mediaUnderstandingProviderIds: [],
|
||||
imageGenerationProviderIds: [],
|
||||
videoGenerationProviderIds: [],
|
||||
webSearchProviderIds: [],
|
||||
toolNames: [],
|
||||
});
|
||||
@@ -470,9 +464,6 @@ function loadPluginRegistrationContractRegistry(): PluginRegistrationContractEnt
|
||||
imageGenerationProviderIds: captured.imageGenerationProviders.map(
|
||||
(provider) => provider.id,
|
||||
),
|
||||
videoGenerationProviderIds: captured.videoGenerationProviders.map(
|
||||
(provider) => provider.id,
|
||||
),
|
||||
webSearchProviderIds: captured.webSearchProviders.map((provider) => provider.id),
|
||||
toolNames: captured.tools.map((tool) => tool.name),
|
||||
});
|
||||
|
||||
@@ -20,7 +20,6 @@ function createPluginRecord(id: string, name: string): PluginRecord {
|
||||
speechProviderIds: [],
|
||||
mediaUnderstandingProviderIds: [],
|
||||
imageGenerationProviderIds: [],
|
||||
videoGenerationProviderIds: [],
|
||||
webSearchProviderIds: [],
|
||||
gatewayMethods: [],
|
||||
cliCommands: [],
|
||||
|
||||
@@ -20,7 +20,6 @@ export function createMockPluginRegistry(
|
||||
speechProviderIds: [],
|
||||
mediaUnderstandingProviderIds: [],
|
||||
imageGenerationProviderIds: [],
|
||||
videoGenerationProviderIds: [],
|
||||
webSearchProviderIds: [],
|
||||
gatewayMethods: [],
|
||||
cliCommands: [],
|
||||
@@ -46,7 +45,6 @@ export function createMockPluginRegistry(
|
||||
speechProviders: [],
|
||||
mediaUnderstandingProviders: [],
|
||||
imageGenerationProviders: [],
|
||||
videoGenerationProviders: [],
|
||||
webSearchProviders: [],
|
||||
httpRoutes: [],
|
||||
gatewayHandlers: {},
|
||||
|
||||
@@ -351,7 +351,6 @@ function createPluginRecord(params: {
|
||||
speechProviderIds: [],
|
||||
mediaUnderstandingProviderIds: [],
|
||||
imageGenerationProviderIds: [],
|
||||
videoGenerationProviderIds: [],
|
||||
webSearchProviderIds: [],
|
||||
gatewayMethods: [],
|
||||
cliCommands: [],
|
||||
|
||||
@@ -12,7 +12,6 @@ export function createEmptyPluginRegistry(): PluginRegistry {
|
||||
speechProviders: [],
|
||||
mediaUnderstandingProviders: [],
|
||||
imageGenerationProviders: [],
|
||||
videoGenerationProviders: [],
|
||||
webSearchProviders: [],
|
||||
gatewayHandlers: {},
|
||||
httpRoutes: [],
|
||||
|
||||
@@ -26,7 +26,6 @@ import {
|
||||
} from "./types.js";
|
||||
import type {
|
||||
ImageGenerationProviderPlugin,
|
||||
VideoGenerationProviderPlugin,
|
||||
OpenClawPluginApi,
|
||||
OpenClawPluginChannelRegistration,
|
||||
OpenClawPluginCliRegistrar,
|
||||
@@ -124,8 +123,6 @@ export type PluginMediaUnderstandingProviderRegistration =
|
||||
PluginOwnedProviderRegistration<MediaUnderstandingProviderPlugin>;
|
||||
export type PluginImageGenerationProviderRegistration =
|
||||
PluginOwnedProviderRegistration<ImageGenerationProviderPlugin>;
|
||||
export type PluginVideoGenerationProviderRegistration =
|
||||
PluginOwnedProviderRegistration<VideoGenerationProviderPlugin>;
|
||||
export type PluginWebSearchProviderRegistration =
|
||||
PluginOwnedProviderRegistration<WebSearchProviderPlugin>;
|
||||
|
||||
@@ -185,7 +182,6 @@ export type PluginRecord = {
|
||||
speechProviderIds: string[];
|
||||
mediaUnderstandingProviderIds: string[];
|
||||
imageGenerationProviderIds: string[];
|
||||
videoGenerationProviderIds: string[];
|
||||
webSearchProviderIds: string[];
|
||||
gatewayMethods: string[];
|
||||
cliCommands: string[];
|
||||
@@ -209,7 +205,6 @@ export type PluginRegistry = {
|
||||
speechProviders: PluginSpeechProviderRegistration[];
|
||||
mediaUnderstandingProviders: PluginMediaUnderstandingProviderRegistration[];
|
||||
imageGenerationProviders: PluginImageGenerationProviderRegistration[];
|
||||
videoGenerationProviders: PluginVideoGenerationProviderRegistration[];
|
||||
webSearchProviders: PluginWebSearchProviderRegistration[];
|
||||
gatewayHandlers: GatewayRequestHandlers;
|
||||
httpRoutes: PluginHttpRouteRegistration[];
|
||||
@@ -649,19 +644,6 @@ export function createPluginRegistry(registryParams: PluginRegistryParams) {
|
||||
});
|
||||
};
|
||||
|
||||
const registerVideoGenerationProvider = (
|
||||
record: PluginRecord,
|
||||
provider: VideoGenerationProviderPlugin,
|
||||
) => {
|
||||
registerUniqueProviderLike({
|
||||
record,
|
||||
provider,
|
||||
kindLabel: "video-generation provider",
|
||||
registrations: registry.videoGenerationProviders,
|
||||
ownedIds: record.videoGenerationProviderIds,
|
||||
});
|
||||
};
|
||||
|
||||
const registerWebSearchProvider = (record: PluginRecord, provider: WebSearchProviderPlugin) => {
|
||||
registerUniqueProviderLike({
|
||||
record,
|
||||
@@ -936,10 +918,6 @@ export function createPluginRegistry(registryParams: PluginRegistryParams) {
|
||||
registrationMode === "full"
|
||||
? (provider) => registerImageGenerationProvider(record, provider)
|
||||
: () => {},
|
||||
registerVideoGenerationProvider:
|
||||
registrationMode === "full"
|
||||
? (provider) => registerVideoGenerationProvider(record, provider)
|
||||
: () => {},
|
||||
registerWebSearchProvider:
|
||||
registrationMode === "full"
|
||||
? (provider) => registerWebSearchProvider(record, provider)
|
||||
|
||||
@@ -47,7 +47,6 @@ export function createPluginRecord(
|
||||
speechProviderIds: [],
|
||||
mediaUnderstandingProviderIds: [],
|
||||
imageGenerationProviderIds: [],
|
||||
videoGenerationProviderIds: [],
|
||||
webSearchProviderIds: [],
|
||||
gatewayMethods: [],
|
||||
cliCommands: [],
|
||||
@@ -111,7 +110,6 @@ export function createPluginLoadResult(
|
||||
speechProviders: [],
|
||||
mediaUnderstandingProviders: [],
|
||||
imageGenerationProviders: [],
|
||||
videoGenerationProviders: [],
|
||||
webSearchProviders: [],
|
||||
tools: [],
|
||||
hooks: [],
|
||||
|
||||
@@ -1,4 +1,13 @@
|
||||
import { beforeEach, describe, expect, it, vi } from "vitest";
|
||||
import {
|
||||
createCompatibilityNotice,
|
||||
createCustomHook,
|
||||
createPluginLoadResult,
|
||||
createPluginRecord,
|
||||
createTypedHook,
|
||||
HOOK_ONLY_MESSAGE,
|
||||
LEGACY_BEFORE_AGENT_START_MESSAGE,
|
||||
} from "./status.test-helpers.js";
|
||||
|
||||
const loadConfigMock = vi.fn();
|
||||
const loadOpenClawPluginsMock = vi.fn();
|
||||
@@ -27,32 +36,22 @@ vi.mock("../agents/workspace.js", () => ({
|
||||
resolveDefaultAgentWorkspaceDir: () => "/default-workspace",
|
||||
}));
|
||||
|
||||
function setPluginLoadResult(overrides: Partial<ReturnType<typeof createPluginLoadResult>>) {
|
||||
loadOpenClawPluginsMock.mockReturnValue(
|
||||
createPluginLoadResult({
|
||||
plugins: [],
|
||||
...overrides,
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
describe("buildPluginStatusReport", () => {
|
||||
beforeEach(async () => {
|
||||
vi.resetModules();
|
||||
loadConfigMock.mockReset();
|
||||
loadOpenClawPluginsMock.mockReset();
|
||||
loadConfigMock.mockReturnValue({});
|
||||
loadOpenClawPluginsMock.mockReturnValue({
|
||||
plugins: [],
|
||||
diagnostics: [],
|
||||
channels: [],
|
||||
providers: [],
|
||||
speechProviders: [],
|
||||
mediaUnderstandingProviders: [],
|
||||
imageGenerationProviders: [],
|
||||
videoGenerationProviders: [],
|
||||
webSearchProviders: [],
|
||||
tools: [],
|
||||
hooks: [],
|
||||
typedHooks: [],
|
||||
channelSetups: [],
|
||||
httpRoutes: [],
|
||||
gatewayHandlers: {},
|
||||
cliRegistrars: [],
|
||||
services: [],
|
||||
commands: [],
|
||||
});
|
||||
setPluginLoadResult({ plugins: [] });
|
||||
({
|
||||
buildAllPluginInspectReports,
|
||||
buildPluginCompatibilityNotices,
|
||||
@@ -83,52 +82,17 @@ describe("buildPluginStatusReport", () => {
|
||||
});
|
||||
|
||||
it("normalizes bundled plugin versions to the core base release", () => {
|
||||
loadOpenClawPluginsMock.mockReturnValue({
|
||||
setPluginLoadResult({
|
||||
plugins: [
|
||||
{
|
||||
createPluginRecord({
|
||||
id: "whatsapp",
|
||||
name: "WhatsApp",
|
||||
description: "Bundled channel plugin",
|
||||
version: "2026.3.22",
|
||||
source: "/tmp/whatsapp/index.ts",
|
||||
origin: "bundled",
|
||||
enabled: true,
|
||||
status: "loaded",
|
||||
toolNames: [],
|
||||
hookNames: [],
|
||||
channelIds: ["whatsapp"],
|
||||
providerIds: [],
|
||||
speechProviderIds: [],
|
||||
mediaUnderstandingProviderIds: [],
|
||||
imageGenerationProviderIds: [],
|
||||
videoGenerationProviderIds: [],
|
||||
webSearchProviderIds: [],
|
||||
gatewayMethods: [],
|
||||
cliCommands: [],
|
||||
services: [],
|
||||
commands: [],
|
||||
httpRoutes: 0,
|
||||
hookCount: 0,
|
||||
configSchema: false,
|
||||
},
|
||||
}),
|
||||
],
|
||||
diagnostics: [],
|
||||
channels: [],
|
||||
providers: [],
|
||||
speechProviders: [],
|
||||
mediaUnderstandingProviders: [],
|
||||
imageGenerationProviders: [],
|
||||
videoGenerationProviders: [],
|
||||
webSearchProviders: [],
|
||||
tools: [],
|
||||
hooks: [],
|
||||
typedHooks: [],
|
||||
channelSetups: [],
|
||||
httpRoutes: [],
|
||||
gatewayHandlers: {},
|
||||
cliRegistrars: [],
|
||||
services: [],
|
||||
commands: [],
|
||||
});
|
||||
|
||||
const report = buildPluginStatusReport({
|
||||
@@ -155,58 +119,21 @@ describe("buildPluginStatusReport", () => {
|
||||
},
|
||||
},
|
||||
});
|
||||
loadOpenClawPluginsMock.mockReturnValue({
|
||||
setPluginLoadResult({
|
||||
plugins: [
|
||||
{
|
||||
createPluginRecord({
|
||||
id: "google",
|
||||
name: "Google",
|
||||
description: "Google provider plugin",
|
||||
source: "/tmp/google/index.ts",
|
||||
origin: "bundled",
|
||||
enabled: true,
|
||||
status: "loaded",
|
||||
toolNames: [],
|
||||
hookNames: [],
|
||||
channelIds: [],
|
||||
providerIds: ["google"],
|
||||
speechProviderIds: [],
|
||||
mediaUnderstandingProviderIds: ["google"],
|
||||
imageGenerationProviderIds: ["google"],
|
||||
videoGenerationProviderIds: [],
|
||||
webSearchProviderIds: ["google"],
|
||||
gatewayMethods: [],
|
||||
cliCommands: [],
|
||||
services: [],
|
||||
commands: [],
|
||||
httpRoutes: 0,
|
||||
hookCount: 0,
|
||||
configSchema: false,
|
||||
},
|
||||
}),
|
||||
],
|
||||
diagnostics: [{ level: "warn", pluginId: "google", message: "watch this surface" }],
|
||||
channels: [],
|
||||
channelSetups: [],
|
||||
providers: [],
|
||||
speechProviders: [],
|
||||
mediaUnderstandingProviders: [],
|
||||
imageGenerationProviders: [],
|
||||
videoGenerationProviders: [],
|
||||
webSearchProviders: [],
|
||||
tools: [],
|
||||
hooks: [],
|
||||
typedHooks: [
|
||||
{
|
||||
pluginId: "google",
|
||||
hookName: "before_agent_start",
|
||||
handler: () => undefined,
|
||||
source: "/tmp/google/index.ts",
|
||||
},
|
||||
],
|
||||
httpRoutes: [],
|
||||
gatewayHandlers: {},
|
||||
cliRegistrars: [],
|
||||
services: [],
|
||||
commands: [],
|
||||
typedHooks: [createTypedHook({ pluginId: "google", hookName: "before_agent_start" })],
|
||||
});
|
||||
|
||||
const inspect = buildPluginInspectReport({ id: "google" });
|
||||
@@ -222,13 +149,7 @@ describe("buildPluginStatusReport", () => {
|
||||
]);
|
||||
expect(inspect?.usesLegacyBeforeAgentStart).toBe(true);
|
||||
expect(inspect?.compatibility).toEqual([
|
||||
{
|
||||
pluginId: "google",
|
||||
code: "legacy-before-agent-start",
|
||||
severity: "warn",
|
||||
message:
|
||||
"still uses legacy before_agent_start; keep regression coverage on this plugin, and prefer before_model_resolve/before_prompt_build for new work.",
|
||||
},
|
||||
createCompatibilityNotice({ pluginId: "google", code: "legacy-before-agent-start" }),
|
||||
]);
|
||||
expect(inspect?.policy).toEqual({
|
||||
allowPromptInjection: false,
|
||||
@@ -242,94 +163,25 @@ describe("buildPluginStatusReport", () => {
|
||||
});
|
||||
|
||||
it("builds inspect reports for every loaded plugin", () => {
|
||||
loadOpenClawPluginsMock.mockReturnValue({
|
||||
setPluginLoadResult({
|
||||
plugins: [
|
||||
{
|
||||
createPluginRecord({
|
||||
id: "lca",
|
||||
name: "LCA",
|
||||
description: "Legacy hook plugin",
|
||||
source: "/tmp/lca/index.ts",
|
||||
origin: "workspace",
|
||||
enabled: true,
|
||||
status: "loaded",
|
||||
toolNames: [],
|
||||
hookNames: [],
|
||||
channelIds: [],
|
||||
providerIds: [],
|
||||
speechProviderIds: [],
|
||||
mediaUnderstandingProviderIds: [],
|
||||
imageGenerationProviderIds: [],
|
||||
videoGenerationProviderIds: [],
|
||||
webSearchProviderIds: [],
|
||||
gatewayMethods: [],
|
||||
cliCommands: [],
|
||||
services: [],
|
||||
commands: [],
|
||||
httpRoutes: 0,
|
||||
hookCount: 1,
|
||||
configSchema: false,
|
||||
},
|
||||
{
|
||||
}),
|
||||
createPluginRecord({
|
||||
id: "microsoft",
|
||||
name: "Microsoft",
|
||||
description: "Hybrid capability plugin",
|
||||
source: "/tmp/microsoft/index.ts",
|
||||
origin: "bundled",
|
||||
enabled: true,
|
||||
status: "loaded",
|
||||
toolNames: [],
|
||||
hookNames: [],
|
||||
channelIds: [],
|
||||
providerIds: ["microsoft"],
|
||||
speechProviderIds: [],
|
||||
mediaUnderstandingProviderIds: [],
|
||||
imageGenerationProviderIds: [],
|
||||
videoGenerationProviderIds: [],
|
||||
webSearchProviderIds: ["microsoft"],
|
||||
gatewayMethods: [],
|
||||
cliCommands: [],
|
||||
services: [],
|
||||
commands: [],
|
||||
httpRoutes: 0,
|
||||
hookCount: 0,
|
||||
configSchema: false,
|
||||
},
|
||||
}),
|
||||
],
|
||||
diagnostics: [],
|
||||
channels: [],
|
||||
channelSetups: [],
|
||||
providers: [],
|
||||
speechProviders: [],
|
||||
mediaUnderstandingProviders: [],
|
||||
imageGenerationProviders: [],
|
||||
videoGenerationProviders: [],
|
||||
webSearchProviders: [],
|
||||
tools: [],
|
||||
hooks: [
|
||||
{
|
||||
pluginId: "lca",
|
||||
events: ["message"],
|
||||
entry: {
|
||||
hook: {
|
||||
name: "legacy",
|
||||
handler: () => undefined,
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
typedHooks: [
|
||||
{
|
||||
pluginId: "lca",
|
||||
hookName: "before_agent_start",
|
||||
handler: () => undefined,
|
||||
source: "/tmp/lca/index.ts",
|
||||
},
|
||||
],
|
||||
httpRoutes: [],
|
||||
gatewayHandlers: {},
|
||||
cliRegistrars: [],
|
||||
services: [],
|
||||
commands: [],
|
||||
hooks: [createCustomHook({ pluginId: "lca", events: ["message"] })],
|
||||
typedHooks: [createTypedHook({ pluginId: "lca", hookName: "before_agent_start" })],
|
||||
});
|
||||
|
||||
const inspect = buildAllPluginInspectReports();
|
||||
@@ -344,221 +196,58 @@ describe("buildPluginStatusReport", () => {
|
||||
});
|
||||
|
||||
it("builds compatibility warnings for legacy compatibility paths", () => {
|
||||
loadOpenClawPluginsMock.mockReturnValue({
|
||||
setPluginLoadResult({
|
||||
plugins: [
|
||||
{
|
||||
createPluginRecord({
|
||||
id: "lca",
|
||||
name: "LCA",
|
||||
description: "Legacy hook plugin",
|
||||
source: "/tmp/lca/index.ts",
|
||||
origin: "workspace",
|
||||
enabled: true,
|
||||
status: "loaded",
|
||||
toolNames: [],
|
||||
hookNames: [],
|
||||
channelIds: [],
|
||||
providerIds: [],
|
||||
speechProviderIds: [],
|
||||
mediaUnderstandingProviderIds: [],
|
||||
imageGenerationProviderIds: [],
|
||||
videoGenerationProviderIds: [],
|
||||
webSearchProviderIds: [],
|
||||
gatewayMethods: [],
|
||||
cliCommands: [],
|
||||
services: [],
|
||||
commands: [],
|
||||
httpRoutes: 0,
|
||||
hookCount: 1,
|
||||
configSchema: false,
|
||||
},
|
||||
}),
|
||||
],
|
||||
diagnostics: [],
|
||||
channels: [],
|
||||
channelSetups: [],
|
||||
providers: [],
|
||||
speechProviders: [],
|
||||
mediaUnderstandingProviders: [],
|
||||
imageGenerationProviders: [],
|
||||
videoGenerationProviders: [],
|
||||
webSearchProviders: [],
|
||||
tools: [],
|
||||
hooks: [],
|
||||
typedHooks: [
|
||||
{
|
||||
pluginId: "lca",
|
||||
hookName: "before_agent_start",
|
||||
handler: () => undefined,
|
||||
source: "/tmp/lca/index.ts",
|
||||
},
|
||||
],
|
||||
httpRoutes: [],
|
||||
gatewayHandlers: {},
|
||||
cliRegistrars: [],
|
||||
services: [],
|
||||
commands: [],
|
||||
typedHooks: [createTypedHook({ pluginId: "lca", hookName: "before_agent_start" })],
|
||||
});
|
||||
|
||||
expect(buildPluginCompatibilityWarnings()).toEqual([
|
||||
"lca still uses legacy before_agent_start; keep regression coverage on this plugin, and prefer before_model_resolve/before_prompt_build for new work.",
|
||||
"lca is hook-only. This remains a supported compatibility path, but it has not migrated to explicit capability registration yet.",
|
||||
`lca ${LEGACY_BEFORE_AGENT_START_MESSAGE}`,
|
||||
`lca ${HOOK_ONLY_MESSAGE}`,
|
||||
]);
|
||||
});
|
||||
|
||||
it("builds structured compatibility notices with deterministic ordering", () => {
|
||||
loadOpenClawPluginsMock.mockReturnValue({
|
||||
setPluginLoadResult({
|
||||
plugins: [
|
||||
{
|
||||
createPluginRecord({
|
||||
id: "hook-only",
|
||||
name: "Hook Only",
|
||||
description: "",
|
||||
source: "/tmp/hook-only/index.ts",
|
||||
origin: "workspace",
|
||||
enabled: true,
|
||||
status: "loaded",
|
||||
toolNames: [],
|
||||
hookNames: [],
|
||||
channelIds: [],
|
||||
providerIds: [],
|
||||
speechProviderIds: [],
|
||||
mediaUnderstandingProviderIds: [],
|
||||
imageGenerationProviderIds: [],
|
||||
videoGenerationProviderIds: [],
|
||||
webSearchProviderIds: [],
|
||||
gatewayMethods: [],
|
||||
cliCommands: [],
|
||||
services: [],
|
||||
commands: [],
|
||||
httpRoutes: 0,
|
||||
hookCount: 1,
|
||||
configSchema: false,
|
||||
},
|
||||
{
|
||||
}),
|
||||
createPluginRecord({
|
||||
id: "legacy-only",
|
||||
name: "Legacy Only",
|
||||
description: "",
|
||||
source: "/tmp/legacy-only/index.ts",
|
||||
origin: "workspace",
|
||||
enabled: true,
|
||||
status: "loaded",
|
||||
toolNames: [],
|
||||
hookNames: [],
|
||||
channelIds: [],
|
||||
providerIds: ["legacy-only"],
|
||||
speechProviderIds: [],
|
||||
mediaUnderstandingProviderIds: [],
|
||||
imageGenerationProviderIds: [],
|
||||
videoGenerationProviderIds: [],
|
||||
webSearchProviderIds: [],
|
||||
gatewayMethods: [],
|
||||
cliCommands: [],
|
||||
services: [],
|
||||
commands: [],
|
||||
httpRoutes: 0,
|
||||
hookCount: 1,
|
||||
configSchema: false,
|
||||
},
|
||||
}),
|
||||
],
|
||||
diagnostics: [],
|
||||
channels: [],
|
||||
channelSetups: [],
|
||||
providers: [],
|
||||
speechProviders: [],
|
||||
mediaUnderstandingProviders: [],
|
||||
imageGenerationProviders: [],
|
||||
videoGenerationProviders: [],
|
||||
webSearchProviders: [],
|
||||
tools: [],
|
||||
hooks: [
|
||||
{
|
||||
pluginId: "hook-only",
|
||||
events: ["message"],
|
||||
entry: {
|
||||
hook: {
|
||||
name: "legacy",
|
||||
handler: () => undefined,
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
typedHooks: [
|
||||
{
|
||||
pluginId: "legacy-only",
|
||||
hookName: "before_agent_start",
|
||||
handler: () => undefined,
|
||||
source: "/tmp/legacy-only/index.ts",
|
||||
},
|
||||
],
|
||||
httpRoutes: [],
|
||||
gatewayHandlers: {},
|
||||
cliRegistrars: [],
|
||||
services: [],
|
||||
commands: [],
|
||||
hooks: [createCustomHook({ pluginId: "hook-only", events: ["message"] })],
|
||||
typedHooks: [createTypedHook({ pluginId: "legacy-only", hookName: "before_agent_start" })],
|
||||
});
|
||||
|
||||
expect(buildPluginCompatibilityNotices()).toEqual([
|
||||
{
|
||||
pluginId: "hook-only",
|
||||
code: "hook-only",
|
||||
severity: "info",
|
||||
message:
|
||||
"is hook-only. This remains a supported compatibility path, but it has not migrated to explicit capability registration yet.",
|
||||
},
|
||||
{
|
||||
pluginId: "legacy-only",
|
||||
code: "legacy-before-agent-start",
|
||||
severity: "warn",
|
||||
message:
|
||||
"still uses legacy before_agent_start; keep regression coverage on this plugin, and prefer before_model_resolve/before_prompt_build for new work.",
|
||||
},
|
||||
createCompatibilityNotice({ pluginId: "hook-only", code: "hook-only" }),
|
||||
createCompatibilityNotice({ pluginId: "legacy-only", code: "legacy-before-agent-start" }),
|
||||
]);
|
||||
});
|
||||
|
||||
it("returns no compatibility warnings for modern capability plugins", () => {
|
||||
loadOpenClawPluginsMock.mockReturnValue({
|
||||
setPluginLoadResult({
|
||||
plugins: [
|
||||
{
|
||||
createPluginRecord({
|
||||
id: "modern",
|
||||
name: "Modern",
|
||||
description: "",
|
||||
source: "/tmp/modern/index.ts",
|
||||
origin: "workspace",
|
||||
enabled: true,
|
||||
status: "loaded",
|
||||
toolNames: [],
|
||||
hookNames: [],
|
||||
channelIds: [],
|
||||
providerIds: ["modern"],
|
||||
speechProviderIds: [],
|
||||
mediaUnderstandingProviderIds: [],
|
||||
imageGenerationProviderIds: [],
|
||||
videoGenerationProviderIds: [],
|
||||
webSearchProviderIds: [],
|
||||
gatewayMethods: [],
|
||||
cliCommands: [],
|
||||
services: [],
|
||||
commands: [],
|
||||
httpRoutes: 0,
|
||||
hookCount: 0,
|
||||
configSchema: false,
|
||||
},
|
||||
}),
|
||||
],
|
||||
diagnostics: [],
|
||||
channels: [],
|
||||
channelSetups: [],
|
||||
providers: [],
|
||||
speechProviders: [],
|
||||
mediaUnderstandingProviders: [],
|
||||
imageGenerationProviders: [],
|
||||
videoGenerationProviders: [],
|
||||
webSearchProviders: [],
|
||||
tools: [],
|
||||
hooks: [],
|
||||
typedHooks: [],
|
||||
httpRoutes: [],
|
||||
gatewayHandlers: {},
|
||||
cliRegistrars: [],
|
||||
services: [],
|
||||
commands: [],
|
||||
});
|
||||
|
||||
expect(buildPluginCompatibilityNotices()).toEqual([]);
|
||||
@@ -566,55 +255,19 @@ describe("buildPluginStatusReport", () => {
|
||||
});
|
||||
|
||||
it("populates bundleCapabilities from plugin record", () => {
|
||||
loadOpenClawPluginsMock.mockReturnValue({
|
||||
setPluginLoadResult({
|
||||
plugins: [
|
||||
{
|
||||
createPluginRecord({
|
||||
id: "claude-bundle",
|
||||
name: "Claude Bundle",
|
||||
description: "A bundle plugin with skills and commands",
|
||||
source: "/tmp/claude-bundle/.claude-plugin/plugin.json",
|
||||
origin: "workspace",
|
||||
enabled: true,
|
||||
status: "loaded",
|
||||
format: "bundle",
|
||||
bundleFormat: "claude",
|
||||
bundleCapabilities: ["skills", "commands", "agents", "settings"],
|
||||
rootDir: "/tmp/claude-bundle",
|
||||
toolNames: [],
|
||||
hookNames: [],
|
||||
channelIds: [],
|
||||
providerIds: [],
|
||||
speechProviderIds: [],
|
||||
mediaUnderstandingProviderIds: [],
|
||||
imageGenerationProviderIds: [],
|
||||
videoGenerationProviderIds: [],
|
||||
webSearchProviderIds: [],
|
||||
gatewayMethods: [],
|
||||
cliCommands: [],
|
||||
services: [],
|
||||
commands: [],
|
||||
httpRoutes: 0,
|
||||
hookCount: 0,
|
||||
configSchema: false,
|
||||
},
|
||||
}),
|
||||
],
|
||||
diagnostics: [],
|
||||
channels: [],
|
||||
channelSetups: [],
|
||||
providers: [],
|
||||
speechProviders: [],
|
||||
mediaUnderstandingProviders: [],
|
||||
imageGenerationProviders: [],
|
||||
videoGenerationProviders: [],
|
||||
webSearchProviders: [],
|
||||
tools: [],
|
||||
hooks: [],
|
||||
typedHooks: [],
|
||||
httpRoutes: [],
|
||||
gatewayHandlers: {},
|
||||
cliRegistrars: [],
|
||||
services: [],
|
||||
commands: [],
|
||||
});
|
||||
|
||||
const inspect = buildPluginInspectReport({ id: "claude-bundle" });
|
||||
@@ -626,51 +279,15 @@ describe("buildPluginStatusReport", () => {
|
||||
});
|
||||
|
||||
it("returns empty bundleCapabilities and mcpServers for non-bundle plugins", () => {
|
||||
loadOpenClawPluginsMock.mockReturnValue({
|
||||
setPluginLoadResult({
|
||||
plugins: [
|
||||
{
|
||||
createPluginRecord({
|
||||
id: "plain-plugin",
|
||||
name: "Plain Plugin",
|
||||
description: "A regular plugin",
|
||||
source: "/tmp/plain-plugin/index.ts",
|
||||
origin: "workspace",
|
||||
enabled: true,
|
||||
status: "loaded",
|
||||
toolNames: [],
|
||||
hookNames: [],
|
||||
channelIds: [],
|
||||
providerIds: ["plain"],
|
||||
speechProviderIds: [],
|
||||
mediaUnderstandingProviderIds: [],
|
||||
imageGenerationProviderIds: [],
|
||||
videoGenerationProviderIds: [],
|
||||
webSearchProviderIds: [],
|
||||
gatewayMethods: [],
|
||||
cliCommands: [],
|
||||
services: [],
|
||||
commands: [],
|
||||
httpRoutes: 0,
|
||||
hookCount: 0,
|
||||
configSchema: false,
|
||||
},
|
||||
}),
|
||||
],
|
||||
diagnostics: [],
|
||||
channels: [],
|
||||
channelSetups: [],
|
||||
providers: [],
|
||||
speechProviders: [],
|
||||
mediaUnderstandingProviders: [],
|
||||
imageGenerationProviders: [],
|
||||
videoGenerationProviders: [],
|
||||
webSearchProviders: [],
|
||||
tools: [],
|
||||
hooks: [],
|
||||
typedHooks: [],
|
||||
httpRoutes: [],
|
||||
gatewayHandlers: {},
|
||||
cliRegistrars: [],
|
||||
services: [],
|
||||
commands: [],
|
||||
});
|
||||
|
||||
const inspect = buildPluginInspectReport({ id: "plain-plugin" });
|
||||
@@ -681,27 +298,18 @@ describe("buildPluginStatusReport", () => {
|
||||
});
|
||||
|
||||
it("formats and summarizes compatibility notices", () => {
|
||||
const notice = {
|
||||
const notice = createCompatibilityNotice({
|
||||
pluginId: "legacy-plugin",
|
||||
code: "legacy-before-agent-start" as const,
|
||||
severity: "warn" as const,
|
||||
message:
|
||||
"still uses legacy before_agent_start; keep regression coverage on this plugin, and prefer before_model_resolve/before_prompt_build for new work.",
|
||||
};
|
||||
code: "legacy-before-agent-start",
|
||||
});
|
||||
|
||||
expect(formatPluginCompatibilityNotice(notice)).toBe(
|
||||
"legacy-plugin still uses legacy before_agent_start; keep regression coverage on this plugin, and prefer before_model_resolve/before_prompt_build for new work.",
|
||||
`legacy-plugin ${LEGACY_BEFORE_AGENT_START_MESSAGE}`,
|
||||
);
|
||||
expect(
|
||||
summarizePluginCompatibility([
|
||||
notice,
|
||||
{
|
||||
pluginId: "legacy-plugin",
|
||||
code: "hook-only",
|
||||
severity: "info",
|
||||
message:
|
||||
"is hook-only. This remains a supported compatibility path, but it has not migrated to explicit capability registration yet.",
|
||||
},
|
||||
createCompatibilityNotice({ pluginId: "legacy-plugin", code: "hook-only" }),
|
||||
]),
|
||||
).toEqual({
|
||||
noticeCount: 2,
|
||||
|
||||
@@ -21,7 +21,6 @@ export type PluginCapabilityKind =
|
||||
| "speech"
|
||||
| "media-understanding"
|
||||
| "image-generation"
|
||||
| "video-generation"
|
||||
| "web-search"
|
||||
| "channel";
|
||||
|
||||
@@ -166,7 +165,6 @@ function buildCapabilityEntries(plugin: PluginRegistry["plugins"][number]) {
|
||||
{ kind: "speech" as const, ids: plugin.speechProviderIds },
|
||||
{ kind: "media-understanding" as const, ids: plugin.mediaUnderstandingProviderIds },
|
||||
{ kind: "image-generation" as const, ids: plugin.imageGenerationProviderIds },
|
||||
{ kind: "video-generation" as const, ids: plugin.videoGenerationProviderIds },
|
||||
{ kind: "web-search" as const, ids: plugin.webSearchProviderIds },
|
||||
{ kind: "channel" as const, ids: plugin.channelIds },
|
||||
].filter((entry) => entry.ids.length > 0);
|
||||
|
||||
@@ -40,7 +40,6 @@ import type {
|
||||
SpeechTelephonySynthesisResult,
|
||||
SpeechVoiceOption,
|
||||
} from "../tts/provider-types.js";
|
||||
import type { VideoGenerationProvider } from "../video-generation/types.js";
|
||||
import type { WizardPrompter } from "../wizard/prompts.js";
|
||||
import type { SecretInputMode } from "./provider-auth-types.js";
|
||||
import type { createVpsAwareOAuthHandlers } from "./provider-oauth-flow.js";
|
||||
@@ -951,7 +950,6 @@ export type PluginSpeechProviderEntry = SpeechProviderPlugin & {
|
||||
|
||||
export type MediaUnderstandingProviderPlugin = MediaUnderstandingProvider;
|
||||
export type ImageGenerationProviderPlugin = ImageGenerationProvider;
|
||||
export type VideoGenerationProviderPlugin = VideoGenerationProvider;
|
||||
|
||||
export type OpenClawPluginGatewayMethod = {
|
||||
method: string;
|
||||
@@ -1354,8 +1352,6 @@ export type OpenClawPluginApi = {
|
||||
registerMediaUnderstandingProvider: (provider: MediaUnderstandingProviderPlugin) => void;
|
||||
/** Register an image generation provider (image generation capability). */
|
||||
registerImageGenerationProvider: (provider: ImageGenerationProviderPlugin) => void;
|
||||
/** Register a video generation provider (video generation capability). */
|
||||
registerVideoGenerationProvider: (provider: VideoGenerationProviderPlugin) => void;
|
||||
/** Register a web search provider (web search capability). */
|
||||
registerWebSearchProvider: (provider: WebSearchProviderPlugin) => void;
|
||||
registerInteractiveHandler: (registration: PluginInteractiveHandlerRegistration) => void;
|
||||
|
||||
Reference in New Issue
Block a user