define_constants();
$this->includes();
add_action('wp_ajax_openai_settings_option', [$this, 'openai_settings_option_callback']);
add_action('wp_ajax_update_settings_option', [$this, 'qcld_update_settings_option_callback']);
add_action('wp_ajax_qcld_rag_settings_option', array($this, 'rag_settings_option_callback'));
add_action('wp_ajax_qcld_openai_response',[$this,'qcld_openai_response_callback']);
add_action('wp_ajax_nopriv_qcld_openai_response', [$this, 'qcld_openai_response_callback']);
add_action('wp_ajax_qcld_stream_openai', [$this, 'qcld_stream_openai_callback']);
add_action('wp_ajax_nopriv_qcld_stream_openai', [$this, 'qcld_stream_openai_callback']);
add_action('wp_ajax_openai_troubleshooting',[$this,'openai_troubleshooting']);
add_action('wp_ajax_wpbot_wizard_save', array($this, 'wpbot_wizard_save_callback'));
add_action('wp_ajax_wpbot_wizard_verify_key', array($this, 'wpbot_wizard_verify_key_callback'));
if (is_admin() && !empty($_GET["page"]) && (($_GET["page"] == "openai-panel_dashboard") || ($_GET["page"] == "openai-panel_file") || ($_GET["page"] == "openai-panel_help"))) {
add_action('admin_enqueue_scripts', array($this, 'qcld_wb_chatbot_admin_scripts'));
}
}
/**
* Define wpbot Constants.
*
* @return void
* @since 1.0.0
*/
public function define_constants() {
if( ! defined( 'QCLD_openai_addon_VERSION' ) ){
define('QCLD_openai_addon_VERSION', $this->version);
}
//define('QCLD_openai_addon_REQUIRED_wpCOMMERCE_VERSION', 2.2);
if( ! defined( 'QCLD_openai_addon_PLUGIN_DIR_PATH' ) ){
define('QCLD_openai_addon_PLUGIN_DIR_PATH', plugin_dir_path(__FILE__));
}
if( ! defined( 'QCLD_openai_addon_PLUGIN_URL' ) ){
define('QCLD_openai_addon_PLUGIN_URL', plugin_dir_url(__FILE__));
}
if( ! defined( 'QCLD_openai_addon_IMG_URL' ) ){
define('QCLD_openai_addon_IMG_URL', QCLD_openai_addon_PLUGIN_URL . "images/");
}
if( ! defined( 'QCLD_openai_addon_IMG_ABSOLUTE_PATH' ) ){
define('QCLD_openai_addon_IMG_ABSOLUTE_PATH', plugin_dir_path(__FILE__) . "images");
}
}
public function qcld_wb_chatbot_admin_scripts(){
// wp_register_style('qlcd-open-ai-bootstap', QCLD_openai_addon_PLUGIN_URL . 'css/openai-bootstrap.css', '', QCLD_openai_addon_VERSION, 'screen');
// wp_enqueue_style('qlcd-open-ai-bootstap');
// wp_register_style('qlcd-open-ai-admin-style', QCLD_openai_addon_PLUGIN_URL . 'css/openai-admin-style.css', '', QCLD_openai_addon_VERSION, 'screen');
// wp_enqueue_style('qlcd-open-ai-admin-style');
// wp_register_script('qlcd-openai_collapse', QCLD_openai_addon_PLUGIN_URL . 'js/collapse.js', array('jquery'),'',QCLD_openai_addon_VERSION,true);
// wp_enqueue_script('qlcd-openai_collapse');
// wp_register_script('qlcd-openai_settings', QCLD_openai_addon_PLUGIN_URL . 'js/openai_settings.js', array('jquery'),'',QCLD_openai_addon_VERSION,true);
// wp_enqueue_script('qlcd-openai_settings');
// wp_localize_script( 'qlcd-openai_settings', 'openai_ajax', array(
// 'url' => admin_url( 'admin-ajax.php' ),
// ) );
}
/**
* Include all required files
*
* since 1.0.0
*
* @return void
*/
public function includes() {
require_once( QCLD_wpCHATBOT_PLUGIN_DIR_PATH . "includes/integration/openai/qcld_wp_OpenAI.php" );
require_once( QCLD_wpCHATBOT_PLUGIN_DIR_PATH . "includes/integration/openai/OpenAi_WPBot_Menu.php" );
require_once( QCLD_wpCHATBOT_PLUGIN_DIR_PATH . "includes/Parsedown.php" );
}
public function buildFormBody( $fields, $boundary )
{
$body = '';
foreach ( $fields as $name => $value ) {
if ( $name == 'data' ) {
continue;
}
$body .= "--$boundary\r\n";
$body .= "Content-Disposition: form-data; name=\"$name\"";
if ( $name == 'file' ) {
$body .= "; filename=\"{$value}\"\r\n";
$body .= "Content-Type: application/json\r\n\r\n";
$body .= $fields['data'] . "\r\n";
}else {
$body .= "\r\n\r\n$value\r\n";
}
}
$body .= "--$boundary--\r\n";
return $body;
}
// public function openai_file_list_callback(){
// $url = 'https://api.openai.com/v1/files';
// $apt_key = "Authorization: Bearer ". get_option('open_ai_api_key');
// $curl = curl_init();
// curl_setopt($curl, CURLOPT_URL, $url);
// $headers = array(
// "Content-Type: application/json",
// $apt_key,
// );
// curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
// curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
// $response = curl_exec($curl);
// curl_close($curl);
// wp_send_json( json_decode($response));
// wp_die();
// }
public function qcld_sanitize_text_or_array_field($array_or_string) {
if( is_string($array_or_string) ){
$array_or_string = sanitize_text_field($array_or_string);
}elseif( is_array($array_or_string) ){
foreach ( $array_or_string as $key => &$value ) {
if ( is_array( $value ) ) {
$value = $this->qcld_sanitize_text_or_array_field($value);
}
else {
$value = sanitize_text_field( $value );
}
}
}
return $array_or_string;
}
// public function openai_file_upload_callback(){
// $uploadedfile = $_FILES['file'];
// $url = 'https://api.openai.com/v1/files';
// $apt_key = "Authorization: Bearer ". get_option('open_ai_api_key');
// $curl = curl_init($url);
// curl_setopt($curl, CURLOPT_URL, $url);
// curl_setopt($curl, CURLOPT_POST, true);
// $headers = array(
// "Content-Type: multipart/form-data",
// $apt_key,
// );
// if (function_exists('curl_file_create')) {
// $tmp_file = curl_file_create($uploadedfile['tmp_name'], 'jsonl', $uploadedfile['name']);
// } else {
// $tmp_file = open($uploadedfile['tmp_name']);
// }
// $data = array('file'=> $tmp_file,'purpose'=> 'fine-tune');
// $init = curl_init();
// //function parameteres
// curl_setopt($init, CURLOPT_URL,$url);
// curl_setopt($init, CURLOPT_HTTPHEADER, $headers);
// curl_setopt($init, CURLOPT_POSTFIELDS, $data);
// curl_setopt($init, CURLOPT_RETURNTRANSFER, true);
// $res = json_decode(curl_exec ($init));
// curl_close ($init);
// if(!empty($res->error)){
// $response['status'] = 'error';
// $response['message'] = $res->error->message;
// }
// if(!empty($res->status)){
// $response['status'] = 'success';
// $response['message'] = 'Successfully Created file' . $res->id ;
// }
// echo wp_send_json([$response]);
// wp_die();
// }
public function openai_finetune_create($file_id,$ft_suffix,$ft_engines){
$api_key = get_option('open_ai_api_key');
$request_headers = array(
'Content-Type' => 'application/json',
'Authorization' => 'Bearer ' . $api_key,
);
$qcld_openai_suffix = isset($ft_suffix) ? $ft_suffix : get_option('qcld_openai_suffix');
$openai_engines = isset($ft_engines) ? $ft_engines : get_option('openai_engines');
$base_engine = explode('-',$openai_engines);
if( $base_engine[0] == 'gpt'){
$url = "https://api.openai.com/v1/fine_tuning/jobs";
$response = wp_remote_post( $url, array(
'headers' => $request_headers,
'body' => wp_json_encode( array('training_file'=>$file_id,'model' => $openai_engines, 'suffix' => $qcld_openai_suffix ) ),
'timeout' => 60,
) );
$result = ! is_wp_error( $response ) ? json_decode( wp_remote_retrieve_body( $response ) ) : null;
}else{
$url = "https://api.openai.com/v1/fine-tunes";
$response = wp_remote_post( $url, array(
'headers' => $request_headers,
'body' => wp_json_encode( array('training_file'=>$file_id,'model' => $base_engine[1], 'suffix' => $qcld_openai_suffix ) ),
'timeout' => 60,
) );
$result = ! is_wp_error( $response ) ? json_decode( wp_remote_retrieve_body( $response ) ) : null;
}
return $result;
}
public function relevant_pagelink($search_query){
$stopwords = explode( ',', get_option('qlcd_wp_chatbot_stop_words') );
$finalQueryWordsWithoutStopWords = $this->qcpd_remove_wa_stopwords( strtolower($search_query), $stopwords );
$cleanWordsWithoutPunctuationMarks = preg_replace('/[\p{P}]/u', '', $finalQueryWordsWithoutStopWords);
$q = trim($cleanWordsWithoutPunctuationMarks);
$links = [];
$post_type_array = get_option('qcld_openai_relevant_post');
//Proceeding with traditional search
$the_query = new WP_Query( array( 'post_status' => 'publish', 'posts_per_page' => 5, 's' => esc_attr( $q ), 'post_type' => $post_type_array ) );
if( $the_query->have_posts() ){
while( $the_query->have_posts() ){
$the_query->the_post();
$url = esc_url( get_permalink() );
$link = '
' . get_the_title() . '';
array_push($links, $link);
} //End of WHILE
wp_reset_postdata();
} //End of IF
$links = array_unique($links);
return $links;
} //End of function relevant_pagelink()
public function openai_retrive_fine_tune($keyword){
$api_key = get_option('open_ai_api_key');
$request_headers = array(
'Content-Type' => 'application/json',
'Authorization' => 'Bearer ' . $api_key,
);
$max_tokens = (int)get_option( 'openai_max_tokens');
$temp = (float)get_option( 'openai_temperature');
$frequency_penalty= (float)get_option( 'frequency_penalty');
$presence_penalty = (float)get_option( 'presence_penalty');
$custom_model = get_option( 'qcld_openai_custom_model');
$custom_model = explode(":", $custom_model);
$prompts = $this->get_prompt($keyword);
if ( isset( $custom_model[1] ) && $custom_model[1] !== 'gpt-3.5-turbo-0613' ) {
$response = wp_remote_post( 'https://api.openai.com/v1/completions', array(
'headers' => $request_headers,
'body' => wp_json_encode( array(
'prompt' => $prompts,
'model' => get_option( 'qcld_openai_custom_model'),
'max_tokens' => $max_tokens,
'temperature' => $temp,
'top_p' => 1,
'presence_penalty' => $frequency_penalty,
'frequency_penalty' => $presence_penalty,
'best_of' => 1,
'stop' => ["\n###\n","###"]
) ),
'timeout' => 60,
) );
if ( is_wp_error( $response ) ) { return ''; }
$result = str_replace( "#", "", wp_remote_retrieve_body( $response ) );
return $result;
} else {
$response = wp_remote_post( 'https://api.openai.com/v1/chat/completions', array(
'headers' => $request_headers,
'body' => wp_json_encode( array(
'model' => get_option( 'qcld_openai_custom_model'),
'messages' => [ [ 'role' => 'user', 'content' => $keyword ] ],
) ),
'timeout' => 60,
) );
if ( is_wp_error( $response ) ) { return ''; }
$results = str_replace( "#", "", wp_remote_retrieve_body( $response ) );
$decoded = json_decode( $results );
return isset( $decoded->choices[0]->message->content ) ? $decoded->choices[0]->message->content : '';
}
}
public function response_form_file($keyword){
$max_tokens = (int)get_option( 'openai_max_tokens');
$temp = (float)get_option( 'openai_temperature');
$frequency_penalty = (float)get_option( 'frequency_penalty');
$presence_penalty = (float)get_option( 'presence_penalty');
$engines = explode('-',get_option( 'openai_engines'));
if($engines[0] != 'gpt'){
// $prompts = $this->get_prompt($keyword);
}
$request_body = [
"prompt" => $keyword,
"model" => get_option( 'qcld_openai_custom_model'),
"max_tokens" => $max_tokens,
"temperature" => 0,
"top_p" => 1,
"stop" => [],
"presence_penalty" => 0,
"frequency_penalty"=> 0,
"best_of"=> 1,
];
$postFields = wp_json_encode($request_body);
$OpenAI = new qcld_wp_OpenAI();
$result = $OpenAI->get_response($postFields);
return $result;
}
public function get_prompt($keyword){
$openai_include_keyword = get_option( 'openai_include_keyword');
$openai_exclude_keyword = get_option( 'openai_exclude_keyword');
$qcld_openai_prompt = get_option('qcld_openai_prompt',true);
}
public function include_exclude_prompt($keyword){
$openai_include_keyword = strtolower(get_option('openai_include_keyword'));
$openai_exclude_keyword = strtolower(get_option('openai_exclude_keyword'));
if((get_option('openai_include_keyword') != '') || (get_option('openai_exclude_keyword') == '')){
$prompts = 'If the query is not relevant to one of the keywords: '.$openai_include_keyword .' then only say DUH. Provide a response only if the following query is relevant to one of the keywords: '.$openai_include_keyword .' The actual query is as follows: '. $keyword;
return $prompts;
}else if((get_option('openai_include_keyword') == '') || (get_option('openai_exclude_keyword') != '')){
$prompts = 'If the query is relevant to one of the keywords: ' .$openai_exclude_keyword . ', then do not respond and only say "DUH." The actual query is as follows: '. $keyword. '?/n';
return $prompts;
}else if((get_option('openai_include_keyword') != '') || (get_option('openai_exclude_keyword') != '')){
$prompts = 'If the query is not relevant to one of the keywords: '.$openai_include_keyword .' then only say "DUH." Provide a response only if the following query is relevant to one of the keywords: '.$openai_include_keyword .' The actual query is as follows: '. $keyword;
return $prompts;
}
}
public function qcld_include_keyword_exist( $keyword ){
$keyword = isset($keyword) ? $keyword : '';
$openai_include_keywords = strtolower(get_option('openai_include_keyword'));
if(!empty($keyword)){
$openai_include_keyword = ( isset( $openai_include_keywords ) ? $openai_include_keywords : '');
if( !empty($openai_include_keyword)){
$include_items = explode(',', $openai_include_keyword);
if(!empty($include_items)){
foreach($include_items as $k => $item){
if((strpos($keyword,trim($item)) !== false) && !empty($item)){
return true;
}
}
}
return false;
}
}
return false;
}
public function qcld_stream_openai_callback() {
if ( ! isset( $_POST['nonce'] ) || ! wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST['nonce'] ) ), 'wp_chatbot' ) ) {
echo "data: [ERROR] Security check failed.\n\n";
flush();
wp_die();
}
if ( get_option( 'is_rate_limiting_enabled' ) == '1' ) {
do_action( 'rate_limit_checker' );
}
if ( function_exists( 'apache_setenv' ) ) {
@apache_setenv( 'no-gzip', 1 ); // phpcs:ignore WordPress.PHP.NoSilencedErrors.Discouraged
}
@ini_set( 'zlib.output_compression', 0 ); // phpcs:ignore WordPress.PHP.NoSilencedErrors.Discouraged
@ini_set( 'implicit_flush', 1 ); // phpcs:ignore WordPress.PHP.NoSilencedErrors.Discouraged
while ( ob_get_level() ) {
ob_end_clean();
}
ob_implicit_flush( true );
header( 'Content-Type: text/event-stream' );
header( 'Cache-Control: no-cache' );
header( 'Connection: keep-alive' );
$api_key = trim( get_option( 'open_ai_api_key' ) );
$keyword = isset( $_POST['keyword'] ) ? sanitize_text_field( wp_unslash( $_POST['keyword'] ) ) : '';
if ( empty( $api_key ) || empty( $keyword ) ) {
echo "data: [ERROR] Missing API key or message.\n\n";
flush();
wp_die();
}
$is_playground = isset( $_POST['is_ai_actions_playground'] ) && intval( $_POST['is_ai_actions_playground'] ) === 1;
$active_ai_action = isset( $_POST['active_ai_action'] ) ? sanitize_text_field( wp_unslash( $_POST['active_ai_action'] ) ) : '';
$raw_ai_history = isset( $_POST['ai_history'] ) ? json_decode( stripslashes( $_POST['ai_history'] ), true ) : array();
$is_ai_action = $is_playground || ! empty( $active_ai_action ) || ( class_exists( 'Qcld_WPBot_Common_Functions' ) && Qcld_WPBot_Common_Functions::is_ai_action_in_progress( $raw_ai_history, $keyword ) );
$system_content = $is_playground ? 'You are a helpful AI assistant. You MUST strictly follow the interactive form instructions if the user asks for them.' : get_option( 'qcld_openai_system_content' );
if ( empty( $system_content ) ) {
$system_content = 'You are a helpful assistant.';
}
// AI Interactive Form
$saved_ai_forms = get_option( 'wpbot_ai_forms', array() );
$active_interactive_forms = array();
if ( get_option( 'enable_ai_interactive_form' ) == '1' && ! empty( $saved_ai_forms ) && is_array( $saved_ai_forms ) ) {
foreach ( $saved_ai_forms as $form ) {
if ( ! isset( $form['interactive'] ) || $form['interactive'] == 1 ) {
$active_interactive_forms[] = $form;
}
}
}
if ( ! empty( $active_interactive_forms ) ) {
$system_content .= "\n\nYou must handle the following interactive forms when the user asks for them:\n";
foreach ( $active_interactive_forms as $form ) {
$system_content .= "\nForm Title: " . $form['title'] . "\nInstructions: " . $form['prompt'] . "\n";
}
$system_content .= "\n\nCRITICAL INSTRUCTIONS FOR INTERACTIVE FORMS:\n";
$system_content .= "When a user triggers an interactive form, you must act as a step-by-step data collection agent.\n";
$system_content .= "1. DO NOT ask all questions at once. Ask exactly ONE question at a time.\n";
$system_content .= "2. Wait for the user's response before asking the next question.\n";
$system_content .= "3. Once all necessary information is collected for the form, you MUST output a final JSON block summarizing the collected data. The keys inside the \"data\" object MUST be dynamically named based on the specific questions you asked during the form collection (e.g., \"Full Name\", \"Company Size\", \"Email\", etc.). The final JSON block must be wrapped EXACTLY in these delimiters:\n";
$system_content .= "__AI_FORM_DATA__{ \"form_title\": \"