UNPKG

n8n

Version:

n8n Workflow Automation Tool

255 lines • 12.7 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); }; Object.defineProperty(exports, "__esModule", { value: true }); exports.AgentsService = void 0; const agent_config_1 = require("@n8n/ai-utilities/agent-config"); const api_types_1 = require("@n8n/api-types"); const backend_common_1 = require("@n8n/backend-common"); const db_1 = require("@n8n/db"); const di_1 = require("@n8n/di"); const permissions_1 = require("@n8n/permissions"); const uuid_1 = require("uuid"); const conflict_error_1 = require("../../errors/response-errors/conflict.error"); const not_found_error_1 = require("../../errors/response-errors/not-found.error"); const agent_chat_attachment_service_1 = require("./agent-chat-attachment.service"); const agent_knowledge_service_1 = require("./agent-knowledge.service"); const agent_execution_service_1 = require("./agent-execution.service"); const agent_runtime_cache_service_1 = require("./agent-runtime-cache.service"); const agent_test_chat_service_1 = require("./agent-test-chat.service"); const chat_integration_service_1 = require("./integrations/chat-integration.service"); const agent_task_repository_1 = require("./repositories/agent-task.repository"); const agent_config_composition_1 = require("./json-config/agent-config-composition"); const agent_repository_1 = require("./repositories/agent.repository"); const sub_agent_cleanup_service_1 = require("./sub-agents/sub-agent-cleanup.service"); const agent_capabilities_1 = require("./utils/agent-capabilities"); const event_service_1 = require("../../events/event.service"); let AgentsService = class AgentsService { constructor(logger, agentRepository, projectRelationRepository, agentChatAttachmentService, agentKnowledgeService, runtimeCacheService, testChatService, agentTaskRepository, subAgentCleanupService, eventService, agentExecutionService) { this.logger = logger; this.agentRepository = agentRepository; this.projectRelationRepository = projectRelationRepository; this.agentChatAttachmentService = agentChatAttachmentService; this.agentKnowledgeService = agentKnowledgeService; this.runtimeCacheService = runtimeCacheService; this.testChatService = testChatService; this.agentTaskRepository = agentTaskRepository; this.subAgentCleanupService = subAgentCleanupService; this.eventService = eventService; this.agentExecutionService = agentExecutionService; } async create(projectId, name, { availableInMCP = false, id, adoptUnconfiguredOnCollision = false, schema, skills, } = {}) { const defaultConfig = { name, model: '', instructions: '', tools: [], skills: [], personalisation: { icon: api_types_1.DEFAULT_AGENT_PERSONALISATION.icon, gradient: (0, api_types_1.getRandomAgentPersonalisationGradient)(), }, }; const { schemaConfig, integrations } = (0, agent_config_composition_1.decomposeJsonConfig)(schema ?? defaultConfig); const agent = this.agentRepository.create({ ...(id ? { id } : {}), name, projectId, schema: schemaConfig, ...(integrations.length > 0 ? { integrations } : {}), ...(skills ? { skills } : {}), versionId: (0, uuid_1.v4)(), availableInMCP, }); let saved; try { saved = await this.agentRepository.save(agent); } catch (error) { if (!id || !(0, db_1.isUniqueConstraintError)(error)) throw error; const conflict = new conflict_error_1.ConflictError('An agent with this id already exists'); if (!adoptUnconfiguredOnCollision) throw conflict; const existing = await this.agentRepository.findByIdAndProjectId(id, projectId); if (!existing || !(0, agent_capabilities_1.isUnconfiguredAgent)(existing.schema, existing.integrations ?? [])) { throw conflict; } this.logger.debug('Adopted concurrently created SDK agent', { agentId: id, projectId }); return existing; } this.logger.debug('Created SDK agent', { agentId: saved.id, projectId }); return saved; } async findByProjectId(projectId) { return await this.agentRepository.findByProjectId(projectId); } async findByProjectIdPaginated(projectId, options) { return await this.agentRepository.findByProjectIdsPaginated([projectId], options); } async findById(agentId, projectId) { return await this.agentRepository.findByIdAndProjectId(agentId, projectId); } async getCapabilitySummary(agentId, projectId) { const entity = await this.agentRepository.findByIdAndProjectId(agentId, projectId); if (!entity) throw new not_found_error_1.NotFoundError('Agent not found'); const schema = entity.schema; const modelId = schema?.model ?? ''; const model = modelId ? (0, agent_config_1.splitModelId)(modelId) : null; const channels = (entity.integrations ?? []).map((integration) => ({ type: integration.type, })); const tools = (schema?.tools ?? []).flatMap((tool) => { switch (tool.type) { case 'custom': return [{ type: 'custom', name: entity.tools[tool.id]?.descriptor?.name ?? tool.id }]; case 'workflow': return [{ type: 'workflow', name: tool.name ?? tool.workflow }]; case 'node': return [ { type: 'node', name: tool.name, nodeType: tool.node?.nodeType, nodeTypeVersion: tool.node?.nodeTypeVersion, }, ]; default: return []; } }); const mcpServers = (schema?.mcpServers ?? []).map((server) => ({ name: server.name })); const skills = (schema?.skills ?? []).map((skill) => ({ id: skill.id, name: entity.skills[skill.id]?.name ?? skill.id, })); const taskRefs = schema?.tasks ?? []; let taskNamesById = {}; if (taskRefs.length > 0) { const taskBodies = await this.agentTaskRepository.findByAgentId(agentId); taskNamesById = Object.fromEntries(taskBodies.map((task) => [task.id, task.name])); } const tasks = taskRefs.map((task) => ({ id: task.id, name: taskNamesById[task.id] ?? task.id, enabled: task.enabled, })); return { id: entity.id, name: entity.name, model, channels, tools, mcpServers, skills, tasks, }; } async findByUser(userId) { const projectRelations = await this.projectRelationRepository.findAllByUser(userId); const projectIds = projectRelations.map((pr) => pr.projectId); if (projectIds.length === 0) return []; return await this.agentRepository.find({ where: { projectId: (0, db_1.In)(projectIds) }, order: { updatedAt: 'DESC' }, }); } async findSummariesInProjects(projectIds, options = {}) { return await this.agentRepository.findSummariesByProjectIds(projectIds, options); } async findByIdForUser(agentId, user) { if ((0, permissions_1.hasGlobalScope)(user, 'agent:read')) { return await this.agentRepository.findById(agentId); } const projectRelations = await this.projectRelationRepository.findAllByUser(user.id); const projectIds = projectRelations.map((pr) => pr.projectId); return await this.agentRepository.findByIdInProjects(agentId, projectIds); } async findByUserPaginated(userId, options) { const projectRelations = await this.projectRelationRepository.findAllByUser(userId); const projectIds = projectRelations.map((pr) => pr.projectId); return await this.agentRepository.findByProjectIdsPaginated(projectIds, options); } async findPublishedByUser(userId) { const projectRelations = await this.projectRelationRepository.findAllByUser(userId); const projectIds = projectRelations.map((pr) => pr.projectId); if (projectIds.length === 0) return []; const agents = await this.agentRepository.find({ where: { projectId: (0, db_1.In)(projectIds) }, relations: { activeVersion: true }, order: { updatedAt: 'DESC' }, }); return agents.filter((agent) => agent.activeVersionId !== null); } async delete(agentId, projectId) { const agent = await this.agentRepository.findByIdAndProjectId(agentId, projectId); if (!agent) { return false; } try { await this.agentKnowledgeService.deleteAllFilesForAgent(projectId, agentId); } catch (error) { this.logger.warn('Failed to delete knowledge files on agent delete', { agentId, error: error instanceof Error ? error.message : error, }); } await this.agentKnowledgeService.destroySandbox(projectId, agentId); try { await this.agentChatAttachmentService.deleteByAgent(agentId); } catch (error) { this.logger.warn('Failed to delete chat attachments on agent delete', { agentId, error: error instanceof Error ? error.message : error, }); } const chatIntegrationService = di_1.Container.get(chat_integration_service_1.ChatIntegrationService); for (const integration of agent.integrations ?? []) { await chatIntegrationService.disconnectChannel(agentId, integration); } await this.agentExecutionService.deleteExecutionLogsForAgent(agentId); await this.agentRepository.remove(agent); this.runtimeCacheService.clearRuntimes(agentId); await this.subAgentCleanupService.removeSubAgentFromParents(agentId, projectId); this.eventService.emit('agent-deleted', { agentId, projectId }); try { const { AgentTaskService } = await import('./agent-task.service.js'); await di_1.Container.get(AgentTaskService).requestReconcile(agentId); } catch (error) { this.logger.warn('Failed to stop tasks on agent delete', { agentId, error: error instanceof Error ? error.message : error, }); } try { await this.testChatService.clearAllTestChatMessages(agentId); } catch (error) { this.logger.warn('Failed to clear test chat on agent delete', { agentId, error: error instanceof Error ? error.message : error, }); } this.logger.debug('Deleted SDK agent', { agentId, projectId }); return true; } }; exports.AgentsService = AgentsService; exports.AgentsService = AgentsService = __decorate([ (0, di_1.Service)(), __metadata("design:paramtypes", [backend_common_1.Logger, agent_repository_1.AgentRepository, db_1.ProjectRelationRepository, agent_chat_attachment_service_1.AgentChatAttachmentService, agent_knowledge_service_1.AgentKnowledgeService, agent_runtime_cache_service_1.AgentRuntimeCacheService, agent_test_chat_service_1.AgentTestChatService, agent_task_repository_1.AgentTaskRepository, sub_agent_cleanup_service_1.SubAgentCleanupService, event_service_1.EventService, agent_execution_service_1.AgentExecutionService]) ], AgentsService); //# sourceMappingURL=agents.service.js.map