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 +88 -9 8.6.6 → 8.8.2 View file →
@@ -204,11 +204,40 @@
204 204 }
205 205 $grok_api_key = get_option( 'qcld_grok_api_key' );
206 206 $keyword = isset($_POST['keyword']) ? sanitize_text_field( wp_unslash($_POST['keyword']) ) : ''; // phpcs:ignore WordPress.Security.NonceVerification.Missing
207 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 +
208 234 $rag_context = "";
209 235 if (get_option('qcld_grok_rag_enabled') == '1') {
210 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 + }
211 240 }
212 241 $relevant_pagelink = Qcld_WPBot_Common_Functions::qcpd_relevant_pagelink( $keyword );
213 242 $relevant_pagelink = array_slice( $relevant_pagelink, 0, 5, true );
214 243 if ( ( get_option( 'page_suggestion_enabled' ) == '1' ) && count( $relevant_pagelink ) > 0 ) {
@@ -227,8 +256,32 @@
227 256 $response['status'] = 'success';
228 257 $response['message'] = $result ;
229 258 wp_send_json( $response );
230 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 +
231 284 $response_mess = wp_remote_post('https://api.x.ai/v1/chat/completions', [
232 285 'headers' => [
233 286 'Authorization' => 'Bearer ' . $grok_api_key,
234 287 'Content-Type' => 'application/json',
@@ -233,12 +286,9 @@
233 286 'Authorization' => 'Bearer ' . $grok_api_key,
234 287 'Content-Type' => 'application/json',
235 288 ],
236 289 'body' => wp_json_encode([
237 - 'messages' => [
238 - ['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.' ],
239 - ['role' => 'user', 'content' => $keyword ]
240 - ],
290 + 'messages' => $messages,
241 291 'model' => 'grok-3-latest',
242 292 'temperature' => 0,
243 293 'stream' => false
244 294 ]),
@@ -245,14 +295,21 @@
245 295 'timeout' => 60,
246 296 ]);
247 297 $response['message'] = '';
248 298 $status_code = wp_remote_retrieve_response_code($response_mess);
249 - // Step 2: Get the raw body (this is almost always what you want)
250 299 $data = wp_remote_retrieve_body($response_mess);
251 - $data = json_decode($data, true); // Decode as associative array
300 + $data = json_decode($data, true);
301 + do_action('qcld_openai_user_rate_cal', 1);
252 302 $response['status'] = 'success';
253 - $response['message'] = $data['choices'][0]['message']['content'] ?? 'No content received'; // true = assoc array
254 - 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 + }
255 312 wp_send_json( $response );
256 313 }
257 314 }
258 315 public function qcld_stream_grok_callback()
@@ -288,9 +345,31 @@
288 345 $headers = [
289 346 'Content-Type: application/json',
290 347 'Authorization: Bearer ' . $api_key,
291 348 ];
292 - $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 + }
293 372 $messages = [];
294 373 // Load previous conversation from cookie if continuity is enabled
295 374 if ($conversation_continuity == 1 && !empty($_COOKIE['last_five_prompt'])) {
296 375 $decoded_cookie = json_decode(stripslashes($_COOKIE['last_five_prompt']), true);