Code viewer for World: Chat with GPT model (clone...
// Default API key and prompt
let apikey = "";
const flanT5ComparisonAPI = "https://api-inference.huggingface.co/models/google/flan-t5-large"; // Hugging Face Flan-T5 for comparison
const myMemoryAPI = "https://api.mymemory.translated.net/get"; // MyMemory API

// Default language-to-model mapping for Helsinki API
const languageModelMap = {
    Spanish: "opus-mt-en-es",
    French: "opus-mt-en-fr",
    Italian: "opus-mt-en-it",
    German: "opus-mt-en-de",
    Arabic: "opus-mt-en-ar",
    Japanese: "opus-mt-en-jap",
    Bulgarian: "opus-mt-en-bg",
};

// Default body styling
$('body').css("margin", "20px");
$('body').css("padding", "20px");

document.write(`
<h1> Translate Text Using Two APIs and then comparing </h1>

<div style="width:100%;  padding: 20px; background-color: #B6D0E2;">
    <h2> Set Up Translation </h2>
    <h3> 1. Enter API key </h3>
    <div id="enterkey">
        API key: <input style="width:50%;" maxlength="2000" id="apikey" placeholder="Enter your Hugging Face API key">
        <button onclick="setkey();" class="ab-normbutton bg-orange-100">Set API Key</button>
    </div>
    <h3> 2. Enter text to translate </h3>
    <div>
        <input style="width:100%;" id="textInput" placeholder="Enter text to translate">
    </div>
    <h3> 3. Select language </h3>
    <select id="languageSelect">
        <option value="Spanish">Spanish</option>
        <option value="French">French</option>
        <option value="Italian">Italian</option>
        <option value="German">German</option>
        <option value="Arabic">Arabic</option>
        <option value="Japanese">Japanese</option>
        <option value="Bulgarian">Bulgarian</option>
    </select>
    <button onclick="translateWithBothAPIs();" class="ab-normbutton bg-orange-100">Translate</button>
</div>

<div style="width:100%; display: flex; justify-content: space-between; margin-top: 20px;">
    <!-- Helsinki Translation -->
    <div style="width:48%; border: 1px solid black; padding: 20px; background-color: #B6D0E2;">
        <h2> Helsinki Translation </h2>
        <h4> Sometimes you have to refresh the page for this to load :)</h4>
        <div id="helsinkiResult" style="background-color: #ffffcc; padding: 10px; border: 1px solid black;"></div>
    </div>
    <!-- MyMemory Translation -->
    <div style="width:48%; border: 1px solid black; padding: 20px; backround:blue">
        <h2> MyMemory Translation </h2>
         <h4>...</h4>
        <div id="myMemoryResult" style="background-color: #ffffcc; padding: 10px; border: 1px solid black;"></div>
    </div>
</div>

<!-- Comparison Section -->
<div style="width:100%; border: 1px solid black; padding: 20px; margin-top: 20px; background-color: #B6D0E2;">
    <h2> Compare Translations </h2>
    <h4> Sometimes these are incorrect answers but this is because it was the best AI with a free API key we could find :(</h4>
    <button onclick="compareTranslations();" class="ab-normbutton bg-orange-100">Compare Results</button>
    <h3> Which translation is better? 1: "Helsinki Translation" or 2: "MyMemory Translation".</h3>
    <div id="comparisonResult" style="background-color: #ffffcc; padding: 10px; border: 1px solid black;"></div>
</div>
`);

// Function to set API key
function setkey() {
    apikey = $("#apikey").val().trim();
    if (apikey) {
        $("#enterkey").html("<b>API key has been set.</b>");
    } else {
        alert("Please enter a valid API key.");
    }
}

// Translate with both APIs
async function translateWithBothAPIs() {
    const inputText = $("#textInput").val().trim();
    const selectedLanguage = $("#languageSelect").val();

    if (!inputText) {
        alert("Please enter text to translate.");
        return;
    }

    if (!apikey) {
        alert("Please set your API key first.");
        return;
    }

    const modelName = languageModelMap[selectedLanguage];
    if (!modelName) {
        alert(`No model found for the selected language: ${selectedLanguage}`);
        return;
    }

    // Display loading messages
    $("#helsinkiResult").html("<i>Loading Helsinki translation...</i>");
    $("#myMemoryResult").html("<i>Loading MyMemory translation...</i>");

    try {
        const [helsinkiTranslation, myMemoryTranslation] = await Promise.all([
            translateWithHelsinki(inputText, modelName),
            translateWithMyMemory(inputText, selectedLanguage)
        ]);

        $("#helsinkiResult").html(`<b>Translation:</b> ${helsinkiTranslation}`);
        $("#myMemoryResult").html(`<b>Translation:</b> ${myMemoryTranslation}`);
    } catch (error) {
        console.error("Translation Error:", error);
    }
}

// Utility function for a timeout because a lot of the api's are slow and need time to give a response
function timeoutPromise(ms) {
    return new Promise((_, reject) => {
        setTimeout(() => reject(new Error("Request timed out")), ms);
    });
}
//We have tested all of the available languages and they usually work but sometimes you have to refresh the page for them to work
// Translate with Helsinki API https://huggingface.co/Helsinki-NLP/opus-mt-en-ar?text=My+name+is+Wolfgang+and+I+live+in+Berlin
//there is a specific one for each language so the modelName changes for each language
async function translateWithHelsinki(inputText, modelName) {
    const huggingFaceURL = `https://api-inference.huggingface.co/models/Helsinki-NLP/${modelName}`;
    const payload = { inputs: inputText };

    try {
        const response = await Promise.race([
            fetch(huggingFaceURL, {
                method: "POST",
                headers: {
                    "Content-Type": "application/json",
                    "Authorization": `Bearer ${apikey}`,
                },
                body: JSON.stringify(payload),
            }),
            timeoutPromise(30000), // 30 seconds timeout
        ]);

        if (response.ok) {
            const data = await response.json();
            return data[0]?.translation_text || "No translation generated.";
        } else {
            const errorText = await response.text();
            throw new Error(`Helsinki API error: ${errorText}`);
        }
    } catch (error) {
        console.error("Helsinki API Error:", error);
        return "Error connecting to Helsinki API.";
    }
}

// Translate with MyMemory API
//https://mymemory.translated.net/en/English/Spanish/hey
async function translateWithMyMemory(inputText, targetLang) {
    const languageCodes = {
        Spanish: "es",
        French: "fr",
        Italian: "it",
        German: "de",
        Arabic: "pl",
        Japanese: "ja",
        Bulgarian: "bg",
    };
    const langCode = languageCodes[targetLang];
    const url = `${myMemoryAPI}?q=${encodeURIComponent(inputText)}&langpair=en|${langCode}`;

    try {
        const response = await fetch(url);
        const data = await response.json();
        return data.responseData.translatedText || "No translation available.";
    } catch (error) {
        console.error("MyMemory API Error:", error);
        return "Error connecting to MyMemory API.";
    }
}

// Compare Translations
//https://huggingface.co/google/flan-t5-large?text=Which+translation+for+%22I+like+shrimp+in+soup%22+to+%22spanish%22+is+better%3F+%22me+gustan+los+camarones+en+sopa%22+or+%22me+gustan+las+gambas+en+sopa%22%60
async function compareTranslations() {
    const helsinkiResult = $("#helsinkiResult").text().trim();
    const myMemoryResult = $("#myMemoryResult").text().trim();
    const inputText = $("#textInput").val().trim();
    const lang = $("#languageSelect").val();

    if (!apikey) {
        $("#comparisonResult").html("<font color=red><b>Please set the API key first.</b></font>");
        return;
    }

    const comparisonPrompt = `Which translation for "${inputText}" to "${lang}" is better? "${helsinkiResult}" or "${myMemoryResult}"`;

    $("#comparisonResult").html("<i>Loading...</i>");

    try {
        const response = await Promise.race([
            fetch(flanT5ComparisonAPI, {
                method: "POST",
                headers: {
                    "Content-Type": "application/json",
                    "Authorization": `Bearer ${apikey}`,
                },
                body: JSON.stringify({ inputs: comparisonPrompt }),
            }),
            timeoutPromise(30000), // 30 seconds timeout
        ]);

        if (response.ok) {
            const data = await response.json();
            const comparison = data[0]?.generated_text || "No comparison available.";
            $("#comparisonResult").html(`<b>Comparison Result:</b><br>${comparison}`);
        } else {
            const errorText = await response.text();
            throw new Error(`Flan-T5 API error: ${errorText}`);
        }
    } catch (error) {
        console.error("Flan-T5 API Error:", error);
        $("#comparisonResult").html("<font color=red><b>Error: Unable to connect to Flan-T5 Comparison API.</b></font>");
    }
}