I have the following PHP code and am struggling to correctly access the partial messages as they are delivered from the API call and send them back to the ajax call, so that the messages can appear on in a div, in real time.
What have I done wrong in my API call?
function ask_question() {
$query = $_POST['query'];
$query_credit = $_POST['queryCredit'];
$user_id = get_current_user_id();
$meta_key = 'ai_anna_credit';
$user_credit = get_user_meta($user_id, $meta_key, true);
if ($user_credit <= 0) {
$response = 'You do not have enough credit for this aiAnna question.';
} else {
$ch = curl_init();
$url = 'https://api.openai.com/v1/completions';
$api_key = 'sk-***********************';
$post_fields = array(
'model' => 'gpt-3.5-turbo',
'messages' => array(
array(
'role' => 'system',
'content' => 'You are aiAnna, CSUKs helpful virtual teacher\'s assistant!'
),
array(
'role' => 'user',
'content' => $query
)
),
'stream' => true // turn on stream mode
);
$header = array(
'Content-Type: application/json',
'Authorization: Bearer ' . $api_key
);
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($post_fields));
curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
// set a callback function to handle the response
curl_setopt($ch, CURLOPT_WRITEFUNCTION, function($ch, $chunk) {
$response_data = json_decode($chunk); // decode the chunk
$response = '';
foreach ($response_data->choices as $choice) {
foreach ($choice->messages as $message) {
if (isset($message->content)) {
$response .= $message->content;
}
}
}
$response = trim($response);
wp_send_json($response); // send the partial response as JSON
return strlen($chunk); // return the length of the chunk
});
$result = curl_exec($ch);
if (curl_errno($ch)) {
$response = 'Error: ' . curl_error($ch);
} else {
$response_data = json_decode($result);
$response = $response_data->choices[0]->message->content;
if (!empty($response)) {
$new_credit = $user_credit - $query_credit;
update_user_meta($user_id, $meta_key, $new_credit);
$user_credit = get_user_meta($user_id, $meta_key, true);
}
}
}
$response_data = array(
'response' => $response,
'user_credit' => $user_credit
);
wp_send_json($response_data);
}
And here is the ajax call:
function askQuestion(query, queryCredit) {
var newCredit = 0;
jQuery.ajax({
type: "POST",
url: "'.$adminAjaxUrl.'",
dataType: "json",
data: {"action": "ask_question", "query" : query, "queryCredit" : queryCredit},
success: function(data) {
console.log(data);
if (data.response == null){
response = "Oh no, aiAnna was not able to fetch a response. Do not worry though as your credit has not been reduced! Please try again!";
}
else {
response = data.response.trim();
}
newCredit = data.user_credit;
var answerOutput = document.getElementById("answerBoxDiv");
answerOutput.innerText = response;
const pattern = /```([\s\S]*?)```/g;
const replacement = "<code>$1</code>";
answerOutput.innerHTML = answerOutput.innerHTML.replace(pattern, replacement);
var creditOutput = document.getElementById("creditMessage");
creditOutput.innerHTML = "Current aiAnna Credit: " + newCredit;
document.getElementById("ai_think_id").style.display = "none";
},
error: function (request, status, error) {
console.log(request.responseText);
}
});
}