Files
Jyotisha/frontend/src/lib/model-provider-policy.ts
T

53 lines
1.9 KiB
TypeScript

import { decryptEpayKey, encryptEpayKey } from "./epay/encryption-core.ts";
export type ModelProviderType = "openai" | "openai-compatible" | "anthropic";
export type ModelProviderCredential = Readonly<{
encryptedApiKey: string | null;
}>;
function encryptionMasterKey(environment: Readonly<Record<string, string | undefined>> = process.env) {
return environment.MODEL_PROVIDER_CONFIG_ENCRYPTION_KEY?.trim() ?? "";
}
export function encryptModelProviderApiKey(
apiKey: string,
environment: Readonly<Record<string, string | undefined>> = process.env,
) {
return encryptEpayKey(apiKey.trim(), encryptionMasterKey(environment));
}
export function decryptModelProviderApiKey(
provider: ModelProviderCredential,
environment: Readonly<Record<string, string | undefined>> = process.env,
) {
if (!provider.encryptedApiKey) return "";
return decryptEpayKey(provider.encryptedApiKey, encryptionMasterKey(environment));
}
export function modelProviderModelsUrl(provider: Readonly<{
providerType: ModelProviderType;
baseUrl: string | null;
}>) {
if (provider.providerType === "openai") return "https://api.openai.com/v1/models";
if (provider.providerType === "anthropic") return "https://api.anthropic.com/v1/models";
const url = new URL(provider.baseUrl ?? "");
url.username = "";
url.password = "";
url.search = "";
url.hash = "";
const basePath = url.pathname.replace(/\/+$/, "");
url.pathname = basePath.endsWith("/models") ? basePath : `${basePath}/models`;
return url.toString();
}
export function modelProviderRequestHeaders(providerType: ModelProviderType, apiKey: string): Readonly<Record<string, string>> {
return providerType === "anthropic"
? { "x-api-key": apiKey, "anthropic-version": "2023-06-01" }
: { authorization: `Bearer ${apiKey}` };
}
export function modelConnectionTestSucceeded(status: number) {
return status >= 200 && status <= 299;
}