UNPKG

manifest

Version:

Self-hosted Manifest LLM router with embedded server, SQLite database, and dashboard

190 lines 9.76 kB
"use strict"; var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; return c > 3 && r && Object.defineProperty(target, key, r), r; }; var __metadata = (this && this.__metadata) || function (k, v) { if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v); }; var __param = (this && this.__param) || function (paramIndex, decorator) { return function (target, key) { decorator(target, key, paramIndex); } }; var ProviderKeyService_1; Object.defineProperty(exports, "__esModule", { value: true }); exports.ProviderKeyService = void 0; const common_1 = require("@nestjs/common"); const typeorm_1 = require("@nestjs/typeorm"); const typeorm_2 = require("typeorm"); const user_provider_entity_1 = require("../../entities/user-provider.entity"); const model_pricing_cache_service_1 = require("../../model-prices/model-pricing-cache.service"); const model_discovery_service_1 = require("../../model-discovery/model-discovery.service"); const routing_cache_service_1 = require("./routing-cache.service"); const provider_service_1 = require("./provider.service"); const crypto_util_1 = require("../../common/utils/crypto.util"); const provider_aliases_1 = require("../../common/utils/provider-aliases"); const subscription_support_1 = require("../../common/utils/subscription-support"); let ProviderKeyService = ProviderKeyService_1 = class ProviderKeyService { providerRepo; pricingCache; discoveryService; routingCache; providerService; logger = new common_1.Logger(ProviderKeyService_1.name); constructor(providerRepo, pricingCache, discoveryService, routingCache, providerService) { this.providerRepo = providerRepo; this.pricingCache = pricingCache; this.discoveryService = discoveryService; this.routingCache = routingCache; this.providerService = providerService; } async getProviderApiKey(agentId, provider, authType) { if (provider.toLowerCase() === 'ollama') return ''; const cached = this.routingCache.getApiKey(agentId, provider, authType); if (cached !== undefined) return cached; const result = await this.resolveProviderApiKey(agentId, provider, authType); this.routingCache.setApiKey(agentId, provider, result, authType); return result; } async getAuthType(agentId, provider, excludeAuthTypes) { const names = (0, provider_aliases_1.expandProviderNames)([provider]); const records = await this.providerService.getProviders(agentId); let matches = records.filter((r) => r.is_active && names.has(r.provider.toLowerCase())); if (excludeAuthTypes && excludeAuthTypes.size > 0) { const filtered = matches.filter((r) => !excludeAuthTypes.has(r.auth_type)); if (filtered.length > 0) matches = filtered; } const subMatch = matches.find((r) => r.auth_type === 'subscription' && r.api_key_encrypted); if (subMatch) return 'subscription'; const withKey = matches.find((r) => r.api_key_encrypted); return withKey?.auth_type ?? matches[0]?.auth_type ?? 'api_key'; } async hasActiveProvider(agentId, provider) { const names = (0, provider_aliases_1.expandProviderNames)([provider]); const records = await this.providerService.getProviders(agentId); return records.some((r) => r.is_active && names.has(r.provider.toLowerCase())); } async getProviderRegion(agentId, provider, authType) { const names = (0, provider_aliases_1.expandProviderNames)([provider]); const records = await this.providerService.getProviders(agentId); const matches = records.filter((r) => r.is_active && names.has(r.provider.toLowerCase())); const match = authType ? matches.find((r) => r.auth_type === authType) : matches[0]; return match?.region ?? null; } async findProviderForModel(agentId, model) { const providers = await this.providerService.getProviders(agentId); for (const p of providers) { if (!p.cached_models) continue; if (p.cached_models.some((m) => m.id === model)) return p.provider; } return undefined; } async getEffectiveModel(agentId, assignment) { if (assignment.override_model !== null) { if (await this.isModelAvailable(agentId, assignment.override_model)) { return assignment.override_model; } this.logger.warn(`Override ${assignment.override_model} falling through to auto ` + `for agent=${agentId} tier=${assignment.tier} ` + `(auto=${assignment.auto_assigned_model})`); } if (assignment.auto_assigned_model === null) { this.logger.warn(`auto_assigned_model is null for agent=${agentId} tier=${assignment.tier}`); } return assignment.auto_assigned_model; } async resolveProviderApiKey(agentId, provider, preferredAuthType) { if (provider.startsWith('custom:')) { const record = await this.providerRepo.findOne({ where: { agent_id: agentId, provider, is_active: true }, }); if (!record) return null; if (!record.api_key_encrypted) return ''; try { return (0, crypto_util_1.decrypt)(record.api_key_encrypted, (0, crypto_util_1.getEncryptionSecret)()); } catch { this.logger.warn(`Failed to decrypt API key for custom provider ${provider}`); return null; } } const names = (0, provider_aliases_1.expandProviderNames)([provider]); const records = await this.providerRepo.find({ where: { agent_id: agentId, is_active: true }, }); const matches = records.filter((r) => (0, subscription_support_1.isManifestUsableProvider)(r) && names.has(r.provider.toLowerCase())); if (matches.length === 0) return null; const candidates = preferredAuthType ? matches.filter((m) => m.auth_type === preferredAuthType) : [...matches].sort((a, b) => { const aPref = a.auth_type === 'api_key' ? 0 : 1; const bPref = b.auth_type === 'api_key' ? 0 : 1; return aPref - bPref; }); for (const match of candidates) { if (!match.api_key_encrypted) continue; try { return (0, crypto_util_1.decrypt)(match.api_key_encrypted, (0, crypto_util_1.getEncryptionSecret)()); } catch { const label = match.auth_type === 'subscription' ? 'token' : 'API key'; this.logger.warn(`Failed to decrypt ${label} for provider ${provider}`); } } return null; } async isModelAvailable(agentId, model) { const discovered = await this.discoveryService.getModelForAgent(agentId, model); if (discovered) return true; const pricing = this.pricingCache.getByModel(model); const inferredPrefix = (0, provider_aliases_1.inferProviderFromModelName)(model); const pricingNames = pricing ? (0, provider_aliases_1.expandProviderNames)([pricing.provider]) : null; const inferredNames = inferredPrefix ? (0, provider_aliases_1.expandProviderNames)([inferredPrefix]) : null; if (pricingNames?.has('qwen') || inferredNames?.has('qwen')) { return false; } const records = (await this.providerRepo.find({ where: { agent_id: agentId, is_active: true }, })).filter(subscription_support_1.isManifestUsableProvider); if (pricing) { const names = (0, provider_aliases_1.expandProviderNames)([pricing.provider]); if (records.find((r) => names.has(r.provider.toLowerCase()))) return true; const canonicalPrefix = (0, provider_aliases_1.inferProviderFromModelName)(pricing.model_name); if (canonicalPrefix) { const cpNames = (0, provider_aliases_1.expandProviderNames)([canonicalPrefix]); if (records.find((r) => cpNames.has(r.provider.toLowerCase()))) return true; } } if (inferredPrefix) { const prefixNames = (0, provider_aliases_1.expandProviderNames)([inferredPrefix]); if (records.find((r) => prefixNames.has(r.provider.toLowerCase()))) return true; } return false; } }; exports.ProviderKeyService = ProviderKeyService; exports.ProviderKeyService = ProviderKeyService = ProviderKeyService_1 = __decorate([ (0, common_1.Injectable)(), __param(0, (0, typeorm_1.InjectRepository)(user_provider_entity_1.UserProvider)), __metadata("design:paramtypes", [typeorm_2.Repository, model_pricing_cache_service_1.ModelPricingCacheService, model_discovery_service_1.ModelDiscoveryService, routing_cache_service_1.RoutingCacheService, provider_service_1.ProviderService]) ], ProviderKeyService); //# sourceMappingURL=provider-key.service.js.map