import { globalsHelper } from "./GlobalsHelper.js";
import { SentenceSplitter } from "./TextSplitter.js";
import { DEFAULT_CHUNK_OVERLAP_RATIO, DEFAULT_CONTEXT_WINDOW, DEFAULT_NUM_OUTPUTS, DEFAULT_PADDING } from "./constants.js";
export function getEmptyPromptTxt(prompt) {
    return prompt({});
}
/**
 * Get biggest empty prompt size from a list of prompts.
 * Used to calculate the maximum size of inputs to the LLM.
 * @param prompts
 * @returns
 */ export function getBiggestPrompt(prompts) {
    const emptyPromptTexts = prompts.map(getEmptyPromptTxt);
    const emptyPromptLengths = emptyPromptTexts.map((text)=>text.length);
    const maxEmptyPromptLength = Math.max(...emptyPromptLengths);
    const maxEmptyPromptIndex = emptyPromptLengths.indexOf(maxEmptyPromptLength);
    return prompts[maxEmptyPromptIndex];
}
/**
 * A collection of helper functions for working with prompts.
 */ export class PromptHelper {
    contextWindow = DEFAULT_CONTEXT_WINDOW;
    numOutput = DEFAULT_NUM_OUTPUTS;
    chunkOverlapRatio = DEFAULT_CHUNK_OVERLAP_RATIO;
    chunkSizeLimit;
    tokenizer;
    separator = " ";
    // eslint-disable-next-line max-params
    constructor(contextWindow = DEFAULT_CONTEXT_WINDOW, numOutput = DEFAULT_NUM_OUTPUTS, chunkOverlapRatio = DEFAULT_CHUNK_OVERLAP_RATIO, chunkSizeLimit, tokenizer, separator = " "){
        this.contextWindow = contextWindow;
        this.numOutput = numOutput;
        this.chunkOverlapRatio = chunkOverlapRatio;
        this.chunkSizeLimit = chunkSizeLimit;
        this.tokenizer = tokenizer || globalsHelper.tokenizer();
        this.separator = separator;
    }
    /**
   * Given a prompt, return the maximum size of the inputs to the prompt.
   * @param prompt
   * @returns
   */ getAvailableContextSize(prompt) {
        const emptyPromptText = getEmptyPromptTxt(prompt);
        const promptTokens = this.tokenizer(emptyPromptText);
        const numPromptTokens = promptTokens.length;
        return this.contextWindow - numPromptTokens - this.numOutput;
    }
    /**
   * Find the maximum size of each chunk given a prompt.
   * @param prompt
   * @param numChunks
   * @param padding
   * @returns
   */ getAvailableChunkSize(prompt, numChunks = 1, padding = 5) {
        const availableContextSize = this.getAvailableContextSize(prompt);
        const result = Math.floor(availableContextSize / numChunks) - padding;
        if (this.chunkSizeLimit) {
            return Math.min(this.chunkSizeLimit, result);
        } else {
            return result;
        }
    }
    /**
   * Creates a text splitter with the correct chunk sizes and overlaps given a prompt.
   * @param prompt
   * @param numChunks
   * @param padding
   * @returns
   */ getTextSplitterGivenPrompt(prompt, numChunks = 1, padding = DEFAULT_PADDING) {
        const chunkSize = this.getAvailableChunkSize(prompt, numChunks, padding);
        if (chunkSize === 0) {
            throw new Error("Got 0 as available chunk size");
        }
        const chunkOverlap = this.chunkOverlapRatio * chunkSize;
        const textSplitter = new SentenceSplitter({
            chunkSize,
            chunkOverlap
        });
        return textSplitter;
    }
    /**
   * Repack resplits the strings based on the optimal text splitter.
   * @param prompt
   * @param textChunks
   * @param padding
   * @returns
   */ repack(prompt, textChunks, padding = DEFAULT_PADDING) {
        const textSplitter = this.getTextSplitterGivenPrompt(prompt, 1, padding);
        const combinedStr = textChunks.join("\n\n");
        return textSplitter.splitText(combinedStr);
    }
}
