PluginProbe
WPBot – AI ChatBot for Live Support, Lead Generation, WordPress Automation, AI Services / 8.8.2
WPBot – AI ChatBot for Live Support, Lead Generation, WordPress Automation, AI Services v8.8.2
8.8.3 8.8.2 8.8.1 8.8.0 8.7.9 8.7.8 8.7.7 8.7.6 8.7.5 8.7.4 8.7.3 8.7.2 8.7.1 8.7.0 8.6.9 8.6.8 8.6.7 8.6.6 8.6.5 8.6.4 8.6.2 8.6.1 8.6.0 8.5.9 8.5.8 All 539 releases
← All changes | includes/integration/openrouter/qcld-bot-openrouter.php +63 -15 8.6.6 → 8.8.2 View file →
@@ -195,9 +195,10 @@
195 195
196 196 $result = wp_remote_post($api_url, $args);
197 197
198 198 if (is_wp_error($result)) {
199 - wp_send_json( array( 'status' => 'error', 'msg' => esc_html__( 'API request failed: ' . $result->get_error_message(), 'chatbot' ) ) );
199 + /* translators: %s: API error message. */
200 + wp_send_json( array( 'status' => 'error', 'msg' => esc_html( sprintf( __( 'API request failed: %s', 'chatbot' ), $result->get_error_message() ) ) ) );
200 201 } else {
201 202 $http_code = wp_remote_retrieve_response_code($result);
202 203 $response_body = wp_remote_retrieve_body($result);
203 204 $msg = json_decode($response_body, true);
@@ -202,12 +203,12 @@
202 203 $response_body = wp_remote_retrieve_body($result);
203 204 $msg = json_decode($response_body, true);
204 205 do_action('qcld_openai_user_rate_cal', 1);
205 206 if ($http_code === 200 && isset($msg['choices'][0]['message']['content'])) {
206 - wp_send_json( array( 'status' => 'success', 'msg' => esc_html__( $msg['choices'][0]['message']['content'], 'chatbot' ) ) );
207 + wp_send_json( array( 'status' => 'success', 'msg' => esc_html( $msg['choices'][0]['message']['content'] ) ) );
207 208 } else {
208 209 $error_message = isset($msg['error']['message']) ? $msg['error']['message'] : 'Invalid API setup or API request failed.';
209 - wp_send_json( array( 'status' => 'error', 'msg' => esc_html__( $error_message, 'chatbot' ) ) );
210 + wp_send_json( array( 'status' => 'error', 'msg' => esc_html( $error_message ) ) );
210 211 }
211 212 }
212 213 wp_die();
213 214 }
@@ -333,19 +334,62 @@
333 334 );
334 335 }
335 336 }
336 337
337 - // Add user message
338 - $messages[] = array(
339 - 'role' => 'user',
340 - 'content' => $keyword
341 - );
338 + $action_prompt = !empty($_POST['action_prompt']) ? wp_unslash($_POST['action_prompt']) : '';
339 + if (!empty($action_prompt)) {
340 + $messages[] = array(
341 + 'role' => 'system',
342 + 'content' => "CRITICAL ACTIVE ACTION INSTRUCTION:\n" . $action_prompt
343 + );
344 + }
345 +
346 + $saved_ai_forms = get_option('wpbot_ai_forms', array());
347 + if (!empty($saved_ai_forms) && is_array($saved_ai_forms)) {
348 + $forms_instruction = "You must handle the following interactive forms when the user asks for them:\n";
349 + foreach ($saved_ai_forms as $form) {
350 + $forms_instruction .= "\nForm Title: " . $form['title'] . "\nInstructions: " . $form['prompt'] . "\n";
351 + }
352 + $forms_instruction .= "\n\nCRITICAL INSTRUCTIONS FOR INTERACTIVE FORMS:\n";
353 + $forms_instruction .= "When a user triggers an interactive form, you must act as a step-by-step data collection agent.\n";
354 + $forms_instruction .= "1. DO NOT ask all questions at once. Ask exactly ONE question at a time.\n";
355 + $forms_instruction .= "2. Wait for the user's response before asking the next question.\n";
356 + $forms_instruction .= "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";
357 + $forms_instruction .= "__AI_FORM_DATA__{ \"form_title\": \"<Form Title>\", \"data\": { \"Question 1\": \"Answer 1\", \"Question 2\": \"Answer 2\" } }__AI_FORM_DATA_END__\n";
358 + $forms_instruction .= "Do not include any other text after this JSON block once the form is complete.\n";
359 + $forms_instruction .= "4. If the user provides an invalid, irrelevant, or nonsensical answer to your question, DO NOT apologize or state that you lack information. Instead, politely inform the user in the language of the conversation (the language the user is speaking in, e.g. German if communicating in German) that their answer is invalid or cannot be assigned, and ask the exact same question again in the user's language. NEVER output the English phrase 'Invalid answer found' unless the user is communicating in English.\n";
360 + $forms_instruction .= "5. MULTI-LANGUAGE SUPPORT: Always communicate, ask questions, validate answers, and reply strictly in the user's language (matching the language used by the user, e.g. German, French, Spanish, etc.). Understand and accept valid answers in the user's language.";
361 + $messages[] = array(
362 + 'role' => 'system',
363 + 'content' => $forms_instruction
364 + );
365 + }
366 +
367 + if (!empty($_POST['ai_history'])) {
368 + $parsed_history = json_decode(wp_unslash($_POST['ai_history']), true);
369 + if (is_array($parsed_history)) {
370 + foreach ($parsed_history as $h) {
371 + if (isset($h['role']) && isset($h['content'])) {
372 + $role = ($h['role'] === 'assistant') ? 'assistant' : 'user';
373 + $messages[] = array(
374 + 'role' => $role,
375 + 'content' => sanitize_text_field($h['content'])
376 + );
377 + }
378 + }
379 + }
380 + }
381 +
382 + $last_msg = end($messages);
383 + if (!$last_msg || $last_msg['role'] !== 'user' || $last_msg['content'] !== $keyword) {
384 + $messages[] = array(
385 + 'role' => 'user',
386 + 'content' => $keyword
387 + );
388 + }
342 389
343 390 if( (get_option('page_suggestion_enabled') == '1') && count($relevant_pagelink) > 0 ){
344 -
345 391 $relevant_post_link = maybe_unserialize(get_option('qlcd_wp_chatbot_relevant_post_link_openai'));
346 -
347 - // Avoid call to undefined function get_wpbot_locale()
348 392 $locale = ( function_exists('get_locale') ) ? get_locale() : 'en_US';
349 393 if ( isset($relevant_post_link[$locale]) && is_array($relevant_post_link[$locale]) ) {
350 394 $relevant_pagelinks = '<br><br><p><em>' . implode('', $relevant_post_link[$locale]) . '</em><p>' . implode("</br>", $relevant_pagelink);
351 395 } elseif ( isset($relevant_post_link[$locale]) ) {
@@ -352,11 +396,9 @@
352 396 $relevant_pagelinks = '<br><br><p><em>' . $relevant_post_link[$locale] . '</em><p>' . implode("</br>", $relevant_pagelink);
353 397 } else {
354 398 $relevant_pagelinks = '<br><br><p><em></em><p>' . implode("</br>", $relevant_pagelink);
355 399 }
356 -
357 -
358 - }else{
400 + } else {
359 401 $relevant_pagelinks = '';
360 402 }
361 403 $Qcld_Parsedown = new Qcld_Parsedown();
362 404 $data = wp_json_encode(array(
@@ -393,9 +435,15 @@
393 435 if ($http_code === 200) {
394 436 $msg = json_decode($response_body);
395 437 if(isset($msg->choices[0]->message->content)) {
396 438 $response['status'] = 'success';
397 - $response['message'] = $Qcld_Parsedown->text($msg->choices[0]->message->content) . $relevant_pagelinks;
439 + $reply_text = $Qcld_Parsedown->text($msg->choices[0]->message->content);
440 + if (strpos($reply_text, 'AI_FORM_DATA') !== false) {
441 + $reply_text = Qcld_WPBot_Common_Functions::format_and_save_ai_form_response($reply_text);
442 + $response['message'] = $reply_text;
443 + } else {
444 + $response['message'] = $reply_text . $relevant_pagelinks;
445 + }
398 446 } else {
399 447 $response['status'] = 'error';
400 448 $response['message'] = 'Sorry, I encountered an error processing your AI request. Please check api key and try again later.';
401 449 }