manifest
Version:
Self-hosted Manifest LLM router with embedded server, SQLite database, and dashboard
176 lines • 8.58 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); }
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.AgentsController = void 0;
const common_1 = require("@nestjs/common");
const typeorm_1 = require("typeorm");
const cache_manager_1 = require("@nestjs/cache-manager");
const config_1 = require("@nestjs/config");
const timeseries_queries_service_1 = require("../services/timeseries-queries.service");
const agent_lifecycle_service_1 = require("../services/agent-lifecycle.service");
const api_key_service_1 = require("../../otlp/services/api-key.service");
const current_user_decorator_1 = require("../../auth/current-user.decorator");
const create_agent_dto_1 = require("../../common/dto/create-agent.dto");
const rename_agent_dto_1 = require("../../common/dto/rename-agent.dto");
const user_cache_interceptor_1 = require("../../common/interceptors/user-cache.interceptor");
const cache_constants_1 = require("../../common/constants/cache.constants");
const local_mode_constants_1 = require("../../common/constants/local-mode.constants");
const slugify_1 = require("../../common/utils/slugify");
const tenant_cache_service_1 = require("../../common/services/tenant-cache.service");
let AgentsController = class AgentsController {
timeseries;
lifecycle;
apiKeyGenerator;
config;
tenantCache;
cacheManager;
constructor(timeseries, lifecycle, apiKeyGenerator, config, tenantCache, cacheManager) {
this.timeseries = timeseries;
this.lifecycle = lifecycle;
this.apiKeyGenerator = apiKeyGenerator;
this.config = config;
this.tenantCache = tenantCache;
this.cacheManager = cacheManager;
}
agentListCacheKey(userId) {
return `${userId}:/api/v1/agents`;
}
async getAgents(user) {
const tenantId = (await this.tenantCache.resolve(user.id)) ?? undefined;
const agents = await this.timeseries.getAgentList(user.id, tenantId);
return { agents };
}
async createAgent(user, body) {
const slug = (0, slugify_1.slugify)(body.name);
if (!slug) {
throw new common_1.BadRequestException('Agent name produces an empty slug');
}
const displayName = body.name.trim();
let result;
try {
result = await this.apiKeyGenerator.onboardAgent({
tenantName: user.id,
agentName: slug,
displayName,
email: user.email,
});
}
catch (error) {
if (error instanceof typeorm_1.QueryFailedError && /unique|duplicate/i.test(error.message)) {
throw new common_1.ConflictException(`Agent "${slug}" already exists`);
}
throw error;
}
await this.cacheManager.del(this.agentListCacheKey(user.id));
return {
agent: { id: result.agentId, name: slug, display_name: displayName },
apiKey: result.apiKey,
};
}
async getAgentKey(user, agentName) {
const keyData = await this.apiKeyGenerator.getKeyForAgent(user.id, agentName);
const customEndpoint = this.config.get('app.pluginOtlpEndpoint', '');
const isLocal = this.config.get('MANIFEST_MODE') === 'local';
const localKey = isLocal && agentName === local_mode_constants_1.LOCAL_AGENT_NAME ? (0, local_mode_constants_1.readLocalApiKey)() : undefined;
const apiKey = localKey ?? keyData.fullKey ?? undefined;
return {
keyPrefix: keyData.keyPrefix,
...(apiKey ? { apiKey } : {}),
...(customEndpoint ? { pluginEndpoint: customEndpoint } : {}),
};
}
async rotateAgentKey(user, agentName) {
const result = await this.apiKeyGenerator.rotateKey(user.id, agentName);
return { apiKey: result.apiKey };
}
async renameAgent(user, agentName, body) {
const slug = (0, slugify_1.slugify)(body.name);
if (!slug) {
throw new common_1.BadRequestException('Agent name produces an empty slug');
}
const displayName = body.name.trim();
await this.lifecycle.renameAgent(user.id, agentName, slug, displayName);
await this.cacheManager.del(this.agentListCacheKey(user.id));
return { renamed: true, name: slug, display_name: displayName };
}
async deleteAgent(user, agentName) {
if (this.config.get('MANIFEST_MODE') === 'local' && agentName === local_mode_constants_1.LOCAL_AGENT_NAME) {
throw new common_1.ForbiddenException('Cannot delete the default local agent');
}
await this.lifecycle.deleteAgent(user.id, agentName);
await this.cacheManager.del(this.agentListCacheKey(user.id));
return { deleted: true };
}
};
exports.AgentsController = AgentsController;
__decorate([
(0, common_1.Get)('agents'),
(0, common_1.UseInterceptors)(user_cache_interceptor_1.UserCacheInterceptor),
(0, cache_manager_1.CacheTTL)(cache_constants_1.AGENT_LIST_CACHE_TTL_MS),
__param(0, (0, current_user_decorator_1.CurrentUser)()),
__metadata("design:type", Function),
__metadata("design:paramtypes", [Object]),
__metadata("design:returntype", Promise)
], AgentsController.prototype, "getAgents", null);
__decorate([
(0, common_1.Post)('agents'),
__param(0, (0, current_user_decorator_1.CurrentUser)()),
__param(1, (0, common_1.Body)()),
__metadata("design:type", Function),
__metadata("design:paramtypes", [Object, create_agent_dto_1.CreateAgentDto]),
__metadata("design:returntype", Promise)
], AgentsController.prototype, "createAgent", null);
__decorate([
(0, common_1.Get)('agents/:agentName/key'),
__param(0, (0, current_user_decorator_1.CurrentUser)()),
__param(1, (0, common_1.Param)('agentName')),
__metadata("design:type", Function),
__metadata("design:paramtypes", [Object, String]),
__metadata("design:returntype", Promise)
], AgentsController.prototype, "getAgentKey", null);
__decorate([
(0, common_1.Post)('agents/:agentName/rotate-key'),
__param(0, (0, current_user_decorator_1.CurrentUser)()),
__param(1, (0, common_1.Param)('agentName')),
__metadata("design:type", Function),
__metadata("design:paramtypes", [Object, String]),
__metadata("design:returntype", Promise)
], AgentsController.prototype, "rotateAgentKey", null);
__decorate([
(0, common_1.Patch)('agents/:agentName'),
__param(0, (0, current_user_decorator_1.CurrentUser)()),
__param(1, (0, common_1.Param)('agentName')),
__param(2, (0, common_1.Body)()),
__metadata("design:type", Function),
__metadata("design:paramtypes", [Object, String, rename_agent_dto_1.RenameAgentDto]),
__metadata("design:returntype", Promise)
], AgentsController.prototype, "renameAgent", null);
__decorate([
(0, common_1.Delete)('agents/:agentName'),
__param(0, (0, current_user_decorator_1.CurrentUser)()),
__param(1, (0, common_1.Param)('agentName')),
__metadata("design:type", Function),
__metadata("design:paramtypes", [Object, String]),
__metadata("design:returntype", Promise)
], AgentsController.prototype, "deleteAgent", null);
exports.AgentsController = AgentsController = __decorate([
(0, common_1.Controller)('api/v1'),
__param(5, (0, common_1.Inject)(cache_manager_1.CACHE_MANAGER)),
__metadata("design:paramtypes", [timeseries_queries_service_1.TimeseriesQueriesService,
agent_lifecycle_service_1.AgentLifecycleService,
api_key_service_1.ApiKeyGeneratorService,
config_1.ConfigService,
tenant_cache_service_1.TenantCacheService, Object])
], AgentsController);
//# sourceMappingURL=agents.controller.js.map