Download src/plugins/contracts/registry.contract.test.ts from SaylorTwift/openclaw: direct link, hf CLI and curl.
- Browser
- Download file 13.3 kB
-
https://huggingface.co/SaylorTwift/openclaw/resolve/main/src/plugins/contracts/registry.contract.test.ts
- Command line
-
hf download hf://SaylorTwift/openclaw/src/plugins/contracts/registry.contract.test.ts
-
curl -L -o registry.contract.test.ts https://huggingface.co/SaylorTwift/openclaw/resolve/main/src/plugins/contracts/registry.contract.test.ts
13.3 kB
| // Registry contract tests cover plugin contract registry contents and lookup behavior. | |
| import { sortUniqueStrings } from "@openclaw/normalization-core/string-normalization"; | |
| import { describe, expect, it } from "vitest"; | |
| import { loadPluginManifestRegistryCore, type PluginManifestRecord } from "../manifest-registry.js"; | |
| import { resolveManifestContractPluginIds } from "../plugin-registry.js"; | |
| import { BUNDLED_PLUGIN_CONTRACT_SNAPSHOTS } from "./inventory/bundled-capability-metadata.js"; | |
| import { pluginRegistrationContractRegistry, providerContractLoadError } from "./registry.js"; | |
| const ACTIVATION_SCOPED_WEB_SEARCH_PLUGIN_IDS = ["codex", "qa-lab"] as const; | |
| const ACTIVATION_SCOPED_WEB_SEARCH_PLUGIN_ID_SET = new Set<string>( | |
| ACTIVATION_SCOPED_WEB_SEARCH_PLUGIN_IDS, | |
| ); | |
| describe("plugin contract registry", () => { | |
| function expectUniqueIds(ids: readonly string[]) { | |
| expect(ids).toEqual([...new Set(ids)]); | |
| } | |
| function expectRegistryPluginIds(params: { | |
| actualPluginIds: readonly string[]; | |
| predicate: (plugin: PluginManifestRecord) => boolean; | |
| }) { | |
| expect(sortUniqueStrings(params.actualPluginIds)).toEqual( | |
| resolveBundledManifestPluginIds(params.predicate), | |
| ); | |
| } | |
| function resolveBundledManifestPluginIds(predicate: (plugin: PluginManifestRecord) => boolean) { | |
| if (process.env.VITEST) { | |
| return BUNDLED_PLUGIN_CONTRACT_SNAPSHOTS.map( | |
| (entry) => | |
| ({ | |
| id: entry.pluginId, | |
| origin: "bundled", | |
| providers: entry.providerIds, | |
| contracts: { | |
| embeddingProviders: entry.embeddingProviderIds, | |
| workerProviders: entry.workerProviderIds, | |
| speechProviders: entry.speechProviderIds, | |
| realtimeTranscriptionProviders: entry.realtimeTranscriptionProviderIds, | |
| realtimeVoiceProviders: entry.realtimeVoiceProviderIds, | |
| mediaUnderstandingProviders: entry.mediaUnderstandingProviderIds, | |
| transcriptSourceProviders: entry.transcriptSourceProviderIds, | |
| documentExtractors: entry.documentExtractorIds, | |
| imageGenerationProviders: entry.imageGenerationProviderIds, | |
| videoGenerationProviders: entry.videoGenerationProviderIds, | |
| musicGenerationProviders: entry.musicGenerationProviderIds, | |
| webContentExtractors: entry.webContentExtractorIds, | |
| webFetchProviders: entry.webFetchProviderIds, | |
| webSearchProviders: entry.webSearchProviderIds, | |
| migrationProviders: entry.migrationProviderIds, | |
| tools: entry.toolNames, | |
| }, | |
| }) as PluginManifestRecord, | |
| ) | |
| .filter(predicate) | |
| .map((plugin) => plugin.id) | |
| .toSorted((left, right) => left.localeCompare(right)); | |
| } | |
| const snapshotPluginIds = new Set( | |
| BUNDLED_PLUGIN_CONTRACT_SNAPSHOTS.map((entry) => entry.pluginId), | |
| ); | |
| return loadPluginManifestRegistryCore({}) | |
| .plugins.filter((plugin) => snapshotPluginIds.has(plugin.id) && predicate(plugin)) | |
| .map((plugin) => plugin.id) | |
| .toSorted((left, right) => left.localeCompare(right)); | |
| } | |
| it("loads bundled non-provider capability registries without import-time failure", () => { | |
| expect(providerContractLoadError).toBeUndefined(); | |
| expect(Array.from(pluginRegistrationContractRegistry)).toStrictEqual( | |
| BUNDLED_PLUGIN_CONTRACT_SNAPSHOTS, | |
| ); | |
| }); | |
| it.each([ | |
| { | |
| name: "does not duplicate bundled provider ids", | |
| ids: () => pluginRegistrationContractRegistry.flatMap((entry) => entry.providerIds), | |
| }, | |
| { | |
| name: "does not duplicate bundled worker provider ids", | |
| ids: () => pluginRegistrationContractRegistry.flatMap((entry) => entry.workerProviderIds), | |
| }, | |
| { | |
| name: "does not duplicate bundled web fetch provider ids", | |
| ids: () => pluginRegistrationContractRegistry.flatMap((entry) => entry.webFetchProviderIds), | |
| }, | |
| { | |
| name: "does not duplicate bundled web search provider ids", | |
| ids: () => pluginRegistrationContractRegistry.flatMap((entry) => entry.webSearchProviderIds), | |
| }, | |
| { | |
| name: "does not duplicate bundled migration provider ids", | |
| ids: () => pluginRegistrationContractRegistry.flatMap((entry) => entry.migrationProviderIds), | |
| }, | |
| { | |
| name: "does not duplicate bundled media provider ids", | |
| ids: () => | |
| pluginRegistrationContractRegistry.flatMap((entry) => entry.mediaUnderstandingProviderIds), | |
| }, | |
| { | |
| name: "does not duplicate bundled transcripts source provider ids", | |
| ids: () => | |
| pluginRegistrationContractRegistry.flatMap((entry) => entry.transcriptSourceProviderIds), | |
| }, | |
| { | |
| name: "does not duplicate bundled realtime transcription provider ids", | |
| ids: () => | |
| pluginRegistrationContractRegistry.flatMap( | |
| (entry) => entry.realtimeTranscriptionProviderIds, | |
| ), | |
| }, | |
| { | |
| name: "does not duplicate bundled realtime voice provider ids", | |
| ids: () => | |
| pluginRegistrationContractRegistry.flatMap((entry) => entry.realtimeVoiceProviderIds), | |
| }, | |
| { | |
| name: "does not duplicate bundled image-generation provider ids", | |
| ids: () => | |
| pluginRegistrationContractRegistry.flatMap((entry) => entry.imageGenerationProviderIds), | |
| }, | |
| ] as const)("$name", ({ ids }) => { | |
| expectUniqueIds(ids()); | |
| }); | |
| it("does not duplicate bundled speech provider ids", () => { | |
| expectUniqueIds(pluginRegistrationContractRegistry.flatMap((entry) => entry.speechProviderIds)); | |
| }); | |
| it.each([ | |
| ["azure-speech", "speechProviderIds", ["azure-speech", "azure"]], | |
| ["microsoft", "speechProviderIds", ["microsoft", "edge"]], | |
| ["tts-local-cli", "speechProviderIds", ["tts-local-cli", "cli"]], | |
| ["volcengine", "speechProviderIds", ["volcengine", "bytedance", "doubao"]], | |
| ["xiaomi", "speechProviderIds", ["xiaomi", "mimo"]], | |
| ["xai", "realtimeVoiceProviderIds", ["xai", "grok-voice", "xai-realtime-voice"]], | |
| ] as const)("declares canonical-first %s %s aliases", (pluginId, contract, providerIds) => { | |
| expect( | |
| pluginRegistrationContractRegistry.find((entry) => entry.pluginId === pluginId)?.[contract], | |
| ).toEqual(providerIds); | |
| }); | |
| it("covers every bundled worker provider plugin discovered from manifests", () => { | |
| expectRegistryPluginIds({ | |
| actualPluginIds: pluginRegistrationContractRegistry | |
| .filter((entry) => entry.workerProviderIds.length > 0) | |
| .map((entry) => entry.pluginId), | |
| predicate: (plugin) => | |
| plugin.origin === "bundled" && (plugin.contracts?.workerProviders?.length ?? 0) > 0, | |
| }); | |
| }); | |
| it("keeps video-only provider auth choices out of text onboarding", () => { | |
| const registry = loadPluginManifestRegistryCore({}); | |
| for (const pluginId of ["alibaba", "runway"]) { | |
| const plugin = registry.plugins.find( | |
| (entry) => entry.origin === "bundled" && entry.id === pluginId, | |
| ); | |
| expect(plugin?.providerAuthChoices).toEqual([ | |
| { | |
| provider: pluginId, | |
| method: "api-key", | |
| choiceId: pluginId === "alibaba" ? "alibaba-model-studio-api-key" : "runway-api-key", | |
| choiceLabel: pluginId === "alibaba" ? "Alibaba Model Studio API key" : "Runway API key", | |
| groupId: pluginId, | |
| groupLabel: pluginId === "alibaba" ? "Alibaba Model Studio" : "Runway", | |
| groupHint: pluginId === "alibaba" ? "DashScope / Model Studio API key" : "API key", | |
| onboardingScopes: ["image-generation"], | |
| optionKey: pluginId === "alibaba" ? "alibabaModelStudioApiKey" : "runwayApiKey", | |
| cliFlag: pluginId === "alibaba" ? "--alibaba-model-studio-api-key" : "--runway-api-key", | |
| cliOption: | |
| pluginId === "alibaba" | |
| ? "--alibaba-model-studio-api-key <key>" | |
| : "--runway-api-key <key>", | |
| cliDescription: | |
| pluginId === "alibaba" ? "Alibaba Model Studio API key" : "Runway API key", | |
| }, | |
| ]); | |
| } | |
| }); | |
| it("exposes the GitHub Copilot non-interactive onboarding token flag from manifest metadata", () => { | |
| const registry = loadPluginManifestRegistryCore({}); | |
| const plugin = registry.plugins.find( | |
| (entry) => entry.origin === "bundled" && entry.id === "github-copilot", | |
| ); | |
| expect(plugin?.providerAuthChoices).toEqual([ | |
| { | |
| provider: "github-copilot", | |
| method: "device", | |
| appGuidedAuth: "device-code", | |
| credentialOnly: true, | |
| channelLogin: {}, | |
| appGuidedSecret: true, | |
| choiceId: "github-copilot", | |
| choiceLabel: "GitHub Copilot", | |
| choiceHint: "Device login with your GitHub account", | |
| assistantPriority: 1, | |
| groupId: "copilot", | |
| groupLabel: "Copilot", | |
| groupHint: "GitHub, GitHub Enterprise + Local Proxy", | |
| optionKey: "githubCopilotToken", | |
| cliFlag: "--github-copilot-token", | |
| cliOption: "--github-copilot-token <token>", | |
| cliDescription: "GitHub Copilot OAuth token", | |
| }, | |
| { | |
| provider: "github-copilot", | |
| method: "device-enterprise", | |
| appGuidedAuth: "device-code", | |
| credentialOnly: true, | |
| choiceId: "github-copilot-enterprise", | |
| choiceLabel: "GitHub Copilot (Enterprise / data residency)", | |
| choiceHint: "Device login against your GitHub Enterprise (*.ghe.com) tenant", | |
| assistantPriority: 2, | |
| groupId: "copilot", | |
| groupLabel: "Copilot", | |
| groupHint: "GitHub, GitHub Enterprise + Local Proxy", | |
| }, | |
| ]); | |
| }); | |
| it("covers every bundled speech plugin discovered from manifests", () => { | |
| expectRegistryPluginIds({ | |
| actualPluginIds: pluginRegistrationContractRegistry | |
| .filter((entry) => entry.speechProviderIds.length > 0) | |
| .map((entry) => entry.pluginId), | |
| predicate: (plugin) => | |
| plugin.origin === "bundled" && (plugin.contracts?.speechProviders?.length ?? 0) > 0, | |
| }); | |
| }); | |
| it("covers every bundled realtime voice plugin discovered from manifests", () => { | |
| expectRegistryPluginIds({ | |
| actualPluginIds: pluginRegistrationContractRegistry | |
| .filter((entry) => entry.realtimeVoiceProviderIds.length > 0) | |
| .map((entry) => entry.pluginId), | |
| predicate: (plugin) => | |
| plugin.origin === "bundled" && (plugin.contracts?.realtimeVoiceProviders?.length ?? 0) > 0, | |
| }); | |
| }); | |
| it("covers every bundled realtime transcription plugin discovered from manifests", () => { | |
| expectRegistryPluginIds({ | |
| actualPluginIds: pluginRegistrationContractRegistry | |
| .filter((entry) => entry.realtimeTranscriptionProviderIds.length > 0) | |
| .map((entry) => entry.pluginId), | |
| predicate: (plugin) => | |
| plugin.origin === "bundled" && | |
| (plugin.contracts?.realtimeTranscriptionProviders?.length ?? 0) > 0, | |
| }); | |
| }); | |
| it("covers every bundled transcripts source plugin discovered from manifests", () => { | |
| expectRegistryPluginIds({ | |
| actualPluginIds: pluginRegistrationContractRegistry | |
| .filter((entry) => entry.transcriptSourceProviderIds.length > 0) | |
| .map((entry) => entry.pluginId), | |
| predicate: (plugin) => | |
| plugin.origin === "bundled" && | |
| (plugin.contracts?.transcriptSourceProviders?.length ?? 0) > 0, | |
| }); | |
| }); | |
| it("covers every bundled web fetch plugin from the shared resolver", () => { | |
| const bundledWebFetchPluginIds = resolveManifestContractPluginIds({ | |
| contract: "webFetchProviders", | |
| origin: "bundled", | |
| }); | |
| expect( | |
| sortUniqueStrings( | |
| pluginRegistrationContractRegistry | |
| .filter((entry) => entry.webFetchProviderIds.length > 0) | |
| .map((entry) => entry.pluginId), | |
| ), | |
| ).toEqual(bundledWebFetchPluginIds); | |
| }); | |
| it("covers every bundled web search plugin from the shared resolver", () => { | |
| const snapshotPluginIds = new Set( | |
| BUNDLED_PLUGIN_CONTRACT_SNAPSHOTS.map((entry) => entry.pluginId), | |
| ); | |
| const bundledWebSearchPluginIds = resolveManifestContractPluginIds({ | |
| contract: "webSearchProviders", | |
| origin: "bundled", | |
| }).filter( | |
| (pluginId) => | |
| snapshotPluginIds.has(pluginId) && | |
| !ACTIVATION_SCOPED_WEB_SEARCH_PLUGIN_ID_SET.has(pluginId), | |
| ); | |
| const expectedPluginIds = sortUniqueStrings([ | |
| ...bundledWebSearchPluginIds, | |
| ...ACTIVATION_SCOPED_WEB_SEARCH_PLUGIN_IDS, | |
| ]); | |
| const actualPluginIds = sortUniqueStrings( | |
| pluginRegistrationContractRegistry | |
| .filter((entry) => entry.webSearchProviderIds.length > 0) | |
| .map((entry) => entry.pluginId), | |
| ); | |
| expect(actualPluginIds).toEqual(expectedPluginIds); | |
| expect( | |
| actualPluginIds.filter((pluginId) => !bundledWebSearchPluginIds.includes(pluginId)), | |
| ).toEqual([...ACTIVATION_SCOPED_WEB_SEARCH_PLUGIN_IDS]); | |
| }); | |
| it("covers every bundled migration provider plugin discovered from manifests", () => { | |
| expectRegistryPluginIds({ | |
| actualPluginIds: pluginRegistrationContractRegistry | |
| .filter((entry) => entry.migrationProviderIds.length > 0) | |
| .map((entry) => entry.pluginId), | |
| predicate: (plugin) => | |
| plugin.origin === "bundled" && (plugin.contracts?.migrationProviders?.length ?? 0) > 0, | |
| }); | |
| }); | |
| }); | |