mirror of
https://github.com/openclaw/openclaw.git
synced 2026-03-19 14:00:51 +00:00
Contracts: harden provider registry loading
This commit is contained in:
@@ -1,15 +1,11 @@
|
||||
import { ensureAuthProfileStore, listProfilesForProvider } from "openclaw/plugin-sdk/agent-runtime";
|
||||
import {
|
||||
definePluginEntry,
|
||||
type ProviderAuthContext,
|
||||
type ProviderResolveDynamicModelContext,
|
||||
type ProviderRuntimeModel,
|
||||
} from "openclaw/plugin-sdk/core";
|
||||
import {
|
||||
coerceSecretRef,
|
||||
ensureAuthProfileStore,
|
||||
githubCopilotLoginCommand,
|
||||
listProfilesForProvider,
|
||||
} from "openclaw/plugin-sdk/provider-auth";
|
||||
import { coerceSecretRef, githubCopilotLoginCommand } from "openclaw/plugin-sdk/provider-auth";
|
||||
import { normalizeModelCompat } from "openclaw/plugin-sdk/provider-models";
|
||||
import { DEFAULT_COPILOT_API_BASE_URL, resolveCopilotApiToken } from "./token.js";
|
||||
import { fetchCopilotUsage } from "./usage.js";
|
||||
|
||||
@@ -1,7 +1,14 @@
|
||||
import { describe } from "vitest";
|
||||
import { providerContractRegistry } from "./registry.js";
|
||||
import { describe, expect, it } from "vitest";
|
||||
import { providerContractLoadError, providerContractRegistry } from "./registry.js";
|
||||
import { installProviderPluginContractSuite } from "./suites.js";
|
||||
|
||||
describe("provider contract registry load", () => {
|
||||
it("loads bundled providers without import-time registry failure", () => {
|
||||
expect(providerContractLoadError).toBeUndefined();
|
||||
expect(providerContractRegistry.length).toBeGreaterThan(0);
|
||||
});
|
||||
});
|
||||
|
||||
for (const entry of providerContractRegistry) {
|
||||
describe(`${entry.pluginId}:${entry.provider.id} provider contract`, () => {
|
||||
installProviderPluginContractSuite({
|
||||
|
||||
@@ -99,19 +99,31 @@ export const providerContractRegistry: ProviderContractEntry[] = buildCapability
|
||||
select: () => [],
|
||||
});
|
||||
|
||||
const loadedBundledProviderRegistry: ProviderContractEntry[] = resolvePluginProviders({
|
||||
bundledProviderAllowlistCompat: true,
|
||||
bundledProviderVitestCompat: true,
|
||||
cache: false,
|
||||
activate: false,
|
||||
})
|
||||
.filter((provider): provider is ProviderPlugin & { pluginId: string } =>
|
||||
Boolean(provider.pluginId),
|
||||
)
|
||||
.map((provider) => ({
|
||||
pluginId: provider.pluginId,
|
||||
provider,
|
||||
}));
|
||||
export let providerContractLoadError: Error | undefined;
|
||||
|
||||
function loadBundledProviderRegistry(): ProviderContractEntry[] {
|
||||
try {
|
||||
providerContractLoadError = undefined;
|
||||
return resolvePluginProviders({
|
||||
bundledProviderAllowlistCompat: true,
|
||||
bundledProviderVitestCompat: true,
|
||||
cache: false,
|
||||
activate: false,
|
||||
})
|
||||
.filter((provider): provider is ProviderPlugin & { pluginId: string } =>
|
||||
Boolean(provider.pluginId),
|
||||
)
|
||||
.map((provider) => ({
|
||||
pluginId: provider.pluginId,
|
||||
provider,
|
||||
}));
|
||||
} catch (error) {
|
||||
providerContractLoadError = error instanceof Error ? error : new Error(String(error));
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
const loadedBundledProviderRegistry: ProviderContractEntry[] = loadBundledProviderRegistry();
|
||||
|
||||
providerContractRegistry.splice(
|
||||
0,
|
||||
@@ -134,6 +146,11 @@ export const providerContractCompatPluginIds = providerContractPluginIds.map((pl
|
||||
export function requireProviderContractProvider(providerId: string): ProviderPlugin {
|
||||
const provider = uniqueProviderContractProviders.find((entry) => entry.id === providerId);
|
||||
if (!provider) {
|
||||
if (providerContractLoadError) {
|
||||
throw new Error(
|
||||
`provider contract entry missing for ${providerId}; bundled provider registry failed to load: ${providerContractLoadError.message}`,
|
||||
);
|
||||
}
|
||||
throw new Error(`provider contract entry missing for ${providerId}`);
|
||||
}
|
||||
return provider;
|
||||
|
||||
Reference in New Issue
Block a user