UNPKG

n8n

Version:

n8n Workflow Automation Tool

770 lines 36.2 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 InstanceAiController_1; Object.defineProperty(exports, "__esModule", { value: true }); exports.InstanceAiController = void 0; const api_types_1 = require("@n8n/api-types"); const backend_common_1 = require("@n8n/backend-common"); const config_1 = require("@n8n/config"); const decorators_1 = require("@n8n/decorators"); const instance_ai_1 = require("@n8n/instance-ai"); const parsers_1 = require("@n8n/instance-ai/parsers"); const node_crypto_1 = require("node:crypto"); const execution_service_1 = require("./eval/execution.service"); const sub_agent_eval_service_1 = require("./eval/sub-agent-eval.service"); const in_process_event_bus_1 = require("./event-bus/in-process-event-bus"); const instance_ai_memory_service_1 = require("./instance-ai-memory.service"); const instance_ai_settings_service_1 = require("./instance-ai-settings.service"); const instance_ai_service_1 = require("./instance-ai.service"); const bad_request_error_1 = require("../../errors/response-errors/bad-request.error"); const conflict_error_1 = require("../../errors/response-errors/conflict.error"); const forbidden_error_1 = require("../../errors/response-errors/forbidden.error"); const not_found_error_1 = require("../../errors/response-errors/not-found.error"); const push_1 = require("../../push"); const url_service_1 = require("../../services/url.service"); const KEEP_ALIVE_INTERVAL_MS = 15_000; let InstanceAiController = InstanceAiController_1 = class InstanceAiController { static getTreeRichnessScore(tree) { let score = 0; const stack = [tree]; while (stack.length > 0) { const node = stack.pop(); score += 100; score += node.toolCalls.length * 10; score += node.timeline.length * 2; score += (node.planItems?.length ?? 0) * 20; score += node.toolCalls.filter((toolCall) => toolCall.confirmation).length * 50; score += node.children.length * 25; stack.push(...node.children); } return score; } static selectBootstrapTree(eventTree, persistedTree) { if (!persistedTree) return eventTree; return InstanceAiController_1.getTreeRichnessScore(persistedTree) > InstanceAiController_1.getTreeRichnessScore(eventTree) ? persistedTree : eventTree; } constructor(instanceAiService, memoryService, settingsService, evalExecutionService, subAgentEvalService, eventBus, moduleRegistry, push, urlService, globalConfig) { this.instanceAiService = instanceAiService; this.memoryService = memoryService; this.settingsService = settingsService; this.evalExecutionService = evalExecutionService; this.subAgentEvalService = subAgentEvalService; this.eventBus = eventBus; this.moduleRegistry = moduleRegistry; this.push = push; this.urlService = urlService; this.gatewayApiKey = globalConfig.instanceAi.gatewayApiKey; } requireInstanceAiEnabled() { if (!this.settingsService.isInstanceAiEnabled()) { throw new forbidden_error_1.ForbiddenError('Instance AI is disabled'); } } stripBrotli(req, _res, next) { const ae = req.headers['accept-encoding']; if (typeof ae === 'string' && ae.includes('br')) { req.headers['accept-encoding'] = ae.replace(/\bbr\b,?\s*/g, '').replace(/,\s*$/, ''); } next(); } async chat(req, _res, threadId, payload) { this.requireInstanceAiEnabled(); if (!payload.message && (!payload.attachments || payload.attachments.length === 0)) { throw new bad_request_error_1.BadRequestError('Either message or attachments must be provided'); } await this.assertThreadAccess(req.user.id, threadId, { allowNew: true }); if (payload.attachments && payload.attachments.length > 0) { try { (0, parsers_1.validateAttachmentMimeTypes)(payload.attachments); } catch (error) { if (error instanceof parsers_1.UnsupportedAttachmentError) { const summary = error.unsupported.map((u) => `${u.fileName} (${u.mimeType})`).join(', '); throw new bad_request_error_1.BadRequestError(`Unsupported attachment type: ${summary}. Supported types include CSV, JSON, ` + 'PDF, DOCX, XLSX, HTML, plain text, markdown, and images.'); } throw error; } } if (this.instanceAiService.hasActiveRun(threadId)) { throw new conflict_error_1.ConflictError('A run is already active for this thread'); } const runId = this.instanceAiService.startRun(req.user, threadId, payload.message, payload.researchMode, payload.attachments, payload.timeZone, payload.pushRef); return { runId }; } async events(req, res, threadId, query) { this.requireInstanceAiEnabled(); const ownership = await this.memoryService.checkThreadOwnership(req.user.id, threadId); if (ownership === 'other_user') { throw new forbidden_error_1.ForbiddenError('Not authorized for this thread'); } if (ownership === 'owned') { await this.instanceAiService.replayUndeliveredTerminalOutcomes(threadId, { delivery: 'event', }); } let ownershipVerified = ownership === 'owned'; let ownershipCheckInFlight = false; const pendingEvents = []; const userId = req.user.id; res.compress = false; res.setHeader('Content-Type', 'text/event-stream; charset=UTF-8'); res.setHeader('Cache-Control', 'no-cache, no-transform'); res.setHeader('Connection', 'keep-alive'); res.setHeader('X-Accel-Buffering', 'no'); res.flushHeaders(); const headerValue = req.headers['last-event-id']; const parsedHeader = headerValue ? parseInt(String(headerValue), 10) : NaN; const cursor = Number.isFinite(parsedHeader) && parsedHeader >= 0 ? parsedHeader : (query.lastEventId ?? 0); const missed = this.eventBus.getEventsAfter(threadId, cursor); for (const stored of missed) { this.writeSseEvent(res, stored); } const threadStatus = this.instanceAiService.getThreadStatus(threadId); const liveGroups = new Map(); if (threadStatus.hasActiveRun || threadStatus.isSuspended) { const groupId = this.instanceAiService.getMessageGroupId(threadId); if (groupId) { liveGroups.set(groupId, { runIds: this.instanceAiService.getRunIdsForMessageGroup(groupId), status: threadStatus.hasActiveRun ? 'active' : 'suspended', }); } } for (const task of threadStatus.backgroundTasks) { if (task.status !== 'running' || !task.messageGroupId) continue; if (!liveGroups.has(task.messageGroupId)) { liveGroups.set(task.messageGroupId, { runIds: this.instanceAiService.getRunIdsForMessageGroup(task.messageGroupId), status: 'background', }); } } for (const [groupId, group] of liveGroups) { const runEvents = this.eventBus.getEventsForRuns(threadId, group.runIds); const groupRunId = group.runIds.at(-1); const persistedSnapshot = await this.memoryService.getLatestRunSnapshot(threadId, { messageGroupId: groupId, runId: groupRunId, }); if (runEvents.length === 0 && !persistedSnapshot) continue; const eventTree = (0, instance_ai_1.buildAgentTreeFromEvents)(runEvents); const agentTree = InstanceAiController_1.selectBootstrapTree(eventTree, persistedSnapshot?.tree); res.write(`event: run-sync\ndata: ${JSON.stringify({ runId: groupRunId, messageGroupId: groupId, runIds: group.runIds, agentTree, status: group.status, backgroundTasks: threadStatus.backgroundTasks, })}\n\n`); } if (liveGroups.size > 0) res.flush?.(); const unsubscribe = this.eventBus.subscribe(threadId, (stored) => { if (ownershipVerified) { this.writeSseEvent(res, stored); return; } pendingEvents.push(stored); if (ownershipCheckInFlight) return; ownershipCheckInFlight = true; void this.memoryService .checkThreadOwnership(userId, threadId) .then((currentOwnership) => { if (currentOwnership === 'other_user') { res.end(); return; } ownershipVerified = true; for (const buffered of pendingEvents) { this.writeSseEvent(res, buffered); } pendingEvents.length = 0; }) .catch(() => { pendingEvents.length = 0; res.end(); }); }); const keepAlive = setInterval(() => { res.write(': ping\n\n'); res.flush?.(); }, KEEP_ALIVE_INTERVAL_MS); const cleanup = () => { unsubscribe(); clearInterval(keepAlive); }; req.once('close', cleanup); res.once('finish', cleanup); } async confirm(req, _res, requestId) { this.requireInstanceAiEnabled(); const parseResult = api_types_1.InstanceAiConfirmRequestDto.safeParse(req.body); if (!parseResult.success) { throw new bad_request_error_1.BadRequestError(parseResult.error.errors[0].message); } const resolved = await this.instanceAiService.resolveConfirmation(req.user.id, requestId, parseResult.data); if (!resolved) { throw new not_found_error_1.NotFoundError('Confirmation request not found or not authorized'); } return { ok: true }; } async cancel(req, _res, threadId) { this.requireInstanceAiEnabled(); await this.assertThreadAccess(req.user.id, threadId); this.instanceAiService.cancelRun(threadId); return { ok: true }; } async feedback(req, _res, threadId, responseId, payload) { this.requireInstanceAiEnabled(); await this.assertThreadAccess(req.user.id, threadId); void this.instanceAiService .submitLangsmithFeedback(req.user, threadId, responseId, payload) .catch(() => { }); return { ok: true }; } async cancelTask(req, _res, threadId, taskId) { this.requireInstanceAiEnabled(); await this.assertThreadAccess(req.user.id, threadId); this.instanceAiService.cancelBackgroundTask(threadId, taskId); return { ok: true }; } async correctTask(req, _res, threadId, taskId, payload) { this.requireInstanceAiEnabled(); await this.assertThreadAccess(req.user.id, threadId); this.instanceAiService.sendCorrectionToTask(threadId, taskId, payload.message); return { ok: true }; } async getCredits(req) { this.requireInstanceAiEnabled(); return await this.instanceAiService.getCredits(req.user); } async getAdminSettings(_req) { return this.settingsService.getAdminSettings(); } async updateAdminSettings(_req, _res, payload) { const result = await this.settingsService.updateAdminSettings(payload); await this.moduleRegistry.refreshModuleSettings('instance-ai'); if (payload.enabled === false || payload.localGatewayDisabled === true) { const disconnectedUserIds = this.instanceAiService.disconnectAllGateways(); if (disconnectedUserIds.length > 0) { this.push.sendToUsers({ type: 'instanceAiGatewayStateChanged', data: { connected: false, directory: null, hostIdentifier: null, toolCategories: [], }, }, disconnectedUserIds); } } return result; } async getUserPreferences(req) { return await this.settingsService.getUserPreferences(req.user); } async updateUserPreferences(req, _res, payload) { const result = await this.settingsService.updateUserPreferences(req.user, payload); if (payload.localGatewayDisabled !== undefined) { await this.moduleRegistry.refreshModuleSettings('instance-ai'); } return result; } async listModelCredentials(req) { return await this.settingsService.listModelCredentials(req.user); } async listServiceCredentials(req) { return await this.settingsService.listServiceCredentials(req.user); } async listThreads(req) { this.requireInstanceAiEnabled(); return await this.memoryService.listThreads(req.user.id); } async ensureThread(req, _res, payload) { this.requireInstanceAiEnabled(); const requestedThreadId = payload.threadId ?? (0, node_crypto_1.randomUUID)(); await this.assertThreadAccess(req.user.id, requestedThreadId, { allowNew: true }); return await this.memoryService.ensureThread(req.user.id, requestedThreadId); } async deleteThread(req, _res, threadId) { this.requireInstanceAiEnabled(); await this.assertThreadAccess(req.user.id, threadId); await this.instanceAiService.clearThreadState(threadId); await this.memoryService.deleteThread(threadId); return { ok: true }; } async renameThread(req, _res, threadId, payload) { this.requireInstanceAiEnabled(); await this.assertThreadAccess(req.user.id, threadId); const thread = await this.memoryService.updateThread(threadId, { title: payload.title, metadata: payload.metadata, }); return { thread }; } async getThreadMessages(req, _res, threadId, query) { this.requireInstanceAiEnabled(); await this.assertThreadAccess(req.user.id, threadId); await this.instanceAiService.replayUndeliveredTerminalOutcomes(threadId); if (query.raw === 'true') { return await this.memoryService.getThreadMessages(req.user.id, threadId, { limit: query.limit, page: query.page, }); } const threadStatus = this.instanceAiService.getThreadStatus(threadId); const activeRunId = this.instanceAiService.getActiveRunId(threadId); const excludeRunIds = []; if (activeRunId) excludeRunIds.push(activeRunId); for (const t of threadStatus.backgroundTasks) { if (t.status === 'running' && t.runId) excludeRunIds.push(t.runId); } const result = await this.memoryService.getRichMessages(req.user.id, threadId, { limit: query.limit, page: query.page, excludeRunIds: excludeRunIds.length > 0 ? excludeRunIds : undefined, }); const nextEventId = this.eventBus.getNextEventId(threadId); return { ...result, nextEventId }; } async getThreadStatus(req, _res, threadId) { this.requireInstanceAiEnabled(); await this.assertThreadAccess(req.user.id, threadId, { allowNew: true }); return this.instanceAiService.getThreadStatus(threadId); } async executeWithLlmMock(req, _res, workflowId, payload) { return await this.evalExecutionService.executeWithLlmMock(workflowId, req.user, payload); } async runSubAgentEval(req, _res, payload) { if (process.env.E2E_TESTS !== 'true' || process.env.NODE_ENV === 'production') { throw new forbidden_error_1.ForbiddenError('Sub-agent evaluation is not enabled'); } return await this.subAgentEvalService.run(req.user, payload); } async createGatewayLink(req) { await this.assertGatewayEnabled(req.user.id); const token = this.instanceAiService.generatePairingToken(req.user.id); const expiresAt = this.instanceAiService.getGatewayApiKeyExpiresAt(req.user.id, token); const ttlSeconds = expiresAt ? Math.max(0, Math.ceil((expiresAt.getTime() - Date.now()) / 1000)) : null; const baseUrl = this.urlService.getInstanceBaseUrl(); const command = `npx @n8n/computer-use ${baseUrl} ${token}`; return { token, command, expiresAt: expiresAt?.toISOString() ?? null, ttlSeconds }; } async gatewayEvents(req, res) { const userId = this.validateGatewayApiKey(this.getGatewayKeyHeader(req)); await this.assertGatewayEnabled(userId); const gateway = this.instanceAiService.getLocalGateway(userId); if (!gateway.isConnected) { throw new forbidden_error_1.ForbiddenError('Local gateway not initialized'); } this.instanceAiService.clearDisconnectTimer(userId); res.compress = false; res.setHeader('Content-Type', 'text/event-stream; charset=UTF-8'); res.setHeader('Cache-Control', 'no-cache, no-transform'); res.setHeader('Connection', 'keep-alive'); res.setHeader('X-Accel-Buffering', 'no'); res.flushHeaders(); const unsubscribeRequest = gateway.onRequest((event) => { res.write(`data: ${JSON.stringify(event)}\n\n`); res.flush?.(); }); const unsubscribeDisconnect = gateway.onDisconnect((event) => { res.write(`data: ${JSON.stringify(event)}\n\n`); res.flush?.(); res.end(); }); const keepAlive = setInterval(() => { res.write(': ping\n\n'); res.flush?.(); }, KEEP_ALIVE_INTERVAL_MS); let cleanedUp = false; const cleanup = () => { if (cleanedUp) return; cleanedUp = true; unsubscribeRequest(); unsubscribeDisconnect(); clearInterval(keepAlive); this.instanceAiService.startDisconnectTimer(userId, () => { this.push.sendToUsers({ type: 'instanceAiGatewayStateChanged', data: { connected: false, directory: null, hostIdentifier: null, toolCategories: [], }, }, [userId]); }); }; req.once('close', cleanup); res.once('finish', cleanup); } async gatewayInit(req, _res, payload) { const key = this.getGatewayKeyHeader(req); const userId = this.validateGatewayApiKey(key); await this.assertGatewayEnabled(userId); this.instanceAiService.initGateway(userId, payload); this.push.sendToUsers({ type: 'instanceAiGatewayStateChanged', data: { connected: true, directory: payload.rootPath, hostIdentifier: payload.hostIdentifier ?? null, toolCategories: payload.toolCategories ?? [], }, }, [userId]); const sessionKey = key ? this.instanceAiService.consumePairingToken(userId, key) : null; if (sessionKey) { return { ok: true, sessionKey }; } return { ok: true }; } gatewayDisconnect(req) { const userId = this.validateGatewayApiKey(this.getGatewayKeyHeader(req)); this.instanceAiService.clearDisconnectTimer(userId); this.instanceAiService.disconnectGateway(userId); this.instanceAiService.clearActiveSessionKey(userId); this.push.sendToUsers({ type: 'instanceAiGatewayStateChanged', data: { connected: false, directory: null, hostIdentifier: null, toolCategories: [] }, }, [userId]); return { ok: true }; } gatewayResponse(req, _res, requestId, payload) { const userId = this.validateGatewayApiKey(this.getGatewayKeyHeader(req)); const resolved = this.instanceAiService.resolveGatewayRequest(userId, requestId, payload.result, payload.error); if (!resolved) { throw new not_found_error_1.NotFoundError('Gateway request not found or already resolved'); } return { ok: true }; } async gatewayStatus(req) { await this.assertGatewayEnabled(req.user.id); return this.instanceAiService.getGatewayStatus(req.user.id); } async gatewayDisconnectSession(req) { const userId = req.user.id; this.instanceAiService.clearDisconnectTimer(userId); this.instanceAiService.disconnectGateway(userId); this.instanceAiService.clearActiveSessionKey(userId); this.push.sendToUsers({ type: 'instanceAiGatewayStateChanged', data: { connected: false, directory: null, hostIdentifier: null, toolCategories: [] }, }, [userId]); return { ok: true }; } async assertThreadAccess(userId, threadId, options) { const ownership = await this.memoryService.checkThreadOwnership(userId, threadId); if (ownership === 'other_user') { throw new forbidden_error_1.ForbiddenError('Not authorized for this thread'); } if (!options?.allowNew && ownership === 'not_found') { throw new not_found_error_1.NotFoundError('Thread not found'); } } async assertGatewayEnabled(userId) { if (await this.settingsService.isLocalGatewayDisabledForUser(userId)) { throw new forbidden_error_1.ForbiddenError('Local gateway is disabled'); } } getGatewayKeyHeader(req) { const raw = req.headers['x-gateway-key']; const value = Array.isArray(raw) ? raw[0] : raw; const parsed = api_types_1.instanceAiGatewayKeySchema.safeParse(value); return parsed.success ? parsed.data : undefined; } validateGatewayApiKey(key) { if (!key) { throw new forbidden_error_1.ForbiddenError('Missing API key'); } const actual = Buffer.from(key); if (this.gatewayApiKey) { const expected = Buffer.from(this.gatewayApiKey); if (expected.length === actual.length && (0, node_crypto_1.timingSafeEqual)(expected, actual)) { return 'env-gateway'; } } const userId = this.instanceAiService.getUserIdForApiKey(key); if (userId) return userId; throw new forbidden_error_1.ForbiddenError('Invalid API key'); } writeSseEvent(res, stored) { res.write(`id: ${stored.id}\ndata: ${JSON.stringify(stored.event)}\n\n`); res.flush?.(); } }; exports.InstanceAiController = InstanceAiController; __decorate([ (0, decorators_1.Middleware)(), __metadata("design:type", Function), __metadata("design:paramtypes", [Object, Object, Function]), __metadata("design:returntype", void 0) ], InstanceAiController.prototype, "stripBrotli", null); __decorate([ (0, decorators_1.Post)('/chat/:threadId'), (0, decorators_1.GlobalScope)('instanceAi:message'), __param(2, (0, decorators_1.Param)('threadId')), __param(3, decorators_1.Body), __metadata("design:type", Function), __metadata("design:paramtypes", [Object, Object, String, api_types_1.InstanceAiSendMessageRequest]), __metadata("design:returntype", Promise) ], InstanceAiController.prototype, "chat", null); __decorate([ (0, decorators_1.Get)('/events/:threadId', { usesTemplates: true }), (0, decorators_1.GlobalScope)('instanceAi:message'), __param(2, (0, decorators_1.Param)('threadId')), __param(3, decorators_1.Query), __metadata("design:type", Function), __metadata("design:paramtypes", [Object, Object, String, api_types_1.InstanceAiEventsQuery]), __metadata("design:returntype", Promise) ], InstanceAiController.prototype, "events", null); __decorate([ (0, decorators_1.Post)('/confirm/:requestId'), (0, decorators_1.GlobalScope)('instanceAi:message'), __param(2, (0, decorators_1.Param)('requestId')), __metadata("design:type", Function), __metadata("design:paramtypes", [Object, Object, String]), __metadata("design:returntype", Promise) ], InstanceAiController.prototype, "confirm", null); __decorate([ (0, decorators_1.Post)('/chat/:threadId/cancel'), (0, decorators_1.GlobalScope)('instanceAi:message'), __param(2, (0, decorators_1.Param)('threadId')), __metadata("design:type", Function), __metadata("design:paramtypes", [Object, Object, String]), __metadata("design:returntype", Promise) ], InstanceAiController.prototype, "cancel", null); __decorate([ (0, decorators_1.Post)('/feedback/:threadId/:responseId'), (0, decorators_1.GlobalScope)('instanceAi:message'), __param(2, (0, decorators_1.Param)('threadId')), __param(3, (0, decorators_1.Param)('responseId')), __param(4, decorators_1.Body), __metadata("design:type", Function), __metadata("design:paramtypes", [Object, Object, String, String, api_types_1.InstanceAiFeedbackRequestDto]), __metadata("design:returntype", Promise) ], InstanceAiController.prototype, "feedback", null); __decorate([ (0, decorators_1.Post)('/chat/:threadId/tasks/:taskId/cancel'), (0, decorators_1.GlobalScope)('instanceAi:message'), __param(2, (0, decorators_1.Param)('threadId')), __param(3, (0, decorators_1.Param)('taskId')), __metadata("design:type", Function), __metadata("design:paramtypes", [Object, Object, String, String]), __metadata("design:returntype", Promise) ], InstanceAiController.prototype, "cancelTask", null); __decorate([ (0, decorators_1.Post)('/chat/:threadId/tasks/:taskId/correct'), (0, decorators_1.GlobalScope)('instanceAi:message'), __param(2, (0, decorators_1.Param)('threadId')), __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.InstanceAiCorrectTaskRequest]), __metadata("design:returntype", Promise) ], InstanceAiController.prototype, "correctTask", null); __decorate([ (0, decorators_1.Get)('/credits'), (0, decorators_1.GlobalScope)('instanceAi:message'), __metadata("design:type", Function), __metadata("design:paramtypes", [Object]), __metadata("design:returntype", Promise) ], InstanceAiController.prototype, "getCredits", null); __decorate([ (0, decorators_1.Get)('/settings'), (0, decorators_1.GlobalScope)('instanceAi:manage'), __metadata("design:type", Function), __metadata("design:paramtypes", [Object]), __metadata("design:returntype", Promise) ], InstanceAiController.prototype, "getAdminSettings", null); __decorate([ (0, decorators_1.Put)('/settings'), (0, decorators_1.GlobalScope)('instanceAi:manage'), __param(2, decorators_1.Body), __metadata("design:type", Function), __metadata("design:paramtypes", [Object, Object, api_types_1.InstanceAiAdminSettingsUpdateRequest]), __metadata("design:returntype", Promise) ], InstanceAiController.prototype, "updateAdminSettings", null); __decorate([ (0, decorators_1.Get)('/preferences'), (0, decorators_1.GlobalScope)('instanceAi:message'), __metadata("design:type", Function), __metadata("design:paramtypes", [Object]), __metadata("design:returntype", Promise) ], InstanceAiController.prototype, "getUserPreferences", null); __decorate([ (0, decorators_1.Put)('/preferences'), (0, decorators_1.GlobalScope)('instanceAi:message'), __param(2, decorators_1.Body), __metadata("design:type", Function), __metadata("design:paramtypes", [Object, Object, api_types_1.InstanceAiUserPreferencesUpdateRequest]), __metadata("design:returntype", Promise) ], InstanceAiController.prototype, "updateUserPreferences", null); __decorate([ (0, decorators_1.Get)('/settings/credentials'), (0, decorators_1.GlobalScope)('instanceAi:message'), __metadata("design:type", Function), __metadata("design:paramtypes", [Object]), __metadata("design:returntype", Promise) ], InstanceAiController.prototype, "listModelCredentials", null); __decorate([ (0, decorators_1.Get)('/settings/service-credentials'), (0, decorators_1.GlobalScope)('instanceAi:manage'), __metadata("design:type", Function), __metadata("design:paramtypes", [Object]), __metadata("design:returntype", Promise) ], InstanceAiController.prototype, "listServiceCredentials", null); __decorate([ (0, decorators_1.Get)('/threads'), (0, decorators_1.GlobalScope)('instanceAi:message'), __metadata("design:type", Function), __metadata("design:paramtypes", [Object]), __metadata("design:returntype", Promise) ], InstanceAiController.prototype, "listThreads", null); __decorate([ (0, decorators_1.Post)('/threads'), (0, decorators_1.GlobalScope)('instanceAi:message'), __param(2, decorators_1.Body), __metadata("design:type", Function), __metadata("design:paramtypes", [Object, Object, api_types_1.InstanceAiEnsureThreadRequest]), __metadata("design:returntype", Promise) ], InstanceAiController.prototype, "ensureThread", null); __decorate([ (0, decorators_1.Delete)('/threads/:threadId'), (0, decorators_1.GlobalScope)('instanceAi:message'), __param(2, (0, decorators_1.Param)('threadId')), __metadata("design:type", Function), __metadata("design:paramtypes", [Object, Object, String]), __metadata("design:returntype", Promise) ], InstanceAiController.prototype, "deleteThread", null); __decorate([ (0, decorators_1.Patch)('/threads/:threadId'), (0, decorators_1.GlobalScope)('instanceAi:message'), __param(2, (0, decorators_1.Param)('threadId')), __param(3, decorators_1.Body), __metadata("design:type", Function), __metadata("design:paramtypes", [Object, Object, String, api_types_1.InstanceAiRenameThreadRequestDto]), __metadata("design:returntype", Promise) ], InstanceAiController.prototype, "renameThread", null); __decorate([ (0, decorators_1.Get)('/threads/:threadId/messages'), (0, decorators_1.GlobalScope)('instanceAi:message'), __param(2, (0, decorators_1.Param)('threadId')), __param(3, decorators_1.Query), __metadata("design:type", Function), __metadata("design:paramtypes", [Object, Object, String, api_types_1.InstanceAiThreadMessagesQuery]), __metadata("design:returntype", Promise) ], InstanceAiController.prototype, "getThreadMessages", null); __decorate([ (0, decorators_1.Get)('/threads/:threadId/status'), (0, decorators_1.GlobalScope)('instanceAi:message'), __param(2, (0, decorators_1.Param)('threadId')), __metadata("design:type", Function), __metadata("design:paramtypes", [Object, Object, String]), __metadata("design:returntype", Promise) ], InstanceAiController.prototype, "getThreadStatus", null); __decorate([ (0, decorators_1.Post)('/eval/execute-with-llm-mock/:workflowId'), (0, decorators_1.GlobalScope)('instanceAi:message'), __param(2, (0, decorators_1.Param)('workflowId')), __param(3, decorators_1.Body), __metadata("design:type", Function), __metadata("design:paramtypes", [Object, Object, String, api_types_1.InstanceAiEvalExecutionRequest]), __metadata("design:returntype", Promise) ], InstanceAiController.prototype, "executeWithLlmMock", null); __decorate([ (0, decorators_1.Post)('/eval/run-sub-agent'), (0, decorators_1.GlobalScope)('instanceAi:message'), __param(2, decorators_1.Body), __metadata("design:type", Function), __metadata("design:paramtypes", [Object, Object, api_types_1.InstanceAiEvalSubAgentRequest]), __metadata("design:returntype", Promise) ], InstanceAiController.prototype, "runSubAgentEval", null); __decorate([ (0, decorators_1.Post)('/gateway/create-link'), (0, decorators_1.GlobalScope)('instanceAi:gateway'), __metadata("design:type", Function), __metadata("design:paramtypes", [Object]), __metadata("design:returntype", Promise) ], InstanceAiController.prototype, "createGatewayLink", null); __decorate([ (0, decorators_1.Get)('/gateway/events', { usesTemplates: true, skipAuth: true }), __metadata("design:type", Function), __metadata("design:paramtypes", [Object, Object]), __metadata("design:returntype", Promise) ], InstanceAiController.prototype, "gatewayEvents", null); __decorate([ (0, decorators_1.Post)('/gateway/init', { skipAuth: true }), __param(2, decorators_1.Body), __metadata("design:type", Function), __metadata("design:paramtypes", [Object, Object, api_types_1.InstanceAiGatewayCapabilitiesDto]), __metadata("design:returntype", Promise) ], InstanceAiController.prototype, "gatewayInit", null); __decorate([ (0, decorators_1.Post)('/gateway/disconnect', { skipAuth: true }), __metadata("design:type", Function), __metadata("design:paramtypes", [Object]), __metadata("design:returntype", void 0) ], InstanceAiController.prototype, "gatewayDisconnect", null); __decorate([ (0, decorators_1.Post)('/gateway/response/:requestId', { skipAuth: true }), __param(2, (0, decorators_1.Param)('requestId')), __param(3, decorators_1.Body), __metadata("design:type", Function), __metadata("design:paramtypes", [Object, Object, String, api_types_1.InstanceAiFilesystemResponseDto]), __metadata("design:returntype", void 0) ], InstanceAiController.prototype, "gatewayResponse", null); __decorate([ (0, decorators_1.Get)('/gateway/status'), (0, decorators_1.GlobalScope)('instanceAi:gateway'), __metadata("design:type", Function), __metadata("design:paramtypes", [Object]), __metadata("design:returntype", Promise) ], InstanceAiController.prototype, "gatewayStatus", null); __decorate([ (0, decorators_1.Post)('/gateway/disconnect-session'), (0, decorators_1.GlobalScope)('instanceAi:gateway'), __metadata("design:type", Function), __metadata("design:paramtypes", [Object]), __metadata("design:returntype", Promise) ], InstanceAiController.prototype, "gatewayDisconnectSession", null); exports.InstanceAiController = InstanceAiController = InstanceAiController_1 = __decorate([ (0, decorators_1.RestController)('/instance-ai'), __metadata("design:paramtypes", [instance_ai_service_1.InstanceAiService, instance_ai_memory_service_1.InstanceAiMemoryService, instance_ai_settings_service_1.InstanceAiSettingsService, execution_service_1.EvalExecutionService, sub_agent_eval_service_1.SubAgentEvalService, in_process_event_bus_1.InProcessEventBus, backend_common_1.ModuleRegistry, push_1.Push, url_service_1.UrlService, config_1.GlobalConfig]) ], InstanceAiController); //# sourceMappingURL=instance-ai.controller.js.map