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.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 8.5.7 All 538 releases
← All changes | includes/integration/grok/qcld-bot-grok.php +90 -12 8.6.0 → 8.8.2 View file →
@@ -168,12 +168,11 @@
168 168 }
169 169 if ( $grok_enabled == '1' ) {
170 170 update_option( 'ai_enabled', 0 );
171 171 update_option( 'qcld_ollama_enabled', 0 );
172 - update_option('qcld_gemini_enabled', 0);
172 + update_option('qcld_gemini_enabled', 0);
173 173 update_option( 'qcld_openrouter_enabled', 0 );
174 - } else {
175 - update_option( 'ai_enabled', 1 );
174 + update_option('disable_wp_chatbot_site_search',1);
176 175 }
177 176 if ( $qcld_grok_system_content != '' ) {
178 177 update_option( 'qcld_grok_system_content', $qcld_grok_system_content );
179 178 }
@@ -205,11 +204,40 @@
205 204 }
206 205 $grok_api_key = get_option( 'qcld_grok_api_key' );
207 206 $keyword = isset($_POST['keyword']) ? sanitize_text_field( wp_unslash($_POST['keyword']) ) : ''; // phpcs:ignore WordPress.Security.NonceVerification.Missing
208 207 $grok_system_content = get_option( 'qcld_grok_system_content' );
208 +
209 + // AI Interactive Form
210 + if (get_option('enable_ai_interactive_form') == '1') {
211 + $saved_ai_forms = get_option('wpbot_ai_forms', array());
212 + if (!empty($saved_ai_forms) && is_array($saved_ai_forms)) {
213 + $grok_system_content .= "\n\nYou must handle the following interactive forms when the user asks for them:\n";
214 + foreach ($saved_ai_forms as $form) {
215 + $grok_system_content .= "\nForm Title: " . $form['title'] . "\nInstructions: " . $form['prompt'] . "\n";
216 + }
217 + $grok_system_content .= "\n\nCRITICAL INSTRUCTIONS FOR INTERACTIVE FORMS:\n";
218 + $grok_system_content .= "When a user triggers an interactive form, you must act as a step-by-step data collection agent.\n";
219 + $grok_system_content .= "1. DO NOT ask all questions at once. Ask exactly ONE question at a time.\n";
220 + $grok_system_content .= "2. Wait for the user's response before asking the next question.\n";
221 + $grok_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";
222 + $grok_system_content .= "__AI_FORM_DATA__{ \"form_title\": \"<Form Title>\", \"data\": { \"Question 1\": \"Answer 1\", \"Question 2\": \"Answer 2\" } }__AI_FORM_DATA_END__\n";
223 + $grok_system_content .= "Do not include any other text after this JSON block once the form is complete.\n";
224 + $grok_system_content .= "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";
225 + $grok_system_content .= "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.";
226 + }
227 + }
228 +
229 + $action_prompt = !empty($_POST['action_prompt']) ? wp_unslash($_POST['action_prompt']) : '';
230 + if (!empty($action_prompt)) {
231 + $grok_system_content .= "\n\nCRITICAL ACTIVE ACTION INSTRUCTION:\n" . $action_prompt;
232 + }
233 +
209 234 $rag_context = "";
210 235 if (get_option('qcld_grok_rag_enabled') == '1') {
211 236 $rag_context = Qcld_Bot_Rag()->run_rag_search($keyword);
237 + if (!empty($rag_context) && $rag_context != "No knowledge base found.") {
238 + $grok_system_content .= "\n\nRelevant Knowledge Base Information:\n" . $rag_context;
239 + }
212 240 }
213 241 $relevant_pagelink = Qcld_WPBot_Common_Functions::qcpd_relevant_pagelink( $keyword );
214 242 $relevant_pagelink = array_slice( $relevant_pagelink, 0, 5, true );
215 243 if ( ( get_option( 'page_suggestion_enabled' ) == '1' ) && count( $relevant_pagelink ) > 0 ) {
@@ -228,8 +256,32 @@
228 256 $response['status'] = 'success';
229 257 $response['message'] = $result ;
230 258 wp_send_json( $response );
231 259 } else {
260 + $messages = [
261 + ['role' => 'system', 'content' => $grok_system_content ?? 'You are a helpful and intelligent assistant for the website "' . site_url() . '". Use live website data and the provided context to respond accurately and briefly. Stay relevant and do not introduce additional topics.' ]
262 + ];
263 +
264 + if (!empty($_POST['ai_history'])) {
265 + $parsed_history = json_decode(wp_unslash($_POST['ai_history']), true);
266 + if (is_array($parsed_history)) {
267 + foreach ($parsed_history as $h) {
268 + if (isset($h['role']) && isset($h['content'])) {
269 + $role = ($h['role'] === 'assistant') ? 'assistant' : 'user';
270 + $messages[] = [
271 + 'role' => $role,
272 + 'content' => sanitize_text_field($h['content'])
273 + ];
274 + }
275 + }
276 + }
277 + }
278 +
279 + $last_msg = end($messages);
280 + if (!$last_msg || $last_msg['role'] !== 'user' || $last_msg['content'] !== $keyword) {
281 + $messages[] = ['role' => 'user', 'content' => $keyword];
282 + }
283 +
232 284 $response_mess = wp_remote_post('https://api.x.ai/v1/chat/completions', [
233 285 'headers' => [
234 286 'Authorization' => 'Bearer ' . $grok_api_key,
235 287 'Content-Type' => 'application/json',
@@ -234,12 +286,9 @@
234 286 'Authorization' => 'Bearer ' . $grok_api_key,
235 287 'Content-Type' => 'application/json',
236 288 ],
237 289 'body' => wp_json_encode([
238 - 'messages' => [
239 - ['role' => 'system', 'content' => $grok_system_content ?? 'You are a helpful and intelligent assistant for the website "' . site_url() . '". Use live website data and the provided context to respond accurately and briefly. Stay relevant and do not introduce additional topics.' ],
240 - ['role' => 'user', 'content' => $keyword ]
241 - ],
290 + 'messages' => $messages,
242 291 'model' => 'grok-3-latest',
243 292 'temperature' => 0,
244 293 'stream' => false
245 294 ]),
@@ -246,14 +295,21 @@
246 295 'timeout' => 60,
247 296 ]);
248 297 $response['message'] = '';
249 298 $status_code = wp_remote_retrieve_response_code($response_mess);
250 - // Step 2: Get the raw body (this is almost always what you want)
251 299 $data = wp_remote_retrieve_body($response_mess);
252 - $data = json_decode($data, true); // Decode as associative array
300 + $data = json_decode($data, true);
301 + do_action('qcld_openai_user_rate_cal', 1);
253 302 $response['status'] = 'success';
254 - $response['message'] = $data['choices'][0]['message']['content'] ?? 'No content received'; // true = assoc array
255 - do_action('qcld_openai_user_rate_cal', 1);
303 + $reply_raw = $data['choices'][0]['message']['content'] ?? 'No content received';
304 + $Parsedown = new Parsedown();
305 + $reply_text = $Parsedown->text($reply_raw);
306 + if (strpos($reply_text, 'AI_FORM_DATA') !== false) {
307 + $reply_text = Qcld_WPBot_Common_Functions::format_and_save_ai_form_response($reply_text);
308 + $response['message'] = $reply_text;
309 + } else {
310 + $response['message'] = $reply_text . $relevant_pagelinks;
311 + }
256 312 wp_send_json( $response );
257 313 }
258 314 }
259 315 public function qcld_stream_grok_callback()
@@ -289,9 +345,31 @@
289 345 $headers = [
290 346 'Content-Type: application/json',
291 347 'Authorization: Bearer ' . $api_key,
292 348 ];
293 - $system_content = 'You are a helpful and intelligent assistant for the website "' . site_url() . '". Use live website data and the provided context to respond accurately and briefly. Stay relevant and do not introduce additional topics.';
349 + $system_content = get_option( 'qcld_grok_system_content' );
350 + if (empty($system_content)) {
351 + $system_content = 'You are a helpful and intelligent assistant for the website "' . site_url() . '". Use live website data and the provided context to respond accurately and briefly. Stay relevant and do not introduce additional topics.';
352 + }
353 + // AI Interactive Form
354 + if (get_option('enable_ai_interactive_form') == '1') {
355 + $saved_ai_forms = get_option('wpbot_ai_forms', array());
356 + if (!empty($saved_ai_forms) && is_array($saved_ai_forms)) {
357 + $system_content .= "\n\nYou must handle the following interactive forms when the user asks for them:\n";
358 + foreach ($saved_ai_forms as $form) {
359 + $system_content .= "\nForm Title: " . $form['title'] . "\nInstructions: " . $form['prompt'] . "\n";
360 + }
361 + $system_content .= "\n\nCRITICAL INSTRUCTIONS FOR INTERACTIVE FORMS:\n";
362 + $system_content .= "When a user triggers an interactive form, you must act as a step-by-step data collection agent.\n";
363 + $system_content .= "1. DO NOT ask all questions at once. Ask exactly ONE question at a time.\n";
364 + $system_content .= "2. Wait for the user's response before asking the next question.\n";
365 + $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";
366 + $system_content .= "__AI_FORM_DATA__{ \"form_title\": \"<Form Title>\", \"data\": { \"Question 1\": \"Answer 1\", \"Question 2\": \"Answer 2\" } }__AI_FORM_DATA_END__\n";
367 + $system_content .= "Do not include any other text after this JSON block once the form is complete.\n";
368 + $system_content .= "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";
369 + $system_content .= "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.";
370 + }
371 + }
294 372 $messages = [];
295 373 // Load previous conversation from cookie if continuity is enabled
296 374 if ($conversation_continuity == 1 && !empty($_COOKIE['last_five_prompt'])) {
297 375 $decoded_cookie = json_decode(stripslashes($_COOKIE['last_five_prompt']), true);