mirror of
https://github.com/openclaw/openclaw.git
synced 2026-03-28 10:22:32 +00:00
refactor: simplify bundled plugin contracts
This commit is contained in:
@@ -1,10 +1,11 @@
|
||||
import path from "node:path";
|
||||
import { collectBundledPluginSources } from "./lib/bundled-plugin-source-utils.mjs";
|
||||
import { formatGeneratedModule } from "./lib/format-generated-module.mjs";
|
||||
import { reportGeneratedOutputCli, writeGeneratedOutput } from "./lib/generated-output-utils.mjs";
|
||||
import { writeGeneratedOutput } from "./lib/generated-output-utils.mjs";
|
||||
|
||||
const GENERATED_BY = "scripts/generate-bundled-plugin-metadata.mjs";
|
||||
const DEFAULT_OUTPUT_PATH = "src/plugins/bundled-plugin-metadata.generated.ts";
|
||||
const DEFAULT_ENTRIES_OUTPUT_PATH = "src/generated/bundled-plugin-entries.generated.ts";
|
||||
const MANIFEST_KEY = "openclaw";
|
||||
const FORMATTER_CWD = path.resolve(import.meta.dirname, "..");
|
||||
const CANONICAL_PACKAGE_ID_ALIASES = {
|
||||
@@ -134,6 +135,19 @@ function formatTypeScriptModule(source, { outputPath }) {
|
||||
});
|
||||
}
|
||||
|
||||
function toIdentifier(dirName) {
|
||||
const cleaned = String(dirName)
|
||||
.replace(/[^a-zA-Z0-9]+(.)/g, (_match, next) => next.toUpperCase())
|
||||
.replace(/[^a-zA-Z0-9]/g, "")
|
||||
.replace(/^[^a-zA-Z]+/g, "");
|
||||
const base = cleaned || "plugin";
|
||||
return `${base[0].toLowerCase()}${base.slice(1)}Plugin`;
|
||||
}
|
||||
|
||||
function normalizeGeneratedImportPath(dirName, builtPath) {
|
||||
return `../../extensions/${dirName}/${String(builtPath).replace(/^\.\//u, "")}`;
|
||||
}
|
||||
|
||||
export function collectBundledPluginMetadata(params = {}) {
|
||||
const repoRoot = path.resolve(params.repoRoot ?? process.cwd());
|
||||
const entries = [];
|
||||
@@ -202,23 +216,73 @@ export const GENERATED_BUNDLED_PLUGIN_METADATA = ${JSON.stringify(entries, null,
|
||||
`;
|
||||
}
|
||||
|
||||
export function writeBundledPluginMetadataModule(params = {}) {
|
||||
const repoRoot = path.resolve(params.repoRoot ?? process.cwd());
|
||||
const outputPath = path.resolve(repoRoot, params.outputPath ?? DEFAULT_OUTPUT_PATH);
|
||||
const next = formatTypeScriptModule(
|
||||
renderBundledPluginMetadataModule(collectBundledPluginMetadata({ repoRoot })),
|
||||
{ outputPath },
|
||||
);
|
||||
return writeGeneratedOutput({
|
||||
repoRoot,
|
||||
outputPath: params.outputPath ?? DEFAULT_OUTPUT_PATH,
|
||||
next,
|
||||
check: params.check,
|
||||
});
|
||||
export function renderBundledPluginEntriesModule(entries) {
|
||||
const imports = entries
|
||||
.map((entry) => {
|
||||
const identifier = toIdentifier(entry.dirName);
|
||||
const importPath = normalizeGeneratedImportPath(entry.dirName, entry.source.built);
|
||||
return `import ${identifier} from "${importPath}";`;
|
||||
})
|
||||
.join("\n");
|
||||
const identifiers = entries.map((entry) => toIdentifier(entry.dirName)).join(",\n ");
|
||||
return `// Auto-generated by ${GENERATED_BY}. Do not edit directly.
|
||||
|
||||
${imports}
|
||||
|
||||
export const GENERATED_BUNDLED_PLUGIN_ENTRIES = [
|
||||
${identifiers}
|
||||
] as const;
|
||||
`;
|
||||
}
|
||||
|
||||
reportGeneratedOutputCli({
|
||||
importMetaUrl: import.meta.url,
|
||||
label: "bundled-plugin-metadata",
|
||||
run: ({ check }) => writeBundledPluginMetadataModule({ check }),
|
||||
});
|
||||
export function writeBundledPluginMetadataModule(params = {}) {
|
||||
const repoRoot = path.resolve(params.repoRoot ?? process.cwd());
|
||||
const entries = collectBundledPluginMetadata({ repoRoot });
|
||||
const outputPath = path.resolve(repoRoot, params.outputPath ?? DEFAULT_OUTPUT_PATH);
|
||||
const entriesOutputPath = path.resolve(
|
||||
repoRoot,
|
||||
params.entriesOutputPath ?? DEFAULT_ENTRIES_OUTPUT_PATH,
|
||||
);
|
||||
const metadataNext = formatTypeScriptModule(renderBundledPluginMetadataModule(entries), {
|
||||
outputPath,
|
||||
});
|
||||
const registryNext = formatTypeScriptModule(renderBundledPluginEntriesModule(entries), {
|
||||
outputPath: entriesOutputPath,
|
||||
});
|
||||
const metadataResult = writeGeneratedOutput({
|
||||
repoRoot,
|
||||
outputPath: params.outputPath ?? DEFAULT_OUTPUT_PATH,
|
||||
next: metadataNext,
|
||||
check: params.check,
|
||||
});
|
||||
const entriesResult = writeGeneratedOutput({
|
||||
repoRoot,
|
||||
outputPath: params.entriesOutputPath ?? DEFAULT_ENTRIES_OUTPUT_PATH,
|
||||
next: registryNext,
|
||||
check: params.check,
|
||||
});
|
||||
return {
|
||||
changed: metadataResult.changed || entriesResult.changed,
|
||||
wrote: metadataResult.wrote || entriesResult.wrote,
|
||||
outputPaths: [metadataResult.outputPath, entriesResult.outputPath],
|
||||
};
|
||||
}
|
||||
|
||||
if (import.meta.url === new URL(process.argv[1] ?? "", "file:").href) {
|
||||
const check = process.argv.includes("--check");
|
||||
const result = writeBundledPluginMetadataModule({ check });
|
||||
if (!result.changed) {
|
||||
process.exitCode = 0;
|
||||
} else if (check) {
|
||||
for (const outputPath of result.outputPaths) {
|
||||
const relativeOutputPath = path.relative(process.cwd(), outputPath);
|
||||
console.error(`[bundled-plugin-metadata] stale generated output at ${relativeOutputPath}`);
|
||||
}
|
||||
process.exitCode = 1;
|
||||
} else {
|
||||
for (const outputPath of result.outputPaths) {
|
||||
const relativeOutputPath = path.relative(process.cwd(), outputPath);
|
||||
console.log(`[bundled-plugin-metadata] wrote ${relativeOutputPath}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,8 +5,6 @@ import {
|
||||
normalizeSpeechProviderId,
|
||||
} from "../../tts/provider-registry.js";
|
||||
import {
|
||||
OPENAI_TTS_MODELS,
|
||||
OPENAI_TTS_VOICES,
|
||||
getTtsProvider,
|
||||
isTtsEnabled,
|
||||
isTtsProviderConfigured,
|
||||
@@ -138,14 +136,8 @@ export const ttsHandlers: GatewayRequestHandlers = {
|
||||
id: provider.id,
|
||||
name: provider.label,
|
||||
configured: provider.isConfigured({ cfg, config }),
|
||||
models:
|
||||
provider.id === "openai" && provider.models == null
|
||||
? [...OPENAI_TTS_MODELS]
|
||||
: [...(provider.models ?? [])],
|
||||
voices:
|
||||
provider.id === "openai" && provider.voices == null
|
||||
? [...OPENAI_TTS_VOICES]
|
||||
: [...(provider.voices ?? [])],
|
||||
models: [...(provider.models ?? [])],
|
||||
voices: [...(provider.voices ?? [])],
|
||||
})),
|
||||
active: getTtsProvider(config, prefsPath),
|
||||
});
|
||||
|
||||
157
src/generated/bundled-plugin-entries.generated.ts
Normal file
157
src/generated/bundled-plugin-entries.generated.ts
Normal file
@@ -0,0 +1,157 @@
|
||||
// Auto-generated by scripts/generate-bundled-plugin-metadata.mjs. Do not edit directly.
|
||||
|
||||
import acpxPlugin from "../../extensions/acpx/index.js";
|
||||
import amazonBedrockPlugin from "../../extensions/amazon-bedrock/index.js";
|
||||
import anthropicPlugin from "../../extensions/anthropic/index.js";
|
||||
import bluebubblesPlugin from "../../extensions/bluebubbles/index.js";
|
||||
import bravePlugin from "../../extensions/brave/index.js";
|
||||
import byteplusPlugin from "../../extensions/byteplus/index.js";
|
||||
import chutesPlugin from "../../extensions/chutes/index.js";
|
||||
import cloudflareAiGatewayPlugin from "../../extensions/cloudflare-ai-gateway/index.js";
|
||||
import copilotProxyPlugin from "../../extensions/copilot-proxy/index.js";
|
||||
import deepgramPlugin from "../../extensions/deepgram/index.js";
|
||||
import deepseekPlugin from "../../extensions/deepseek/index.js";
|
||||
import diagnosticsOtelPlugin from "../../extensions/diagnostics-otel/index.js";
|
||||
import diffsPlugin from "../../extensions/diffs/index.js";
|
||||
import discordPlugin from "../../extensions/discord/index.js";
|
||||
import duckduckgoPlugin from "../../extensions/duckduckgo/index.js";
|
||||
import elevenlabsPlugin from "../../extensions/elevenlabs/index.js";
|
||||
import exaPlugin from "../../extensions/exa/index.js";
|
||||
import falPlugin from "../../extensions/fal/index.js";
|
||||
import feishuPlugin from "../../extensions/feishu/index.js";
|
||||
import firecrawlPlugin from "../../extensions/firecrawl/index.js";
|
||||
import githubCopilotPlugin from "../../extensions/github-copilot/index.js";
|
||||
import googlePlugin from "../../extensions/google/index.js";
|
||||
import googlechatPlugin from "../../extensions/googlechat/index.js";
|
||||
import groqPlugin from "../../extensions/groq/index.js";
|
||||
import huggingfacePlugin from "../../extensions/huggingface/index.js";
|
||||
import imessagePlugin from "../../extensions/imessage/index.js";
|
||||
import ircPlugin from "../../extensions/irc/index.js";
|
||||
import kilocodePlugin from "../../extensions/kilocode/index.js";
|
||||
import kimiCodingPlugin from "../../extensions/kimi-coding/index.js";
|
||||
import linePlugin from "../../extensions/line/index.js";
|
||||
import llmTaskPlugin from "../../extensions/llm-task/index.js";
|
||||
import lobsterPlugin from "../../extensions/lobster/index.js";
|
||||
import matrixPlugin from "../../extensions/matrix/index.js";
|
||||
import mattermostPlugin from "../../extensions/mattermost/index.js";
|
||||
import memoryCorePlugin from "../../extensions/memory-core/index.js";
|
||||
import memoryLancedbPlugin from "../../extensions/memory-lancedb/index.js";
|
||||
import microsoftFoundryPlugin from "../../extensions/microsoft-foundry/index.js";
|
||||
import microsoftPlugin from "../../extensions/microsoft/index.js";
|
||||
import minimaxPlugin from "../../extensions/minimax/index.js";
|
||||
import mistralPlugin from "../../extensions/mistral/index.js";
|
||||
import modelstudioPlugin from "../../extensions/modelstudio/index.js";
|
||||
import moonshotPlugin from "../../extensions/moonshot/index.js";
|
||||
import msteamsPlugin from "../../extensions/msteams/index.js";
|
||||
import nextcloudTalkPlugin from "../../extensions/nextcloud-talk/index.js";
|
||||
import nostrPlugin from "../../extensions/nostr/index.js";
|
||||
import nvidiaPlugin from "../../extensions/nvidia/index.js";
|
||||
import ollamaPlugin from "../../extensions/ollama/index.js";
|
||||
import openProsePlugin from "../../extensions/open-prose/index.js";
|
||||
import openaiPlugin from "../../extensions/openai/index.js";
|
||||
import opencodeGoPlugin from "../../extensions/opencode-go/index.js";
|
||||
import opencodePlugin from "../../extensions/opencode/index.js";
|
||||
import openrouterPlugin from "../../extensions/openrouter/index.js";
|
||||
import openshellPlugin from "../../extensions/openshell/index.js";
|
||||
import perplexityPlugin from "../../extensions/perplexity/index.js";
|
||||
import qianfanPlugin from "../../extensions/qianfan/index.js";
|
||||
import sglangPlugin from "../../extensions/sglang/index.js";
|
||||
import signalPlugin from "../../extensions/signal/index.js";
|
||||
import slackPlugin from "../../extensions/slack/index.js";
|
||||
import synologyChatPlugin from "../../extensions/synology-chat/index.js";
|
||||
import syntheticPlugin from "../../extensions/synthetic/index.js";
|
||||
import tavilyPlugin from "../../extensions/tavily/index.js";
|
||||
import telegramPlugin from "../../extensions/telegram/index.js";
|
||||
import tlonPlugin from "../../extensions/tlon/index.js";
|
||||
import togetherPlugin from "../../extensions/together/index.js";
|
||||
import twitchPlugin from "../../extensions/twitch/index.js";
|
||||
import venicePlugin from "../../extensions/venice/index.js";
|
||||
import vercelAiGatewayPlugin from "../../extensions/vercel-ai-gateway/index.js";
|
||||
import vllmPlugin from "../../extensions/vllm/index.js";
|
||||
import voiceCallPlugin from "../../extensions/voice-call/index.js";
|
||||
import volcenginePlugin from "../../extensions/volcengine/index.js";
|
||||
import whatsappPlugin from "../../extensions/whatsapp/index.js";
|
||||
import xaiPlugin from "../../extensions/xai/index.js";
|
||||
import xiaomiPlugin from "../../extensions/xiaomi/index.js";
|
||||
import zaiPlugin from "../../extensions/zai/index.js";
|
||||
import zaloPlugin from "../../extensions/zalo/index.js";
|
||||
import zalouserPlugin from "../../extensions/zalouser/index.js";
|
||||
|
||||
export const GENERATED_BUNDLED_PLUGIN_ENTRIES = [
|
||||
acpxPlugin,
|
||||
amazonBedrockPlugin,
|
||||
anthropicPlugin,
|
||||
bluebubblesPlugin,
|
||||
bravePlugin,
|
||||
byteplusPlugin,
|
||||
chutesPlugin,
|
||||
cloudflareAiGatewayPlugin,
|
||||
copilotProxyPlugin,
|
||||
deepgramPlugin,
|
||||
deepseekPlugin,
|
||||
diagnosticsOtelPlugin,
|
||||
diffsPlugin,
|
||||
discordPlugin,
|
||||
duckduckgoPlugin,
|
||||
elevenlabsPlugin,
|
||||
exaPlugin,
|
||||
falPlugin,
|
||||
feishuPlugin,
|
||||
firecrawlPlugin,
|
||||
githubCopilotPlugin,
|
||||
googlePlugin,
|
||||
googlechatPlugin,
|
||||
groqPlugin,
|
||||
huggingfacePlugin,
|
||||
imessagePlugin,
|
||||
ircPlugin,
|
||||
kilocodePlugin,
|
||||
kimiCodingPlugin,
|
||||
linePlugin,
|
||||
llmTaskPlugin,
|
||||
lobsterPlugin,
|
||||
matrixPlugin,
|
||||
mattermostPlugin,
|
||||
memoryCorePlugin,
|
||||
memoryLancedbPlugin,
|
||||
microsoftPlugin,
|
||||
microsoftFoundryPlugin,
|
||||
minimaxPlugin,
|
||||
mistralPlugin,
|
||||
modelstudioPlugin,
|
||||
moonshotPlugin,
|
||||
msteamsPlugin,
|
||||
nextcloudTalkPlugin,
|
||||
nostrPlugin,
|
||||
nvidiaPlugin,
|
||||
ollamaPlugin,
|
||||
openProsePlugin,
|
||||
openaiPlugin,
|
||||
opencodePlugin,
|
||||
opencodeGoPlugin,
|
||||
openrouterPlugin,
|
||||
openshellPlugin,
|
||||
perplexityPlugin,
|
||||
qianfanPlugin,
|
||||
sglangPlugin,
|
||||
signalPlugin,
|
||||
slackPlugin,
|
||||
synologyChatPlugin,
|
||||
syntheticPlugin,
|
||||
tavilyPlugin,
|
||||
telegramPlugin,
|
||||
tlonPlugin,
|
||||
togetherPlugin,
|
||||
twitchPlugin,
|
||||
venicePlugin,
|
||||
vercelAiGatewayPlugin,
|
||||
vllmPlugin,
|
||||
voiceCallPlugin,
|
||||
volcenginePlugin,
|
||||
whatsappPlugin,
|
||||
xaiPlugin,
|
||||
xiaomiPlugin,
|
||||
zaiPlugin,
|
||||
zaloPlugin,
|
||||
zalouserPlugin,
|
||||
] as const;
|
||||
10
src/plugins/bundled-plugin-entries.ts
Normal file
10
src/plugins/bundled-plugin-entries.ts
Normal file
@@ -0,0 +1,10 @@
|
||||
import { GENERATED_BUNDLED_PLUGIN_ENTRIES } from "../generated/bundled-plugin-entries.generated.js";
|
||||
import type { OpenClawPluginDefinition } from "./types.js";
|
||||
|
||||
type BundledRegistrablePlugin = OpenClawPluginDefinition & {
|
||||
id: string;
|
||||
register: NonNullable<OpenClawPluginDefinition["register"]>;
|
||||
};
|
||||
|
||||
export const BUNDLED_PLUGIN_ENTRIES =
|
||||
GENERATED_BUNDLED_PLUGIN_ENTRIES as unknown as readonly BundledRegistrablePlugin[];
|
||||
@@ -1,46 +1,7 @@
|
||||
import amazonBedrockPlugin from "../../../extensions/amazon-bedrock/index.js";
|
||||
import anthropicPlugin from "../../../extensions/anthropic/index.js";
|
||||
import byteplusPlugin from "../../../extensions/byteplus/index.js";
|
||||
import chutesPlugin from "../../../extensions/chutes/index.js";
|
||||
import cloudflareAiGatewayPlugin from "../../../extensions/cloudflare-ai-gateway/index.js";
|
||||
import copilotProxyPlugin from "../../../extensions/copilot-proxy/index.js";
|
||||
import deepgramPlugin from "../../../extensions/deepgram/index.js";
|
||||
import deepseekPlugin from "../../../extensions/deepseek/index.js";
|
||||
import elevenLabsPlugin from "../../../extensions/elevenlabs/index.js";
|
||||
import falPlugin from "../../../extensions/fal/index.js";
|
||||
import githubCopilotPlugin from "../../../extensions/github-copilot/index.js";
|
||||
import googlePlugin from "../../../extensions/google/index.js";
|
||||
import groqPlugin from "../../../extensions/groq/index.js";
|
||||
import huggingFacePlugin from "../../../extensions/huggingface/index.js";
|
||||
import kilocodePlugin from "../../../extensions/kilocode/index.js";
|
||||
import kimiCodingPlugin from "../../../extensions/kimi-coding/index.js";
|
||||
import microsoftFoundryPlugin from "../../../extensions/microsoft-foundry/index.js";
|
||||
import microsoftPlugin from "../../../extensions/microsoft/index.js";
|
||||
import minimaxPlugin from "../../../extensions/minimax/index.js";
|
||||
import mistralPlugin from "../../../extensions/mistral/index.js";
|
||||
import modelStudioPlugin from "../../../extensions/modelstudio/index.js";
|
||||
import moonshotPlugin from "../../../extensions/moonshot/index.js";
|
||||
import nvidiaPlugin from "../../../extensions/nvidia/index.js";
|
||||
import ollamaPlugin from "../../../extensions/ollama/index.js";
|
||||
import openAIPlugin from "../../../extensions/openai/index.js";
|
||||
import opencodeGoPlugin from "../../../extensions/opencode-go/index.js";
|
||||
import opencodePlugin from "../../../extensions/opencode/index.js";
|
||||
import openrouterPlugin from "../../../extensions/openrouter/index.js";
|
||||
import qianfanPlugin from "../../../extensions/qianfan/index.js";
|
||||
import sglangPlugin from "../../../extensions/sglang/index.js";
|
||||
import syntheticPlugin from "../../../extensions/synthetic/index.js";
|
||||
import togetherPlugin from "../../../extensions/together/index.js";
|
||||
import venicePlugin from "../../../extensions/venice/index.js";
|
||||
import vercelAiGatewayPlugin from "../../../extensions/vercel-ai-gateway/index.js";
|
||||
import vllmPlugin from "../../../extensions/vllm/index.js";
|
||||
import volcenginePlugin from "../../../extensions/volcengine/index.js";
|
||||
import xaiPlugin from "../../../extensions/xai/index.js";
|
||||
import xiaomiPlugin from "../../../extensions/xiaomi/index.js";
|
||||
import zaiPlugin from "../../../extensions/zai/index.js";
|
||||
import { bundledWebSearchPluginRegistrations } from "../../bundled-web-search-registry.js";
|
||||
import { BUNDLED_PLUGIN_ENTRIES } from "../bundled-plugin-entries.js";
|
||||
import { createCapturedPluginRegistration } from "../captured-registration.js";
|
||||
import { loadPluginManifestRegistry } from "../manifest-registry.js";
|
||||
import { resolvePluginProviders } from "../provider-auth-choice.runtime.js";
|
||||
import type {
|
||||
ImageGenerationProviderPlugin,
|
||||
MediaUnderstandingProviderPlugin,
|
||||
@@ -118,28 +79,6 @@ function dedupePlugins<T extends RegistrablePlugin>(
|
||||
|
||||
export let providerContractLoadError: Error | undefined;
|
||||
|
||||
function loadBundledProviderRegistry(): ProviderContractEntry[] {
|
||||
try {
|
||||
providerContractLoadError = undefined;
|
||||
return resolvePluginProviders({
|
||||
bundledProviderAllowlistCompat: true,
|
||||
bundledProviderVitestCompat: true,
|
||||
cache: false,
|
||||
activate: false,
|
||||
})
|
||||
.filter((provider: ProviderPlugin): provider is ProviderPlugin & { pluginId: string } =>
|
||||
Boolean(provider.pluginId),
|
||||
)
|
||||
.map((provider: ProviderPlugin & { pluginId: string }) => ({
|
||||
pluginId: provider.pluginId,
|
||||
provider,
|
||||
}));
|
||||
} catch (error) {
|
||||
providerContractLoadError = error instanceof Error ? error : new Error(String(error));
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
function createLazyArrayView<T>(load: () => T[]): T[] {
|
||||
return new Proxy([] as T[], {
|
||||
get(_target, prop) {
|
||||
@@ -181,23 +120,21 @@ let mediaUnderstandingProviderContractRegistryCache:
|
||||
let imageGenerationProviderContractRegistryCache: ImageGenerationProviderContractEntry[] | null =
|
||||
null;
|
||||
let pluginRegistrationContractRegistryCache: PluginRegistrationContractEntry[] | null = null;
|
||||
let providerRegistrationEntriesLoaded = false;
|
||||
|
||||
function loadProviderContractRegistry(): ProviderContractEntry[] {
|
||||
if (!providerContractRegistryCache) {
|
||||
providerContractRegistryCache = buildCapabilityContractRegistry({
|
||||
plugins: bundledProviderPlugins,
|
||||
select: (captured) => captured.providers,
|
||||
}).map((entry) => ({
|
||||
pluginId: entry.pluginId,
|
||||
provider: entry.provider,
|
||||
}));
|
||||
}
|
||||
if (!providerRegistrationEntriesLoaded) {
|
||||
const registrationEntries = loadPluginRegistrationContractRegistry();
|
||||
if (!providerRegistrationEntriesLoaded) {
|
||||
mergeProviderContractRegistrations(registrationEntries, providerContractRegistryCache);
|
||||
providerRegistrationEntriesLoaded = true;
|
||||
try {
|
||||
providerContractLoadError = undefined;
|
||||
providerContractRegistryCache = buildCapabilityContractRegistry({
|
||||
plugins: bundledProviderPlugins,
|
||||
select: (captured) => captured.providers,
|
||||
}).map((entry) => ({
|
||||
pluginId: entry.pluginId,
|
||||
provider: entry.provider,
|
||||
}));
|
||||
} catch (error) {
|
||||
providerContractLoadError = error instanceof Error ? error : new Error(String(error));
|
||||
providerContractRegistryCache = [];
|
||||
}
|
||||
}
|
||||
return providerContractRegistryCache;
|
||||
@@ -243,7 +180,7 @@ export function requireProviderContractProvider(providerId: string): ProviderPlu
|
||||
const provider = uniqueProviderContractProviders.find((entry) => entry.id === providerId);
|
||||
if (!provider) {
|
||||
if (!providerContractLoadError) {
|
||||
loadBundledProviderRegistry();
|
||||
loadProviderContractRegistry();
|
||||
}
|
||||
if (providerContractLoadError) {
|
||||
throw new Error(
|
||||
@@ -338,92 +275,52 @@ export const mediaUnderstandingProviderContractRegistry: MediaUnderstandingProvi
|
||||
export const imageGenerationProviderContractRegistry: ImageGenerationProviderContractEntry[] =
|
||||
createLazyArrayView(loadImageGenerationProviderContractRegistry);
|
||||
|
||||
const bundledProviderPlugins = dedupePlugins([
|
||||
amazonBedrockPlugin,
|
||||
anthropicPlugin,
|
||||
byteplusPlugin,
|
||||
chutesPlugin,
|
||||
cloudflareAiGatewayPlugin,
|
||||
copilotProxyPlugin,
|
||||
deepseekPlugin,
|
||||
githubCopilotPlugin,
|
||||
falPlugin,
|
||||
googlePlugin,
|
||||
huggingFacePlugin,
|
||||
kilocodePlugin,
|
||||
kimiCodingPlugin,
|
||||
microsoftFoundryPlugin,
|
||||
minimaxPlugin,
|
||||
mistralPlugin,
|
||||
modelStudioPlugin,
|
||||
moonshotPlugin,
|
||||
nvidiaPlugin,
|
||||
ollamaPlugin,
|
||||
openAIPlugin,
|
||||
opencodePlugin,
|
||||
opencodeGoPlugin,
|
||||
openrouterPlugin,
|
||||
qianfanPlugin,
|
||||
sglangPlugin,
|
||||
syntheticPlugin,
|
||||
togetherPlugin,
|
||||
venicePlugin,
|
||||
vercelAiGatewayPlugin,
|
||||
vllmPlugin,
|
||||
volcenginePlugin,
|
||||
xaiPlugin,
|
||||
xiaomiPlugin,
|
||||
zaiPlugin,
|
||||
]);
|
||||
|
||||
const bundledRegistrablePluginsById = new Map(
|
||||
dedupePlugins([
|
||||
...bundledProviderPlugins,
|
||||
elevenLabsPlugin,
|
||||
microsoftPlugin,
|
||||
deepgramPlugin,
|
||||
groqPlugin,
|
||||
...bundledWebSearchPlugins,
|
||||
]).map((plugin) => [plugin.id, plugin]),
|
||||
dedupePlugins([...BUNDLED_PLUGIN_ENTRIES, ...bundledWebSearchPlugins]).map((plugin) => [
|
||||
plugin.id,
|
||||
plugin,
|
||||
]),
|
||||
);
|
||||
|
||||
function resolveBundledCapabilityPluginIds(
|
||||
capability: "speechProviders" | "mediaUnderstandingProviders" | "imageGenerationProviders",
|
||||
function resolveBundledManifestPluginIds(
|
||||
predicate: (plugin: ReturnType<typeof loadPluginManifestRegistry>["plugins"][number]) => boolean,
|
||||
): string[] {
|
||||
return loadPluginManifestRegistry({})
|
||||
.plugins.filter(
|
||||
(plugin) => plugin.origin === "bundled" && (plugin[capability]?.length ?? 0) > 0,
|
||||
)
|
||||
.plugins.filter((plugin) => plugin.origin === "bundled" && predicate(plugin))
|
||||
.map((plugin) => plugin.id)
|
||||
.toSorted((left, right) => left.localeCompare(right));
|
||||
}
|
||||
|
||||
function resolveBundledCapabilityPlugins(
|
||||
capability: "speechProviders" | "mediaUnderstandingProviders" | "imageGenerationProviders",
|
||||
function resolveBundledRegistrablePlugins(
|
||||
predicate: (plugin: ReturnType<typeof loadPluginManifestRegistry>["plugins"][number]) => boolean,
|
||||
): RegistrablePlugin[] {
|
||||
return resolveBundledCapabilityPluginIds(capability).flatMap((pluginId) => {
|
||||
return resolveBundledManifestPluginIds(predicate).flatMap((pluginId) => {
|
||||
const plugin = bundledRegistrablePluginsById.get(pluginId);
|
||||
return plugin ? [plugin] : [];
|
||||
});
|
||||
}
|
||||
|
||||
const bundledSpeechPlugins = resolveBundledCapabilityPlugins("speechProviders");
|
||||
const bundledMediaUnderstandingPlugins = resolveBundledCapabilityPlugins(
|
||||
"mediaUnderstandingProviders",
|
||||
const bundledProviderPlugins = resolveBundledRegistrablePlugins(
|
||||
(plugin) => plugin.providers.length > 0,
|
||||
);
|
||||
const bundledSpeechPlugins = resolveBundledRegistrablePlugins(
|
||||
(plugin) => (plugin.speechProviders?.length ?? 0) > 0,
|
||||
);
|
||||
const bundledMediaUnderstandingPlugins = resolveBundledRegistrablePlugins(
|
||||
(plugin) => (plugin.mediaUnderstandingProviders?.length ?? 0) > 0,
|
||||
);
|
||||
const bundledImageGenerationPlugins = resolveBundledRegistrablePlugins(
|
||||
(plugin) => (plugin.imageGenerationProviders?.length ?? 0) > 0,
|
||||
);
|
||||
const bundledImageGenerationPlugins = resolveBundledCapabilityPlugins("imageGenerationProviders");
|
||||
|
||||
const bundledPluginRegistrationList = dedupePlugins([
|
||||
...bundledProviderPlugins,
|
||||
...bundledSpeechPlugins,
|
||||
...bundledMediaUnderstandingPlugins,
|
||||
...bundledImageGenerationPlugins,
|
||||
...bundledWebSearchPlugins,
|
||||
]);
|
||||
|
||||
function mergeIds(existing: string[], next: string[]): string[] {
|
||||
return next.length > 0 ? next : existing;
|
||||
}
|
||||
|
||||
function upsertPluginRegistrationContractEntry(
|
||||
entries: PluginRegistrationContractEntry[],
|
||||
next: PluginRegistrationContractEntry,
|
||||
@@ -433,46 +330,27 @@ function upsertPluginRegistrationContractEntry(
|
||||
entries.push(next);
|
||||
return;
|
||||
}
|
||||
existing.cliBackendIds = mergeIds(existing.cliBackendIds, next.cliBackendIds);
|
||||
existing.providerIds = mergeIds(existing.providerIds, next.providerIds);
|
||||
existing.speechProviderIds = mergeIds(existing.speechProviderIds, next.speechProviderIds);
|
||||
existing.mediaUnderstandingProviderIds = mergeIds(
|
||||
existing.mediaUnderstandingProviderIds,
|
||||
next.mediaUnderstandingProviderIds,
|
||||
existing.cliBackendIds = [
|
||||
...new Set([...existing.cliBackendIds, ...next.cliBackendIds]),
|
||||
].toSorted((left, right) => left.localeCompare(right));
|
||||
existing.providerIds = [...new Set([...existing.providerIds, ...next.providerIds])].toSorted(
|
||||
(left, right) => left.localeCompare(right),
|
||||
);
|
||||
existing.imageGenerationProviderIds = mergeIds(
|
||||
existing.imageGenerationProviderIds,
|
||||
next.imageGenerationProviderIds,
|
||||
existing.speechProviderIds = [
|
||||
...new Set([...existing.speechProviderIds, ...next.speechProviderIds]),
|
||||
].toSorted((left, right) => left.localeCompare(right));
|
||||
existing.mediaUnderstandingProviderIds = [
|
||||
...new Set([...existing.mediaUnderstandingProviderIds, ...next.mediaUnderstandingProviderIds]),
|
||||
].toSorted((left, right) => left.localeCompare(right));
|
||||
existing.imageGenerationProviderIds = [
|
||||
...new Set([...existing.imageGenerationProviderIds, ...next.imageGenerationProviderIds]),
|
||||
].toSorted((left, right) => left.localeCompare(right));
|
||||
existing.webSearchProviderIds = [
|
||||
...new Set([...existing.webSearchProviderIds, ...next.webSearchProviderIds]),
|
||||
].toSorted((left, right) => left.localeCompare(right));
|
||||
existing.toolNames = [...new Set([...existing.toolNames, ...next.toolNames])].toSorted(
|
||||
(left, right) => left.localeCompare(right),
|
||||
);
|
||||
existing.webSearchProviderIds = mergeIds(
|
||||
existing.webSearchProviderIds,
|
||||
next.webSearchProviderIds,
|
||||
);
|
||||
existing.toolNames = mergeIds(existing.toolNames, next.toolNames);
|
||||
}
|
||||
|
||||
function mergeProviderContractRegistrations(
|
||||
registrationEntries: PluginRegistrationContractEntry[],
|
||||
providerEntries: ProviderContractEntry[],
|
||||
): void {
|
||||
const byPluginId = new Map<string, string[]>();
|
||||
for (const entry of providerEntries) {
|
||||
const providerIds = byPluginId.get(entry.pluginId) ?? [];
|
||||
providerIds.push(entry.provider.id);
|
||||
byPluginId.set(entry.pluginId, providerIds);
|
||||
}
|
||||
for (const [pluginId, providerIds] of byPluginId) {
|
||||
upsertPluginRegistrationContractEntry(registrationEntries, {
|
||||
pluginId,
|
||||
cliBackendIds: [],
|
||||
providerIds: providerIds.toSorted((left, right) => left.localeCompare(right)),
|
||||
speechProviderIds: [],
|
||||
mediaUnderstandingProviderIds: [],
|
||||
imageGenerationProviderIds: [],
|
||||
webSearchProviderIds: [],
|
||||
toolNames: [],
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function loadPluginRegistrationContractRegistry(): PluginRegistrationContractEntry[] {
|
||||
@@ -497,13 +375,6 @@ function loadPluginRegistrationContractRegistry(): PluginRegistrationContractEnt
|
||||
}
|
||||
pluginRegistrationContractRegistryCache = entries;
|
||||
}
|
||||
if (providerContractRegistryCache && !providerRegistrationEntriesLoaded) {
|
||||
mergeProviderContractRegistrations(
|
||||
pluginRegistrationContractRegistryCache,
|
||||
providerContractRegistryCache,
|
||||
);
|
||||
providerRegistrationEntriesLoaded = true;
|
||||
}
|
||||
return pluginRegistrationContractRegistryCache;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user