





















@@ -1,88 +1,53 @@
1-import { afterEach, describe, expect, it, vi } from "vitest";
2-import { createEmptyPluginRegistry } from "../plugins/registry.js";
3-import { setActivePluginRegistry } from "../plugins/runtime.js";
1+import { beforeEach, describe, expect, it, vi } from "vitest";
42import {
53buildMediaUnderstandingRegistry,
64getMediaUnderstandingProvider,
75} from "./provider-registry.js";
6+import type { MediaUnderstandingProvider } from "./types.js";
879-vi.mock("../plugins/capability-provider-runtime.js", async () => {
10-const actual = await vi.importActual<typeof import("../plugins/capability-provider-runtime.js")>(
11-"../plugins/capability-provider-runtime.js",
12-);
13-const runtime =
14-await vi.importActual<typeof import("../plugins/runtime.js")>("../plugins/runtime.js");
15-return {
16- ...actual,
17-resolvePluginCapabilityProviders: ({ key }: { key: string }) =>
18-key !== "mediaUnderstandingProviders"
19- ? []
20- : (() => {
21-const activeProviders =
22-runtime
23-.getActivePluginRegistry()
24-?.mediaUnderstandingProviders.map((entry) => entry.provider) ?? [];
25-return activeProviders.length > 0
26- ? activeProviders
27- : [
28-{ id: "groq", capabilities: ["image", "audio"] },
29-{ id: "deepgram", capabilities: ["audio"] },
30-];
31-})(),
32-};
33-});
8+const resolvePluginCapabilityProvidersMock = vi.hoisted(() => vi.fn());
9+10+vi.mock("../plugins/capability-provider-runtime.js", () => ({
11+resolvePluginCapabilityProviders: resolvePluginCapabilityProvidersMock,
12+}));
13+14+function createMediaProvider(
15+params: Pick<MediaUnderstandingProvider, "id" | "capabilities"> &
16+Partial<MediaUnderstandingProvider>,
17+): MediaUnderstandingProvider {
18+return params;
19+}
34203521describe("media-understanding provider registry", () => {
36-afterEach(() => {
37-setActivePluginRegistry(createEmptyPluginRegistry());
22+beforeEach(() => {
23+resolvePluginCapabilityProvidersMock.mockReset();
24+resolvePluginCapabilityProvidersMock.mockReturnValue([]);
3825});
392640-it("loads bundled providers by default when no active registry is present", () => {
27+it("loads media providers from the capability runtime", () => {
28+resolvePluginCapabilityProvidersMock.mockReturnValue([
29+createMediaProvider({ id: "groq", capabilities: ["image", "audio"] }),
30+createMediaProvider({ id: "deepgram", capabilities: ["audio"] }),
31+]);
32+4133const registry = buildMediaUnderstandingRegistry();
34+4235expect(getMediaUnderstandingProvider("groq", registry)?.id).toBe("groq");
4336expect(getMediaUnderstandingProvider("deepgram", registry)?.id).toBe("deepgram");
44-});
45-46-it("merges plugin-registered media providers into the active registry", async () => {
47-const pluginRegistry = createEmptyPluginRegistry();
48-pluginRegistry.mediaUnderstandingProviders.push({
49-pluginId: "google",
50-pluginName: "Google Plugin",
51-source: "test",
52-provider: {
53-id: "google",
54-capabilities: ["image", "audio", "video"],
55-describeImage: async () => ({ text: "plugin image" }),
56-transcribeAudio: async () => ({ text: "plugin audio" }),
57-describeVideo: async () => ({ text: "plugin video" }),
58-},
37+expect(resolvePluginCapabilityProvidersMock).toHaveBeenCalledWith({
38+key: "mediaUnderstandingProviders",
39+cfg: undefined,
5940});
60-setActivePluginRegistry(pluginRegistry);
61-62-const registry = buildMediaUnderstandingRegistry();
63-const provider = getMediaUnderstandingProvider("gemini", registry);
64-65-expect(provider?.id).toBe("google");
66-expect(await provider?.describeVideo?.({} as never)).toEqual({ text: "plugin video" });
6741});
684269-it("keeps provider id normalization behavior for plugin-owned providers", () => {
70-const pluginRegistry = createEmptyPluginRegistry();
71-pluginRegistry.mediaUnderstandingProviders.push({
72-pluginId: "google",
73-pluginName: "Google Plugin",
74-source: "test",
75-provider: {
76-id: "google",
77-capabilities: ["image", "audio", "video"],
78-},
79-});
80-setActivePluginRegistry(pluginRegistry);
43+it("keeps provider id normalization behavior for capability providers", () => {
44+resolvePluginCapabilityProvidersMock.mockReturnValue([
45+createMediaProvider({ id: "google", capabilities: ["image", "audio", "video"] }),
46+]);
81478248const registry = buildMediaUnderstandingRegistry();
83-const provider = getMediaUnderstandingProvider("gemini", registry);
844985-expect(provider?.id).toBe("google");
50+expect(getMediaUnderstandingProvider("gemini", registry)?.id).toBe("google");
8651});
87528853it("auto-registers media-understanding for config providers with image-capable models (#51392)", () => {
@@ -109,21 +74,15 @@ describe("media-understanding provider registry", () => {
10974expect(textOnlyProvider).toBeUndefined();
11075});
11176112-it("does not override plugin-registered providers when config also has image-capable models", async () => {
113-const pluginRegistry = createEmptyPluginRegistry();
114-pluginRegistry.mediaUnderstandingProviders.push({
115-pluginId: "google",
116-pluginName: "Google Plugin",
117-source: "test",
118-provider: {
77+it("does not override capability providers when config also has image-capable models", async () => {
78+resolvePluginCapabilityProvidersMock.mockReturnValue([
79+createMediaProvider({
11980id: "google",
12081capabilities: ["image", "audio", "video"],
12182describeImage: async () => ({ text: "plugin image" }),
12283transcribeAudio: async () => ({ text: "plugin audio" }),
123-},
124-});
125-setActivePluginRegistry(pluginRegistry);
126-84+}),
85+]);
12786const cfg = {
12887models: {
12988providers: {
@@ -140,6 +99,10 @@ describe("media-understanding provider registry", () => {
14099expect(provider?.capabilities).toEqual(["image", "audio", "video"]);
141100expect(await provider?.describeImage?.({} as never)).toEqual({ text: "plugin image" });
142101expect(await provider?.transcribeAudio?.({} as never)).toEqual({ text: "plugin audio" });
102+expect(resolvePluginCapabilityProvidersMock).toHaveBeenCalledWith({
103+key: "mediaUnderstandingProviders",
104+ cfg,
105+});
143106});
144107145108it("does not auto-register providers with audio or video only inputs", () => {
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。