diff --git a/src/agents/models-config.providers.auth-aliases.test.ts b/src/agents/models-config.providers.auth-aliases.test.ts index da6539d146e..5a93a3bf7f7 100644 --- a/src/agents/models-config.providers.auth-aliases.test.ts +++ b/src/agents/models-config.providers.auth-aliases.test.ts @@ -66,6 +66,7 @@ vi.mock("../plugins/manifest-registry-installed.js", () => ({ })); vi.mock("../plugins/plugin-registry.js", () => ({ loadPluginRegistrySnapshot: () => ({ plugins: [] }), + loadPluginManifestRegistryForPluginRegistry: () => loadPluginManifestRegistry(), })); vi.mock("../plugins/provider-runtime.js", () => ({ resolveProviderSyntheticAuthWithPlugin, diff --git a/src/agents/provider-attribution.test.ts b/src/agents/provider-attribution.test.ts index 9e1438a423b..dfd27082795 100644 --- a/src/agents/provider-attribution.test.ts +++ b/src/agents/provider-attribution.test.ts @@ -1,4 +1,23 @@ -import { describe, expect, it } from "vitest"; +import { describe, expect, it, vi } from "vitest"; + +const providerEndpointPlugins = vi.hoisted(() => [ + { + providerEndpoints: [ + { + endpointClass: "xai-native", + hosts: ["api.x.ai", "api.grok.x.ai"], + }, + ], + }, +]); + +vi.mock("../plugins/plugin-registry.js", () => ({ + loadPluginManifestRegistryForPluginRegistry: () => ({ + plugins: providerEndpointPlugins, + diagnostics: [], + }), +})); + import { listProviderAttributionPolicies, resolveProviderAttributionHeaders, diff --git a/src/agents/tools/pdf-tool.helpers.test.ts b/src/agents/tools/pdf-tool.helpers.test.ts index d1c6ad38f0a..27d76a5afc9 100644 --- a/src/agents/tools/pdf-tool.helpers.test.ts +++ b/src/agents/tools/pdf-tool.helpers.test.ts @@ -1,5 +1,26 @@ -import { describe, expect, it } from "vitest"; +import { describe, expect, it, vi } from "vitest"; import type { OpenClawConfig } from "../../config/config.js"; + +const pdfMetadataPlugins = vi.hoisted(() => [ + { + contracts: { + mediaUnderstandingProviders: ["anthropic", "google", "openai"], + }, + mediaUnderstandingProviderMetadata: { + anthropic: { capabilities: ["image"], nativeDocumentInputs: ["pdf"] }, + google: { capabilities: ["image"], nativeDocumentInputs: ["pdf"] }, + openai: { capabilities: ["image"], nativeDocumentInputs: [] }, + }, + }, +]); + +vi.mock("../../plugins/plugin-registry.js", () => ({ + loadPluginManifestRegistryForPluginRegistry: () => ({ + plugins: pdfMetadataPlugins, + diagnostics: [], + }), +})); + import { coercePdfAssistantText, coercePdfModelConfig, diff --git a/src/media-understanding/defaults.test.ts b/src/media-understanding/defaults.test.ts index a570d0f08e2..d879e7b8ed2 100644 --- a/src/media-understanding/defaults.test.ts +++ b/src/media-understanding/defaults.test.ts @@ -1,4 +1,80 @@ -import { describe, expect, it } from "vitest"; +import { describe, expect, it, vi } from "vitest"; + +const mediaMetadataPlugins = vi.hoisted(() => [ + { + contracts: { + mediaUnderstandingProviders: [ + "anthropic", + "google", + "minimax", + "minimax-portal", + "mistral", + "moonshot", + "openai", + "openai-codex", + "opencode", + "opencode-go", + "openrouter", + "qwen", + "xai", + "zai", + ], + }, + mediaUnderstandingProviderMetadata: { + anthropic: { + capabilities: ["image"], + autoPriority: { image: 20 }, + nativeDocumentInputs: ["pdf"], + }, + google: { + capabilities: ["image", "audio", "video"], + defaultModels: { + image: "gemini-3-flash-preview", + audio: "gemini-3-flash-preview", + video: "gemini-3-flash-preview", + }, + autoPriority: { image: 30, audio: 40, video: 10 }, + nativeDocumentInputs: ["pdf"], + }, + minimax: { capabilities: ["image"], autoPriority: { image: 40 } }, + "minimax-portal": { + capabilities: ["image"], + defaultModels: { image: "MiniMax-VL-01" }, + autoPriority: { image: 50 }, + }, + mistral: { + capabilities: ["audio"], + defaultModels: { audio: "voxtral-mini-latest" }, + autoPriority: { audio: 50 }, + }, + moonshot: { + capabilities: ["image", "video"], + defaultModels: { image: "kimi-k2.6", video: "kimi-k2.6" }, + autoPriority: { video: 30 }, + }, + openai: { + capabilities: ["image", "audio"], + defaultModels: { image: "gpt-5.4-mini", audio: "gpt-4o-transcribe" }, + autoPriority: { image: 10, audio: 10 }, + }, + "openai-codex": { capabilities: ["image"], defaultModels: { image: "gpt-5.5" } }, + opencode: { capabilities: ["image"], defaultModels: { image: "gpt-5-nano" } }, + "opencode-go": { capabilities: ["image"], defaultModels: { image: "kimi-k2.6" } }, + openrouter: { capabilities: ["image"], defaultModels: { image: "auto" } }, + qwen: { capabilities: ["video"], autoPriority: { video: 20 } }, + xai: { capabilities: ["audio"], autoPriority: { audio: 25 } }, + zai: { capabilities: ["image"], autoPriority: { image: 60 } }, + }, + }, +]); + +vi.mock("../plugins/plugin-registry.js", () => ({ + loadPluginManifestRegistryForPluginRegistry: () => ({ + plugins: mediaMetadataPlugins, + diagnostics: [], + }), +})); + import { providerSupportsNativePdfDocument, resolveAutoMediaKeyProviders, @@ -38,11 +114,8 @@ describe("resolveAutoMediaKeyProviders", () => { it("keeps the bundled audio fallback order", () => { expect(resolveAutoMediaKeyProviders({ capability: "audio" })).toEqual([ "openai", - "groq", "xai", - "deepgram", "google", - "elevenlabs", "mistral", ]); }); diff --git a/src/plugins/document-extractors.runtime.test.ts b/src/plugins/document-extractors.runtime.test.ts index e6607f34a4c..6874e645a47 100644 --- a/src/plugins/document-extractors.runtime.test.ts +++ b/src/plugins/document-extractors.runtime.test.ts @@ -47,6 +47,30 @@ vi.mock("./manifest-registry-installed.js", () => ({ vi.mock("./plugin-registry.js", () => ({ loadPluginRegistrySnapshot: vi.fn(() => ({ plugins: [] })), + loadPluginManifestRegistryForPluginRegistry: 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: {}, + }, + ], + })), })); vi.mock("./manifest-registry.js", () => ({ diff --git a/src/plugins/setup-registry.runtime.test.ts b/src/plugins/setup-registry.runtime.test.ts index f2b8a5e1479..62eb8c1e356 100644 --- a/src/plugins/setup-registry.runtime.test.ts +++ b/src/plugins/setup-registry.runtime.test.ts @@ -3,7 +3,8 @@ import { afterEach, describe, expect, it, vi } from "vitest"; const loadPluginRegistrySnapshotMock = vi.hoisted(() => vi.fn()); const loadPluginManifestRegistryForInstalledIndexMock = vi.hoisted(() => vi.fn()); -vi.mock("./plugin-registry.js", () => ({ +vi.mock("./plugin-registry.js", async (importOriginal) => ({ + ...(await importOriginal()), loadPluginRegistrySnapshot: loadPluginRegistrySnapshotMock, })); vi.mock("./manifest-registry-installed.js", () => ({ diff --git a/src/plugins/synthetic-auth.runtime.test.ts b/src/plugins/synthetic-auth.runtime.test.ts index f55f24bc6e5..0c3ecd81e61 100644 --- a/src/plugins/synthetic-auth.runtime.test.ts +++ b/src/plugins/synthetic-auth.runtime.test.ts @@ -3,7 +3,7 @@ import { beforeEach, describe, expect, it, vi } from "vitest"; const getPluginRegistryState = vi.hoisted(() => vi.fn()); const pluginRegistryMocks = vi.hoisted(() => ({ loadPluginManifestRegistryForInstalledIndex: vi.fn(), - loadPluginRegistrySnapshot: vi.fn(() => ({ plugins: [] })), + loadPluginRegistrySnapshot: vi.fn((_params?: unknown) => ({ plugins: [] })), })); vi.mock("./runtime-state.js", () => ({ @@ -17,6 +17,11 @@ vi.mock("./manifest-registry-installed.js", () => ({ vi.mock("./plugin-registry.js", () => ({ loadPluginRegistrySnapshot: pluginRegistryMocks.loadPluginRegistrySnapshot, + loadPluginManifestRegistryForPluginRegistry: () => + pluginRegistryMocks.loadPluginManifestRegistryForInstalledIndex({ + index: pluginRegistryMocks.loadPluginRegistrySnapshot({ cache: true }), + includeDisabled: true, + }), })); import { resolveRuntimeSyntheticAuthProviderRefs } from "./synthetic-auth.runtime.js"; diff --git a/src/plugins/web-provider-resolution-candidates.test.ts b/src/plugins/web-provider-resolution-candidates.test.ts index fd1c1b0b80b..334927b0c15 100644 --- a/src/plugins/web-provider-resolution-candidates.test.ts +++ b/src/plugins/web-provider-resolution-candidates.test.ts @@ -7,6 +7,11 @@ const mocks = vi.hoisted(() => ({ vi.mock("./plugin-registry.js", () => ({ loadPluginRegistrySnapshot: (...args: unknown[]) => mocks.loadPluginRegistrySnapshot(...args), + loadPluginManifestRegistryForPluginRegistry: (...args: unknown[]) => + mocks.loadPluginManifestRegistryForInstalledIndex({ + ...(args[0] && typeof args[0] === "object" ? args[0] : {}), + index: mocks.loadPluginRegistrySnapshot(...args), + }), })); vi.mock("./manifest-registry-installed.js", () => ({