"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.openai = exports.Models = void 0;
exports.readPromptFile = readPromptFile;
exports.singlePrompt = singlePrompt;
exports.summarizeTexts = summarizeTexts;
exports.chunkText = chunkText;
exports.summarizeFiles = summarizeFiles;
exports.summarizeFile = summarizeFile;
exports.askGptVision = askGptVision;
const fs = __importStar(require("fs"));
const openai_1 = __importDefault(require("openai"));
const conversion_1 = require("./conversion");
const config_1 = require("./config");
const clients_1 = require("./clients");
const contextLimits_1 = require("./clients/contextLimits");
const config = (0, config_1.getConfigSync)();
const OPENAI_KEY = process.env.OPENAI_KEY;
const types_1 = require("./types");
Object.defineProperty(exports, "Models", { enumerable: true, get: function () { return types_1.Models; } });
const services_1 = require("./services");
const openai = () => new openai_1.default({
    apiKey: OPENAI_KEY,
    ...(config.openaiBaseUrl && { baseURL: config.openaiBaseUrl }),
});
exports.openai = openai;
function readPromptFile(promptFile, input) {
    if (promptFile) {
        if (fs.existsSync(promptFile)) {
            const promptTemplate = fs.readFileSync(promptFile, "utf-8");
            if (promptTemplate.includes("{text}")) {
                if (input) {
                    return promptTemplate.replaceAll("{text}", input);
                }
                return promptTemplate;
            }
            else {
                if (input) {
                    return `${promptTemplate}\n\n${input}`;
                }
                return promptTemplate;
            }
        }
    }
    return input;
}
async function singlePrompt(userPrompt, model = "", agent = "") {
    const { Agents } = (0, services_1.services)();
    if (agent) {
        const agentConfig = await Agents.getAgent(agent);
        if (!agentConfig) {
            throw new Error(`Agent ${agent} not found`);
        }
        if (model) {
            agentConfig.setModel(model);
        }
        return agentConfig.call(userPrompt);
    }
    if (!model) {
        model = types_1.Models.openai.GPT_54_Nano;
    }
    const resp = await clients_1.Clients.createCompletion("", {
        model,
        messages: [{ role: "user", content: userPrompt }],
    });
    return resp?.choices?.[0]?.message?.content;
}
function estimateTokens(text) {
    return Math.ceil(text.length / 4);
}
async function summarizeTexts(texts, template, model = "", agent = "") {
    const effectiveModel = model || types_1.Models.openai.GPT_54_Nano;
    const combinedText = texts.join("\n\n");
    const combinedContent = template.replaceAll("{text}", combinedText);
    const estimatedTokens = estimateTokens(combinedContent);
    const contextLimit = (0, contextLimits_1.getModelContextLimit)(effectiveModel);
    console.log(`summarizeTexts: ${texts.length} text(s), ~${estimatedTokens} estimated tokens, context limit: ${contextLimit}`);
    if (estimatedTokens < contextLimit) {
        console.log("summarizeTexts: fits in context window, using single prompt");
        return singlePrompt(combinedContent, model, agent).catch((err) => {
            return `Texts of combined length ${combinedText.length} could not be summarized due to error: ${err.message}`;
        });
    }
    console.log("summarizeTexts: exceeds context window, summarizing texts individually");
    const summaries = [];
    for (const text of texts) {
        const content = template.replaceAll("{text}", text);
        console.log(content);
        const summary = await singlePrompt(content, model, agent).catch((err) => {
            return `Text of length ${text.length} could not be summarized due to error: ${err.message}`;
        });
        summaries.push(summary);
    }
    if (summaries.length === 1) {
        return summaries[0];
    }
    const finalPrompt = `Generate a final output for this prompt ${template} with these incremental summaries: ` +
        summaries.join("\n\n");
    const finalSummary = await singlePrompt(finalPrompt, model, agent);
    return finalSummary;
}
async function chunkText(text, chunkSize) {
    chunkSize = chunkSize || text.length;
    const docs = [];
    for (let i = 0; i < text.length; i += chunkSize) {
        docs.push(text.slice(i, i + chunkSize));
    }
    return docs;
}
async function summarizeFiles(files, template, model = "", agent = "") {
    const texts = [];
    for (const file of files) {
        const text = `file: ${file}\n` + (await (0, conversion_1.convertToText)(file));
        texts.push(text);
    }
    return summarizeTexts(texts, template, model, agent);
}
async function summarizeFile(file, template, model = "", agent = "") {
    return await summarizeFiles([file], template, model, agent);
}
async function askGptVision(imageUrl, question, provider = "openai", model = types_1.Models.openai.GPT_4o) {
    const response = await clients_1.Clients.createCompletion(provider, {
        model,
        max_tokens: 2500,
        messages: [
            {
                role: "user",
                content: [
                    { type: "text", text: question },
                    {
                        type: "image_url",
                        image_url: {
                            url: imageUrl,
                        },
                    },
                ],
            },
        ],
    });
    return response;
}
//# sourceMappingURL=ai.js.map