n8n
Version:
n8n Workflow Automation Tool
1,041 lines • 49.8 kB
JavaScript
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
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 __importStar = (this && this.__importStar) || (function () {
var ownKeys = function(o) {
ownKeys = Object.getOwnPropertyNames || function (o) {
var ar = [];
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
return ar;
};
return ownKeys(o);
};
return function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
__setModuleDefault(result, mod);
return result;
};
})();
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 __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.AgentsController = void 0;
const api_types_1 = require("@n8n/api-types");
const decorators_1 = require("@n8n/decorators");
const di_1 = require("@n8n/di");
const crypto_1 = require("crypto");
const multer_1 = __importDefault(require("multer"));
const credentials_service_1 = require("../../credentials/credentials.service");
const bad_request_error_1 = require("../../errors/response-errors/bad-request.error");
const not_found_error_1 = require("../../errors/response-errors/not-found.error");
const agents_credential_provider_1 = require("./adapters/agents-credential-provider");
const agent_execution_service_1 = require("./agent-execution.service");
const agent_knowledge_service_1 = require("./agent-knowledge.service");
const agent_message_mapper_1 = require("./agent-message-mapper");
const agent_upload_middleware_1 = require("./agent-upload.middleware");
const agent_sse_stream_1 = require("./agent-sse-stream");
const agent_task_service_1 = require("./agent-task.service");
const agents_service_1 = require("./agents.service");
const agents_builder_service_1 = require("./builder/agents-builder.service");
const builder_tool_names_1 = require("./builder/builder-tool-names");
const agent_chat_integration_1 = require("./integrations/agent-chat-integration");
const chat_integration_service_1 = require("./integrations/chat-integration.service");
const slack_app_setup_service_1 = require("./integrations/slack-app-setup.service");
const agent_repository_1 = require("./repositories/agent.repository");
const agent_memory_scope_1 = require("./utils/agent-memory-scope");
const agentUploadMiddleware = di_1.Container.get(agent_upload_middleware_1.AgentUploadMiddleware);
function makeBuilderToolEvents(send) {
let streamingToolName;
return {
toolInputStart: (name) => {
streamingToolName = name;
},
toolInputDelta: (_toolCallId, delta) => {
if (streamingToolName === builder_tool_names_1.BUILDER_TOOLS.BUILD_CUSTOM_TOOL) {
send({ type: 'code-delta', delta });
}
},
toolResult: (name) => {
if (name === builder_tool_names_1.BUILDER_TOOLS.WRITE_CONFIG || name === builder_tool_names_1.BUILDER_TOOLS.PATCH_CONFIG) {
send({ type: 'config-updated' });
streamingToolName = undefined;
}
if (name === builder_tool_names_1.BUILDER_TOOLS.CREATE_SKILL) {
send({ type: 'config-updated' });
streamingToolName = undefined;
}
if (name === builder_tool_names_1.BUILDER_TOOLS.CREATE_TASK) {
send({ type: 'config-updated' });
streamingToolName = undefined;
}
if (name === builder_tool_names_1.BUILDER_TOOLS.BUILD_CUSTOM_TOOL) {
send({ type: 'tool-updated' });
streamingToolName = undefined;
}
},
};
}
let AgentsController = class AgentsController {
constructor(agentsService, agentsBuilderService, credentialsService, chatIntegrationService, agentRepository, agentExecutionService, chatIntegrationRegistry, slackAppSetupService, agentTaskService, agentKnowledgeService) {
this.agentsService = agentsService;
this.agentsBuilderService = agentsBuilderService;
this.credentialsService = credentialsService;
this.chatIntegrationService = chatIntegrationService;
this.agentRepository = agentRepository;
this.agentExecutionService = agentExecutionService;
this.chatIntegrationRegistry = chatIntegrationRegistry;
this.slackAppSetupService = slackAppSetupService;
this.agentTaskService = agentTaskService;
this.agentKnowledgeService = agentKnowledgeService;
}
async validateIntegration(dto) {
const integrationParseResult = await api_types_1.AgentIntegrationSchema.safeParseAsync(dto);
if (!integrationParseResult.success) {
throw new bad_request_error_1.BadRequestError(integrationParseResult.error.message);
}
const integration = integrationParseResult.data;
if (integration.type === 'telegram' && !integration.settings) {
throw new bad_request_error_1.BadRequestError('Telegram integration settings are required');
}
return integration;
}
async withRunnableState(agent, projectId, user) {
const credentialProvider = new agents_credential_provider_1.AgentsCredentialProvider(this.credentialsService, projectId, user);
const [{ missing }, hasPublishHistory] = await Promise.all([
this.agentsService.validateAgentIsRunnable(agent.id, projectId, credentialProvider),
this.agentsService.hasPublishHistory(agent.id),
]);
return Object.assign(agent, {
isRunnable: missing.length === 0,
hasPublishHistory,
});
}
async create(req, _res, payload) {
const { projectId } = req.params;
const agent = await this.agentsService.create(projectId, payload.name);
return await this.withRunnableState(agent, projectId, req.user);
}
async list(req) {
if (req.query.all === 'true') {
return await this.agentsService.findByUser(req.user.id);
}
return await this.agentsService.findByProjectId(req.params.projectId);
}
async getConfig(req) {
const { projectId, agentId } = req.params;
return await this.agentsService.getConfig(agentId, projectId);
}
async putConfig(req, _res, agentId, payload) {
const { projectId } = req.params;
const { config } = payload;
return await this.agentsService.updateConfig(agentId, projectId, config);
}
async deleteTool(req, _res, agentId, toolId) {
const { projectId } = req.params;
await this.agentsService.deleteCustomTool(agentId, projectId, toolId);
return { ok: true };
}
async listSkills(req) {
const { projectId, agentId } = req.params;
return await this.agentsService.listSkills(agentId, projectId);
}
async getSkill(req, _res, agentId, skillId) {
const { projectId } = req.params;
return await this.agentsService.getSkill(agentId, projectId, skillId);
}
async createSkill(req, _res, agentId, payload) {
const { projectId } = req.params;
const skill = {
name: payload.name,
description: payload.description,
instructions: payload.instructions,
};
return await this.agentsService.createAndAttachSkill(agentId, projectId, skill);
}
async updateSkill(req, _res, agentId, skillId, payload) {
const { projectId } = req.params;
return await this.agentsService.updateSkill(agentId, projectId, skillId, payload);
}
async deleteSkill(req, _res, agentId, skillId) {
const { projectId } = req.params;
await this.agentsService.deleteSkill(agentId, projectId, skillId);
return { ok: true };
}
async getModelCatalog() {
const { fetchProviderCatalog } = await Promise.resolve().then(() => __importStar(require('@n8n/agents')));
return await fetchProviderCatalog();
}
listIntegrations() {
return this.agentsService.listChatIntegrations();
}
async listThreads(req) {
const limit = Math.min(Math.max(Number(req.query.limit) || 20, 1), 100);
return await this.agentExecutionService.getThreads(req.params.projectId, limit, req.query.cursor, req.query.agentId);
}
async getThread(req) {
const result = await this.agentExecutionService.getThreadDetail(req.params.threadId, req.params.projectId, req.query.agentId);
if (!result) {
throw new not_found_error_1.NotFoundError(`Thread "${req.params.threadId}" not found`);
}
return result;
}
async deleteThread(req) {
const { projectId, threadId } = req.params;
const deleted = await this.agentExecutionService.deleteThread(projectId, threadId);
if (!deleted) {
throw new not_found_error_1.NotFoundError(`Thread "${threadId}" not found`);
}
return { success: true };
}
async get(req, _res, agentId) {
const agent = await this.agentsService.findById(agentId, req.params.projectId);
if (!agent) {
throw new not_found_error_1.NotFoundError(`Agent "${agentId}" not found`);
}
return await this.withRunnableState(agent, req.params.projectId, req.user);
}
async update(req, _res, agentId, payload) {
const { name, description } = payload;
let agent = await this.agentsService.findById(agentId, req.params.projectId);
if (!agent) {
throw new not_found_error_1.NotFoundError(`Agent "${agentId}" not found`);
}
if (name !== undefined) {
agent = await this.agentsService.updateName(agentId, req.params.projectId, name);
}
if (description !== undefined && agent) {
const latestUpdatedAt = agent.updatedAt instanceof Date ? agent.updatedAt.toISOString() : agent.updatedAt;
agent = await this.agentsService.updateDescription(agentId, req.params.projectId, description, latestUpdatedAt);
}
if (!agent) {
throw new not_found_error_1.NotFoundError(`Agent "${agentId}" not found`);
}
return await this.withRunnableState(agent, req.params.projectId, req.user);
}
assertKnowledgeBaseEnabled() {
if (!this.agentsService.isKnowledgeBaseModuleEnabled()) {
throw new not_found_error_1.NotFoundError('Agent knowledge base is not enabled');
}
}
async listFiles(_req, _res, projectId, agentId) {
this.assertKnowledgeBaseEnabled();
return await this.agentKnowledgeService.listFiles(agentId, projectId);
}
async uploadFiles(req, _res, projectId, agentId) {
const files = req.files ?? [];
try {
this.assertKnowledgeBaseEnabled();
if (req.fileUploadError) {
const error = req.fileUploadError;
if (error instanceof multer_1.default.MulterError) {
throw new bad_request_error_1.BadRequestError(`File upload error: ${error.message}`);
}
throw error;
}
if (files.length === 0) {
throw new bad_request_error_1.BadRequestError('No files uploaded');
}
return await this.agentKnowledgeService.uploadFiles(agentId, projectId, files);
}
catch (error) {
await (0, agent_upload_middleware_1.cleanupUploadedTempFiles)(files);
throw error;
}
}
async deleteFile(_req, _res, projectId, agentId, fileId) {
this.assertKnowledgeBaseEnabled();
await this.agentKnowledgeService.deleteFile(agentId, projectId, fileId);
return { success: true };
}
async delete(req, _res, agentId) {
const deleted = await this.agentsService.delete(agentId, req.params.projectId);
if (!deleted) {
throw new not_found_error_1.NotFoundError(`Agent "${agentId}" not found`);
}
return { success: true };
}
async publish(req, _res, agentId, payload) {
const agent = await this.agentsService.publishAgent(agentId, req.params.projectId, req.user, payload?.versionId);
return await this.withRunnableState(agent, req.params.projectId, req.user);
}
async unpublish(req, _res, agentId) {
const agent = await this.agentsService.unpublishAgent(agentId, req.params.projectId);
return await this.withRunnableState(agent, req.params.projectId, req.user);
}
async revertToPublished(req, _res, agentId) {
const agent = await this.agentsService.revertToPublishedAgent(agentId, req.params.projectId);
return await this.withRunnableState(agent, req.params.projectId, req.user);
}
async revertToVersion(req, _res, agentId, payload) {
const agent = await this.agentsService.revertToVersion(agentId, req.params.projectId, payload.versionId);
return await this.withRunnableState(agent, req.params.projectId, req.user);
}
async listVersions(req, _res, agentId, query) {
return await this.agentsService.listPublishHistory(agentId, req.params.projectId, query.take, query.skip);
}
async chat(req, res, agentId, payload) {
const { projectId } = req.params;
const { message, sessionId } = payload;
const credentialProvider = new agents_credential_provider_1.AgentsCredentialProvider(this.credentialsService, projectId, req.user);
const { send } = (0, agent_sse_stream_1.initSseStream)(res);
if (sessionId) {
const existing = await this.agentExecutionService.findThreadById(sessionId);
if (existing && !(0, agent_execution_service_1.threadBelongsTo)(existing, projectId, agentId)) {
send({ type: 'error', message: 'Session not found' });
res.end();
return;
}
}
const threadId = sessionId ?? (0, crypto_1.randomUUID)();
const { missing } = await this.agentsService.validateAgentIsRunnable(agentId, projectId, credentialProvider);
if (missing.length > 0) {
send({
type: 'error',
message: 'This agent is not ready to run yet.',
errorCode: 'agent_misconfigured',
missing,
});
res.end();
return;
}
try {
await (0, agent_sse_stream_1.pumpChunks)(this.agentsService.executeForChat({
agentId,
projectId,
message,
userId: req.user.id,
memory: {
threadId,
resourceId: (0, agent_memory_scope_1.draftChatMemoryResourceId)(req.user.id),
},
}), send);
send({ type: 'done', sessionId: threadId });
}
catch (error) {
const errorMessage = error instanceof Error ? error.message : 'Chat failed';
send({ type: 'error', message: errorMessage });
}
res.end();
}
async getChatMessages(req) {
const { projectId, agentId, threadId } = req.params;
const agent = await this.agentsService.findById(agentId, projectId);
if (!agent)
throw new not_found_error_1.NotFoundError(`Agent "${agentId}" not found`);
const history = await this.agentsService.getConversationHistory({
threadId,
projectId,
agentId,
});
if (!history) {
throw new not_found_error_1.NotFoundError(`Thread "${threadId}" not found`);
}
return history;
}
async getBuilderMessages(req) {
const { projectId, agentId } = req.params;
const agent = await this.agentsService.findById(agentId, projectId);
if (!agent)
throw new not_found_error_1.NotFoundError(`Agent "${agentId}" not found`);
const memory = await this.agentsBuilderService.getBuilderMessages(agentId);
const checkpoint = await this.agentsBuilderService.findOpenCheckpoint(agentId);
const openSuspensions = Object.values(checkpoint?.pendingToolCalls ?? {})
.filter((tc) => tc.suspended)
.map((tc) => ({
toolCallId: tc.toolCallId,
runId: tc.runId,
}));
let messages;
if (!checkpoint) {
messages = (0, agent_message_mapper_1.messagesToDto)(memory);
}
else {
const memoryIds = new Set(memory.map((m) => m.id));
const newFromCheckpoint = checkpoint.messageList.messages.filter((m) => !memoryIds.has(m.id));
messages = (0, agent_message_mapper_1.messagesToDto)([...memory, ...newFromCheckpoint]);
}
return { messages, openSuspensions };
}
async clearBuilderMessages(req) {
const { projectId, agentId } = req.params;
const agent = await this.agentsService.findById(agentId, projectId);
if (!agent)
throw new not_found_error_1.NotFoundError(`Agent "${agentId}" not found`);
await this.agentsBuilderService.clearBuilderMessages(agentId);
return { ok: true };
}
async getTestChatMessages(req) {
const { projectId, agentId } = req.params;
const agent = await this.agentsService.findById(agentId, projectId);
if (!agent)
throw new not_found_error_1.NotFoundError(`Agent "${agentId}" not found`);
const messages = await this.agentsService.getTestChatMessages(agentId, req.user.id);
return (0, agent_message_mapper_1.messagesToDto)(messages);
}
async clearTestChatMessages(req) {
const { projectId, agentId } = req.params;
const agent = await this.agentsService.findById(agentId, projectId);
if (!agent)
throw new not_found_error_1.NotFoundError(`Agent "${agentId}" not found`);
await this.agentsService.clearTestChatMessages(agentId, req.user.id);
return { ok: true };
}
async build(req, res, agentId, payload) {
const { projectId } = req.params;
const { message } = payload;
const agent = await this.agentsService.findById(agentId, projectId);
if (!agent)
throw new not_found_error_1.NotFoundError(`Agent "${agentId}" not found`);
const credentialProvider = new agents_credential_provider_1.AgentsCredentialProvider(this.credentialsService, projectId, req.user);
const { send } = (0, agent_sse_stream_1.initSseStream)(res);
try {
const suspended = await (0, agent_sse_stream_1.pumpChunks)(this.agentsBuilderService.buildAgent(agentId, projectId, message, credentialProvider, req.user), send, makeBuilderToolEvents(send));
if (!suspended) {
send({ type: 'done' });
}
}
catch (error) {
const errorMessage = error instanceof Error ? error.message : 'Build failed';
const errorCode = error && typeof error === 'object' && 'code' in error
? error.code
: undefined;
send({
type: 'error',
message: errorMessage,
...(typeof errorCode === 'string' ? { code: errorCode } : {}),
});
}
res.end();
}
async buildResume(req, res, agentId, payload) {
const { projectId } = req.params;
const { runId, toolCallId, resumeData } = payload;
const agent = await this.agentsService.findById(agentId, projectId);
if (!agent)
throw new not_found_error_1.NotFoundError(`Agent "${agentId}" not found`);
const credentialProvider = new agents_credential_provider_1.AgentsCredentialProvider(this.credentialsService, projectId, req.user);
const { send } = (0, agent_sse_stream_1.initSseStream)(res);
try {
const suspended = await (0, agent_sse_stream_1.pumpChunks)(this.agentsBuilderService.resumeBuild(agentId, projectId, runId, toolCallId, resumeData, credentialProvider, req.user), send, makeBuilderToolEvents(send));
if (!suspended) {
send({ type: 'done' });
}
}
catch (error) {
const errorMessage = error instanceof Error ? error.message : 'Resume failed';
send({ type: 'error', message: errorMessage });
}
res.end();
}
async connectIntegration(req, _res, agentId) {
const integration = await this.validateIntegration(req.body);
const { credentialId } = integration;
const agent = await this.agentRepository.findByIdAndProjectId(agentId, req.params.projectId);
if (!agent)
throw new not_found_error_1.NotFoundError(`Agent "${agentId}" not found`);
const usableCredentials = await this.credentialsService.getCredentialsAUserCanUseInAWorkflow(req.user, { projectId: agent.projectId });
const credential = usableCredentials.find((c) => c.id === credentialId);
if (!credential)
throw new not_found_error_1.NotFoundError(`Credential "${credentialId}" not found`);
const integrationImpl = this.chatIntegrationRegistry.require(integration.type);
if (!integrationImpl.credentialTypes.includes(credential.type)) {
throw new bad_request_error_1.BadRequestError(`${integrationImpl.displayLabel} integrations do not support ${credential.type} credentials`);
}
if (!agent.activeVersionId) {
await this.agentsService.saveCredentialIntegration(agent, integration, { broadcast: false });
const publishedAgent = await this.agentsService.publishAgent(agentId, agent.projectId, req.user, undefined, { syncIntegrations: false });
await this.chatIntegrationService.connect(agentId, integration, req.user.id, agent.projectId);
await this.chatIntegrationService.broadcastIntegrationChange(agentId, integration, 'connect');
return {
status: 'connected',
agent: await this.withRunnableState(publishedAgent, agent.projectId, req.user),
};
}
await this.chatIntegrationService.connect(agentId, integration, req.user.id, agent.projectId);
await this.agentsService.saveCredentialIntegration(agent, integration);
return { status: 'connected' };
}
async createSlackApp(req, _res, agentId, payload) {
return await this.slackAppSetupService.createApp({
projectId: req.params.projectId,
agentId,
appConfigurationToken: payload.appConfigurationToken,
user: req.user,
});
}
async getSlackAppManifest(req, _res, agentId) {
return await this.slackAppSetupService.getManualManifest({
projectId: req.params.projectId,
agentId,
});
}
async handleSlackAppOAuthCallback(req, res, agentId) {
const { code, state, error, error_description: errorDescription } = req.query;
if (error) {
return res.render('oauth-error-callback', {
error: {
message: error,
...(errorDescription ? { reason: errorDescription } : {}),
},
});
}
if (!code || !state) {
return res.render('oauth-error-callback', {
error: { message: 'Insufficient parameters for Slack app setup callback.' },
});
}
try {
await this.slackAppSetupService.completeInstall({
projectId: req.params.projectId,
agentId,
code,
state,
});
return res.render('oauth-callback');
}
catch (callbackError) {
const message = callbackError instanceof Error ? callbackError.message : 'Slack app setup failed';
return res.render('oauth-error-callback', {
error: { message },
});
}
}
async disconnectIntegration(req, _res, agentId, payload) {
const { type, credentialId } = payload;
const agent = await this.agentRepository.findByIdAndProjectId(agentId, req.params.projectId);
if (!agent)
throw new not_found_error_1.NotFoundError(`Agent "${agentId}" not found`);
await this.chatIntegrationService.disconnect(agentId, { type, credentialId });
await this.agentsService.removeCredentialIntegration(agent, type, credentialId);
return { status: 'disconnected' };
}
async getAgentOrThrow(agentId, projectId) {
const agent = await this.agentRepository.findByIdAndProjectId(agentId, projectId);
if (!agent)
throw new not_found_error_1.NotFoundError(`Agent "${agentId}" not found`);
return agent;
}
async listTasks(req, _res, agentId) {
await this.getAgentOrThrow(agentId, req.params.projectId);
return await this.agentTaskService.list(agentId);
}
async createTask(req, _res, agentId, payload) {
await this.getAgentOrThrow(agentId, req.params.projectId);
return await this.agentTaskService.create(agentId, payload);
}
async updateTask(req, _res, agentId, taskId, payload) {
await this.getAgentOrThrow(agentId, req.params.projectId);
return await this.agentTaskService.update(agentId, taskId, payload);
}
async deleteTask(req, _res, agentId, taskId) {
await this.getAgentOrThrow(agentId, req.params.projectId);
await this.agentTaskService.delete(agentId, taskId);
return { success: true };
}
async runTaskNow(req, _res, agentId, taskId) {
await this.getAgentOrThrow(agentId, req.params.projectId);
await this.agentTaskService.runNow(agentId, taskId, req.user.id);
return { success: true };
}
async integrationStatus(req, _res, agentId) {
const agent = await this.agentRepository.findByIdAndProjectId(agentId, req.params.projectId);
if (!agent)
throw new not_found_error_1.NotFoundError(`Agent "${agentId}" not found`);
const chatIntegrations = (agent.integrations ?? []).map((i) => ({
type: i.type,
credentialId: i.credentialId,
...('settings' in i ? { settings: i.settings } : {}),
}));
return {
status: chatIntegrations.length > 0 ? 'connected' : 'disconnected',
integrations: chatIntegrations,
};
}
async handleWebhook(req, res) {
const { agentId, platform } = req.params;
const webhookHandler = this.chatIntegrationService.getWebhookHandler(agentId, platform);
if (!webhookHandler) {
const integration = this.chatIntegrationRegistry.get(platform);
const earlyResponse = integration?.handleUnauthenticatedWebhook?.(req.body);
if (earlyResponse) {
res.status(earlyResponse.status).json(earlyResponse.body);
return;
}
res.status(404).json({ error: `No active ${platform} integration for agent "${agentId}"` });
return;
}
const forwardedProto = req.headers['x-forwarded-proto'];
const protocol = (Array.isArray(forwardedProto) ? forwardedProto[0] : forwardedProto) ?? req.protocol;
const forwardedHost = req.headers['x-forwarded-host'];
const host = (Array.isArray(forwardedHost) ? forwardedHost[0] : forwardedHost) ??
req.headers.host ??
'localhost';
const url = `${protocol}://${host}${req.originalUrl}`;
let requestBody;
if (req.method !== 'GET' && req.method !== 'HEAD') {
const rawBody = req.rawBody;
if (rawBody) {
requestBody = rawBody.toString('utf-8');
}
else if (req.headers['content-type']?.includes('application/json')) {
requestBody = JSON.stringify(req.body);
}
else if (req.headers['content-type']?.includes('application/x-www-form-urlencoded')) {
requestBody = new URLSearchParams(req.body).toString();
}
else {
requestBody = JSON.stringify(req.body);
}
}
const sanitizedHeaders = {};
for (const [key, value] of Object.entries(req.headers)) {
if (typeof value === 'string') {
sanitizedHeaders[key] = value;
}
else if (Array.isArray(value)) {
sanitizedHeaders[key] = value.join(', ');
}
}
const webRequest = new globalThis.Request(url, {
method: req.method,
headers: sanitizedHeaders,
body: requestBody,
});
const backgroundTasks = [];
const waitUntil = (task) => {
backgroundTasks.push(task.catch((error) => {
console.warn('[AgentsController] Background task failed:', error instanceof Error ? error.message : String(error));
}));
};
const webResponse = await webhookHandler(webRequest, { waitUntil });
res.status(webResponse.status);
webResponse.headers.forEach((value, key) => {
res.setHeader(key, value);
});
const body = await webResponse.text();
res.send(body);
}
};
exports.AgentsController = AgentsController;
__decorate([
(0, decorators_1.Post)('/'),
(0, decorators_1.ProjectScope)('agent:create'),
__param(2, decorators_1.Body),
__metadata("design:type", Function),
__metadata("design:paramtypes", [Object, Object, api_types_1.CreateAgentDto]),
__metadata("design:returntype", Promise)
], AgentsController.prototype, "create", null);
__decorate([
(0, decorators_1.Get)('/'),
(0, decorators_1.ProjectScope)('agent:list'),
__metadata("design:type", Function),
__metadata("design:paramtypes", [Object]),
__metadata("design:returntype", Promise)
], AgentsController.prototype, "list", null);
__decorate([
(0, decorators_1.Get)('/:agentId/config'),
(0, decorators_1.ProjectScope)('agent:read'),
__metadata("design:type", Function),
__metadata("design:paramtypes", [Object]),
__metadata("design:returntype", Promise)
], AgentsController.prototype, "getConfig", null);
__decorate([
(0, decorators_1.Put)('/:agentId/config'),
(0, decorators_1.ProjectScope)('agent:update'),
__param(2, (0, decorators_1.Param)('agentId')),
__param(3, decorators_1.Body),
__metadata("design:type", Function),
__metadata("design:paramtypes", [Object, Object, String, api_types_1.UpdateAgentConfigDto]),
__metadata("design:returntype", Promise)
], AgentsController.prototype, "putConfig", null);
__decorate([
(0, decorators_1.Delete)('/:agentId/tools/:toolId'),
(0, decorators_1.ProjectScope)('agent:update'),
__param(2, (0, decorators_1.Param)('agentId')),
__param(3, (0, decorators_1.Param)('toolId')),
__metadata("design:type", Function),
__metadata("design:paramtypes", [Object, Object, String, String]),
__metadata("design:returntype", Promise)
], AgentsController.prototype, "deleteTool", null);
__decorate([
(0, decorators_1.Get)('/:agentId/skills'),
(0, decorators_1.ProjectScope)('agent:read'),
__metadata("design:type", Function),
__metadata("design:paramtypes", [Object]),
__metadata("design:returntype", Promise)
], AgentsController.prototype, "listSkills", null);
__decorate([
(0, decorators_1.Get)('/:agentId/skills/:skillId'),
(0, decorators_1.ProjectScope)('agent:read'),
__param(2, (0, decorators_1.Param)('agentId')),
__param(3, (0, decorators_1.Param)('skillId')),
__metadata("design:type", Function),
__metadata("design:paramtypes", [Object, Object, String, String]),
__metadata("design:returntype", Promise)
], AgentsController.prototype, "getSkill", null);
__decorate([
(0, decorators_1.Post)('/:agentId/skills'),
(0, decorators_1.ProjectScope)('agent:update'),
__param(2, (0, decorators_1.Param)('agentId')),
__param(3, decorators_1.Body),
__metadata("design:type", Function),
__metadata("design:paramtypes", [Object, Object, String, api_types_1.CreateAgentSkillDto]),
__metadata("design:returntype", Promise)
], AgentsController.prototype, "createSkill", null);
__decorate([
(0, decorators_1.Patch)('/:agentId/skills/:skillId'),
(0, decorators_1.ProjectScope)('agent:update'),
__param(2, (0, decorators_1.Param)('agentId')),
__param(3, (0, decorators_1.Param)('skillId')),
__param(4, decorators_1.Body),
__metadata("design:type", Function),
__metadata("design:paramtypes", [Object, Object, String, String, api_types_1.UpdateAgentSkillDto]),
__metadata("design:returntype", Promise)
], AgentsController.prototype, "updateSkill", null);
__decorate([
(0, decorators_1.Delete)('/:agentId/skills/:skillId'),
(0, decorators_1.ProjectScope)('agent:update'),
__param(2, (0, decorators_1.Param)('agentId')),
__param(3, (0, decorators_1.Param)('skillId')),
__metadata("design:type", Function),
__metadata("design:paramtypes", [Object, Object, String, String]),
__metadata("design:returntype", Promise)
], AgentsController.prototype, "deleteSkill", null);
__decorate([
(0, decorators_1.Get)('/catalog/models'),
(0, decorators_1.ProjectScope)('agent:read'),
__metadata("design:type", Function),
__metadata("design:paramtypes", []),
__metadata("design:returntype", Promise)
], AgentsController.prototype, "getModelCatalog", null);
__decorate([
(0, decorators_1.Get)('/catalog/integrations'),
(0, decorators_1.ProjectScope)('agent:read'),
__metadata("design:type", Function),
__metadata("design:paramtypes", []),
__metadata("design:returntype", Array)
], AgentsController.prototype, "listIntegrations", null);
__decorate([
(0, decorators_1.Get)('/threads'),
(0, decorators_1.ProjectScope)('agent:read'),
__metadata("design:type", Function),
__metadata("design:paramtypes", [Object]),
__metadata("design:returntype", Promise)
], AgentsController.prototype, "listThreads", null);
__decorate([
(0, decorators_1.Get)('/threads/:threadId'),
(0, decorators_1.ProjectScope)('agent:read'),
__metadata("design:type", Function),
__metadata("design:paramtypes", [Object]),
__metadata("design:returntype", Promise)
], AgentsController.prototype, "getThread", null);
__decorate([
(0, decorators_1.Delete)('/threads/:threadId'),
(0, decorators_1.ProjectScope)('agent:update'),
__metadata("design:type", Function),
__metadata("design:paramtypes", [Object]),
__metadata("design:returntype", Promise)
], AgentsController.prototype, "deleteThread", null);
__decorate([
(0, decorators_1.Get)('/:agentId'),
(0, decorators_1.ProjectScope)('agent:read'),
__param(2, (0, decorators_1.Param)('agentId')),
__metadata("design:type", Function),
__metadata("design:paramtypes", [Object, Object, String]),
__metadata("design:returntype", Promise)
], AgentsController.prototype, "get", null);
__decorate([
(0, decorators_1.Patch)('/:agentId'),
(0, decorators_1.ProjectScope)('agent:update'),
__param(2, (0, decorators_1.Param)('agentId')),
__param(3, decorators_1.Body),
__metadata("design:type", Function),
__metadata("design:paramtypes", [Object, Object, String, api_types_1.UpdateAgentDto]),
__metadata("design:returntype", Promise)
], AgentsController.prototype, "update", null);
__decorate([
(0, decorators_1.Get)('/:agentId/files'),
(0, decorators_1.ProjectScope)('agent:read'),
__param(2, (0, decorators_1.Param)('projectId')),
__param(3, (0, decorators_1.Param)('agentId')),
__metadata("design:type", Function),
__metadata("design:paramtypes", [Object, Object, String, String]),
__metadata("design:returntype", Promise)
], AgentsController.prototype, "listFiles", null);
__decorate([
(0, decorators_1.Post)('/:agentId/files', {
middlewares: [agentUploadMiddleware.array('files')],
}),
(0, decorators_1.ProjectScope)('agent:update'),
__param(2, (0, decorators_1.Param)('projectId')),
__param(3, (0, decorators_1.Param)('agentId')),
__metadata("design:type", Function),
__metadata("design:paramtypes", [Object, Object, String, String]),
__metadata("design:returntype", Promise)
], AgentsController.prototype, "uploadFiles", null);
__decorate([
(0, decorators_1.Delete)('/:agentId/files/:fileId'),
(0, decorators_1.ProjectScope)('agent:update'),
__param(2, (0, decorators_1.Param)('projectId')),
__param(3, (0, decorators_1.Param)('agentId')),
__param(4, (0, decorators_1.Param)('fileId')),
__metadata("design:type", Function),
__metadata("design:paramtypes", [Object, Object, String, String, String]),
__metadata("design:returntype", Promise)
], AgentsController.prototype, "deleteFile", null);
__decorate([
(0, decorators_1.Delete)('/:agentId'),
(0, decorators_1.ProjectScope)('agent:delete'),
__param(2, (0, decorators_1.Param)('agentId')),
__metadata("design:type", Function),
__metadata("design:paramtypes", [Object, Object, String]),
__metadata("design:returntype", Promise)
], AgentsController.prototype, "delete", null);
__decorate([
(0, decorators_1.Post)('/:agentId/publish'),
(0, decorators_1.ProjectScope)('agent:publish'),
__param(2, (0, decorators_1.Param)('agentId')),
__param(3, decorators_1.Body),
__metadata("design:type", Function),
__metadata("design:paramtypes", [Object, Object, String, api_types_1.PublishAgentDto]),
__metadata("design:returntype", Promise)
], AgentsController.prototype, "publish", null);
__decorate([
(0, decorators_1.Post)('/:agentId/unpublish'),
(0, decorators_1.ProjectScope)('agent:unpublish'),
__param(2, (0, decorators_1.Param)('agentId')),
__metadata("design:type", Function),
__metadata("design:paramtypes", [Object, Object, String]),
__metadata("design:returntype", Promise)
], AgentsController.prototype, "unpublish", null);
__decorate([
(0, decorators_1.Post)('/:agentId/revert-to-published'),
(0, decorators_1.ProjectScope)('agent:update'),
__param(2, (0, decorators_1.Param)('agentId')),
__metadata("design:type", Function),
__metadata("design:paramtypes", [Object, Object, String]),
__metadata("design:returntype", Promise)
], AgentsController.prototype, "revertToPublished", null);
__decorate([
(0, decorators_1.Post)('/:agentId/revert-to-version'),
(0, decorators_1.ProjectScope)('agent:update'),
__param(2, (0, decorators_1.Param)('agentId')),
__param(3, decorators_1.Body),
__metadata("design:type", Function),
__metadata("design:paramtypes", [Object, Object, String, api_types_1.RevertAgentToVersionDto]),
__metadata("design:returntype", Promise)
], AgentsController.prototype, "revertToVersion", null);
__decorate([
(0, decorators_1.Get)('/:agentId/versions'),
(0, decorators_1.ProjectScope)('agent:read'),
__param(2, (0, decorators_1.Param)('agentId')),
__param(3, decorators_1.Query),
__metadata("design:type", Function),
__metadata("design:paramtypes", [Object, Object, String, api_types_1.PaginationDto]),
__metadata("design:returntype", Promise)
], AgentsController.prototype, "listVersions", null);
__decorate([
(0, decorators_1.Post)('/:agentId/chat', { usesTemplates: true }),
(0, decorators_1.ProjectScope)('agent:execute'),
__param(2, (0, decorators_1.Param)('agentId')),
__param(3, decorators_1.Body),
__metadata("design:type", Function),
__metadata("design:paramtypes", [Object, Object, String, api_types_1.AgentChatMessageDto]),
__metadata("design:returntype", Promise)
], AgentsController.prototype, "chat", null);
__decorate([
(0, decorators_1.Get)('/:agentId/chat/:threadId/messages'),
(0, decorators_1.ProjectScope)('agent:read'),
__metadata("design:type", Function),
__metadata("design:paramtypes", [Object]),
__metadata("design:returntype", Promise)
], AgentsController.prototype, "getChatMessages", null);
__decorate([
(0, decorators_1.Get)('/:agentId/build/messages'),
(0, decorators_1.ProjectScope)('agent:read'),
__metadata("design:type", Function),
__metadata("design:paramtypes", [Object]),
__metadata("design:returntype", Promise)
], AgentsController.prototype, "getBuilderMessages", null);
__decorate([
(0, decorators_1.Delete)('/:agentId/build/messages'),
(0, decorators_1.ProjectScope)('agent:update'),
__metadata("design:type", Function),
__metadata("design:paramtypes", [Object]),
__metadata("design:returntype", Promise)
], AgentsController.prototype, "clearBuilderMessages", null);
__decorate([
(0, decorators_1.Get)('/:agentId/chat/messages'),
(0, decorators_1.ProjectScope)('agent:read'),
__metadata("design:type", Function),
__metadata("design:paramtypes", [Object]),
__metadata("design:returntype", Promise)
], AgentsController.prototype, "getTestChatMessages", null);
__decorate([
(0, decorators_1.Delete)('/:agentId/chat/messages'),
(0, decorators_1.ProjectScope)('agent:update'),
__metadata("design:type", Function),
__metadata("design:paramtypes", [Object]),
__metadata("design:returntype", Promise)
], AgentsController.prototype, "clearTestChatMessages", null);
__decorate([
(0, decorators_1.Post)('/:agentId/build', { usesTemplates: true }),
(0, decorators_1.ProjectScope)('agent:update'),
__param(2, (0, decorators_1.Param)('agentId')),
__param(3, decorators_1.Body),
__metadata("design:type", Function),
__metadata("design:paramtypes", [Object, Object, String, api_types_1.AgentChatMessageDto]),
__metadata("design:returntype", Promise)
], AgentsController.prototype, "build", null);
__decorate([
(0, decorators_1.Post)('/:agentId/build/resume', { usesTemplates: true }),
(0, decorators_1.ProjectScope)('agent:update'),
__param(2, (0, decorators_1.Param)('agentId')),
__param(3, decorators_1.Body),
__metadata("design:type", Function),
__metadata("design:paramtypes", [Object, Object, String, api_types_1.AgentBuildResumeDto]),
__metadata("design:returntype", Promise)
], AgentsController.prototype, "buildResume", null);
__decorate([
(0, decorators_1.Post)('/:agentId/integrations/connect'),
(0, decorators_1.ProjectScope)('agent:update'),
__param(2, (0, decorators_1.Param)('agentId')),
__metadata("design:type", Function),
__metadata("design:paramtypes", [Object, Object, String]),
__metadata("design:returntype", Promise)
], AgentsController.prototype, "connectIntegration", null);
__decorate([
(0, decorators_1.Post)('/:agentId/integrations/slack/app'),
(0, decorators_1.ProjectScope)('agent:update'),
__param(2, (0, decorators_1.Param)('agentId')),
__param(3, decorators_1.Body),
__metadata("design:type", Function),
__metadata("design:paramtypes", [Object, Object, String, api_types_1.CreateSlackAgentAppDto]),
__metadata("design:returntype", Promise)
], AgentsController.prototype, "createSlackApp", null);
__decorate([
(0, decorators_1.Get)('/:agentId/integrations/slack/manifest'),
(0, decorators_1.ProjectScope)('agent:read'),
__param(2, (0, decorators_1.Param)('agentId')),
__metadata("design:type", Function),
__metadata("design:paramtypes", [Object, Object, String]),
__metadata("design:returntype", Promise)
], AgentsController.prototype, "getSlackAppManifest", null);
__decorate([
(0, decorators_1.Get)('/:agentId/integrations/slack/oauth/callback', { skipAuth: true, usesTemplates: true }),
__param(2, (0, decorators_1.Param)('agentId')),
__metadata("design:type", Function),
__metadata("design:paramtypes", [Object, Object, String]),
__metadata("design:returntype", Promise)
], AgentsController.prototype, "handleSlackAppOAuthCallback", null);
__decorate([
(0, decorators_1.Post)('/:agentId/integrations/disconnect'),
(0, decorators_1.ProjectScope)('agent:update'),
__param(2, (0, decorators_1.Param)('agentId')),
__param(3, decorators_1.Body),
__metadata("design:type", Function),
__metadata("design:paramtypes", [Object, Object, String, api_types_1.AgentDisconnectIntegrationDto]),
__metadata("design:returntype", Promise)
], AgentsController.prototype, "disconnectIntegration", null);
__decorate([
(0, decorators_1.Get)('/:agentId/tasks'),
(0, decorators_1.ProjectScope)('agent:read'),
__param(2, (0, decorators_1.Param)('agentId')),
__metadata("design:type", Function),
__metadata("design:paramtypes", [Object, Object, String]),
__metadata("design:returntype", Promise)
], AgentsController.prototype, "listTasks", null);
__decorate([
(0, decorators_1.Post)('/:agentId/tasks'),
(0, decorators_1.ProjectScope)('agent:update'),
__param(2, (0, decorators_1.Param)('agentId')),
__param(3, decorators_1.Body),
__metadata("design:type", Function),
__metadata("design:paramtypes", [Object, Object, String, api_types_1.CreateAgentTaskDto]),
__metadata("design:returntype", Promise)
], AgentsController.prototype, "createTask", null);
__decorate([
(0, decorators_1.Patch)('/:agentId/tasks/:taskId'),
(0, decorators_1.ProjectScope)('agent:update'),
__param(2, (0, decorators_1.Param)('agentId')),
__param(3, (0, decorators_1.Param)('taskId')),
__param(4, decorators_1.Body),
__metadata("design:type", Function),
__metadata("design:paramtypes", [Object, Object, String, String, api_types_1.UpdateAgentTaskDto]),
__metadata("design:returntype", Promise)
], AgentsController.prototype, "updateTask", null);
__decorate([
(0, decorators_1.Delete)('/:agentId/tasks/:taskId'),
(0, decorators_1.ProjectScope)('agent:update'),
__param(2, (0, decorators_1.Param)('agentId')),
__param(3, (0, decorators_1.Param)('taskId')),
__metadata("design:type", Function),
__metadata("design:paramtypes", [Object, Object, String, String]),
__metadata("design:returntype", Promise)
], AgentsController.prototype, "deleteTask", null);
__decorate([
(0, decorators_1.Post)('/:agentId/tasks/:taskId/run'),
(0, decorators_1.ProjectScope)('agent:execute'),
__param(2, (0, decorators_1.Param)('agentId')),
__param(3, (0, decorators_1.Param)('taskId')),
__metadata("design:type", Function),
__metadata("design:paramtypes", [Object, Object, String, String]),
__metadata("design:returntype", Promise)
], AgentsController.prototype, "runTaskNow", null);
__decorate([
(0, decorators_1.Get)('/:agentId/integrations/status'),
(0, decorators_1.ProjectScope)('agent:read'),
__param(2, (0, decorators_1.Param)('agentId')),
__metadata("design:type", Function),
__metadata("design:paramtypes", [Object, Object, String]),
__metadata("design:returntype", Promise)
], AgentsController.prototype, "integrationStatus", null);
__decorate([
(0, decorators_1.Post)('/:agentId/webhooks/:platform', { skipAuth: true, allowBots: true }),
__metadata("design:type", Function),
__metadata("design:paramtypes", [Object, Object]),
__metadata("design:returntype", Promise)
], AgentsController.prototype, "handleWebhook", null);
exports.AgentsController = AgentsController = __decorate([
(0, decorators_1.RestController)('/projects/:projectId/agents/v2'),
__metadata("design:paramtypes", [agents_service_1.AgentsService,
agents_builder_service_1.AgentsBuilderService,
credentials_service_1.CredentialsService,
chat_integration_service_1.ChatIntegrationService,
agent_repository_1.AgentRepository,
agent_execution_service_1.AgentExecutionService,
agent_chat_integration_1.ChatIntegrationRegistry,
slack_app_setup_service_1.SlackAppSetupService,
agent_task_service_1.AgentTaskService,
agent_knowledge_service_1.AgentKnowledgeService])
], AgentsController);
//# sourceMappingURL=agents.controller.js.map