import { getHeaders } from "../../continueServer/stubs/headers.js";
import { SERVER_URL } from "../../util/parameters.js";
import { Telemetry } from "../../util/posthog.js";
import { BaseLLM } from "../index.js";
import { streamResponse } from "../stream.js";
class FreeTrial extends BaseLLM {
    static providerName = "free-trial";
    ghAuthToken = undefined;
    setupGhAuthToken(ghAuthToken) {
        this.ghAuthToken = ghAuthToken;
    }
    async _getHeaders() {
        if (!this.ghAuthToken) {
            throw new Error("Please sign in with GitHub in order to use the free trial. If you'd like to use Continue without signing in, you can set up your own local model or API key.");
        }
        return {
            "Content-Type": "application/json",
            Authorization: `Bearer ${this.ghAuthToken}`,
            ...(await getHeaders()),
        };
    }
    async _countTokens(prompt, model, isPrompt) {
        if (!Telemetry.client) {
            throw new Error('In order to use the free trial, telemetry must be enabled so that we can monitor abuse. To enable telemetry, set "allowAnonymousTelemetry": true in config.json and make sure the box is checked in IDE settings. If you use your own model (local or API key), telemetry will never be required.');
        }
        const event = isPrompt
            ? "free_trial_prompt_tokens"
            : "free_trial_completion_tokens";
        Telemetry.capture(event, {
            tokens: this.countTokens(prompt),
            model,
        });
    }
    _convertArgs(options) {
        return {
            model: options.model,
            frequency_penalty: options.frequencyPenalty,
            presence_penalty: options.presencePenalty,
            max_tokens: options.maxTokens,
            stop: options.model === "starcoder-7b"
                ? options.stop
                : options.stop?.slice(0, 2),
            temperature: options.temperature,
            top_p: options.topP,
        };
    }
    async *_streamComplete(prompt, options) {
        const args = this._convertArgs(this.collectArgs(options));
        await this._countTokens(prompt, args.model, true);
        const response = await this.fetch(`${SERVER_URL}/stream_complete`, {
            method: "POST",
            headers: await this._getHeaders(),
            body: JSON.stringify({
                prompt,
                ...args,
            }),
        });
        let completion = "";
        for await (const value of streamResponse(response)) {
            yield value;
            completion += value;
        }
        this._countTokens(completion, args.model, false);
    }
    _convertMessage(message) {
        if (typeof message.content === "string") {
            return message;
        }
        const parts = message.content.map((part) => {
            return {
                type: part.type,
                text: part.text,
                image_url: { ...part.imageUrl, detail: "low" },
            };
        });
        return {
            ...message,
            content: parts,
        };
    }
    async *_streamChat(messages, options) {
        const args = this._convertArgs(this.collectArgs(options));
        await this._countTokens(messages.map((m) => m.content).join("\n"), args.model, true);
        const response = await this.fetch(`${SERVER_URL}/stream_chat`, {
            method: "POST",
            headers: await this._getHeaders(),
            body: JSON.stringify({
                messages: messages.map(this._convertMessage),
                ...args,
            }),
        });
        let completion = "";
        for await (const chunk of streamResponse(response)) {
            yield {
                role: "assistant",
                content: chunk,
            };
            completion += chunk;
        }
        this._countTokens(completion, args.model, false);
    }
    async listModels() {
        return [
            "llama3-70b",
            "gpt-4o",
            "gpt-3.5-turbo",
            "claude-3-sonnet-20240229",
            "claude-3-haiku-20240307",
            "gemini-1.5-pro-latest",
        ];
    }
}
export default FreeTrial;
