"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.startAgentTaskDefinition = void 0;
exports.startAgentTask = startAgentTask;
const fs = __importStar(require("fs"));
const path = __importStar(require("path"));
const child_process_1 = require("child_process");
const PROCESSES_DIR = path.join(process.cwd(), ".knowhow", "processes");
const AGENTS_DIR = path.join(process.cwd(), ".knowhow", "processes", "agents");
function generateTaskId(prompt) {
    const words = prompt
        .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);
}
async function startAgentTask(params) {
    const { messageId, prompt, taskId: providedTaskId, resume, syncFs, provider, model, agentName, maxTimeLimit, maxSpendLimit, } = params;
    if (!prompt) {
        throw new Error("prompt is required to create a chat task");
    }
    const taskId = providedTaskId ?? generateTaskId(prompt);
    const agentTaskDir = path.join(AGENTS_DIR, taskId);
    const args = ["agent"];
    if (messageId) {
        args.push("--message-id", messageId);
    }
    else if (syncFs) {
        args.push("--sync-fs");
    }
    if (syncFs || providedTaskId) {
        args.push("--task-id", taskId);
    }
    if (provider) {
        args.push("--provider", provider);
    }
    if (model) {
        args.push("--model", model);
    }
    if (agentName) {
        args.push("--agent-name", agentName);
    }
    if (maxTimeLimit !== undefined) {
        args.push("--max-time-limit", String(maxTimeLimit));
    }
    if (maxSpendLimit !== undefined) {
        args.push("--max-spend-limit", String(maxSpendLimit));
    }
    if (resume) {
        args.push("--resume");
    }
    const timeoutMs = maxTimeLimit ? maxTimeLimit * 60 * 1000 : 60 * 60 * 1000;
    fs.mkdirSync(PROCESSES_DIR, { recursive: true });
    const logBaseName = `knowhow_${Math.floor(Date.now() / 1000)}`;
    const logPath = path.join(PROCESSES_DIR, `${logBaseName}.txt`);
    const fd = fs.openSync(logPath, "w");
    const header = `CMD: knowhow ${args.join(" ")}\n` +
        `START: ${new Date().toISOString()}\n` +
        `---\n`;
    fs.writeSync(fd, header);
    const child = (0, child_process_1.spawn)("knowhow", args, {
        stdio: ["pipe", fd, fd],
        detached: true,
    });
    const pid = child.pid;
    fs.writeSync(fd, `PID: ${pid}\n`);
    child.stdin.write(prompt, "utf8");
    child.stdin.end();
    return new Promise((resolve) => {
        let settled = false;
        const done = (msg) => {
            if (settled)
                return;
            settled = true;
            try {
                fs.closeSync(fd);
            }
            catch { }
            resolve(msg);
        };
        child.once("error", (e) => {
            done(`Failed to start agent: ${String(e)}\nLogs: ${logPath}`);
        });
        const syncFsNote = syncFs
            ? `\nTask ID: ${taskId}\nAgent dir: ${agentTaskDir}\n` +
                `To send agent messages, write to: ${agentTaskDir}/input.txt\n` +
                `To check status, read: ${agentTaskDir}/status.txt\n`
            : "";
        const detachTime = 5 * 1000;
        const tid = setTimeout(() => {
            try {
                child.unref();
            }
            catch { }
            done(`Agent started (pid=${pid}), running in background.\n` +
                `Logs: ${logPath}\n` +
                syncFsNote);
        }, detachTime);
        child.once("exit", (code) => {
            clearTimeout(tid);
            done(`Agent finished with exit code ${code}.\nLogs: ${logPath}\n` +
                syncFsNote);
        });
    });
}
exports.startAgentTaskDefinition = {
    type: "function",
    function: {
        name: "startAgentTask",
        description: "Create a new chat task in Knowhow based on a message ID and prompt. This allows worker agents to start tasks and update knowhow's backend with all CLI agent options. " +
            "When syncFs is true, the agent creates a directory at .knowhow/processes/agents/{taskId}/ with status.txt, input.txt, and metadata.json. " +
            "You can send follow-up messages to the running agent by writing content to .knowhow/processes/agents/{taskId}/input.txt. " +
            "The return value includes the taskId and agent directory path when syncFs is used.",
        parameters: {
            type: "object",
            properties: {
                messageId: {
                    type: "string",
                    description: "The ID of the message in Knowhow to associate with this task (optional)",
                },
                syncFs: {
                    type: "boolean",
                    description: "Enable filesystem-based synchronization for the task. Use this when no messageId is available.",
                },
                prompt: {
                    type: "string",
                    description: "The prompt or description for the task to be created",
                },
                provider: {
                    type: "string",
                    description: "AI provider (openai, anthropic, google, xai). Default: openai",
                },
                model: {
                    type: "string",
                    description: "Specific model for the provider",
                },
                agentName: {
                    type: "string",
                    description: "Which agent to use. Default: Patcher",
                },
                maxTimeLimit: {
                    type: "number",
                    description: "Time limit for agent execution in minutes. Default: 30",
                },
                maxSpendLimit: {
                    type: "number",
                    description: "Cost limit for agent execution in dollars. Default: 10",
                },
                taskId: {
                    type: "string",
                    description: "Pre-generated task ID to use for this agent run. When provided with syncFs, the agent directory will use this ID for a predictable path. Required when using resume.",
                },
                resume: {
                    type: "boolean",
                    description: "Resume a previously started task from where it left off. Must be used together with taskId which identifies the task to resume.",
                },
            },
            required: ["prompt"],
        },
    },
};
//# sourceMappingURL=startAgentTask.js.map