"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.SessionManager = void 0;
const fs = __importStar(require("fs"));
const fsPromises = __importStar(require("fs/promises"));
const path = __importStar(require("path"));
class SessionManager {
    sessionsDir;
    constructor(sessionsDir = "./.knowhow/chats/sessions") {
        this.sessionsDir = sessionsDir;
        this.ensureSessionsDirectoryExists();
    }
    ensureSessionsDirectoryExists() {
        if (!fs.existsSync(this.sessionsDir)) {
            fs.mkdirSync(this.sessionsDir, { recursive: true });
        }
    }
    generateTaskId(initialInput) {
        const words = initialInput
            .toLowerCase()
            .replace(/[^\w\s]/g, "")
            .split(/\s+/)
            .filter((word) => word.length > 2)
            .slice(0, 9);
        const wordPart = words.join("-") || "task";
        const epochSeconds = Math.floor(Date.now() / 1000);
        const fullId = `${epochSeconds}-${wordPart}`;
        return fullId.slice(0, 80);
    }
    saveSession(taskId, taskInfo, threads) {
        try {
            const sessionPath = path.join(this.sessionsDir, `${taskId}.json`);
            const session = {
                sessionId: taskId,
                knowhowMessageId: taskInfo.knowhowMessageId,
                knowhowTaskId: taskInfo.knowhowTaskId,
                chatSessionId: taskInfo.chatSessionId,
                taskId,
                agentName: taskInfo.agentName,
                initialInput: taskInfo.initialInput,
                status: taskInfo.status,
                startTime: taskInfo.startTime,
                endTime: taskInfo.endTime,
                totalCost: taskInfo.totalCost,
                threads,
                currentThread: 0,
                lastUpdated: Date.now(),
            };
            fs.writeFileSync(sessionPath, JSON.stringify(session, null, 2));
        }
        catch (error) {
            console.error(`Error saving session ${taskId}:`, error);
        }
    }
    updateSession(taskId, taskInfo, threads) {
        try {
            const sessionPath = path.join(this.sessionsDir, `${taskId}.json`);
            if (fs.existsSync(sessionPath)) {
                const session = JSON.parse(fs.readFileSync(sessionPath, "utf8"));
                session.threads = threads;
                session.lastUpdated = Date.now();
                if (taskInfo) {
                    session.status = taskInfo.status;
                    session.endTime = taskInfo.endTime;
                    session.totalCost = taskInfo.totalCost;
                    session.knowhowMessageId = taskInfo.knowhowMessageId;
                    session.knowhowTaskId = taskInfo.knowhowTaskId;
                    session.chatSessionId = taskInfo.chatSessionId;
                }
                fs.writeFileSync(sessionPath, JSON.stringify(session, null, 2));
            }
        }
        catch (error) {
            console.error(`Error updating session ${taskId}:`, error);
        }
    }
    loadSession(sessionId) {
        try {
            const sessionPath = path.join(this.sessionsDir, `${sessionId}.json`);
            if (fs.existsSync(sessionPath)) {
                const content = fs.readFileSync(sessionPath, "utf-8");
                return JSON.parse(content);
            }
        }
        catch (error) {
            console.error(`Failed to load session ${sessionId}:`, error);
        }
        return null;
    }
    listAvailableSessions() {
        try {
            const files = fs.readdirSync(this.sessionsDir);
            const sessionFiles = files.filter((f) => f.endsWith(".json"));
            const sessions = [];
            const thresholdTime = 15 * 60 * 1000;
            for (const file of sessionFiles) {
                const filePath = path.join(this.sessionsDir, file);
                try {
                    const content = fs.readFileSync(filePath, "utf8");
                    const session = JSON.parse(content);
                    const isStale = Date.now() - session.lastUpdated > thresholdTime;
                    const isRunning = session.status === "running";
                    if (isRunning && isStale) {
                        console.log(`🧹 Marking stale session ${session.sessionId} as failed (last updated: ${new Date(session.lastUpdated).toLocaleString()})`);
                        session.status = "failed";
                        fs.writeFileSync(filePath, JSON.stringify(session, null, 2));
                    }
                    sessions.push(session);
                }
                catch (error) {
                    console.warn(`Failed to read session file ${file}:`, error.message);
                }
            }
            return sessions.sort((a, b) => b.lastUpdated - a.lastUpdated);
        }
        catch (error) {
            console.warn("Failed to list sessions:", error.message);
            return [];
        }
    }
    sessionExists(sessionId) {
        const sessionPath = path.join(this.sessionsDir, `${sessionId}.json`);
        return fs.existsSync(sessionPath);
    }
    deleteSession(sessionId) {
        try {
            const sessionPath = path.join(this.sessionsDir, `${sessionId}.json`);
            if (fs.existsSync(sessionPath)) {
                fs.unlinkSync(sessionPath);
                return true;
            }
        }
        catch (error) {
            console.error(`Failed to delete session ${sessionId}:`, error);
        }
        return false;
    }
    async logSessionTable(runningTasks, savedSessions) {
        console.log("\n📋 Sessions & Tasks:");
        const data = [];
        savedSessions.forEach((session) => {
            const lastUpdated = new Date(session.lastUpdated).toLocaleString();
            const inputPreview = session.initialInput && session.initialInput.length > 30
                ? session.initialInput.substring(0, 27) + "..."
                : session.initialInput || "[No input]";
            const cost = session.totalCost
                ? `$${session.totalCost.toFixed(3)}`
                : "$0.000";
            data.push({
                ID: session.sessionId,
                Agent: session.agentName,
                Status: session.status,
                Type: "saved",
                Time: lastUpdated,
                Cost: cost,
                "Initial Input": inputPreview,
            });
        });
        runningTasks.forEach((task) => {
            const elapsed = task.endTime
                ? `${Math.round((task.endTime - task.startTime) / 1000)}s`
                : `${Math.round((Date.now() - task.startTime) / 1000)}s`;
            const cost = `$${task.totalCost.toFixed(3)}`;
            const inputPreview = task.initialInput.length > 30
                ? task.initialInput.substring(0, 27) + "..."
                : task.initialInput;
            data.push({
                ID: task.taskId,
                Agent: task.agentName,
                Status: task.status,
                Type: "running",
                Time: elapsed,
                Cost: cost,
                "Initial Input": inputPreview,
            });
        });
        console.table(data);
    }
    async logRunningTasks(runningTasks, savedSessions) {
        console.log("\n📋 Available Sessions & Tasks:");
        console.log("─".repeat(80));
        console.log("ID".padEnd(25) + "Agent".padEnd(15) + "Status".padEnd(12) + "Type");
        console.log("─".repeat(80));
        savedSessions.forEach((session) => {
            console.log(session.sessionId.padEnd(25) +
                session.agentName.padEnd(15) +
                session.status.padEnd(12) +
                "saved");
        });
        runningTasks.forEach((task) => {
            console.log(task.taskId.padEnd(25) +
                task.agentName.padEnd(15) +
                task.status.padEnd(12) +
                "running");
        });
        console.log("─".repeat(80));
    }
    async discoverFsAgents(registeredIds, includeCompleted = false) {
        const agentsDir = path.join(".knowhow", "processes", "agents");
        if (!fs.existsSync(agentsDir))
            return [];
        const results = [];
        try {
            const entries = await fsPromises.readdir(agentsDir, { withFileTypes: true });
            for (const entry of entries) {
                if (!entry.isDirectory())
                    continue;
                const taskId = entry.name;
                if (registeredIds.has(taskId))
                    continue;
                const metadataPath = path.join(agentsDir, taskId, "metadata.json");
                try {
                    const raw = await fsPromises.readFile(metadataPath, "utf-8");
                    const metadata = JSON.parse(raw);
                    const status = metadata.status || "unknown";
                    if (!includeCompleted && (status === "completed" || status === "killed")) {
                        continue;
                    }
                    results.push({
                        taskId,
                        agentName: metadata.agentName || "unknown",
                        status,
                        totalCostUsd: metadata.totalCostUsd,
                    });
                }
                catch {
                }
            }
        }
        catch {
        }
        return results;
    }
}
exports.SessionManager = SessionManager;
//# sourceMappingURL=SessionManager.js.map