"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.Cohere = void 0;
const cohere_ai_1 = require("cohere-ai");
const env_1 = require("@langchain/core/utils/env");
const llms_1 = require("@langchain/core/language_models/llms");
/**
 * Class representing a Cohere Large Language Model (LLM). It interacts
 * with the Cohere API to generate text completions.
 * @example
 * ```typescript
 * const model = new Cohere({
 *   temperature: 0.7,
 *   maxTokens: 20,
 *   maxRetries: 5,
 * });
 *
 * const res = await model.invoke(
 *   "Question: What would be a good company name for a company that makes colorful socks?\nAnswer:"
 * );
 * console.log({ res });
 * ```
 */
class Cohere extends llms_1.LLM {
    static lc_name() {
        return "Cohere";
    }
    get lc_secrets() {
        return {
            apiKey: "COHERE_API_KEY",
            api_key: "COHERE_API_KEY",
        };
    }
    get lc_aliases() {
        return {
            apiKey: "cohere_api_key",
            api_key: "cohere_api_key",
        };
    }
    constructor(fields) {
        super(fields ?? {});
        Object.defineProperty(this, "lc_serializable", {
            enumerable: true,
            configurable: true,
            writable: true,
            value: true
        });
        Object.defineProperty(this, "temperature", {
            enumerable: true,
            configurable: true,
            writable: true,
            value: 0
        });
        Object.defineProperty(this, "maxTokens", {
            enumerable: true,
            configurable: true,
            writable: true,
            value: 250
        });
        Object.defineProperty(this, "model", {
            enumerable: true,
            configurable: true,
            writable: true,
            value: void 0
        });
        Object.defineProperty(this, "apiKey", {
            enumerable: true,
            configurable: true,
            writable: true,
            value: void 0
        });
        Object.defineProperty(this, "client", {
            enumerable: true,
            configurable: true,
            writable: true,
            value: void 0
        });
        const apiKey = fields?.apiKey ?? (0, env_1.getEnvironmentVariable)("COHERE_API_KEY");
        if (!apiKey) {
            throw new Error("Please set the COHERE_API_KEY environment variable or pass it to the constructor as the apiKey field.");
        }
        this.client = new cohere_ai_1.CohereClient({
            token: apiKey,
        });
        this.maxTokens = fields?.maxTokens ?? this.maxTokens;
        this.temperature = fields?.temperature ?? this.temperature;
        this.model = fields?.model ?? this.model;
    }
    _llmType() {
        return "cohere";
    }
    invocationParams(options) {
        const params = {
            model: this.model,
            numGenerations: options.numGenerations,
            maxTokens: options.maxTokens ?? this.maxTokens,
            truncate: options.truncate,
            temperature: options.temperature ?? this.temperature,
            preset: options.preset,
            endSequences: options.endSequences,
            stopSequences: options.stop ?? options.stopSequences,
            k: options.k,
            p: options.p,
            frequencyPenalty: options.frequencyPenalty,
            presencePenalty: options.presencePenalty,
            returnLikelihoods: options.returnLikelihoods,
        };
        // Filter undefined entries
        return Object.fromEntries(Object.entries(params).filter(([, value]) => value !== undefined));
    }
    /** @ignore */
    async _call(prompt, options, runManager) {
        const generateResponse = await this.caller.callWithOptions({ signal: options.signal }, async () => {
            let response;
            try {
                response = await this.client.generate({
                    prompt,
                    ...this.invocationParams(options),
                });
                // eslint-disable-next-line @typescript-eslint/no-explicit-any
            }
            catch (e) {
                e.status = e.status ?? e.statusCode;
                throw e;
            }
            return response;
        });
        try {
            await runManager?.handleLLMNewToken(generateResponse.generations[0].text);
            return generateResponse.generations[0].text;
        }
        catch {
            console.log(generateResponse);
            throw new Error("Could not parse response.");
        }
    }
}
exports.Cohere = Cohere;
