Eine aufbereitete Darstellung der Quelle

 
     
 
 
Anforderungen  |   Konzepte  |   Entwurf  |   Entwicklung  |   Qualitätssicherung  |   Lebenszyklus  |   Steuerung
 
 
 
 

Benutzer

Quelle  provider-flow.test.ts  Sprache: unbekannt

 
import { beforeEach, describe, expect, it, vi } from "vitest";

type ResolveProviderInstallCatalogEntries =
  typeof import("../plugins/provider-install-catalog.js").resolveProviderInstallCatalogEntries;
type ResolveManifestProviderAuthChoices =
  typeof import("../plugins/provider-auth-choices.js").resolveManifestProviderAuthChoices;
type ResolveProviderWizardOptions =
  typeof import("../plugins/provider-wizard.js").resolveProviderWizardOptions;
type ResolveProviderModelPickerEntries =
  typeof import("../plugins/provider-wizard.js").resolveProviderModelPickerEntries;
type ResolvePluginProviders =
  typeof import("../plugins/providers.runtime.js").resolvePluginProviders;

const resolveProviderInstallCatalogEntries = vi.hoisted(() =>
  vi.fn<ResolveProviderInstallCatalogEntries>(() => []),
);
vi.mock("../plugins/provider-install-catalog.js", () => ({
  resolveProviderInstallCatalogEntries,
}));

const resolveManifestProviderAuthChoices = vi.hoisted(() =>
  vi.fn<ResolveManifestProviderAuthChoices>(() => []),
);
vi.mock("../plugins/provider-auth-choices.js", () => ({
  resolveManifestProviderAuthChoices,
}));

const resolveProviderWizardOptions = vi.hoisted(() =>
  vi.fn<ResolveProviderWizardOptions>(() => []),
);
const resolveProviderModelPickerEntries = vi.hoisted(() =>
  vi.fn<ResolveProviderModelPickerEntries>(() => []),
);
vi.mock("../plugins/provider-wizard.js", () => ({
  resolveProviderWizardOptions,
  resolveProviderModelPickerEntries,
}));

const resolvePluginProviders = vi.hoisted(() => vi.fn<ResolvePluginProviders>(() => []));
vi.mock("../plugins/providers.runtime.js", () => ({
  resolvePluginProviders,
}));

import {
  resolveProviderModelPickerFlowContributions,
  resolveProviderSetupFlowContributions,
} from "./provider-flow.js";

describe("provider flow install catalog contributions", () => {
  beforeEach(() => {
    resolveManifestProviderAuthChoices.mockReset();
    resolveManifestProviderAuthChoices.mockReturnValue([]);
    resolveProviderInstallCatalogEntries.mockReset();
    resolveProviderInstallCatalogEntries.mockReturnValue([]);
    resolveProviderWizardOptions.mockReset();
    resolveProviderWizardOptions.mockReturnValue([]);
    resolveProviderModelPickerEntries.mockReset();
    resolveProviderModelPickerEntries.mockReturnValue([]);
    resolvePluginProviders.mockReset();
    resolvePluginProviders.mockReturnValue([]);
  });

  it("surfaces manifest provider auth choices before setup runtime loads", () => {
    resolveManifestProviderAuthChoices.mockReturnValue([
      {
        pluginId: "openai-compatible",
        providerId: "openai-compatible",
        methodId: "api-key",
        choiceId: "openai-compatible-api-key",
        choiceLabel: "OpenAI-compatible API key",
        choiceHint: "Use a compatible endpoint",
        assistantPriority: -5,
        assistantVisibility: "visible",
        groupId: "openai-compatible",
        groupLabel: "OpenAI-compatible",
        groupHint: "Self-hosted and compatible providers",
        onboardingScopes: ["text-inference"],
      },
    ]);

    expect(resolveProviderSetupFlowContributions()).toEqual([
      {
        id: "provider:setup:openai-compatible-api-key",
        kind: "provider",
        surface: "setup",
        providerId: "openai-compatible",
        pluginId: "openai-compatible",
        option: {
          value: "openai-compatible-api-key",
          label: "OpenAI-compatible API key",
          hint: "Use a compatible endpoint",
          assistantPriority: -5,
          assistantVisibility: "visible",
          group: {
            id: "openai-compatible",
            label: "OpenAI-compatible",
            hint: "Self-hosted and compatible providers",
          },
        },
        onboardingScopes: ["text-inference"],
        source: "manifest",
      },
    ]);
    expect(resolveManifestProviderAuthChoices).toHaveBeenCalledWith(
      expect.objectContaining({
        includeUntrustedWorkspacePlugins: false,
      }),
    );
  });

  it("prefers manifest setup contributions over duplicate runtime and install-catalog entries", () => {
    resolveManifestProviderAuthChoices.mockReturnValue([
      {
        pluginId: "openai",
        providerId: "openai",
        methodId: "api-key",
        choiceId: "openai-api-key",
        choiceLabel: "OpenAI API key",
      },
    ]);
    resolveProviderWizardOptions.mockReturnValue([
      {
        value: "openai-api-key",
        label: "Runtime OpenAI API key",
        groupId: "openai",
        groupLabel: "OpenAI",
      },
    ]);
    resolveProviderInstallCatalogEntries.mockReturnValue([
      {
        pluginId: "openai",
        providerId: "openai",
        methodId: "api-key",
        choiceId: "openai-api-key",
        choiceLabel: "Catalog OpenAI API key",
        label: "OpenAI",
        origin: "bundled",
        install: {
          npmSpec: "@openclaw/openai",
        },
      },
    ]);

    expect(resolveProviderSetupFlowContributions()).toEqual([
      {
        id: "provider:setup:openai-api-key",
        kind: "provider",
        surface: "setup",
        providerId: "openai",
        pluginId: "openai",
        option: {
          value: "openai-api-key",
          label: "OpenAI API key",
          group: {
            id: "openai",
            label: "OpenAI API key",
          },
        },
        source: "manifest",
      },
    ]);
  });

  it("surfaces install-catalog provider choices when runtime setup options are absent", () => {
    resolveProviderInstallCatalogEntries.mockReturnValue([
      {
        pluginId: "vllm",
        providerId: "vllm",
        methodId: "server",
        choiceId: "vllm",
        choiceLabel: "vLLM",
        choiceHint: "Local server",
        groupId: "vllm",
        groupLabel: "vLLM",
        onboardingScopes: ["text-inference"],
        label: "vLLM",
        origin: "bundled",
        install: {
          npmSpec: "@openclaw/vllm",
        },
      },
    ]);

    expect(resolveProviderSetupFlowContributions()).toEqual([
      {
        id: "provider:setup:vllm",
        kind: "provider",
        surface: "setup",
        providerId: "vllm",
        pluginId: "vllm",
        option: {
          value: "vllm",
          label: "vLLM",
          hint: "Local server",
          group: {
            id: "vllm",
            label: "vLLM",
          },
        },
        onboardingScopes: ["text-inference"],
        source: "install-catalog",
      },
    ]);
    expect(resolveProviderInstallCatalogEntries).toHaveBeenCalledWith(
      expect.objectContaining({
        includeUntrustedWorkspacePlugins: false,
      }),
    );
  });

  it("adds a fallback group when install-catalog entries omit group metadata", () => {
    resolveProviderInstallCatalogEntries.mockReturnValue([
      {
        pluginId: "demo-provider",
        providerId: "demo-provider",
        methodId: "api-key",
        choiceId: "demo-provider-api-key",
        choiceLabel: "Demo Provider API key",
        label: "Demo Provider API key",
        origin: "global",
        install: {
          npmSpec: "@vendor/demo-provider",
        },
      },
    ]);

    expect(resolveProviderSetupFlowContributions()).toEqual([
      {
        id: "provider:setup:demo-provider-api-key",
        kind: "provider",
        surface: "setup",
        providerId: "demo-provider",
        pluginId: "demo-provider",
        option: {
          value: "demo-provider-api-key",
          label: "Demo Provider API key",
          group: {
            id: "demo-provider",
            label: "Demo Provider API key",
          },
        },
        source: "install-catalog",
      },
    ]);
  });

  it("hides install-catalog choices that cannot be enabled", () => {
    resolveProviderInstallCatalogEntries.mockReturnValue([
      {
        pluginId: "blocked-provider",
        providerId: "blocked-provider",
        methodId: "api-key",
        choiceId: "blocked-provider-api-key",
        choiceLabel: "Blocked Provider API key",
        label: "Blocked Provider",
        origin: "global",
        install: {
          npmSpec: "@vendor/blocked-provider",
        },
      },
    ]);

    expect(
      resolveProviderSetupFlowContributions({
        config: {
          plugins: {
            enabled: false,
          },
        },
      }),
    ).toEqual([]);
  });

  it("hides install-catalog choices outside a configured plugin allowlist", () => {
    resolveProviderInstallCatalogEntries.mockReturnValue([
      {
        pluginId: "blocked-provider",
        providerId: "blocked-provider",
        methodId: "api-key",
        choiceId: "blocked-provider-api-key",
        choiceLabel: "Blocked Provider API key",
        label: "Blocked Provider",
        origin: "global",
        install: {
          npmSpec: "@vendor/blocked-provider@1.2.3",
          expectedIntegrity: "sha512-blocked",
        },
      },
    ]);

    expect(
      resolveProviderSetupFlowContributions({
        config: {
          plugins: {
            allow: ["openai"],
          },
        },
      }),
    ).toEqual([]);
  });

  it("prefers runtime setup contributions over duplicate install-catalog entries", () => {
    resolveProviderWizardOptions.mockReturnValue([
      {
        value: "openai-api-key",
        label: "OpenAI API key",
        groupId: "openai",
        groupLabel: "OpenAI",
      },
    ]);
    resolveProviderInstallCatalogEntries.mockReturnValue([
      {
        pluginId: "openai",
        providerId: "openai",
        methodId: "api-key",
        choiceId: "openai-api-key",
        choiceLabel: "OpenAI API key",
        groupId: "openai",
        groupLabel: "OpenAI",
        label: "OpenAI",
        origin: "bundled",
        install: {
          npmSpec: "@openclaw/openai",
        },
      },
    ]);

    expect(resolveProviderSetupFlowContributions()).toEqual([
      {
        id: "provider:setup:openai-api-key",
        kind: "provider",
        surface: "setup",
        providerId: "openai",
        option: {
          value: "openai-api-key",
          label: "OpenAI API key",
          group: {
            id: "openai",
            label: "OpenAI",
          },
        },
        source: "runtime",
      },
    ]);
  });

  it("keeps docs attached to runtime model-picker contributions", () => {
    resolvePluginProviders.mockReturnValue([
      {
        id: "openai",
        label: "OpenAI",
        docsPath: "/providers/openai",
        auth: [],
      },
    ]);
    resolveProviderModelPickerEntries.mockReturnValue([
      {
        value: "provider-plugin:openai:gpt-5.4",
        label: "GPT-5.4",
      },
    ]);

    expect(resolveProviderModelPickerFlowContributions()).toEqual([
      {
        id: "provider:model-picker:provider-plugin:openai:gpt-5.4",
        kind: "provider",
        surface: "model-picker",
        providerId: "openai",
        option: {
          value: "provider-plugin:openai:gpt-5.4",
          label: "GPT-5.4",
          docs: {
            path: "/providers/openai",
          },
        },
        source: "runtime",
      },
    ]);
  });
});

Messung V0.5 in Prozent
C=100 H=100 G=100

[Dauer der Verarbeitung: 0.11 Sekunden, vorverarbeitet 2026-09-28]

                                                                                                                                                                                                                                                                                                                                                                                                     


Neuigkeiten

     Aktuelles
     Motto des Tages

Open Source Software

     Quellcodebibliothek
     Eigene Quellcodes
     Fremde Quellcodes
     Suchen

Jenseits des Üblichen ....

Besucherstatistik

Besucherstatistik

Statistik
#Sources=1126864
#Domains=1897691