Code viewer for World: Razi Chat Advanced
// talk to OpenAI GPT model (ChatGPT)
// adapted from:
// https://platform.openai.com/docs/api-reference/making-requests

// advanced world to showcase the power of OpenAI GPT-3.5 model. 
 const MUSICFILE = '/uploads/yorozi/Rema.mp3';
 AB.backgroundMusic ( MUSICFILE );

const openaiURL = "https://api.openai.com/v1/chat/completions"; // can POST to this 3rd party URL
const themodel = "gpt-3.5-turbo"; // the OpenAI model we are going to talk to

// default API key and prompt:
var apikey = "";
var theprompt = "";
var temperature = 0.7; // Default temperature value

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

document.write(`

<h1> Razi Chat with GPT model </h1>

<div id=enterkey>
    Enter your OpenAI API key:
    <input style='width:25vw;' maxlength='2000' NAME="apikey" id="apikey" VALUE=''>
    <button onclick='setkey();' class=ab-normbutton>Set API key</button>
</div>

<pre>

</pre>

<div style="width:60vw; background-color:lightblue;  border: 2px solid black; margin:20; padding: 20px;">
    <h3> Enter a "prompt" here </h3>
    <input style="width:50vw;" id=me value="What is Artificial Intelligence?">
    <button onclick="sendchat();" class=ab-normbutton> Send </button>
    <label for="temperature-slider">Temperature: (Randomness)</label>
    <input type="range" id="temperature-slider" min="0" max="1" step="0.1" value="0.1" onchange="adjustTemperature()">
</div>

<div style="width:60vw; background-color:lightblue;  border: 1px solid black; margin:20; padding: 20px;">
    <h3> GPT replies to Razi here.</h3>
    <div id=them> </div>
</div>
<b>NB: Feel free to input as many prompts as you want. Also, you can regenerate using the same prompt for more accurate answers.</b>

<div style="width:60vw; background-color:lightblue;  border: 1px solid black; margin:20; padding: 20px;">
    <h3> Enter a "prompt" here </h3>
    <input style="width:50vw;" id=graphicsRequest value="I want 5 blue boxes">
    <button onclick="generateGraphics();" class=ab-normbutton>Generate Graphics</button>
</div>
<div style="width:60vw; background-color:lightblue;  border: 1px solid black; margin:20; padding: 20px;">
    <h3> GPT generates here.</h3>
    <div id="containerId" class="code-container"></div>
</div>

`);

function setkey() {
    apikey = jQuery("input#apikey").val();
    apikey = apikey.trim();
    $("#enterkey").html("<b> API key has been set. </b>");
}

// Enter will also send chat:
document.getElementById('me').onkeydown = function (event) { if (event.keyCode == 13) sendchat(); };

function adjustTemperature() {
    temperature = parseFloat(document.getElementById("temperature-slider").value);
}

// Create a variable to hold the generated Three.js code
//use the GPT model to generate the code and store it in that variable
let threeJSCode = "";

function getCode() {
    const graphicsRequest = $("#graphicsRequest").val();
    
    theprompt = "Generate ONLY the exact Three.js graphic code for the following request. Do not add comments. Here is the request: "+ graphicsRequest;
     // construct request as JSON
    var thedata = {
        "model": themodel,
        "temperature": temperature,
        "messages": [{ "role": "user", "content": theprompt }]
    };
    // then as a string representing that JSON:
    var thedatastring = JSON.stringify(thedata);
    // HTTP headers must be set up with API key:
    $.ajaxSetup({
        headers: {
            "Content-Type": "application/json",
            "Authorization": "Bearer " + apikey
        }
    });
    
     // POST to 3rd party URL:
    $.ajax({
        type: "POST",
        url: openaiURL,
        data: thedatastring,
        dataType: "json",
        success: function (d, rc) { successfn(d, rc); },
        error: function () { errorfn(); }
    });
    threeJSCode = thedatastring;
    return threeJSCode;
}

function generateGraphics() {
      getCode();
      // Load the graphics.js file and execute the generated code
      const scriptElement = document.createElement('script');
      scriptElement.src = 'graphics.js';

      scriptElement.addEventListener('load', () => {
        const container = document.getElementById('containerId');
        const renderer = new THREE.WebGLRenderer();
        renderer.setSize(container.offsetWidth, container.offsetHeight);
        container.appendChild(renderer.domElement);

        const scene = new THREE.Scene();
        const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);

        const scriptElement = document.getElementById('graphicsRequest');
        theprompt = scriptElement.value;

        // Execute the Three.js code in the loaded script
        const request = new XMLHttpRequest();
        request.open('GET', 'graphics.js');
        request.onload = function () {
          if (request.status === 200) {
            const code = request.responseText;
            eval(code);
          } else {
            console.error('Error loading graphics.js', request.status);
          }
        };
        request.send();

        function animate() {
          requestAnimationFrame(animate);

          renderer.render(scene, camera);
        }

        animate();
      });
    }

// --- Send my line of text ----------------------------------------------------------------
function sendchat() {
    theprompt = $("#me").val();

    // construct request as JSON
    var thedata = {
        "model": themodel,
        "temperature": temperature,
        "messages": [{ "role": "user", "content": theprompt }]
    };

    // then as a string representing that JSON:
    var thedatastring = JSON.stringify(thedata);

    // HTTP headers must be set up with API key:
    $.ajaxSetup({
        headers: {
            "Content-Type": "application/json",
            "Authorization": "Bearer " + apikey
        }
    });

    // POST to 3rd party URL:
    $.ajax({
        type: "POST",
        url: openaiURL,
        data: thedatastring,
        dataType: "json",
        success: function (d, rc) { successfn(d, rc); },
        error: function () { errorfn(); }
    });
}

// global variable to examine return data in console
var a;

function successfn(data, rc) {
    a = data;
    var answer = a["choices"][0].message.content;
    $("#them").html(answer);
}

function errorfn() {
    if (apikey === "") $("#them").html("<font color=red><b> Enter API key to be able to chat. </b></font>");
    else $("#them").html("<font color=red><b> Unknown error. </b></font>");
}