manifest
Version:
Self-hosted Manifest LLM router with embedded server, SQLite database, and dashboard
190 lines • 9.76 kB
JavaScript
;
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