"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 __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;
    };
})();
Object.defineProperty(exports, "__esModule", { value: true });
exports.Gatekeeper = void 0;
const fs = __importStar(require("fs"));
const path = __importStar(require("path"));
const IntentClassifier_1 = require("./IntentClassifier");
const OmniMemory_1 = require("../memory/OmniMemory");
const SquadManager_1 = require("../squads/SquadManager");
const SkillRegistry_1 = require("../skills/SkillRegistry");
const Brain_1 = require("./Brain");
const SessionManager_1 = require("../memory/SessionManager");
const TaskExecutor_1 = require("./TaskExecutor");
const ExecutorHealth_1 = require("./ExecutorHealth");
const OrchestrationLoop_1 = require("./OrchestrationLoop");
const CommandLanguage_1 = require("./CommandLanguage");
const CommandRouter_1 = require("./CommandRouter");
const RuntimePolicy_1 = require("./RuntimePolicy");
const ConversationMemory_1 = require("../memory/ConversationMemory");
const ModelManager_1 = require("./ModelManager");
const WorldClassCommands_1 = require("../cli/WorldClassCommands");
const GovernanceLayer_1 = require("./GovernanceLayer");
const child_process_1 = require("child_process");
const DreamGoalStore_1 = require("./DreamGoalStore");
class Gatekeeper {
    memory;
    squadManager;
    skillRegistry;
    brain;
    sessionManager;
    taskExecutor;
    executorHealth;
    orchestrationLoop = null;
    commandLanguage;
    commandRouter;
    runtimePolicy;
    conversationMemory;
    modelManager;
    worldCommands;
    governance;
    systemSoul = "";
    systemIdentity = "";
    executorPolicy = null;
    constructor() {
        this.memory = new OmniMemory_1.OmniMemory();
        this.squadManager = new SquadManager_1.SquadManager();
        this.skillRegistry = new SkillRegistry_1.SkillRegistry();
        this.brain = new Brain_1.Brain();
        this.sessionManager = new SessionManager_1.SessionManager();
        this.taskExecutor = new TaskExecutor_1.TaskExecutor();
        this.executorHealth = new ExecutorHealth_1.ExecutorHealth();
        this.commandLanguage = new CommandLanguage_1.CommandLanguage();
        this.commandRouter = new CommandRouter_1.CommandRouter();
        this.runtimePolicy = new RuntimePolicy_1.RuntimePolicy();
        this.conversationMemory = new ConversationMemory_1.ConversationMemory(this.memory, this.sessionManager);
        this.modelManager = new ModelManager_1.ModelManager();
        this.worldCommands = new WorldClassCommands_1.WorldClassCommands();
        this.governance = new GovernanceLayer_1.GovernanceLayer();
        this.loadSystemPersona();
        this.loadExecutorPolicy();
    }
    loadSystemPersona() {
        try {
            const soulPath = path.join(process.cwd(), 'system', 'SOUL.md');
            const identityPath = path.join(process.cwd(), 'system', 'IDENTITY.md');
            if (fs.existsSync(soulPath))
                this.systemSoul = fs.readFileSync(soulPath, 'utf-8');
            if (fs.existsSync(identityPath))
                this.systemIdentity = fs.readFileSync(identityPath, 'utf-8');
        }
        catch (e) {
            console.error("[GATEKEEPER] Erro ao carregar persona do sistema:", e);
        }
    }
    loadExecutorPolicy() {
        try {
            const policyPath = path.join(process.cwd(), 'executor-policy.json');
            if (fs.existsSync(policyPath)) {
                this.executorPolicy = JSON.parse(fs.readFileSync(policyPath, 'utf-8'));
            }
        }
        catch (e) {
            console.error('[GATEKEEPER] Erro ao carregar executor-policy.json:', e);
            this.executorPolicy = null;
        }
    }
    async routeTask(task, userInput, userId = "default", options) {
        console.log(`\n[GATEKEEPER] Intenção: ${task.intent} | Budget: $${task.budgetLimit} | User: ${userId}`);
        const dreamGoalResponse = new DreamGoalStore_1.DreamGoalStore().handleSlashCommand(userInput);
        if (dreamGoalResponse) {
            this.sessionManager.addMessage(userId, 'user', userInput);
            this.sessionManager.addMessage(userId, 'agent', dreamGoalResponse);
            return dreamGoalResponse;
        }
        const parsedCommand = this.commandLanguage.parse(userInput);
        const commandResult = this.commandRouter.route(parsedCommand);
        if (commandResult) {
            this.sessionManager.addMessage(userId, 'user', userInput);
            this.sessionManager.addMessage(userId, 'agent', commandResult);
            return commandResult;
        }
        this.sessionManager.addMessage(userId, 'user', userInput);
        const normalizedInput = userInput.toLowerCase().trim();
        if (/\b(delete|remove|erase|deletar|apagar|remover)\b/i.test(normalizedInput)) {
            const guardDecision = this.governance.evaluate(userInput);
            if (!guardDecision.allowed && guardDecision.requiresConsent) {
                const blocked = '🚫 Operação destrutiva bloqueada. Regra #1: nunca deletar sem aprovação explícita do Rafa. Confirme de forma explícita para prosseguir.';
                this.sessionManager.addMessage(userId, 'agent', blocked);
                return blocked;
            }
        }
        // v1.3 (Story 4.1) — best-effort OutcomeSimulator call before routing.
        // Persists prediction rationale to .artifacts/missions/<taskId>.thought-trace.json
        // (the existing ConsequenceThoughtTrace path). Failure is non-fatal:
        // the simulator is advisory, not a gate. Disable with OPENLIFE_OUTCOME_SIMULATION=off.
        if (process.env.OPENLIFE_OUTCOME_SIMULATION !== 'off') {
            try {
                const { OutcomeSimulator } = require('./OutcomeSimulator');
                const sim = new OutcomeSimulator();
                const prediction = sim.simulate({
                    intent: task.intent,
                    riskLevel: 'low',
                    fallbackAvailable: true,
                    governanceBlocking: false,
                });
                // Persist alongside any ConsequenceThoughtTrace (best-effort).
                const path = require('path');
                const fs = require('fs');
                const traceDir = path.join(process.cwd(), '.artifacts', 'missions');
                try {
                    fs.mkdirSync(traceDir, { recursive: true });
                    const traceId = `gatekeeper-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;
                    fs.writeFileSync(path.join(traceDir, `${traceId}.thought-trace.json`), JSON.stringify({
                        schemaVersion: '1.0.0',
                        stage: 'gatekeeper.pre-dispatch',
                        createdAt: new Date().toISOString(),
                        userId,
                        intent: task.intent,
                        prediction,
                    }, null, 2));
                }
                catch { /* ignore filesystem hiccups — simulator is advisory */ }
            }
            catch { /* OutcomeSimulator unavailable in some test contexts — proceed */ }
        }
        if (/(agentes\s+ativos|lista\s+de\s+agentes|quais\s+agentes|agents\s+active)/i.test(normalizedInput)) {
            const real = this.worldCommands.agentsListReal();
            const preview = real.items.slice(0, 20).map((a) => `- ${a.id} (${a.role})`).join('\n');
            const direct = `Agentes ativos reais (${real.total}) [fonte: AgentRegistry]:\n${preview}`;
            this.sessionManager.addMessage(userId, 'agent', direct);
            return direct;
        }
        if (/(squads\s+ativas|lista\s+de\s+squads|quais\s+squads)/i.test(normalizedInput)) {
            const real = this.worldCommands.squadsListReal();
            const preview = real.items.slice(0, 20).map((a) => `- ${a.id} (${a.domain})`).join('\n');
            const direct = `Squads reais (${real.total}) [fonte: SquadRegistry]:\n${preview}`;
            this.sessionManager.addMessage(userId, 'agent', direct);
            return direct;
        }
        if (/(skills\s+ativas|lista\s+de\s+skills|quais\s+skills)/i.test(normalizedInput)) {
            const real = this.worldCommands.skillsListReal();
            const preview = real.items.slice(0, 20).map((a) => `- ${a.id}`).join('\n');
            const direct = `Skills reais (${real.total}) [fonte: SkillRegistry]:\n${preview}`;
            this.sessionManager.addMessage(userId, 'agent', direct);
            return direct;
        }
        if (/(route|rotear|roteie|roteamento|auto.?cria|criar capacidades|crie capacidades|criar skill|criar agente|criar squad)/i.test(normalizedInput)) {
            const wantsAutoCreate = /(auto.?cria|criar capacidades|crie capacidades|criar skill|criar agente|criar squad|se nao tiver|se não tiver|lacuna)/i.test(normalizedInput);
            const args = ['bin/openlife.js', 'route', 'intent', userInput, '--limit', '5'];
            if (wantsAutoCreate)
                args.push('--auto-create');
            const routed = (0, child_process_1.spawnSync)('node', args, { cwd: process.cwd(), encoding: 'utf-8' });
            if (routed.status === 0) {
                const payload = JSON.parse(routed.stdout);
                const created = payload.autoCreate?.created || [];
                const direct = [
                    `Roteamento OpenLife: ${payload.intent}`,
                    `Squad: ${payload.squads?.[0]?.id || 'n/a'} (${payload.squads?.[0]?.score || 0})`,
                    `Agente: ${payload.agents?.[0]?.id || 'n/a'} (${payload.agents?.[0]?.score || 0})`,
                    `Skill: ${payload.skills?.[0]?.id || 'n/a'} (${payload.skills?.[0]?.score || 0})`,
                    wantsAutoCreate ? `Auto-criação: ${created.length ? created.map((x) => `${x.type}:${x.id}`).join(', ') : 'nenhuma lacuna detectada'}` : 'Auto-criação: desativada'
                ].join('\n');
                this.sessionManager.addMessage(userId, 'agent', direct);
                return direct;
            }
            const direct = `Falha no roteamento determinístico: ${routed.stderr || routed.stdout}`;
            this.sessionManager.addMessage(userId, 'agent', direct);
            return direct;
        }
        if (/(mcp\s+status|status\s+do\s+mcp|mcps\s+ativos)/i.test(normalizedInput)) {
            const real = this.worldCommands.mcpStatusReal();
            const checks = Object.entries(real.checks).map(([k, v]) => `- ${k}: ${v.available ? 'OK' : 'FALHA'}${v.path ? ` (${v.path})` : ''}`).join('\n');
            const direct = `MCP status real:\n${checks}`;
            this.sessionManager.addMessage(userId, 'agent', direct);
            return direct;
        }
        if (/(qual\s+modelo|que\s+modelo|which\s+model|modelo\s+ativo|modelo\s+atual)/i.test(normalizedInput)) {
            const cfg = this.modelManager.getModelConfig();
            const fallbackTxt = cfg.fallbacks.length
                ? cfg.fallbacks.map((f, i) => `${i + 1}) ${f.raw}`).join(' | ')
                : 'nenhum fallback configurado';
            const direct = `Estou usando ${cfg.primary.raw} como modelo principal. Fallbacks: ${fallbackTxt}.`;
            this.sessionManager.addMessage(userId, 'agent', direct);
            return direct;
        }
        let finalResponse = "";
        switch (task.intent) {
            case IntentClassifier_1.TaskIntent.KNOWLEDGE_RETRIEVAL: {
                const useMemoryContext = this.shouldUseMemoryContext(userInput);
                const recoveredContext = useMemoryContext
                    ? await this.conversationMemory.recoverContext(userId, userInput)
                    : { recentHistory: this.getRecentSessionHistory(userId), memorySnippet: '', autoRecovered: false };
                finalResponse = await this.handleFastPath(userInput, recoveredContext.recentHistory, recoveredContext.memorySnippet, useMemoryContext);
                break;
            }
            case IntentClassifier_1.TaskIntent.ENGINEERING_BUILD:
            case IntentClassifier_1.TaskIntent.RESEARCH_ANALYSIS: {
                const recoveredContext = await this.conversationMemory.recoverContext(userId, userInput);
                finalResponse = await this.handleComplexPath(userInput, task, recoveredContext.recentHistory, userId, options?.mode);
                break;
            }
            default:
                finalResponse = await this.handleFastPath(userInput, this.getRecentSessionHistory(userId), '', false);
        }
        this.sessionManager.addMessage(userId, 'agent', finalResponse);
        return finalResponse;
    }
    getRecentSessionHistory(userId) {
        const session = this.sessionManager.getSession(userId);
        return session.history
            .slice(-4)
            .map((h) => `${h.role}: ${h.content}`)
            .join('\n');
    }
    shouldUseMemoryContext(input) {
        const normalized = input.toLowerCase();
        if (String(process.env.OPENLIFE_FASTPATH_MEMORY || 'auto').toLowerCase() === 'always')
            return true;
        if (String(process.env.OPENLIFE_FASTPATH_MEMORY || 'auto').toLowerCase() === 'off')
            return false;
        if (input.length > 240)
            return true;
        return /(lembra|memória|memoria|projeto|openlife|lara|aiobuilder|catalog|catálogo|railway|github|deploy|repo|arquivo|documento|histórico|historico)/i.test(normalized);
    }
    async handleFastPath(input, recentHistory, recoveredMemory, useMemoryContext) {
        console.log(useMemoryContext
            ? "[FAST PATH] GPT-5.5 com contexto de memória seletivo..."
            : "[FAST PATH] GPT-5.5 modo compacto sem OmniMemory...");
        const searchResult = useMemoryContext ? (recoveredMemory || await this.memory.search(input)) : '';
        // v1.14.0 — Project-context composer: opt-out via OPENLIFE_CONTEXT_COMPOSER=off.
        let projectContextBlock = '';
        if ((process.env.OPENLIFE_CONTEXT_COMPOSER || '').toLowerCase() !== 'off') {
            try {
                const { ContextComposer } = await Promise.resolve().then(() => __importStar(require('./context/ContextComposer')));
                const composer = new ContextComposer();
                const out = await composer.compose(input, { budgetTokens: 4000 });
                if (out.block) {
                    projectContextBlock = `${out.block}\n`;
                    const traceTxt = out.trace.map(t => `${t.source}=${t.n}`).join(' ');
                    console.log(`[CONTEXT] ${traceTxt} tokens=${out.usedTokens}/4000`);
                }
            }
            catch (err) {
                if ((process.env.OPENLIFE_DEBUG || '').toLowerCase() === 'true') {
                    console.warn('[CONTEXT] composer failed:', err);
                }
            }
        }
        const systemPrompt = `
Identidade:
${this.systemIdentity.substring(0, 900)}

${searchResult ? `Contexto relevante:\n${searchResult.substring(0, 900)}\n` : ''}${projectContextBlock}Histórico recente:
${recentHistory.slice(-1200)}

Dream/Goal atual do usuário:
${new DreamGoalStore_1.DreamGoalStore().summary()}

Instruções:
- Responda diretamente à última mensagem, em português natural.
- Seja rápido e conciso por padrão.
- Não mencione comandos internos, tool calls ou detalhes de execução.
- Se precisar de contexto profundo, diga objetivamente o que falta.
`;
        try {
            return await this.brain.thinkFast(systemPrompt, input);
        }
        catch (err) {
            const code = (err instanceof Error ? err.message : String(err)) || 'FAST_PATH_FAILURE';
            console.error(`[FAST PATH ERROR] ${code}`);
            return [
                'Executor GPT-5.5 indisponível ou lento demais neste momento.',
                `Motivo técnico: ${code}`,
                'Ação: verifique OAuth do Codex e tente novamente.'
            ].join('\n');
        }
    }
    getOrchestrationLoop() {
        if (!this.orchestrationLoop) {
            this.orchestrationLoop = new OrchestrationLoop_1.OrchestrationLoop(this.brain, this.taskExecutor);
        }
        return this.orchestrationLoop;
    }
    async handleComplexPath(input, task, recentHistory, userId, forcedMode) {
        console.log("[COMPLEX PATH] Iniciando orquestração agêntica (Managed Mode / Local)...");
        const normalized = input.toLowerCase();
        const inferredMode = forcedMode || (normalized.includes('como serviço') || normalized.includes('como servico') || normalized.includes('--mode service')
            ? 'service'
            : 'task');
        const orchestration = await this.getOrchestrationLoop().run(task, input, userId, recentHistory, { mode: inferredMode, origin: 'telegram' });
        const state = orchestration.state;
        const missionPath = orchestration.missionPath;
        const executionAttempt = [...state.attempts].reverse().find(a => a.role === 'executor');
        const lastArtifact = state.artifacts[state.artifacts.length - 1] || 'n/a';
        const usedFallback = state.attempts.some(a => a.role === 'executor' && a.status === 'partial');
        console.log("[SELF-EVALUATION LOOP] Analisando o resultado real do loop multiagente...");
        const traceMode = String(process.env.OPENLIFE_REASONING_MODE || 'errors').toLowerCase();
        const isResearchTask = task.intent === IntentClassifier_1.TaskIntent.RESEARCH_ANALYSIS && inferredMode === 'task';
        if (isResearchTask) {
            return orchestration.response;
        }
        const toolTrace = state.attempts.slice(-10).map((a) => {
            const raw = String(a.summary || '').replace(/\n/g, ' ');
            const m = raw.match(/^TOOL_TRACE\s+(search_files|read_file|write_file|terminal):\s*(.*)$/i);
            if (m) {
                const label = m[1].toLowerCase();
                const icon = label === 'search_files' ? '🔎' : label === 'read_file' ? '📖' : label === 'write_file' ? '✍️' : '💻';
                const body = String(m[2] || '').split(' | ')[0].slice(0, 120);
                return `${icon} ${label}: "${body}${raw.length > 120 ? '...' : ''}"`;
            }
            const mAll = Array.from(raw.matchAll(/TOOL_TRACE\s+(search_files|read_file|write_file|terminal):\s*([^|]+)/ig));
            if (mAll.length > 0) {
                return mAll.map((mm) => {
                    const label = String(mm[1]).toLowerCase();
                    const icon = label === 'search_files' ? '🔎' : label === 'read_file' ? '📖' : label === 'write_file' ? '✍️' : '💻';
                    const body = String(mm[2] || '').trim().slice(0, 100);
                    return `${icon} ${label}: "${body}${body.length >= 100 ? '...' : ''}"`;
                }).join('\n');
            }
            const s = raw.slice(0, 100);
            const low = s.toLowerCase();
            const icon = /(search|grep|find)/.test(low) ? '🔎'
                : /(read|cat|open|load)/.test(low) ? '📖'
                    : /(write|patch|edit|create file)/.test(low) ? '✍️'
                        : '💻';
            const label = /(search|grep|find)/.test(low) ? 'search_files'
                : /(read|cat|open|load)/.test(low) ? 'read_file'
                    : /(write|patch|edit|create file)/.test(low) ? 'write_file'
                        : 'terminal';
            return `${icon} ${label}: "${s}${raw.length > 100 ? '...' : ''}"`;
        }).join('\n');
        const evalPrompt = `
Você é o Córtex OPEN-LIFE. Um loop multiagente acabou de executar a seguinte tarefa:
"${input}"

Resultado da execução:
- status geral do estado: ${state.status}
- taskId: ${state.taskId}
- artifact principal: ${lastArtifact}
- passos do plano: ${state.plan.join(' | ')}
- quantidade de attempts: ${state.attempts.length}
- última tentativa de executor: ${executionAttempt?.summary || 'n/a'}
- review findings: ${state.reviewFindings.map(r => `${r.nextAction}:${r.score}`).join(' | ')}
- houve fallback operacional: ${usedFallback ? 'sim' : 'não'}
- mission state persistido em: ${missionPath}
- agentes escolhidos: ${state.chosenAgents.map(a => a.id).join(' | ')}
- memory candidates: ${state.memoryCandidates.join(' | ')}
- resposta sintetizada: ${orchestration.response.substring(0, 1500)}

Histórico da sessão:
${recentHistory}

Escreva uma resposta curta e de alto nível para o usuário dizendo:
1. se a execução real funcionou ou falhou
2. onde o artifact principal foi salvo
3. onde o mission state foi salvo
4. se a orquestração multiagente já está ativa
5. se houve iteração/review loop ou paralelismo
6. um resumo do que o sistema realmente entregou
`;
        const final = await this.brain.think(evalPrompt, "Gere a mensagem de conclusão de status com base na execução real do loop multiagente.");
        return traceMode === 'always' && toolTrace ? `${toolTrace}\n\n${final}` : final;
    }
    selectExecutors(task, input) {
        const normalized = input.toLowerCase();
        if (normalized.includes('gemini'))
            return this.filterAvailableExecutors(['gemini', 'codex']);
        if (normalized.includes('claude'))
            return this.filterAvailableExecutors(['claude', 'codex']);
        if (normalized.includes('openclaude'))
            return this.filterAvailableExecutors(['openclaude', 'codex']);
        const route = this.executorPolicy?.routes?.[task.intent];
        if (route?.preferred?.length) {
            const policyExecutors = route.preferred.filter((name) => name === 'codex' || name === 'gemini' || name === 'claude' || name === 'openclaude');
            return this.runtimePolicy.decide(task.intent, policyExecutors).preferred;
        }
        return this.runtimePolicy.decide(task.intent).preferred;
    }
    filterAvailableExecutors(executors) {
        const filtered = executors.filter((executor) => {
            const health = this.executorHealth.get(executor);
            if (!health)
                return true;
            return health.available !== false;
        });
        return filtered.length ? filtered : ['codex'];
    }
}
exports.Gatekeeper = Gatekeeper;
