2026-03-15 16:09:40 -07:00

83 lines
2.8 KiB
TypeScript

import { emptyPluginConfigSchema, type OpenClawPluginApi } from "openclaw/plugin-sdk/core";
import { ensureAuthProfileStore, listProfilesForProvider } from "../../src/agents/auth-profiles.js";
import {
buildCloudflareAiGatewayModelDefinition,
resolveCloudflareAiGatewayBaseUrl,
} from "../../src/agents/cloudflare-ai-gateway.js";
import { resolveNonEnvSecretRefApiKeyMarker } from "../../src/agents/model-auth-markers.js";
import { coerceSecretRef } from "../../src/config/types.secrets.js";
const PROVIDER_ID = "cloudflare-ai-gateway";
const PROVIDER_ENV_VAR = "CLOUDFLARE_AI_GATEWAY_API_KEY";
function resolveApiKeyFromCredential(
cred: ReturnType<typeof ensureAuthProfileStore>["profiles"][string] | undefined,
): string | undefined {
if (!cred || cred.type !== "api_key") {
return undefined;
}
const keyRef = coerceSecretRef(cred.keyRef);
if (keyRef && keyRef.id.trim()) {
return keyRef.source === "env"
? keyRef.id.trim()
: resolveNonEnvSecretRefApiKeyMarker(keyRef.source);
}
return cred.key?.trim() || undefined;
}
const cloudflareAiGatewayPlugin = {
id: PROVIDER_ID,
name: "Cloudflare AI Gateway Provider",
description: "Bundled Cloudflare AI Gateway provider plugin",
configSchema: emptyPluginConfigSchema(),
register(api: OpenClawPluginApi) {
api.registerProvider({
id: PROVIDER_ID,
label: "Cloudflare AI Gateway",
docsPath: "/providers/cloudflare-ai-gateway",
envVars: ["CLOUDFLARE_AI_GATEWAY_API_KEY"],
auth: [],
catalog: {
order: "late",
run: async (ctx) => {
const authStore = ensureAuthProfileStore(ctx.agentDir, {
allowKeychainPrompt: false,
});
const envManagedApiKey = ctx.env[PROVIDER_ENV_VAR]?.trim() ? PROVIDER_ENV_VAR : undefined;
for (const profileId of listProfilesForProvider(authStore, PROVIDER_ID)) {
const cred = authStore.profiles[profileId];
if (!cred || cred.type !== "api_key") {
continue;
}
const apiKey = envManagedApiKey ?? resolveApiKeyFromCredential(cred);
if (!apiKey) {
continue;
}
const accountId = cred.metadata?.accountId?.trim();
const gatewayId = cred.metadata?.gatewayId?.trim();
if (!accountId || !gatewayId) {
continue;
}
const baseUrl = resolveCloudflareAiGatewayBaseUrl({ accountId, gatewayId });
if (!baseUrl) {
continue;
}
return {
provider: {
baseUrl,
api: "anthropic-messages",
apiKey,
models: [buildCloudflareAiGatewayModelDefinition()],
},
};
}
return null;
},
},
});
},
};
export default cloudflareAiGatewayPlugin;