"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); }
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.SystemPromptsService = void 0;
const common_1 = require("@nestjs/common");
const typeorm_1 = require("@nestjs/typeorm");
const typeorm_2 = require("typeorm");
const core_entities_1 = require("../core-entities");
const mcp_service_1 = require("../mcp/mcp.service");
const context_generation_service_1 = require("../context-generation/context-generation.service");
const custom_variables_service_1 = require("../custom-variables/custom-variables.service");
let SystemPromptsService = class SystemPromptsService {
    constructor(systemPromptsRepository, dataSource, mcpService, contextGenerationService, handlerRegistry, customVariablesService) {
        this.systemPromptsRepository = systemPromptsRepository;
        this.dataSource = dataSource;
        this.mcpService = mcpService;
        this.contextGenerationService = contextGenerationService;
        this.handlerRegistry = handlerRegistry;
        this.customVariablesService = customVariablesService;
        this.ALL_TOOL_NAMES = [
            'create_file',
            'overwrite_file',
            'delete_file',
            'patch',
            'quick_edit',
            'apply_diff',
            'execute_code',
            'run_command',
            'request_context',
            'final',
            'html_final',
            'ask_user',
            'new_session',
            'write_todo',
            'invoke_subagent',
            'list_sub_agents',
            'get_session_history',
            'generate_title',
            'get_messages',
            'discard_messages',
            'manage_system_prompts',
            'manage_context_templates',
            'manage_context_snippets',
            'manage_custom_snippets',
            'manage_custom_variables',
            'manage_agents',
            'manage_sub_agents',
            'manage_mcp_servers',
            'manage_tool_hooks',
        ];
    }
    parseEnabledTools(value) {
        if (!value) {
            return 'all';
        }
        if (value === 'all') {
            return 'all';
        }
        try {
            const tools = JSON.parse(value);
            if (Array.isArray(tools)) {
                const validTools = tools.filter((tool) => this.ALL_TOOL_NAMES.includes(tool));
                return validTools;
            }
            return 'all';
        }
        catch (e) {
            return 'all';
        }
    }
    serializeEnabledTools(value) {
        if (value === 'all') {
            return 'all';
        }
        return JSON.stringify(value);
    }
    async _renderPrompt(content, sessionId, sessionName) {
        const mcpToolsDefinition = await this.mcpService.getMcpToolsDefinition();
        const toolDefinitions = {};
        for (const handler of this.handlerRegistry.values()) {
            toolDefinitions[handler.toolName] = handler.getDefinition();
        }
        const enabledVariables = await this.customVariablesService.findAllEnabled();
        const variablesObject = enabledVariables.reduce((acc, curr) => {
            acc[curr.key] = curr.value;
            return acc;
        }, {});
        variablesObject['METADATA'] = {
            session_id: sessionId || '',
            session_name: sessionName || 'Untitled Session',
            instance_name: process.env.REPOBURG_INSTANCE_NAME || 'default',
        };
        const renderedContent = await this.contextGenerationService.render(content, {
            mcpServers: mcpToolsDefinition,
            tools: toolDefinitions,
            VAR: variablesObject,
        });
        return renderedContent;
    }
    async create(createSystemPromptDto) {
        const { enabledTools, enabledMcpTools, ...dtoData } = createSystemPromptDto;
        const prompt = this.systemPromptsRepository.create({
            ...dtoData,
            enabledTools: enabledTools !== undefined
                ? this.serializeEnabledTools(enabledTools)
                : null,
            enabledMcpTools: enabledMcpTools !== undefined
                ? this.serializeEnabledMcpTools(enabledMcpTools)
                : null,
        });
        return this.systemPromptsRepository.save(prompt);
    }
    async findAll() {
        const prompts = await this.systemPromptsRepository.find({
            order: { prompt_name: 'ASC' },
        });
        for (const prompt of prompts) {
            prompt.prompt_content = await this._renderPrompt(prompt.prompt_content);
        }
        return prompts;
    }
    async findAllRaw() {
        return this.systemPromptsRepository.find({
            order: { prompt_name: 'ASC' },
        });
    }
    async findOne(id) {
        const prompt = await this.systemPromptsRepository.findOneBy({ id });
        if (!prompt) {
            throw new common_1.NotFoundException(`SystemPrompt with ID "${id}" not found`);
        }
        prompt.prompt_content = await this._renderPrompt(prompt.prompt_content);
        return prompt;
    }
    async findOneWithSession(id, sessionId, sessionName) {
        const prompt = await this.systemPromptsRepository.findOneBy({ id });
        if (!prompt) {
            throw new common_1.NotFoundException(`SystemPrompt with ID "${id}" not found`);
        }
        prompt.prompt_content = await this._renderPrompt(prompt.prompt_content, sessionId, sessionName);
        return prompt;
    }
    async findByName(name) {
        return this.systemPromptsRepository.findOneBy({ prompt_name: name });
    }
    async findByBuiltinKey(builtinKey) {
        return this.systemPromptsRepository.findOneBy({ builtin_key: builtinKey });
    }
    async findOneRaw(id) {
        const prompt = await this.systemPromptsRepository.findOneBy({ id });
        if (!prompt) {
            throw new common_1.NotFoundException(`SystemPrompt with ID "${id}" not found`);
        }
        return prompt;
    }
    async updateBuiltinContent(id, promptContent, enabledTools, enabledMcpTools) {
        const prompt = await this.systemPromptsRepository.findOneBy({ id });
        if (!prompt) {
            throw new common_1.NotFoundException(`SystemPrompt with ID "${id}" not found`);
        }
        prompt.prompt_content = promptContent;
        prompt.enabledTools = this.serializeEnabledTools(enabledTools);
        if (enabledMcpTools !== undefined) {
            prompt.enabledMcpTools = this.serializeEnabledMcpTools(enabledMcpTools);
        }
        return this.systemPromptsRepository.save(prompt);
    }
    async findDefault() {
        const prompt = await this.systemPromptsRepository.findOneBy({
            is_default: true,
        });
        if (prompt) {
            prompt.prompt_content = await this._renderPrompt(prompt.prompt_content);
        }
        return prompt;
    }
    async findDefaultWithSession(sessionId, sessionName) {
        const prompt = await this.systemPromptsRepository.findOneBy({
            is_default: true,
        });
        if (prompt) {
            prompt.prompt_content = await this._renderPrompt(prompt.prompt_content, sessionId, sessionName);
        }
        return prompt;
    }
    async update(id, updateSystemPromptDto) {
        const prompt = await this.systemPromptsRepository.findOneBy({ id });
        if (!prompt) {
            throw new common_1.NotFoundException(`SystemPrompt with ID "${id}" not found`);
        }
        if (prompt.is_builtin) {
            throw new common_1.ForbiddenException(`Cannot modify built-in system prompt "${prompt.prompt_name}". Duplicate it to create your own version.`);
        }
        const updateData = { ...updateSystemPromptDto };
        delete updateData.is_default;
        if (updateData.enabledMcpTools !== undefined) {
            prompt.enabledMcpTools = this.serializeEnabledMcpTools(updateData.enabledMcpTools);
            delete updateData.enabledMcpTools;
        }
        this.systemPromptsRepository.merge(prompt, updateData);
        const updatedPrompt = await this.systemPromptsRepository.save(prompt);
        updatedPrompt.prompt_content = await this._renderPrompt(updatedPrompt.prompt_content);
        return updatedPrompt;
    }
    async remove(id) {
        const prompt = await this.systemPromptsRepository.findOneBy({ id });
        if (!prompt) {
            throw new common_1.NotFoundException(`SystemPrompt with ID "${id}" not found`);
        }
        await this.systemPromptsRepository.remove(prompt);
    }
    async duplicate(id) {
        const original = await this.systemPromptsRepository.findOneBy({ id });
        if (!original) {
            throw new common_1.NotFoundException(`SystemPrompt with ID "${id}" not found`);
        }
        let newName = `${original.prompt_name} (Copy)`;
        let suffix = 2;
        while (await this.systemPromptsRepository.findOneBy({ prompt_name: newName })) {
            newName = `${original.prompt_name} (Copy ${suffix})`;
            suffix++;
        }
        const duplicate = this.systemPromptsRepository.create({
            prompt_name: newName,
            prompt_content: original.prompt_content,
            url: original.url,
            enabledTools: original.enabledTools,
            enabledMcpTools: original.enabledMcpTools,
            followup_token_limit: original.followup_token_limit,
            is_builtin: false,
            builtin_key: null,
        });
        const saved = await this.systemPromptsRepository.save(duplicate);
        saved.prompt_content = await this._renderPrompt(saved.prompt_content);
        return saved;
    }
    async setDefault(id) {
        const newDefaultPrompt = await this.systemPromptsRepository.findOneBy({
            id,
        });
        if (!newDefaultPrompt) {
            throw new common_1.NotFoundException(`SystemPrompt with ID "${id}" not found`);
        }
        await this.dataSource.transaction(async (manager) => {
            const currentDefault = await manager.findOneBy(core_entities_1.SystemPrompt, {
                is_default: true,
            });
            if (currentDefault && currentDefault.id !== newDefaultPrompt.id) {
                currentDefault.is_default = false;
                await manager.save(currentDefault);
            }
            if (!newDefaultPrompt.is_default) {
                newDefaultPrompt.is_default = true;
                await manager.save(newDefaultPrompt);
            }
        });
        newDefaultPrompt.prompt_content = await this._renderPrompt(newDefaultPrompt.prompt_content);
        return newDefaultPrompt;
    }
    async preview(previewDto) {
        const rendered_content = await this._renderPrompt(previewDto.prompt_content);
        return { rendered_content };
    }
    getToolNames() {
        return Array.from(this.handlerRegistry.keys());
    }
    async getEnabledTools(systemPromptId) {
        const systemPrompt = await this.systemPromptsRepository.findOneBy({
            id: systemPromptId,
        });
        if (!systemPrompt) {
            throw new common_1.NotFoundException(`SystemPrompt with ID "${systemPromptId}" not found`);
        }
        return this.parseEnabledTools(systemPrompt.enabledTools);
    }
    async setEnabledTools(systemPromptId, enabledTools) {
        const systemPrompt = await this.systemPromptsRepository.findOneBy({
            id: systemPromptId,
        });
        if (!systemPrompt) {
            throw new common_1.NotFoundException(`SystemPrompt with ID "${systemPromptId}" not found`);
        }
        let cleanedTools;
        if (Array.isArray(enabledTools)) {
            cleanedTools = enabledTools.filter((tool) => this.ALL_TOOL_NAMES.includes(tool));
        }
        else {
            cleanedTools = enabledTools;
        }
        systemPrompt.enabledTools = this.serializeEnabledTools(cleanedTools);
        await this.systemPromptsRepository.save(systemPrompt);
        return { enabledTools: this.parseEnabledTools(systemPrompt.enabledTools) };
    }
    async getToolsForPrompt(systemPromptId) {
        const enabledTools = await this.getEnabledTools(systemPromptId);
        if (enabledTools === 'all') {
            return this.ALL_TOOL_NAMES;
        }
        const validTools = enabledTools.filter((tool) => this.ALL_TOOL_NAMES.includes(tool));
        return validTools;
    }
    async toggleTool(systemPromptId, toolName) {
        if (!this.ALL_TOOL_NAMES.includes(toolName)) {
            throw new Error(`Invalid tool name "${toolName}". Valid tools: ${this.ALL_TOOL_NAMES.join(', ')}`);
        }
        const systemPrompt = await this.systemPromptsRepository.findOneBy({
            id: systemPromptId,
        });
        if (!systemPrompt) {
            throw new common_1.NotFoundException(`SystemPrompt with ID "${systemPromptId}" not found`);
        }
        const currentEnabled = this.parseEnabledTools(systemPrompt.enabledTools);
        if (currentEnabled === 'all') {
            const enabledArray = this.ALL_TOOL_NAMES.filter((t) => t !== toolName);
            systemPrompt.enabledTools = this.serializeEnabledTools(enabledArray);
        }
        else {
            const enabled = currentEnabled;
            const index = enabled.indexOf(toolName);
            if (index === -1) {
                enabled.push(toolName);
                if (enabled.length === this.ALL_TOOL_NAMES.length) {
                    systemPrompt.enabledTools = this.serializeEnabledTools('all');
                }
                else {
                    systemPrompt.enabledTools = this.serializeEnabledTools(enabled);
                }
            }
            else {
                enabled.splice(index, 1);
                systemPrompt.enabledTools =
                    enabled.length > 0
                        ? this.serializeEnabledTools(enabled)
                        : this.serializeEnabledTools([]);
            }
        }
        await this.systemPromptsRepository.save(systemPrompt);
        return { enabledTools: this.parseEnabledTools(systemPrompt.enabledTools) };
    }
    getAllToolNames() {
        return [...this.ALL_TOOL_NAMES];
    }
    parseEnabledMcpToolsWithDefault(value) {
        const parsed = this.mcpService.parseEnabledMcpTools(value);
        return parsed === null ? 'all' : parsed;
    }
    serializeEnabledMcpTools(value) {
        return this.mcpService.serializeEnabledMcpTools(value);
    }
    async getAllMcpToolNames() {
        return this.mcpService.getActiveMcpToolNames();
    }
    async getEnabledMcpTools(systemPromptId) {
        const systemPrompt = await this.systemPromptsRepository.findOneBy({
            id: systemPromptId,
        });
        if (!systemPrompt) {
            throw new common_1.NotFoundException(`SystemPrompt with ID "${systemPromptId}" not found`);
        }
        return this.parseEnabledMcpToolsWithDefault(systemPrompt.enabledMcpTools);
    }
    async setEnabledMcpTools(systemPromptId, enabledMcpTools) {
        const systemPrompt = await this.systemPromptsRepository.findOneBy({
            id: systemPromptId,
        });
        if (!systemPrompt) {
            throw new common_1.NotFoundException(`SystemPrompt with ID "${systemPromptId}" not found`);
        }
        systemPrompt.enabledMcpTools =
            this.serializeEnabledMcpTools(enabledMcpTools);
        await this.systemPromptsRepository.save(systemPrompt);
        return {
            enabledMcpTools: this.parseEnabledMcpToolsWithDefault(systemPrompt.enabledMcpTools),
        };
    }
    async toggleMcpTool(systemPromptId, mcpToolName) {
        const systemPrompt = await this.systemPromptsRepository.findOneBy({
            id: systemPromptId,
        });
        if (!systemPrompt) {
            throw new common_1.NotFoundException(`SystemPrompt with ID "${systemPromptId}" not found`);
        }
        const currentEnabled = this.parseEnabledMcpToolsWithDefault(systemPrompt.enabledMcpTools);
        if (currentEnabled === 'all') {
            const allActiveMcpTools = await this.mcpService.getActiveMcpToolNames();
            const enabledArray = allActiveMcpTools.filter((t) => t !== mcpToolName);
            systemPrompt.enabledMcpTools =
                this.serializeEnabledMcpTools(enabledArray);
        }
        else {
            const enabled = [...currentEnabled];
            const index = enabled.indexOf(mcpToolName);
            if (index === -1) {
                enabled.push(mcpToolName);
                const allActiveMcpTools = await this.mcpService.getActiveMcpToolNames();
                if (allActiveMcpTools.length > 0 &&
                    allActiveMcpTools.every((t) => enabled.includes(t))) {
                    systemPrompt.enabledMcpTools = this.serializeEnabledMcpTools('all');
                }
                else {
                    systemPrompt.enabledMcpTools = this.serializeEnabledMcpTools(enabled);
                }
            }
            else {
                enabled.splice(index, 1);
                systemPrompt.enabledMcpTools =
                    enabled.length > 0
                        ? this.serializeEnabledMcpTools(enabled)
                        : this.serializeEnabledMcpTools([]);
            }
        }
        await this.systemPromptsRepository.save(systemPrompt);
        return {
            enabledMcpTools: this.parseEnabledMcpToolsWithDefault(systemPrompt.enabledMcpTools),
        };
    }
    async getMcpToolsForPrompt(systemPromptId) {
        const enabledMcpTools = await this.getEnabledMcpTools(systemPromptId);
        const allActiveMcpTools = await this.mcpService.getActiveMcpToolNames();
        if (enabledMcpTools === 'all') {
            return allActiveMcpTools;
        }
        return this.mcpService.resolveMcpToolNames(enabledMcpTools, allActiveMcpTools);
    }
};
exports.SystemPromptsService = SystemPromptsService;
exports.SystemPromptsService = SystemPromptsService = __decorate([
    (0, common_1.Injectable)(),
    __param(0, (0, typeorm_1.InjectRepository)(core_entities_1.SystemPrompt)),
    __param(4, (0, common_1.Inject)('ACTION_HANDLER_REGISTRY')),
    __metadata("design:paramtypes", [typeorm_2.Repository,
        typeorm_2.DataSource,
        mcp_service_1.McpService,
        context_generation_service_1.ContextGenerationService,
        Map,
        custom_variables_service_1.CustomVariablesService])
], SystemPromptsService);
//# sourceMappingURL=system-prompts.service.js.map