@mastra/core
Version:
180 lines (173 loc) • 6.71 kB
JavaScript
import { shouldEnableGateway, getGatewayId } from './chunk-26L3FC2R.js';
import fs from 'fs/promises';
import path from 'path';
function hasAttachmentCapabilities(gateway) {
return "getAttachmentCapabilities" in gateway && typeof gateway.getAttachmentCapabilities === "function";
}
function hasTemperatureCapabilities(gateway) {
return "getTemperatureCapabilities" in gateway && typeof gateway.getTemperatureCapabilities === "function";
}
async function atomicWriteFile(filePath, content, encoding = "utf-8") {
const randomSuffix = Math.random().toString(36).substring(2, 15);
const tempPath = `${filePath}.${process.pid}.${Date.now()}.${randomSuffix}.tmp`;
try {
await fs.writeFile(tempPath, content, encoding);
await fs.rename(tempPath, filePath);
} catch (error) {
try {
await fs.unlink(tempPath);
} catch {
}
throw error;
}
}
async function fetchProvidersFromGateways(gateways) {
const enabledGateways = [];
for (const gateway of gateways) {
if (shouldEnableGateway(gateway)) {
enabledGateways.push(gateway);
}
}
const allProviders = {};
const allModels = {};
const allAttachmentCapabilities = {};
const allTemperatureCapabilities = {};
const failedGateways = [];
const maxRetries = 3;
for (const gateway of enabledGateways) {
let providers = null;
for (let attempt = 1; attempt <= maxRetries; attempt++) {
try {
providers = await gateway.fetchProviders();
break;
} catch {
if (attempt < maxRetries) {
const delayMs = Math.min(1e3 * Math.pow(2, attempt - 1), 5e3);
await new Promise((resolve) => setTimeout(resolve, delayMs));
}
}
}
if (!providers) {
failedGateways.push(getGatewayId(gateway));
continue;
}
const gatewayId = getGatewayId(gateway);
const isProviderRegistry = gatewayId === "models.dev";
const gatewayAttachmentCaps = hasAttachmentCapabilities(gateway) ? gateway.getAttachmentCapabilities() : void 0;
const gatewayTemperatureCaps = hasTemperatureCapabilities(gateway) ? gateway.getTemperatureCapabilities() : void 0;
for (const [providerId, config] of Object.entries(providers)) {
const typeProviderId = isProviderRegistry ? providerId : providerId === gatewayId ? gatewayId : `${gatewayId}/${providerId}`;
allProviders[typeProviderId] = config;
allModels[typeProviderId] = config.models.sort();
if (gatewayAttachmentCaps?.[providerId]) {
allAttachmentCapabilities[typeProviderId] = gatewayAttachmentCaps[providerId];
}
if (gatewayTemperatureCaps?.[providerId]) {
allTemperatureCapabilities[typeProviderId] = gatewayTemperatureCaps[providerId];
}
}
}
return {
providers: allProviders,
models: allModels,
attachmentCapabilities: allAttachmentCapabilities,
temperatureCapabilities: allTemperatureCapabilities,
failedGateways
};
}
function generateTypesContent(models) {
const providerModelsEntries = Object.entries(models).map(([provider, modelList]) => {
const modelsList = modelList.map((m) => `'${m}'`);
const needsQuotes = !/^[a-zA-Z_$][a-zA-Z0-9_$]*$/.test(provider);
const providerKey = needsQuotes ? `'${provider}'` : provider;
const singleLine = ` readonly ${providerKey}: readonly [${modelsList.join(", ")}];`;
if (singleLine.length > 120) {
const formattedModels = modelList.map((m) => ` '${m}',`).join("\n");
return ` readonly ${providerKey}: readonly [
${formattedModels}
];`;
}
return singleLine;
}).join("\n");
return `/**
* THIS FILE IS AUTO-GENERATED - DO NOT EDIT
* Generated from model gateway providers
*/
/**
* Provider models mapping type
* This is derived from the JSON data and provides type-safe access
*/
export type ProviderModelsMap = {
${providerModelsEntries}
};
/**
* Union type of all registered provider IDs
*/
export type Provider = keyof ProviderModelsMap;
/**
* Provider models mapping interface
*/
export interface ProviderModels {
[key: string]: string[];
}
/**
* OpenAI-compatible model ID type
* Dynamically derived from ProviderModelsMap
* Full provider/model paths (e.g., "openai/gpt-4o", "anthropic/claude-3-5-sonnet-20241022")
*/
export type ModelRouterModelId =
| {
[P in Provider]: \`\${P}/\${ProviderModelsMap[P][number]}\`;
}[Provider]
| \`mastra/\${ProviderModelsMap['openrouter'][number]}\`
| (string & {});
/**
* Extract the model part from a ModelRouterModelId for a specific provider
* Dynamically derived from ProviderModelsMap
* Example: ModelForProvider<'openai'> = 'gpt-4o' | 'gpt-4-turbo' | ...
*/
export type ModelForProvider<P extends Provider> = ProviderModelsMap[P][number];
`;
}
async function writeRegistryFiles(jsonPath, typesPath, providers, models, attachmentCapabilities, temperatureCapabilities) {
const jsonDir = path.dirname(jsonPath);
const typesDir = path.dirname(typesPath);
await fs.mkdir(jsonDir, { recursive: true });
await fs.mkdir(typesDir, { recursive: true });
const registryData = {
providers,
models,
version: "1.0.0"
};
await atomicWriteFile(jsonPath, JSON.stringify(registryData, null, 2), "utf-8");
const typeContent = generateTypesContent(models);
await atomicWriteFile(typesPath, typeContent, "utf-8");
const hasCapabilities = attachmentCapabilities && Object.keys(attachmentCapabilities).length > 0 || temperatureCapabilities && Object.keys(temperatureCapabilities).length > 0;
if (hasCapabilities) {
const capDir = path.join(jsonDir, "capabilities");
await fs.mkdir(capDir, { recursive: true });
try {
const existing = await fs.readdir(capDir);
for (const file of existing) {
if (file.endsWith(".json")) {
await fs.unlink(path.join(capDir, file));
}
}
} catch {
}
const allProviderIds = /* @__PURE__ */ new Set([
...attachmentCapabilities ? Object.keys(attachmentCapabilities) : [],
...temperatureCapabilities ? Object.keys(temperatureCapabilities) : []
]);
for (const provider of allProviderIds) {
const capData = {};
if (attachmentCapabilities?.[provider]) capData.attachment = attachmentCapabilities[provider];
if (temperatureCapabilities?.[provider]) capData.temperature = temperatureCapabilities[provider];
const providerFile = path.join(capDir, `${provider}.json`);
await atomicWriteFile(providerFile, JSON.stringify(capData, null, 2), "utf-8");
}
}
}
export { atomicWriteFile, fetchProvidersFromGateways, generateTypesContent, writeRegistryFiles };
//# sourceMappingURL=registry-generator-XJSWEAGI.js.map
//# sourceMappingURL=registry-generator-XJSWEAGI.js.map