// Cloned by Anand on 26 Nov 2023 from World "Chat with GPT model" by Starter user
// Please leave this clone trail here.
//Practical 2 :
//Use an AI API to achieve a function:
//2 worlds - Hello world to introduce the API and one where API is used heavily .
//Pick top 2 news article and TL;DR those.
const openaiURL = "https://api.openai.com/v1/chat/completions"; // can POST to this 3rd party URL
const openai_moderations_URL = "https://api.openai.com/v1/moderations";
const themodel = "gpt-3.5-turbo"; // the OpenAI model we are going to talk to
//const apikey = "";// 01983019283; //copy GPT API Key
const prompts = [];
var apikey = "";
prompts[0] = "What makes a relationship great is...";
prompts[1] = "Two truths and a lie ...";
prompts[2] = "I'm hoping you...";
prompts[3] = "If I could eat only one meal for the rest of my life it would be ...";
prompts[4] = "My third-grade teacher described me as ...";
prompts[5] = "I'm a great +1 because ...";
prompts[6] = "I promise I won't judge you if ...";
prompts[7] = "My zombie apocalypse plan is ..." ;
prompts[8] = "A pro and con of dating me ...";
prompts[9] = "I will never shut up about ...";
prompts[10] = "My personal hell is ...";
prompts[11] = "A world would be a better place with more ...";
prompts[12] = "I'm still not over ...";
prompts[13] = "Quickest way to my heart ...";
prompts[14] = "After work you can find me ...";
prompts[15] = "My current obsession ...";
prompts[16] = "If I could have one superpower it'd be ...";
prompts[17] = "Favorite quality in a person ...";
// default API key and prompt:
var topic = "hello";
var final_str;
var content_moderation_failed = 0;
var content_moderation_reasons = [];
var gpt_temperature = 0.2;
// default body is margin 0 and padding 0
// give it more whitespace:
$('body').css( "margin", "100px" );
$('body').css( "padding", "100px" );
$('body').css( "background-color", "red");
$('body').css( "box-sizing", "border-box" );
$('body').css( "list-style", "none" );
$('InfoDiv').css ("font-family", "Arial");
document.write ( `
<h1> Your AI wingman </h1>
<div id=enterkey>
Enter API key:
<input style='width:25vw;' maxlength='2000' NAME="apikey" id="apikey" VALUE='' >
<button onclick='setkey();' class=ab-normbutton >Set API key</button>
</div>
<div class="InfoDiv" style="width:60vw; background-color:pink; border: 1px solid black; margin:20; padding: 20px;">
<h3> Answer a few questions and get an AI-generated dating app profile </h3>
Who are you ?:
<select id="Gender", name = "Gender" required>
<option value="Man" selected>Man</option>
<option value="Woman">Woman</option>
<option value="Non-Binary">Non-Binary</option>
</select>
<hr>
How old are you :
<input type=number style='width:5vw;' maxlength='2' NAME="Age" id="EnterAge" required>
<hr>
Pick some interests <br>
<input class="interestCheckbox" type="checkbox" id="interest1" name="Biking" >
<label for="interest1"> Biking </label>
<input class="interestCheckbox" type="checkbox" id="interest2" name="Hiking" >
<label for="interest2"> Hiking </label>
<input class="interestCheckbox" type="checkbox" id="interest3" name="Road Trips" >
<label for="interest3"> Road Trips </label>
<input class="interestCheckbox" type="checkbox" id="interest4" name="Bouldering" >
<label for="interest4"> Bouldering </label>
<input class="interestCheckbox" type="checkbox" id="interest5" name="Skiing" >
<label for="interest5"> Skiing </label>
<input class="interestCheckbox" type="checkbox" id="interest6" name="wine tasting" >
<label for="interest6"> Wine tasting </label>
<input class="interestCheckbox" type="checkbox" id="interest7" name="dancing" >
<label for="interest7"> Dancing </label>
<input class="interestCheckbox" type="checkbox" id="interest8" name="watching movies" >
<label for="interest8"> Watching Movies </label><br>
<pre>
</pre>
Want to add your own ? (90's sitcoms, cafe-hopping ...) :
<input type=text style='width:50vw;' maxlength='2000' NAME="Interests" value="sea swimming, bowling, kayaking" id="UserDefInterests"> <br>
<hr>
Which personality trait do you lean towards ?:
<select id="Personality">
<option label="Introvert">Introvert</option>
<option label="Extrovert">Extrovert</option>
</select>
<hr>
What are you looking for?
<select id="RelationGoal">
<option label="Something Casual">Something Casual</option>
<option label="A Long term partner">Long term partner</option>
<option label="Not sure yet">Not sure yet</option>
</select>
<hr>
What characteristics are you looking for in your partner ? (Humorous, sporty, nerdy ...) :
<input type=text style='width:50vw;' maxlength='2000' NAME="characteristics" value="funny, kind" id="characteristics"> <br>
<hr>
<h3> Can you put some basic details apart from the options selected above (the more detailed the better) </h3>
<input type=text style='width:50vw;' maxlength='2000' NAME="basicinfo" value="I'm an easy going person who loves to be outdoors and explore new places" id="basicinfo"> <br>
<hr>
Which Dating App would you be using ?
<select id="App_ID">
<option label="Bumble">Bumble</option>
<option label="Hinge">Hinge</option>
<option label="Tinder">Tinder</option>
</select>
<hr>
Qurkiness level : A quirky response may be very random - you might find some funny bits and pieces (Keep it below 65 - explained in report).
<div class="slidecontainer">
<input type="range" min="0" max="100" value="25" class="slider" id="myRange">
<p>Quirkiness Index: <span id="demo"></span></p>
</div>
<hr>
<br>
<hr>
<button onclick='setInterests();' class=ab-normbutton >Submit</button>
</div>
</div>
<div style="width:60vw; background-color:#ffffff; border: 1px solid black; margin:20; padding: 20px;">
<div id=content_moderation > </div>
</div>
<div style="width:60vw; background-color:#ffffcc; border: 1px solid black; margin:20; padding: 20px;">
<h3> Response: </h3>
<div id=them > </div>
</div>
<p> <i> Caution : :: .<br>
The AI model has generated this based on an idea it has about you - it may or may not be accurate !.
If you end up going on a date - disclose the information ! Gets you a topic to talk on !!
</i> </p>
<pre>
</pre>
` );
function setInterests() {
my_gender = jQuery("select#Gender").val();
my_age = jQuery("input#EnterAge").val();
final_str = `My information : Age: ${my_age} Gender: ${my_gender}. Hobbies/Interests:`;
var my_interests = [];
var checkedValue = null;
var inputElements = document.getElementsByClassName('interestCheckbox');
for(var i=0; inputElements[i]; ++i){
var j = 0;
if(inputElements[i].checked){
my_interests[j] = inputElements[i].name;
final_str = final_str.concat(my_interests[j], ", ");
console.log("Interests : " + my_interests[j])
j = j+1;
}
}
if(my_interests.length === 0) {
}
var my_add_interests = jQuery("#UserDefInterests").val()
var my_personality = jQuery("select#Personality").val();
var my_relation_goal = jQuery("select#RelationGoal").val();
var my_partner_characteristics = jQuery("#characteristics").val()
var my_basicinfo = jQuery("#basicinfo").val()
var user_inputs = [];
user_inputs[0] = my_add_interests;
user_inputs[1] = my_partner_characteristics;
user_inputs[2] = my_basicinfo;
//Check moderations on content provided by users:
//Need to do this on each smaller string because GPT's moderation failed to detect foul phrases on the final string which is passed.
for(var i=0; i<user_inputs.length ; i++) {
check_content_moderation(user_inputs[i]);
console.log("done with loop");
}
if(content_moderation_failed == 1) {
var info = "<font color=red><b> Content moderation failed - your inputs possibly contain language indicating : ";
for(var i=0; i<content_moderation_reasons.length; i++) {
info = info.concat(content_moderation_reasons[i], " ");
}
info = info.concat("</b></font>")
console.log("content moderation failed, info = " + info);
$("#content_moderation").html ( info );
content_moderation_failed = 0;
} else {
//Don't bother continuing if content moderation failed
if(my_add_interests) {
final_str = final_str.concat(" ", my_add_interests)
}
final_str.concat(" Personality leans towards: ", my_personality);
if(my_relation_goal){
if(my_relation_goal == "Not sure yet"){
//Keep it a mystery
} else {
final_str = final_str.concat(" Looking for: ", my_relation_goal)
}
}
if(my_partner_characteristics) {
final_str = final_str.concat(" I get along really well with someone who has the following traits: ", my_partner_characteristics);
}
if(my_basicinfo) {
final_str = final_str.concat(" Some more information: ", my_basicinfo);
}
console.log(final_str);
$("#content_moderation").html ( " " );
sendchat();
}
}
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('newstopic').onkeydown = function(event) { if (event.keyCode == 13) sendchat(); };
var slider = document.getElementById("myRange");
var m_output = document.getElementById("demo");
m_output.innerHTML = slider.value;
slider.oninput = function() {
gpt_temperature = mapRange(this.value, 0, 100, 0.1, 1.8);
m_output.innerHTML = this.value;
console.log("gpt-temp = " + gpt_temperature);
}
function mapRange(value, inMin, inMax, outMin, outMax) {
return ((value - inMin) * (outMax - outMin)) / (inMax - inMin) + outMin;
}
// --- Send my line of text ----------------------------------------------------------------
function sendchat()
{
var dating_app = jQuery("select#App_ID").val();
//var shuffledprompts = shuffle(prompts);
let gpt_query = `${final_str}. \n Can you generate a funny and punchy bio best suited for the dating app ${dating_app}. which you can generate using my information provided above ?`;
//if(dating_app == "Bumble" || dating_app == "Hinge") {
if(dating_app.match(/Bumble|Hinge/)) {
//Tinder does not require an app as of now
gpt_query = gpt_query.concat(" Also pick some prompts which ", dating_app ," provides which can be best answered by the information provided, add some twist to the prompts but keep it all real");
}
for(var i =1 ; i < prompts.length + 1; i++) {
if(prompts[i]){
//gpt_query = gpt_query.concat(`${i}. `, prompts[i], " ");
}
}
console.log(gpt_query);
var thedata = {
"model": themodel,
"temperature": gpt_temperature,
"messages": [{
"role": "user",
"content": gpt_query
}]
};
// then as string representing that JSON:
var thedatastring = JSON.stringify ( thedata );
$.ajaxSetup({
headers:
{
"Content-Type": "application/json",
"Authorization": "Bearer " + apikey
}
});
console.log(thedatastring);
//First check for moderation of input data - make sure there's no offensive things in there
$.ajax({
type: "POST",
url: openaiURL,
data: thedatastring,
dataType: "json",
success: function ( d, rc ) { successfn ( d, rc ); },
error: function() { errorfn (); }
});
//Send in the second token to actually generate a prompt.
}
// global variable to examine return data in console
var a;
function check_content_moderation (data) {
var moderation_data = {
"input": data
} ;
var moderation_str = JSON.stringify(moderation_data);
console.log("moderation input = : " + moderation_str);
$.ajaxSetup({
headers:
{
"Content-Type": "application/json",
"Authorization": "Bearer " + apikey
}
});
$.ajax({
type: "POST",
url: openai_moderations_URL,
async: false,
data: moderation_str,
dataType: "json",
success: function ( d, rc ) { mod_successfn ( d, rc ); },
error: function() { errorfn (); }
});
// _callback();
}
function mod_successfn(data, rc) {
a = data;
console.log("moderation success : " + a["results"][0].flagged);
if(a["results"][0].flagged === true ) {
content_moderation_failed = 1;
var obj = a["results"][0].categories;
for (var key in obj) {
if(obj[key] === true) {
content_moderation_reasons.push(key);
}
console.log("moderation content : " + key + " : " + obj[key] + "content_mod = " + content_moderation_failed);
}
}
}
function mod_errorfn(data, rc) {
console.log("something went wrong with moderation API ");
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>" );
}
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>" );
}