"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;
    };
})();
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.DefaultIntentResolver = exports.AgentCommunicationManager = void 0;
const fs = __importStar(require("fs-extra"));
const path_1 = __importDefault(require("path"));
class AgentCommunicationManager {
    constructor(orchestrator, intentResolver) {
        this.messageHistory = [];
        this.orchestrator = orchestrator;
        this.intentResolver = intentResolver || new DefaultIntentResolver();
    }
    async sendMessage(message) {
        this.messageHistory.push({
            ...message,
            timestamp: new Date().toISOString(),
        });
        // Save communication log for debugging
        await this.saveMessageLog(message);
    }
    async receiveMessage(agentName) {
        // Get the latest message for this agent
        const messages = this.messageHistory.filter((m) => m.to === agentName);
        return messages.length > 0 ? messages[messages.length - 1] : null;
    }
    async broadcastMessage(message) {
        const agentNames = this.orchestrator.listAgents();
        for (const agentName of agentNames) {
            await this.sendMessage({
                ...message,
                to: agentName,
            });
        }
    }
    async getMessageHistory(agentName) {
        if (!agentName)
            return this.messageHistory;
        return this.messageHistory.filter((m) => m.from === agentName || m.to === agentName);
    }
    async clearHistory() {
        this.messageHistory = [];
    }
    async saveMessageLog(message) {
        try {
            const logDir = path_1.default.join(process.cwd(), ".mycontext", "agent-logs");
            await fs.ensureDir(logDir);
            const logFile = path_1.default.join(logDir, `communication-${new Date().toISOString().split("T")[0]}.json`);
            let logs = [];
            if (await fs.pathExists(logFile)) {
                logs = await fs.readJson(logFile);
            }
            logs.push(message);
            await fs.writeJson(logFile, logs, { spaces: 2 });
        }
        catch (error) {
            // Silent fail - logging shouldn't break the workflow
        }
    }
    // Auto workflow orchestration
    async runAutoWorkflow(initialAgent, context, config) {
        let currentAgent = initialAgent;
        const outputs = {};
        let retryCount = 0;
        let attempts = 0;
        const maxAttempts = config.agents.length * 2; // Safety limit
        while (currentAgent && attempts < maxAttempts) {
            attempts++;
            try {
                // Execute current agent
                const agentOutput = await this.orchestrator.executeAgent(currentAgent, {
                    context,
                    previousOutputs: outputs,
                    retryCount,
                });
                outputs[currentAgent] = agentOutput;
                // Analyze output and determine next action
                const intent = await this.intentResolver.analyzeOutput(agentOutput, context);
                // Send completion message
                await this.sendMessage({
                    id: `${currentAgent}-${Date.now()}`,
                    from: currentAgent,
                    to: "coordinator",
                    type: "completion",
                    payload: { output: agentOutput, intent },
                    timestamp: new Date().toISOString(),
                });
                // Check if we should trigger next agent
                if (config.enableAutoTransition &&
                    (await this.intentResolver.shouldTriggerNextAgent(intent, context))) {
                    const nextAgent = await this.intentResolver.getNextAgent(intent, context);
                    if (nextAgent) {
                        // Create starter prompt for next agent
                        const starterPrompt = await this.intentResolver.createStarterPrompt(intent, context);
                        // Update context with new starter prompt
                        context = {
                            ...context,
                            userPrompt: starterPrompt,
                            previousOutputs: outputs,
                        };
                        // Send request to next agent
                        await this.sendMessage({
                            id: `transition-${Date.now()}`,
                            from: currentAgent,
                            to: nextAgent,
                            type: "request",
                            payload: {
                                starterPrompt,
                                context: context,
                                intent,
                            },
                            timestamp: new Date().toISOString(),
                        });
                        currentAgent = nextAgent;
                        retryCount = 0;
                    }
                    else {
                        // No next agent, workflow complete
                        break;
                    }
                }
                else if (intent.action === "refine" &&
                    retryCount < config.retryLimit) {
                    // Same agent needs to retry/refine
                    retryCount++;
                    context = {
                        ...context,
                        userPrompt: intent.nextSteps?.join(" ") || "Please refine the output",
                        previousOutputs: outputs,
                    };
                }
                else {
                    // Workflow complete or max retries reached
                    break;
                }
            }
            catch (error) {
                await this.sendMessage({
                    id: `error-${Date.now()}`,
                    from: currentAgent,
                    to: "coordinator",
                    type: "error",
                    payload: { error: error.message, retryCount },
                    timestamp: new Date().toISOString(),
                });
                if (retryCount < config.retryLimit) {
                    retryCount++;
                }
                else {
                    break;
                }
            }
        }
        return {
            success: Object.keys(outputs).length > 0,
            outputs,
            messages: this.messageHistory,
        };
    }
}
exports.AgentCommunicationManager = AgentCommunicationManager;
// Default intent resolver implementation
class DefaultIntentResolver {
    async analyzeOutput(output, _context) {
        // Simple heuristic-based analysis
        const confidence = this.calculateConfidence(output);
        if (confidence < 0.3) {
            return {
                action: "refine",
                reason: "Output quality below threshold",
                confidence,
                nextSteps: ["Improve output quality", "Add missing details"],
            };
        }
        if (confidence > 0.8) {
            return {
                action: "complete",
                reason: "High quality output achieved",
                confidence,
                nextSteps: ["Proceed to next stage"],
            };
        }
        return {
            action: "generate",
            reason: "Acceptable output, continue workflow",
            confidence,
            nextSteps: ["Continue to next agent"],
        };
    }
    async shouldTriggerNextAgent(intent, _context) {
        return (intent.action === "complete" ||
            (intent.action === "generate" && intent.confidence > 0.6));
    }
    async getNextAgent(_intent, context) {
        // Simple sequential flow for now
        const sequence = ["CodeGenSubAgent", "QASubAgent", "DocsSubAgent"];
        // Find current agent in sequence (based on context)
        if (context.previousOutputs) {
            const completed = Object.keys(context.previousOutputs);
            for (let i = 0; i < sequence.length; i++) {
                const agent = sequence[i];
                if (agent && !completed.includes(agent)) {
                    return agent;
                }
            }
        }
        return sequence[0]; // Default to first agent
    }
    async createStarterPrompt(intent, context) {
        const basePrompt = context.userPrompt || "Generate high-quality output";
        if (intent.action === "refine") {
            return `${basePrompt}\n\nPlease refine the previous output with these improvements:\n${intent.reason || "General improvements"}`;
        }
        if (context.previousOutputs &&
            Object.keys(context.previousOutputs).length > 0) {
            const previousContext = Object.entries(context.previousOutputs)
                .map(([agent, output]) => `${agent}: ${typeof output === "string"
                ? output.substring(0, 200) + "..."
                : "Generated output"}`)
                .join("\n");
            return `${basePrompt}\n\nBuild upon previous agent outputs:\n${previousContext}`;
        }
        return basePrompt;
    }
    calculateConfidence(output) {
        if (!output)
            return 0;
        if (typeof output === "string") {
            // Simple heuristics for string output
            const length = output.length;
            const hasStructure = output.includes("\n") || output.includes("```");
            const hasDetails = length > 100;
            let score = 0.5;
            if (hasStructure)
                score += 0.2;
            if (hasDetails)
                score += 0.2;
            if (length > 500)
                score += 0.1;
            return Math.min(score, 1.0);
        }
        if (typeof output === "object") {
            // Object-based output confidence
            const keys = Object.keys(output);
            const hasCode = "code" in output;
            const hasMetadata = "metadata" in output;
            let score = 0.6;
            if (hasCode)
                score += 0.2;
            if (hasMetadata)
                score += 0.1;
            if (keys.length > 3)
                score += 0.1;
            return Math.min(score, 1.0);
        }
        return 0.5; // Default confidence
    }
}
exports.DefaultIntentResolver = DefaultIntentResolver;
//# sourceMappingURL=AgentCommunicationManager.js.map