PHP Classes

File: example.phpopenaichat.php

Recommend this page to a friend!
  Classes of JImmy Bo   OpenAI Chat API PHP Completions Class   example.phpopenaichat.php   Download  
File: example.phpopenaichat.php
Role: Example script
Content type: text/plain
Description: An example using the class PHPOpenAIChat
Class: OpenAI Chat API PHP Completions Class
Chat application like ChatGPT using OpenAI GPT API
Author: By
Last change: updated to handle new gpt-3.5-16k and gpt-4-32k models
Date: 8 months ago
Size: 51,793 bytes
 

Contents

Class file image Download
<?php $apiKey = "your-openai-api-key-here"; # set your openai key here // version: 1.0 // filename: example.phpopenaichat.php // author: https://www.phpclasses.org/browse/author/144301.html // description: An application to hold conversations using the OpenAI API to access the GPT-3.5-Turbo model and the GPT-4 model. // license: BSD License // TODO: DONE. Conversation loading/saving // TODO: DONE. Edit previous message sections by clicking their div in the window to change their content // TODO: When contracting messages array to fit into maxtokens, start throwing away everything after first agent and first prompt. // TODO: A oneshot section for a single message that is not part of the conversation. // TODO: DONE. save/load agent /* Description: An application to hold conversations using the OpenAI API to access the GPT-3.5-Turbo model and the GPT-4 model. Very versatile and lets you edit the conversation's past to change the future responses. Let's you save/load/delete conversations and agents using JSON flatfiles. Programmed using PHP 8. Uses jQuery CDN for jQuery. PHP Curl required to connect to API with class.phpopenaichat.php. I found ChatGPT to be lacking, so I made my own. Messages in conversation only show an excerpt. Click on them to see the full message. */ /* Features: - uses class class.phpopenaichat.php to drive the application's API request. - Persistent conversation using $_SESSION - Persistent controls that dynamically update on the server side whenever they are changed client side - Using jQuery to dynamically update the page without reloading it - Ability to save/load/delete conversations in a JSON file in the _saved directory (create in this program's root, and set as read/writeable - Ability to edit previous conversation messages by clicking on them in the window (Both agent and user messages can be edited) - Ability to save/load/delete agent into a JSON file in the _saved_agents directory (create in this program's root, and set as read/writeable - Minimal CSS styling for better code clarity - Ability to change the model, temperature, frequency penalty, presence penalty, and max tokens, previous conversation, and agent between prompts - frequency penalty, presence penalty let the AI know to not repeat itself or to not repeat the user's input - temperature is how random the AI's response is. 0.0 is the most predictable, 1.0+ is the most random - agents help the model align to a specific style of conversation. (ie. a doctor, a lawyer, a child, a teenager, a parent, etc.) - multiuser - Can run multiple instances at same time, but just use different browsers or a private window so that each instance has its own session. - GPT 4 is in beta at the moment, so you have to request access. - API access costs money, so be aware of that. (gpt 3.5 turbo is dirt cheap at the moment) - This is not secured for production use. It is just a proof of concept, and made for closed/private access from trusted individuals. - Using a command processor on the return from the server let's the server dynamically redefine the controls on the client side. - server has a copy of the clients data, so client's side is more of an indicator than a director. - API can take a few seconds to return a response, so be patient when it seems nothing is working after sending a prompt. devnotes: june 2023 - added to example: - added support for gpt-3.5-turbo-16k (16k token model of gpt-3.5-turbo) - added support for gpt-4-32k (32k token model of gpt-4) */ // start our session for persistent parts of the application ob_start(); session_start(); // destroy session // session_destroy(); exit; // setting some defaults for the application if(!isset($_SESSION['messages'])) $_SESSION['messages'] = []; // current conversation if(!isset($_SESSION['agent'])) $_SESSION['agent'] = "You are a friendly and helpful assistant."; if(!isset($_SESSION['model'])) $_SESSION['model'] = "gpt-3.5-turbo"; // default model if(!isset($_SESSION['temperature'])) $_SESSION['temperature'] = 1.0; // default temperature if(!isset($_SESSION['freq_penalty'])) $_SESSION['freq_penalty'] = 0.0; // default frequency penalty if(!isset($_SESSION['pres_penalty'])) $_SESSION['pres_penalty'] = 0.0; // default presence penalty if(!isset($_SESSION['max_tokens'])) $_SESSION['max_tokens'] = 4090; // default max tokens # --- require_once('class.phpopenaichat.php'); // create new instance of PHPOpenAIChat $openAIChat = new PHPOpenAIChat($apiKey); // unused?... for now function send_and_append($prompt, $messages) { global $openAIChat; $response = $openAIChat->sendMessage($messages); $text = $openAIChat->get_response_text($response); $messages = $openAIChat->append_response_to_messages($messages, $text); return $messages; } // end send_and_append() function html_messages($messages) { if(empty($messages)) return ''; $html = ' <style> .messages { padding-bottom:200px; } .message_content textarea { width: 98%; /* height: 100%; */ height:auto; border: none; background-color: transparent; } </style> '; $row_count = 0; $even_odd = "odd"; foreach($messages as $message) { $the_content = htmlentities($message['content']); $html .= '<div class="message '.$even_odd.'" row_count="'.$row_count.'" >'; $html .= '<div class="message_role">'.$message['role'].'</div>'; $html .= '<div class="message_content"><textarea class="autoExpand" name="message_content_textarea" row_count="'. $row_count.'" onchange="btn_update_message_content(this);">'. $the_content.'</textarea></div>'; $html .= '</div>'; $row_count++; $even_odd = ($even_odd == "even") ? "odd" : "even"; } return $html; } // end html_messages() function change_message_content($messages, $index, $content) { // will let us click and edit a message div and have ajax send back to server to change conversation history $messages[$index]['content'] = $content; return $messages; } // end change_message_content() function get_conversation_titles() { $titles = []; $files = glob('_saved/*.json'); foreach($files as $file) { $json = file_get_contents($file); $json = json_decode($json, true); // substr out the _saved/ part of the filename $just_file = substr($file, strlen('_saved/') ); $titles[] = [ 'title' => $json['title'], 'file' => $just_file ]; } return $titles; } // end get_conversation_titles() function html_conversation_combobox() { // return the html for a dropdown combobox of all the saved conversations $titles = get_conversation_titles(); $html = '<select id="conversation_combobox" name="conversation_combobox" >'; foreach($titles as $title) { $html .= '<option value="'.$title['file'].'">'.$title['title'].'</option>'; } $html .= '</select>'; return $html; } function get_agents_titles() { $titles = []; $files = glob('_saved_agents/*.json'); foreach($files as $file) { $json = file_get_contents($file); $json = json_decode($json, true); // substr out the _agents/ part of the filename $just_file = substr($file, strlen('_saved_agents/') ); $titles[] = [ 'title' => $json['title'], 'file' => $just_file ]; } return $titles; } // end get_agents_titles() function html_agents_combobox() { // return the html for a dropdown combobox of all the saved agents $titles = get_agents_titles(); $html = '<select id="agents_combobox" name="agents_combobox" >'; foreach($titles as $title) { $html .= '<option value="'.$title['file'].'">'.$title['title'].'</option>'; } $html .= '</select>'; return $html; } // end html_agents_combobox() # --- # gets ajax request and then returns json data and quits. if(!empty($_GET['ajax'])) { switch($_GET['ajax']) { case 'delete_conversation': $file = $_POST['flds']['file']; $file = trim($file); if(empty($file)) { $return_arr[] = array( "command" => 'alert', "process" => "delete_conversation", "msg" => "file empty" ); break; // error: no file specified } $file = '_saved/'.$file; // if file doesn't exist error out if(!file_exists($file)) { $return_arr[] = array( "command" => 'alert', "process" => "delete_conversation", "msg" => "file does not exist" ); break; // error: file does not exist } unlink($file); $return_arr[] = array( "command" => 'alert', "process" => "delete_conversation", "msg" => "file deleted" ); $return_arr[] = array( "command" => 'html', "selector" => '#conversation_combobox', "msg" => html_conversation_combobox() ); break; case 'load_conversation': $file = $_POST['flds']['file']; $file = trim($file); if(empty($file)) { $return_arr[] = array( "command" => 'alert', "process" => "load_conversation", "msg" => "file empty" ); break; // error: no file specified } $file = '_saved/'.$file; // if file doesn't exist error out if(!file_exists($file)) { $return_arr[] = array( "command" => 'alert', "process" => "load_conversation", "msg" => "file does not exist" ); break; // error: file does not exist } $json = file_get_contents($file); $json = json_decode($json, true); $messages = $json['messages']; $_SESSION['messages'] = $messages; $messages_html = html_messages($messages); $return_arr[] = array( "command" => 'html', "process" => "load_conversation", "selector" => '.output', "msg" => $messages_html ); // update textareas $return_arr[] = array( "command" => 'resize_textareas', "process" => "load_conversation" ); break; case 'save_conversation': $conversation_title = $_POST['flds']['title']; $messages = $_SESSION['messages']; // now create a folder named '_saved' and save the conversation as a json file in that folder // file will be a timestamp_hash.json // json will be format: // "title": "conversation title", // "messages": {$_SESSION['messages']} // create folder if it doesn't exist if(!file_exists('_saved')) @mkdir('_saved'); // if dir doesn't exist... abort with alert error if(!file_exists('_saved')) { $return_arr[] = array( "command" => 'alert', "process" => "save_conversation", "msg" => "could not create _saved folder" ); break; // error: could not create _saved folder } // create a unique filename $filename = time().'_'.md5(time()).'.json'; $filepath = '_saved/'.$filename; // save the file... $json_data = array( "title" => $conversation_title, "messages" => $messages ); $json_data = json_encode($json_data); // store it to file $result = file_put_contents($filepath, $json_data); // create json data $json_data = array( "title" => $conversation_title, "messages" => $messages ); $return_arr[] = array( "command" => 'alert', "process" => "save_conversation", "msg" => "saved conversation" ); $return_arr[] = array( "command" => 'val', 'selector' => 'input[name="save-message_title"]', 'msg' => '' ); $return_arr[] = array( "command" => 'html', "selector" => '#conversation_combobox', "msg" => html_conversation_combobox() ); break; // case 'save_conversation' case 'change_message_content': $index = $_POST['flds']['row_count']; $content = $_POST['flds']['message_content']; $messages = $_SESSION['messages']; $messages = change_message_content($messages, $index, $content); $_SESSION['messages'] = $messages; $return_arr[] = array( "command" => 'alert', "process" => "change_message_content", "msg" => "changed message content", "index" => $index, "content" => $content ); break; // case 'change_message_content' case 'update_conversation': $messages = $_SESSION['messages']; $html_messages = html_messages($messages); $return_arr[] = array( "command" => 'html', 'selector' => '.output', 'msg' => $html_messages ); break; // case 'update_conversation' case 'delete_agent': $file = $_POST['flds']['file']; $file = trim($file); if(empty($file)) { $return_arr[] = array( "command" => 'alert', "process" => "delete_agent", "msg" => "file empty" ); break; // error: no file specified } $file = '_saved_agents/'.$file; // if file doesn't exist error out if(!file_exists($file)) { $return_arr[] = array( "command" => 'alert', "process" => "delete_agent", "msg" => "file does not exist" ); break; // error: file does not exist } unlink($file); $return_arr[] = array( "command" => 'alert', "process" => "delete_agent", "msg" => "file deleted" ); $return_arr[] = array( "command" => 'html', "selector" => '#agents_combobox', "msg" => html_agents_combobox() ); break; case 'save_agent': $agent_name = $_POST['flds']['title']; $agent = $_SESSION['agent']; // create folder if it doesn't exist if(!file_exists('_saved_agents')) @mkdir('_saved_agents'); // if dir doesn't exist... abort with alert error if(!file_exists('_saved_agents')) { $return_arr[] = array( "command" => 'alert', "process" => "save_agent", "msg" => "could not create _saved_agents folder" ); break; // error: could not create _saved_agents folder } // create a unique filename $filename = time().'_'.md5(time()).'.json'; $filepath = '_saved_agents/'.$filename; // save the file... $json_data = array( "title" => $agent_name, "agent" => $agent ); $json_data = json_encode($json_data); // store it to file $result = file_put_contents($filepath, $json_data); $return_arr[] = array( "command" => 'alert', "process" => "save_agent", "msg" => "saved agent" ); $return_arr[] = array( "command" => 'val', 'selector' => 'input[name="save-agent_title"]', 'msg' => '' ); $return_arr[] = array( "command" => 'html', "selector" => '#agents_combobox', "msg" => html_agents_combobox() ); break; // case 'save_assistant' case 'load_agent': $file = $_POST['flds']['file']; $file = trim($file); if(empty($file)) { $return_arr[] = array( "command" => 'alert', "process" => "load_agent", "msg" => "file empty" ); break; // error: no file specified } $file = '_saved_agents/'.$file; // if file doesn't exist error out if(!file_exists($file)) { $return_arr[] = array( "command" => 'alert', "process" => "load_agent", "msg" => "file does not exist" ); break; // error: file does not exist } $json = file_get_contents($file); $json = json_decode($json, true); $agent = $json['agent']; $_SESSION['agent'] = $agent; $return_arr[] = array( "command" => 'val', "process" => "load_agent", "selector" => '#text_agent', "msg" => $agent ); break; // case 'load_agent' case 'one-shot': // function one_shot($api_key, $prompt, $agent='You are a helpful assistant.', $temperature=1.0, $max_tokens=4000, $model="gpt-3.5-turbo") // returns text /* "prompt": $('textarea[name="prompt"]').val(), "agent": $('textarea[name="agent"]').val(), "temperature": $('input[name="temperature"]').val(), "max_tokens": $('input[name="max_tokens"]').val(), */ global $apiKey; $prompt = $_POST['flds']['prompt']; $agent = $_POST['flds']['agent']; $temperature = $_POST['flds']['temperature']; $max_tokens = 4000; $model = $_POST['flds']['model']; $api_key = $apiKey; // trim and clean $prompt $prompt = trim($prompt); // if prompt empty return error $text = one_shot($api_key, $prompt, $agent, $temperature, $max_tokens, $model); $return_arr[] = array( "command" => 'val', "process" => "one-shot", "selector" => 'textarea[name="response"]', "msg" => $text ); $return_arr[] = array( 'command' => 'enable_input', 'selector' => '.one_shot .the-button' ); break; // case 'one-shot' // --------------------------------------------------------------------- case 'prompt': $prompt = $_POST['flds']['prompt']; // trim and clean $prompt $prompt = trim($prompt); // if prompt empty return error if(empty($prompt)) { $return_arr[] = array( "command" => 'alert', "process" => "prompt", "msg" => "prompt is empty" ); } else { $messages = $_SESSION['messages']; // first set agent $messages = $openAIChat->set_agent($messages, $_SESSION['agent']); $openAIChat->model = $_SESSION['model']; $openAIChat->temperature = (float) round($_SESSION['temperature'],1); $openAIChat->freq_penalty = (float) round($_SESSION['freq_penalty'],1); $openAIChat->pres_penalty = (float) round($_SESSION['pres_penalty'],1); $openAIChat->set_max_tokens( 4090 ); // print_r($prompt); // add prompt to messages conversation $messages = $openAIChat->add_prompt_to_messages($messages, $prompt); // print("\r\n\r\n"); // print_r($messages); $response = $openAIChat->sendMessage($messages); $text = $openAIChat->get_response_text($response); // print_r($response); // print("\r\n\r\n-----------\r\n\r\n"); // print($text); // if text empty return error if(empty($text)) { $return_arr[] = array( "command" => 'alert', "process" => "prompt", "msg" => "api error:returned nothing", "model" => $_SESSION['model'], "response" => $response ); break; } // append response to messages conversation $messages = $openAIChat->append_response_to_messages($messages, $text); // save messages to session $_SESSION['messages'] = $messages; $return_arr[] = array( "command" => 'success', "process" => "prompt", "prompt" => $prompt, "agent" => $_SESSION['agent'], "model" => $_SESSION['model'], "temperature" => $_SESSION['temperature'], "freq_penalty" => $_SESSION['freq_penalty'], "pres_penalty" => $_SESSION['pres_penalty'], "max_tokens" => $_SESSION['max_tokens'], "text" => $text, "response" => $response ); $return_arr[] = array( "command" => 'update_conversation' ); $return_arr[] = array( "command" => 'val', 'selector' => 'textarea[name="text_prompt"]', 'msg' => '' ); $return_arr[] = array( 'command' => 'html', 'selector' => '.output', 'msg' => html_messages($messages) ); $return_arr[] = array( 'command' => 'enable_input', 'selector' => '#send-button' ); $return_arr[] = array( 'command' => 'resize_textareas' ); } break; // case 'prompt' // --------------------------------------------------------------------- case 'change_agent': $agent = $_POST['flds']['agent']; $_SESSION['agent'] = $agent; $return_arr[] = array( "command" => 'success', "process" => "change_agent" ); $return_arr[] = array( "command" => 'response_text', "agent" => $agent ); break; // case 'change_agent' case 'change_model': $model = $_POST['flds']['model']; $_SESSION['model'] = $model; $return_arr[] = array( "command" => 'success', "process" => "change_model", "model" => $model ); break; // case 'change_model' case 'change_temperature': $temperature = $_POST['flds']['temperature']; $_SESSION['temperature'] = $temperature; $return_arr[] = array( "command" => 'success', "process" => "change_temperature", "temperature" => $temperature ); print("TEMP CHANGED"); break; // case 'change_temperature' case 'change_freq_penalty': $freq_penalty = $_POST['flds']['freq_penalty']; $_SESSION['freq_penalty'] = $freq_penalty; $return_arr[] = array( "command" => 'success', "process" => "change_freq_penalty", "freq_penalty" => $freq_penalty ); break; // case 'change_freq_penalty' case 'change_pres_penalty': $pres_penalty = $_POST['flds']['pres_penalty']; $_SESSION['pres_penalty'] = $pres_penalty; $return_arr[] = array( "command" => 'success', "process" => "change_pres_penalty", "pres_penalty" => $pres_penalty ); break; // case 'change_pres_penalty' case 'change_max_tokens': $max_tokens = $_POST['flds']['max_tokens']; $_SESSION['max_tokens'] = $max_tokens; $return_arr[] = array( "command" => 'success', "process" => "change_max_tokens", "max_tokens" => $max_tokens ); break; // case 'change_max_tokens' case 'reset_messages': $_SESSION['messages'] = []; $return_arr[] = array( "command" => 'success', "process" => "reset_messages" ); $return_arr[] = array( "command" => 'html', 'selector' => '.output', 'msg' => html_messages($_SESSION['messages']) ); break; // case 'reset_messages' } // end switch($_GET['ajax']) if(!empty($return_arr) && is_array($return_arr)) die(json_encode($return_arr)); die(); } // end if(!empty($_GET['ajax'])) ?> <!DOCTYPE html> <html lang="en"> <head> <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script> <script> // BEGIN --> JAVASCRIPT COMMAND PROCESSOR // function do_cmd_post(url, send_data) { $.post( url, { flds: send_data /* in php will appear as $_POST['flds'] */ }, function( return_data ) { do_cmd_process(return_data); }, "json" ); // punt any returned data to processor } // --- function do_cmd_process(data) // handle data coming back from ajax { if (data instanceof Array) { data.forEach(function(entry) { console.log(entry.command); //console.log(entry.message); // handle returned commands // switch(entry.command) { // generic commands // case 'alert': alert(entry.msg); break; case 'log': console.log(entry.msg); break; case 'append': $(entry.selector).append(entry.msg); break; case 'prepend': $(entry.selector).prepend(entry.msg); break; case 'html': $(entry.selector).html(entry.msg); break; case 'val': $(entry.selector).val(entry.msg); break; case 'focus': $(entry.selector).focus(); break; case 'blur': $(entry.selector).blur(); break; case 'clear': $(entry.selector).val(''); break; case 'js': eval(entry.msg); break; case 'resize_textarea_to_fit_contents': $(entry.selector).height(0); $(entry.selector).height($(entry.selector)[0].scrollHeight); break; case 'disable_input': $(entry.selector).prop('disabled', true); break; case 'enable_input': $(entry.selector).prop('disabled', false); break; case 'resize_textareas': $(".message_content textarea").each(function(){ $(this).css("height", ($(this).prop("scrollHeight")) + "px"); }); break; } // end : switch (entry.command) }); // end : data.forEach(function(entry) } // end : if (data instanceof Array) } // end : function do_cmd_process(data) // END --> JAVASCRIPT COMMAND PROCESSOR // </script> </head> <body> <br /><br /> <?php ?> <div class='output' id="output" style='width: 100%; overflow: scroll; border: 1px solid #000;'><?php echo html_messages($_SESSION['messages']); ?></div> <div class='row'> <input type='text' name='save-message_title' id='save-message_title' value='' placeholder='Save Conversation Title' /> <input type='button' value='Save Conversation' onclick='btn_save_conversation();' /> <?php echo html_conversation_combobox(); ?> <input type='button' value='Load Conversation' onclick='btn_load_conversation();' /> <input type='button' value='Delete Conversation' onclick='btn_delete_conversation();' /> <input type='button' value='Reset Conversation' onclick='btn_reset_messages();' /> </div> <br /> <br /> <textarea name="text_agent" id='text_agent' onchange="btn_change_agent();" style='width: 100%; height: 100px; overflow: scroll; border: 1px solid #000;' ><?php echo $_SESSION['agent']; ?></textarea> <div class='row'> <input type='text' name='save-agent_title' id='save-agent_title' value='' placeholder='Save Agent Title' /> <input type='button' value='Save Agent' onclick='btn_save_agent();' /> <?php echo html_agents_combobox(); ?> <input type='button' value='Load Agent' onclick='btn_load_agent();' /> <input type='button' value='Update Agent' onclick='btn_change_agent();' /> <input type='button' value='Delete Agent' onclick='btn_delete_agent();' /> </div> <br /><br /> <textarea name="text_prompt" style='width: 100%; height: 100px; overflow: scroll; border: 1px solid #000;'></textarea> <input type='button' id='send-button' value='Send Prompt' onclick='btn_send_prompt();' /> <br /><br /> <!-- a combo box to select between gpt-3.5-turbo and gpt-4 --> <select id="model" name="model" onchange="btn_change_model();"> <option value="gpt-3.5-turbo" <?php if($_SESSION['model']=="gpt-3.5-turbo") echo "SELECTED" ?> >gpt-3.5-turbo</option> <option value="gpt-3.5-turbo-16k" <?php if($_SESSION['model']=="gpt-3.5-turbo-16k") echo "SELECTED" ?> >gpt-3.5-turbo-16k</option> <option value="gpt-4" <?php if($_SESSION['model']=="gpt-4") echo "SELECTED" ?>>gpt-4</option> <option value="gpt-4-32k" <?php if($_SESSION['model']=="gpt-4-32k") echo "SELECTED" ?>>gpt-4-32k</option> </select> <script> function btn_delete_agent() { // confirm delete // if(!confirm('Are you sure you want to delete this agent?')) return; var send_data = { "file": $('select[name="agents_combobox"]').val() }; do_cmd_post('example.phpopenaichat.php?ajax=delete_agent', send_data); } function btn_save_agent() { // data already on server so just send a title. var send_data = { "title": $('input[name="save-agent_title"]').val() }; do_cmd_post('example.phpopenaichat.php?ajax=save_agent', send_data); } function btn_load_agent() { var send_data = { "file": $('select[name="agents_combobox"]').val() }; do_cmd_post('example.phpopenaichat.php?ajax=load_agent', send_data); } function btn_delete_conversation() { // confirm delete if(!confirm('Are you sure you want to delete this conversation?')) return; var send_data = { "file": $('select[name="conversation_combobox"]').val() }; do_cmd_post('example.phpopenaichat.php?ajax=delete_conversation', send_data); } function btn_load_conversation() { var send_data = { "file": $('select[name="conversation_combobox"]').val() }; do_cmd_post('example.phpopenaichat.php?ajax=load_conversation', send_data); } function btn_save_conversation() { // data already on server so just send a title. // if title empty, alert and abort. if($('input[name="save-message_title"]').val()=='') { alert('Please enter a title for this conversation.'); return; } var send_data = { "title": $('input[name="save-message_title"]').val() }; do_cmd_post('example.phpopenaichat.php?ajax=save_conversation', send_data); } function btn_send_prompt() { // disable #send-button $('#send-button').prop('disabled', true); // confirm if(!confirm('Are you sure you want to send this prompt?')) { $('#send-button').prop('disabled', false); return; } var send_data = { "prompt": $('textarea[name="text_prompt"]').val(), }; do_cmd_post('example.phpopenaichat.php?ajax=prompt', send_data); } function btn_change_agent() { // confirm changes if(!confirm('Are you sure you want to change the agent on the server? (server must have an agent sent for it to process an agent)')) return; var send_data = { "agent": $('textarea[name="text_agent"]').val(), }; do_cmd_post('example.phpopenaichat.php?ajax=change_agent', send_data); } function btn_change_model() { var send_data = { "model": $('select[name="model"]').val(), }; do_cmd_post('example.phpopenaichat.php?ajax=change_model', send_data); } function btn_change_temp() { var send_data = { "temperature": $('input[name="temperature"]').val(), }; do_cmd_post('example.phpopenaichat.php?ajax=change_temperature', send_data); } function btn_change_freq_penalty() { var send_data = { "freq_penalty": $('input[name="freq_penalty"]').val(), }; do_cmd_post('example.phpopenaichat.php?ajax=change_freq_penalty', send_data); } function btn_change_pres_penalty() { var send_data = { "pres_penalty": $('input[name="pres_penalty"]').val(), }; do_cmd_post('example.phpopenaichat.php?ajax=change_pres_penalty', send_data); } function btn_reset_messages() { var send_data = { "reset_messages": 1, }; do_cmd_post('example.phpopenaichat.php?ajax=reset_messages', send_data); } function btn_max_tokens() { var send_data = { "max_tokens": $('input[name="max_tokens"]').val(), }; do_cmd_post('example.phpopenaichat.php?ajax=change_max_tokens', send_data); } function btn_edit_in_place() { /* $html .= '<div class="message" row_count="'+$row_count+'" >'; $html .= '<div class="message_role">'.$message['role'].'</div>'; $html .= '<div class="message_content" onclick="btn_edit_in_place();">'.$message['content'].'</div>'; $html .= '</div>'; */ /* swap out the div with a textarea */ var row_count = 1; var message_content = $('div.message_content[row_count="'+row_count+'"]').html(); $('div.message_content[row_count="'+row_count+'"]').html('<textarea name="message_content" row_count="'+row_count+'" style="width: 100%; height: 100px; overflow: scroll; border: 1px solid #000;">'+message_content+'</textarea>'); } function btn_update_message_content(that) { the_row = $(that).attr('row_count'); the_msg = $(that).val(); // var row_count = $('textarea[name="message_content"]').attr('row_count'); // var message_content = $('textarea[name="message_content_textarea"]').val(); // alert(the_msg); // alert(the_row); var send_data = { "row_count": the_row, "message_content": the_msg, }; // get user confirmation to continue if(confirm("Are you sure you want to update the message content?")) { do_cmd_post('example.phpopenaichat.php?ajax=change_message_content', send_data); } else { alert("reload page to restore original message content."); } } </script> <br /><br /> <!-- a slider to select temperature --> <label for="temperature">Temperature</label> <input type="range" id="temperature" onchange="btn_change_temp();" name="temperature" min="0.0" max="2.0" step="0.1" value="<?php echo $_SESSION["temperature"] ?>"> <div id="temperature_value"></div> <!-- a slider to select frequency penalty --> <label for="freq_penalty">Frequency Penalty</label> <input type="range" id="freq_penalty" onchange="btn_change_freq_penalty();" name="freq_penalty" min="0.0" max="1.0" step="0.1" value="<?php echo $_SESSION["freq_penalty"] ?>"> <div id="freq_penalty_value"></div> <!-- a slider to select presence penalty --> <label for="pres_penalty">Presence Penalty</label> <input type="range" id="pres_penalty" onchange="btn_change_pres_penalty();" name="pres_penalty" min="0.0" max="1.0" step="0.1" value="<?php echo $_SESSION["pres_penalty"] ?>"> <div id="pres_penalty_value"></div> <!-- a text input to select max tokens --> <label for="max_tokens">Max Tokens</label> <input type="number" id="max_tokens" onchange="btn_max_tokens();" name="max_tokens" min="1" max="100" value="<?php echo $_SESSION["max_tokens"] ?>"> <br /><br /> <!-- reset messages button --> <input type='button' value='Reset Messages' onclick='btn_reset_messages();' /> <br /><br /> <!-- jquery to add a div under the sliders to show the current value of the sliders. --> <script> $(document).ready(function(){ $('#temperature_value').html($('#temperature').val()); $('#freq_penalty_value').html($('#freq_penalty').val()); $('#pres_penalty_value').html($('#pres_penalty').val()); }); </script> <!-- jquery to update the divs when the sliders are moved --> <script> $(document).ready(function(){ $('#temperature').on('input', function() { $('#temperature_value').html($('#temperature').val()); }); $('#freq_penalty').on('input', function() { $('#freq_penalty_value').html($('#freq_penalty').val()); }); $('#pres_penalty').on('input', function() { $('#pres_penalty_value').html($('#pres_penalty').val()); }); }); </script> <pre> <?php // print_r($_SESSION['messages']); ?> </pre> <script> // make tab character act like a normal tab character in textareas $(document).delegate('textarea', 'keydown', function(e) { var keyCode = e.keyCode || e.which; if (keyCode == 9) { e.preventDefault(); var start = $(this).get(0).selectionStart; var end = $(this).get(0).selectionEnd; // set textarea value to: text before caret + tab + text after caret $(this).val($(this).val().substring(0, start) + "\t" + $(this).val().substring(end)); // put caret at right position again $(this).get(0).selectionStart = $(this).get(0).selectionEnd = start + 1; } }); </script> <script> // javascript to handle expanding textarea to fit content height whenever focus is on it and user is typing $(document).ready(function(){ // $(".message_content textarea").css("height", "auto"); // set each textarea on load to the size of its contents in the .messages area $(".message_content textarea").each(function(){ $(this).css("height", ($(this).prop("scrollHeight")) + "px"); }); // handle dynamic loaded divs $(".message_content textarea").on("focus", function(){ // $(this).css("height", "auto"); $(this).css("height", ($(this).prop("scrollHeight")) + "px"); }); $(".message_content textarea").on("blur", function(){ // $(this).css("height", "auto"); $(this).css("height", ($(this).prop("scrollHeight")) + "px"); }); $(".message_content textarea").on("change", function(){ // $(this).css("height", "auto"); $(this).css("height", ($(this).prop("scrollHeight")) + "px"); }); // $(".message_content textarea").on("keyup", function(){ // $(this).css("height", "auto"); // // $(this).css("height", ($(this).prop("scrollHeight")) + "px"); // }); }); </script> <style> .messages { } .message { border-bottom: 3px solid red; } .message.even { background-color: #eee; } .message_content { padding:3vw; } </style> <!-- one shot section --> <hr /> <?php function one_shot($api_key, $prompt, $agent='You are a helpful assistant.', $temperature=1.0, $max_tokens=4000, $model="gpt-3.5-turbo") { $temperature = (float) round($temperature,1); $max_tokens = (int) $max_tokens; // if $prompt empty return '' else get response and return the text... $messages = []; $AIChat = new PHPOpenAIChat($api_key); $AIChat->model = $model; $AIChat->temperature = $temperature; $AIChat->set_max_tokens($max_tokens); $AIChat->set_agent($messages, $agent); $messages = $AIChat->add_prompt_to_messages($messages, $prompt); if (empty($prompt)) return ''; else { $response = $AIChat->sendMessage($messages); $text = $AIChat->get_response_text($response); // print_r($response); return $text; } } // end one_shot() ?> <style> .one_shot { display: grid; grid-template-columns: 1fr 1fr 1fr; grid-gap: 1vw; } .one_shot .col { padding: 1vw; } .one_shot textarea { width: 100%; height: 10vw; } .one_shot input { width: 100%; } </style> <div class='title'>One Shot Section - Enter a prompt and get a single one-off response</div> <div class='one_shot'> <div class='col'><textarea class='prompt' name='prompt' id='prompt' placeholder='prompt'></textarea></div> <div class='col'><textarea class='agent' name='agent' id='agent' placeholder='agent'></textarea></div> <div class='col'><textarea class='response' name='response' id='response' placeholder='response'></textarea></div> <!-- model combo box --> <!-- a combo box to select between gpt-3.5-turbo and gpt-4 --> <select id="model" name="model" onchange="btn_change_model();"> <option value="gpt-3.5-turbo" <?php if($_SESSION['model']=="gpt-3.5-turbo") echo "SELECTED" ?> >gpt-3.5-turbo</option> <option value="gpt-4" <?php if($_SESSION['model']=="gpt-4") echo "SELECTED" ?>>gpt-4</option> </select> <div class='col'><input type='text' class='temperature' name='temperature' id='temperature' placeholder='temperature' value='1.0' /></div> <div class='col'><input type='button' class='the-button' value='One Shot' onclick='btn_one_shot();' /></div> </div><!-- end one shot section --> <script> function btn_one_shot() { var send_data = { "prompt": $('textarea[name="prompt"]').val(), "agent": $('textarea[name="agent"]').val(), "temperature": $('input[name="temperature"]').val(), "max_tokens": $('input[name="max_tokens"]').val(), "model": $('select[name="model"]').val(), }; // disable #send-button $('.one_shot .the-button').prop('disabled', true); do_cmd_post('example.phpopenaichat.php?ajax=one-shot', send_data); } </script> </body> </html>