n8n
Version:
n8n Workflow Automation Tool
770 lines • 36.2 kB
JavaScript
"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 /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