import { Document } from "@langchain/core/documents";
import { BaseRetriever, } from "@langchain/core/retrievers";
import { getEnvironmentVariable } from "@langchain/core/utils/env";
/**
 * A class for retrieving documents related to a given search term
 * using the Tavily Search API.
 */
export class TavilySearchAPIRetriever extends BaseRetriever {
    static lc_name() {
        return "TavilySearchAPIRetriever";
    }
    get lc_namespace() {
        return ["langchain", "retrievers", "tavily_search_api"];
    }
    constructor(fields) {
        super(fields);
        Object.defineProperty(this, "k", {
            enumerable: true,
            configurable: true,
            writable: true,
            value: 10
        });
        Object.defineProperty(this, "includeGeneratedAnswer", {
            enumerable: true,
            configurable: true,
            writable: true,
            value: false
        });
        Object.defineProperty(this, "includeRawContent", {
            enumerable: true,
            configurable: true,
            writable: true,
            value: false
        });
        Object.defineProperty(this, "includeImages", {
            enumerable: true,
            configurable: true,
            writable: true,
            value: false
        });
        Object.defineProperty(this, "searchDepth", {
            enumerable: true,
            configurable: true,
            writable: true,
            value: "basic"
        });
        Object.defineProperty(this, "includeDomains", {
            enumerable: true,
            configurable: true,
            writable: true,
            value: void 0
        });
        Object.defineProperty(this, "excludeDomains", {
            enumerable: true,
            configurable: true,
            writable: true,
            value: void 0
        });
        Object.defineProperty(this, "kwargs", {
            enumerable: true,
            configurable: true,
            writable: true,
            value: {}
        });
        Object.defineProperty(this, "apiKey", {
            enumerable: true,
            configurable: true,
            writable: true,
            value: void 0
        });
        this.k = fields?.k ?? this.k;
        this.includeGeneratedAnswer =
            fields?.includeGeneratedAnswer ?? this.includeGeneratedAnswer;
        this.includeRawContent =
            fields?.includeRawContent ?? this.includeRawContent;
        this.includeImages = fields?.includeImages ?? this.includeImages;
        this.searchDepth = fields?.searchDepth ?? this.searchDepth;
        this.includeDomains = fields?.includeDomains ?? this.includeDomains;
        this.excludeDomains = fields?.excludeDomains ?? this.excludeDomains;
        this.kwargs = fields?.kwargs ?? this.kwargs;
        this.apiKey = fields?.apiKey ?? getEnvironmentVariable("TAVILY_API_KEY");
        if (this.apiKey === undefined) {
            throw new Error(`No Tavily API key found. Either set an environment variable named "TAVILY_API_KEY" or pass an API key as "apiKey".`);
        }
    }
    async _getRelevantDocuments(query, _runManager) {
        const body = {
            query,
            include_answer: this.includeGeneratedAnswer,
            include_raw_content: this.includeRawContent,
            include_images: this.includeImages,
            max_results: this.k,
            search_depth: this.searchDepth,
            api_key: this.apiKey,
        };
        if (this.includeDomains) {
            body.include_domains = this.includeDomains;
        }
        if (this.excludeDomains) {
            body.exclude_domains = this.excludeDomains;
        }
        const response = await fetch("https://api.tavily.com/search", {
            method: "POST",
            headers: {
                "content-type": "application/json",
            },
            body: JSON.stringify({ ...body, ...this.kwargs }),
        });
        const json = await response.json();
        if (!response.ok) {
            throw new Error(`Request failed with status code ${response.status}: ${json.error}`);
        }
        if (!Array.isArray(json.results)) {
            throw new Error(`Could not parse Tavily results. Please try again.`);
        }
        // eslint-disable-next-line @typescript-eslint/no-explicit-any
        const docs = json.results.map((result) => {
            const pageContent = this.includeRawContent
                ? result.raw_content
                : result.content;
            const metadata = {
                title: result.title,
                source: result.url,
                ...Object.fromEntries(Object.entries(result).filter(([k]) => !["content", "title", "url", "raw_content"].includes(k))),
                images: json.images,
            };
            return new Document({ pageContent, metadata });
        });
        if (this.includeGeneratedAnswer) {
            docs.push(new Document({
                pageContent: json.answer,
                metadata: {
                    title: "Suggested Answer",
                    source: "https://tavily.com/",
                },
            }));
        }
        return docs;
    }
}
