Changeset 3459102
- Timestamp:
- 02/11/2026 03:48:47 PM (9 days ago)
- Location:
- mxchat-basic
- Files:
-
- 127 added
- 11 edited
-
tags/3.0.6 (added)
-
tags/3.0.6/admin (added)
-
tags/3.0.6/admin/class-ajax-handler.php (added)
-
tags/3.0.6/admin/class-knowledge-manager.php (added)
-
tags/3.0.6/admin/class-pinecone-manager.php (added)
-
tags/3.0.6/css (added)
-
tags/3.0.6/css/actions.css (added)
-
tags/3.0.6/css/admin-add-ons.css (added)
-
tags/3.0.6/css/admin-pro.css (added)
-
tags/3.0.6/css/admin-sidebar.css (added)
-
tags/3.0.6/css/admin-style.css (added)
-
tags/3.0.6/css/chat-style.css (added)
-
tags/3.0.6/css/chat-transcripts.css (added)
-
tags/3.0.6/css/content-selector.css (added)
-
tags/3.0.6/css/intent-style.css (added)
-
tags/3.0.6/css/knowledge-style.css (added)
-
tags/3.0.6/css/test-panel.css (added)
-
tags/3.0.6/images (added)
-
tags/3.0.6/images/Icon-01.svg (added)
-
tags/3.0.6/images/Icon-02.svg (added)
-
tags/3.0.6/images/Icon-03.svg (added)
-
tags/3.0.6/images/Icon-04.svg (added)
-
tags/3.0.6/images/addons (added)
-
tags/3.0.6/images/addons/mxchat-admin-assistant.png (added)
-
tags/3.0.6/images/addons/mxchat-assistant-api.png (added)
-
tags/3.0.6/images/addons/mxchat-forms.png (added)
-
tags/3.0.6/images/addons/mxchat-image-analysis.png (added)
-
tags/3.0.6/images/addons/mxchat-moderation.png (added)
-
tags/3.0.6/images/addons/mxchat-multi-bot.png (added)
-
tags/3.0.6/images/addons/mxchat-perplexity.png (added)
-
tags/3.0.6/images/addons/mxchat-theme.png (added)
-
tags/3.0.6/images/addons/mxchat-trigger.png (added)
-
tags/3.0.6/images/addons/mxchat-veo.png (added)
-
tags/3.0.6/images/addons/mxchat-woo.png (added)
-
tags/3.0.6/images/icon-128x128.png (added)
-
tags/3.0.6/images/pro-only-dark.png (added)
-
tags/3.0.6/includes (added)
-
tags/3.0.6/includes/admin-actions-page.php (added)
-
tags/3.0.6/includes/admin-knowledge-page.php (added)
-
tags/3.0.6/includes/admin-pro-page.php (added)
-
tags/3.0.6/includes/admin-settings-page.php (added)
-
tags/3.0.6/includes/admin-transcripts-page.php (added)
-
tags/3.0.6/includes/class-mxchat-addons.php (added)
-
tags/3.0.6/includes/class-mxchat-admin.php (added)
-
tags/3.0.6/includes/class-mxchat-chunker.php (added)
-
tags/3.0.6/includes/class-mxchat-integrator.php (added)
-
tags/3.0.6/includes/class-mxchat-meta-box.php (added)
-
tags/3.0.6/includes/class-mxchat-public.php (added)
-
tags/3.0.6/includes/class-mxchat-user.php (added)
-
tags/3.0.6/includes/class-mxchat-utils.php (added)
-
tags/3.0.6/includes/class-mxchat-woocommerce.php (added)
-
tags/3.0.6/includes/class-mxchat-word-handler.php (added)
-
tags/3.0.6/includes/pdf-parser (added)
-
tags/3.0.6/includes/pdf-parser/alt_autoload.php (added)
-
tags/3.0.6/includes/pdf-parser/src (added)
-
tags/3.0.6/includes/pdf-parser/src/Smalot (added)
-
tags/3.0.6/includes/pdf-parser/src/Smalot/PdfParser (added)
-
tags/3.0.6/includes/pdf-parser/src/Smalot/PdfParser/Config.php (added)
-
tags/3.0.6/includes/pdf-parser/src/Smalot/PdfParser/Document.php (added)
-
tags/3.0.6/includes/pdf-parser/src/Smalot/PdfParser/Element (added)
-
tags/3.0.6/includes/pdf-parser/src/Smalot/PdfParser/Element.php (added)
-
tags/3.0.6/includes/pdf-parser/src/Smalot/PdfParser/Element/ElementArray.php (added)
-
tags/3.0.6/includes/pdf-parser/src/Smalot/PdfParser/Element/ElementBoolean.php (added)
-
tags/3.0.6/includes/pdf-parser/src/Smalot/PdfParser/Element/ElementDate.php (added)
-
tags/3.0.6/includes/pdf-parser/src/Smalot/PdfParser/Element/ElementHexa.php (added)
-
tags/3.0.6/includes/pdf-parser/src/Smalot/PdfParser/Element/ElementMissing.php (added)
-
tags/3.0.6/includes/pdf-parser/src/Smalot/PdfParser/Element/ElementName.php (added)
-
tags/3.0.6/includes/pdf-parser/src/Smalot/PdfParser/Element/ElementNull.php (added)
-
tags/3.0.6/includes/pdf-parser/src/Smalot/PdfParser/Element/ElementNumeric.php (added)
-
tags/3.0.6/includes/pdf-parser/src/Smalot/PdfParser/Element/ElementString.php (added)
-
tags/3.0.6/includes/pdf-parser/src/Smalot/PdfParser/Element/ElementStruct.php (added)
-
tags/3.0.6/includes/pdf-parser/src/Smalot/PdfParser/Element/ElementXRef.php (added)
-
tags/3.0.6/includes/pdf-parser/src/Smalot/PdfParser/Encoding (added)
-
tags/3.0.6/includes/pdf-parser/src/Smalot/PdfParser/Encoding.php (added)
-
tags/3.0.6/includes/pdf-parser/src/Smalot/PdfParser/Encoding/AbstractEncoding.php (added)
-
tags/3.0.6/includes/pdf-parser/src/Smalot/PdfParser/Encoding/EncodingLocator.php (added)
-
tags/3.0.6/includes/pdf-parser/src/Smalot/PdfParser/Encoding/ISOLatin1Encoding.php (added)
-
tags/3.0.6/includes/pdf-parser/src/Smalot/PdfParser/Encoding/ISOLatin9Encoding.php (added)
-
tags/3.0.6/includes/pdf-parser/src/Smalot/PdfParser/Encoding/MacRomanEncoding.php (added)
-
tags/3.0.6/includes/pdf-parser/src/Smalot/PdfParser/Encoding/PDFDocEncoding.php (added)
-
tags/3.0.6/includes/pdf-parser/src/Smalot/PdfParser/Encoding/PostScriptGlyphs.php (added)
-
tags/3.0.6/includes/pdf-parser/src/Smalot/PdfParser/Encoding/StandardEncoding.php (added)
-
tags/3.0.6/includes/pdf-parser/src/Smalot/PdfParser/Encoding/WinAnsiEncoding.php (added)
-
tags/3.0.6/includes/pdf-parser/src/Smalot/PdfParser/Exception (added)
-
tags/3.0.6/includes/pdf-parser/src/Smalot/PdfParser/Exception/EmptyPdfException.php (added)
-
tags/3.0.6/includes/pdf-parser/src/Smalot/PdfParser/Exception/EncodingNotFoundException.php (added)
-
tags/3.0.6/includes/pdf-parser/src/Smalot/PdfParser/Exception/MissingPdfHeaderException.php (added)
-
tags/3.0.6/includes/pdf-parser/src/Smalot/PdfParser/Exception/NotImplementedException.php (added)
-
tags/3.0.6/includes/pdf-parser/src/Smalot/PdfParser/Font (added)
-
tags/3.0.6/includes/pdf-parser/src/Smalot/PdfParser/Font.php (added)
-
tags/3.0.6/includes/pdf-parser/src/Smalot/PdfParser/Font/FontCIDFontType0.php (added)
-
tags/3.0.6/includes/pdf-parser/src/Smalot/PdfParser/Font/FontCIDFontType2.php (added)
-
tags/3.0.6/includes/pdf-parser/src/Smalot/PdfParser/Font/FontTrueType.php (added)
-
tags/3.0.6/includes/pdf-parser/src/Smalot/PdfParser/Font/FontType0.php (added)
-
tags/3.0.6/includes/pdf-parser/src/Smalot/PdfParser/Font/FontType1.php (added)
-
tags/3.0.6/includes/pdf-parser/src/Smalot/PdfParser/Font/FontType3.php (added)
-
tags/3.0.6/includes/pdf-parser/src/Smalot/PdfParser/Header.php (added)
-
tags/3.0.6/includes/pdf-parser/src/Smalot/PdfParser/PDFObject.php (added)
-
tags/3.0.6/includes/pdf-parser/src/Smalot/PdfParser/Page.php (added)
-
tags/3.0.6/includes/pdf-parser/src/Smalot/PdfParser/Pages.php (added)
-
tags/3.0.6/includes/pdf-parser/src/Smalot/PdfParser/Parser.php (added)
-
tags/3.0.6/includes/pdf-parser/src/Smalot/PdfParser/RawData (added)
-
tags/3.0.6/includes/pdf-parser/src/Smalot/PdfParser/RawData/FilterHelper.php (added)
-
tags/3.0.6/includes/pdf-parser/src/Smalot/PdfParser/RawData/RawDataParser.php (added)
-
tags/3.0.6/includes/pdf-parser/src/Smalot/PdfParser/XObject (added)
-
tags/3.0.6/includes/pdf-parser/src/Smalot/PdfParser/XObject/Form.php (added)
-
tags/3.0.6/includes/pdf-parser/src/Smalot/PdfParser/XObject/Image.php (added)
-
tags/3.0.6/js (added)
-
tags/3.0.6/js/activation-script.js (added)
-
tags/3.0.6/js/admin-status.js (added)
-
tags/3.0.6/js/chat-script.js (added)
-
tags/3.0.6/js/content-selector.js (added)
-
tags/3.0.6/js/embedding-check.js (added)
-
tags/3.0.6/js/floating-script.js (added)
-
tags/3.0.6/js/knowledge-processing.js (added)
-
tags/3.0.6/js/meta-box.js (added)
-
tags/3.0.6/js/mxchat-admin.js (added)
-
tags/3.0.6/js/mxchat-test-streaming.js (added)
-
tags/3.0.6/js/mxchat_actions.js (added)
-
tags/3.0.6/js/mxchat_pro.js (added)
-
tags/3.0.6/js/mxchat_transcripts.js (added)
-
tags/3.0.6/js/my-color-picker.js (added)
-
tags/3.0.6/js/test-panel.js (added)
-
tags/3.0.6/languages (added)
-
tags/3.0.6/languages/mxchat.pot (added)
-
tags/3.0.6/mxchat-basic.php (added)
-
tags/3.0.6/readme.txt (added)
-
trunk/admin/class-ajax-handler.php (modified) (2 diffs)
-
trunk/admin/class-knowledge-manager.php (modified) (1 diff)
-
trunk/css/chat-transcripts.css (modified) (3 diffs)
-
trunk/includes/admin-knowledge-page.php (modified) (2 diffs)
-
trunk/includes/admin-settings-page.php (modified) (1 diff)
-
trunk/includes/class-mxchat-admin.php (modified) (14 diffs)
-
trunk/includes/class-mxchat-integrator.php (modified) (46 diffs)
-
trunk/js/chat-script.js (modified) (13 diffs)
-
trunk/js/mxchat-admin.js (modified) (2 diffs)
-
trunk/mxchat-basic.php (modified) (4 diffs)
-
trunk/readme.txt (modified) (6 diffs)
Legend:
- Unmodified
- Added
- Removed
-
mxchat-basic/trunk/admin/class-ajax-handler.php
r3448781 r3459102 95 95 'grok-3-mini-fast-beta', 'grok-2', 96 96 'deepseek-chat', 97 'claude-opus-4-6', 'claude-opus-4-5', 97 98 'claude-sonnet-4-5-20250929', 'claude-opus-4-1-20250805', 'claude-haiku-4-5-20251001', 98 'claude-opus-4-20250514', 'claude-sonnet-4-20250514', 'claude-3-7-sonnet-20250219', 99 'claude-3-5-sonnet-20241022', 'claude-3-opus-20240229', 'claude-3-sonnet-20240229', 100 'claude-3-haiku-20240307', 101 'gpt-5.2', 'gpt-5.1-2025-11-13', 'gpt-5', 'gpt-5-mini', 'gpt-5-nano', 'gpt-4.1-2025-04-14', 102 'gpt-4o', 'gpt-4o-mini', 'gpt-4-turbo', 'gpt-4', 'gpt-3.5-turbo', 99 'claude-opus-4-20250514', 'claude-sonnet-4-20250514', 100 'gpt-5.2', 'gpt-5.1-chat-latest', 'gpt-5.1-2025-11-13', 'gpt-5', 'gpt-5-mini', 'gpt-5-nano', 103 101 ); 104 102 … … 165 163 case 'similarity_threshold': 166 164 //error_log('MXChat Save: Processing similarity_threshold'); 167 // Save to the options array 168 $options[$name] = $value; 165 // Validate and save - enforce min 20, max 85 166 $threshold = intval($value); 167 if ($threshold < 20) $threshold = 20; 168 if ($threshold > 85) $threshold = 85; 169 $options[$name] = $threshold; 170 break; 171 case 'rag_sources_limit': 172 //error_log('MXChat Save: Processing rag_sources_limit'); 173 // Validate and save - enforce min 3, max 10, default 6 174 $rag_limit = intval($value); 175 if ($rag_limit < 3) $rag_limit = 3; 176 if ($rag_limit > 10) $rag_limit = 10; 177 $options[$name] = $rag_limit; 169 178 break; 170 179 case 'user_message_bg_color': -
mxchat-basic/trunk/admin/class-knowledge-manager.php
r3442157 r3459102 1031 1031 } 1032 1032 } 1033 1034 // Fallback: Return the body content if no specific selector matches 1035 $debug("Using body fallback"); 1033 1034 // Generic container selectors for non-CMS sites (like .asp pages) 1035 $debug("Trying generic container selectors"); 1036 $generic_selectors = [ 1037 '//div[@id="main"]', 1038 '//div[@id="wrapper"]', 1039 '//div[@id="page"]', 1040 '//div[@id="site-content"]', 1041 '//div[contains(@class, "main-content")]', 1042 '//div[contains(@class, "page-content")]', 1043 '//div[contains(@class, "site-content")]', 1044 ]; 1045 1046 foreach ($generic_selectors as $selector) { 1047 $debug("Trying generic selector: " . $selector); 1048 $nodes = $xpath->query($selector); 1049 if ($nodes && $nodes->length > 0) { 1050 $content = $dom->saveHTML($nodes->item(0)); 1051 if (!empty($content)) { 1052 $debug("Returning content from generic selector: " . $selector); 1053 return $content; 1054 } 1055 } 1056 } 1057 1058 // Paragraph-based content detection - find regions with substantial text 1059 $debug("Trying paragraph-based content detection"); 1060 $paragraphs = $xpath->query('//p[string-length(normalize-space()) > 50]'); 1061 if ($paragraphs && $paragraphs->length >= 3) { 1062 $debug("Found " . $paragraphs->length . " substantial paragraphs"); 1063 // Collect all substantial paragraphs and their content 1064 $paragraph_content = ''; 1065 foreach ($paragraphs as $p) { 1066 $paragraph_content .= $dom->saveHTML($p) . "\n"; 1067 } 1068 if (!empty($paragraph_content)) { 1069 $debug("Returning paragraph-based content"); 1070 return $paragraph_content; 1071 } 1072 } 1073 1074 // Improved body fallback - strip nav/header/footer elements first 1075 $debug("Using improved body fallback"); 1036 1076 $body = $dom->getElementsByTagName('body'); 1037 1077 if ($body->length > 0) { 1038 return $dom->saveHTML($body->item(0)); 1039 } 1040 1078 // Clone the body to avoid modifying the original DOM 1079 $body_clone = $body->item(0)->cloneNode(true); 1080 1081 // Remove common non-content elements by tag name 1082 $remove_tags = ['nav', 'header', 'footer', 'aside', 'script', 'style', 'noscript']; 1083 foreach ($remove_tags as $tag) { 1084 $elements = $body_clone->getElementsByTagName($tag); 1085 // Iterate backwards to safely remove elements 1086 for ($i = $elements->length - 1; $i >= 0; $i--) { 1087 $el = $elements->item($i); 1088 if ($el && $el->parentNode) { 1089 $el->parentNode->removeChild($el); 1090 } 1091 } 1092 } 1093 1094 // Remove elements with common non-content class names using XPath on the cloned body 1095 $temp_dom = new DOMDocument(); 1096 @$temp_dom->appendChild($temp_dom->importNode($body_clone, true)); 1097 $temp_xpath = new DOMXPath($temp_dom); 1098 1099 $remove_class_patterns = [ 1100 '//*[contains(@class, "nav")]', 1101 '//*[contains(@class, "menu")]', 1102 '//*[contains(@class, "sidebar")]', 1103 '//*[contains(@class, "footer")]', 1104 '//*[contains(@class, "header")]', 1105 '//*[contains(@id, "nav")]', 1106 '//*[contains(@id, "menu")]', 1107 '//*[contains(@id, "sidebar")]', 1108 '//*[contains(@id, "footer")]', 1109 '//*[contains(@id, "header")]', 1110 ]; 1111 1112 foreach ($remove_class_patterns as $pattern) { 1113 $elements = $temp_xpath->query($pattern); 1114 if ($elements) { 1115 for ($i = $elements->length - 1; $i >= 0; $i--) { 1116 $el = $elements->item($i); 1117 if ($el && $el->parentNode) { 1118 $el->parentNode->removeChild($el); 1119 } 1120 } 1121 } 1122 } 1123 1124 $cleaned_content = $temp_dom->saveHTML(); 1125 if (!empty($cleaned_content)) { 1126 $debug("Returning cleaned body content"); 1127 return $cleaned_content; 1128 } 1129 } 1130 1041 1131 // Last resort: return the original HTML 1042 1132 $debug("Returning original HTML"); -
mxchat-basic/trunk/css/chat-transcripts.css
r3446370 r3459102 832 832 .mxch-user-info { 833 833 flex: 1; 834 min-width: 0; /* Allow flex item to shrink below content size */ 835 overflow: hidden; 834 836 } 835 837 … … 838 840 font-weight: 600; 839 841 color: #111827; 842 overflow: hidden; 843 text-overflow: ellipsis; 844 white-space: nowrap; 840 845 } 841 846 … … 844 849 color: #6b7280; 845 850 margin-top: 2px; 851 overflow: hidden; 852 text-overflow: ellipsis; 853 white-space: nowrap; 846 854 } 847 855 -
mxchat-basic/trunk/includes/admin-knowledge-page.php
r3448781 r3459102 1543 1543 // Get current chat model to check compatibility 1544 1544 $mxchat_options = get_option('mxchat_options', array()); 1545 $current_model = $mxchat_options['model'] ?? 'gpt- 4o';1545 $current_model = $mxchat_options['model'] ?? 'gpt-5.1-chat-latest'; 1546 1546 $is_openai_model = preg_match('/^(gpt-|o1-|o3-)/', $current_model); 1547 1547 ?> … … 1556 1556 <div class="mxch-notice mxch-notice-info" style="margin-bottom: 20px;"> 1557 1557 <svg class="mxch-notice-icon" xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="12" cy="12" r="10"/><line x1="12" y1="16" x2="12" y2="12"/><line x1="12" y1="8" x2="12.01" y2="8"/></svg> 1558 <span><strong><?php esc_html_e('Requires OpenAI Chat Model.', 'mxchat'); ?></strong> <?php esc_html_e('Vector Store search only works with OpenAI models (gpt- 4o, gpt-4o-mini, etc.). Create Vector Stores in your OpenAI Dashboard.', 'mxchat'); ?></span>1558 <span><strong><?php esc_html_e('Requires OpenAI Chat Model.', 'mxchat'); ?></strong> <?php esc_html_e('Vector Store search only works with OpenAI models (gpt-5.1-chat-latest, gpt-5-mini, etc.). Create Vector Stores in your OpenAI Dashboard.', 'mxchat'); ?></span> 1559 1559 </div> 1560 1560 -
mxchat-basic/trunk/includes/admin-settings-page.php
r3444379 r3459102 267 267 $admin_instance->mxchat_similarity_threshold_callback(); 268 268 }, __('Adjust threshold for content matching. Lower values = more matches, higher values = stricter matching.', 'mxchat')); 269 270 // RAG Sources Limit 271 mxchat_render_field_wrapper('rag_sources_limit', __('RAG Sources Limit', 'mxchat'), function() use ($admin_instance) { 272 $admin_instance->mxchat_rag_sources_limit_callback(); 273 }, __('Number of knowledge base sources (pages/documents) to include in AI context. Higher values provide more context but use more tokens.', 'mxchat')); 269 274 270 275 // Contextual Awareness -
mxchat-basic/trunk/includes/class-mxchat-admin.php
r3448781 r3459102 128 128 - When knowledge base information is unclear or contradictory, acknowledge the limitation rather than guessing 129 129 - Better to admit insufficient information than provide inaccurate answers', 130 'model' => esc_html__('gpt- 4o', 'mxchat'),130 'model' => esc_html__('gpt-5.1-chat-latest', 'mxchat'), 131 131 'rate_limit_logged_out' => esc_html__('100', 'mxchat'), 132 132 'role_rate_limits' => array(), … … 307 307 // Get user's selected model and API key 308 308 $options = get_option('mxchat_options', []); 309 $selected_model = $options['model'] ?? 'gpt- 4o';309 $selected_model = $options['model'] ?? 'gpt-5.1-chat-latest'; 310 310 311 311 // Get the provider from the model … … 1553 1553 // Get user's selected model and determine provider 1554 1554 $options = get_option('mxchat_options', []); 1555 $selected_model = $options['model'] ?? 'gpt- 4o';1555 $selected_model = $options['model'] ?? 'gpt-5.1-chat-latest'; 1556 1556 1557 1557 // Check if using OpenRouter … … 4575 4575 ); 4576 4576 4577 // RAG Sources Limit Slider 4578 add_settings_field( 4579 'rag_sources_limit', // Field ID 4580 esc_html__('RAG Sources Limit', 'mxchat'), // Field title 4581 array($this, 'mxchat_rag_sources_limit_callback'), // Callback function 4582 'mxchat-chatbot', // Page 4583 'mxchat_chatbot_section' // Section 4584 ); 4585 4577 4586 add_settings_field( 4578 4587 'append_to_body', … … 5574 5583 $instructions 5575 5584 ); 5585 // Personalization hint 5586 echo '<p class="description" style="margin-top: 8px;">'; 5587 echo esc_html__('Use {visitor_name} to personalize AI responses when lead capture is enabled.', 'mxchat') . '<br>'; 5588 echo '<code style="font-size: 12px;">' . esc_html__('Example: The visitor\'s name is {visitor_name}. Address them by name.', 'mxchat') . '</code>'; 5589 echo '</p>'; 5576 5590 // Sample instructions button 5577 5591 echo '<div class="mxchat-instructions-container">'; … … 5681 5695 ), 5682 5696 esc_html__('Claude Models', 'mxchat') => array( 5697 'claude-opus-4-6' => esc_html__('Claude Opus 4.6 (Most Capable - Recommended)', 'mxchat'), 5698 'claude-opus-4-5' => esc_html__('Claude Opus 4.5 (Highly Capable)', 'mxchat'), 5683 5699 'claude-sonnet-4-5-20250929' => esc_html__('Claude Sonnet 4.5 (Best for Agents & Coding)', 'mxchat'), 5684 5700 'claude-opus-4-1-20250805' => esc_html__('Claude Opus 4.1 (Exceptional for Complex Tasks)', 'mxchat'), 5685 5701 'claude-haiku-4-5-20251001' => esc_html__('Claude Haiku 4.5 (Fastest & Most Intelligent)', 'mxchat'), 5686 'claude-opus-4-20250514' => esc_html__('Claude 4 Opus ( Most Capable)', 'mxchat'),5702 'claude-opus-4-20250514' => esc_html__('Claude 4 Opus (Complex Tasks)', 'mxchat'), 5687 5703 'claude-sonnet-4-20250514' => esc_html__('Claude 4 Sonnet (High Performance)', 'mxchat'), 5688 'claude-3-7-sonnet-20250219' => esc_html__('Claude 3.7 Sonnet (High Intelligence)', 'mxchat'),5689 'claude-3-opus-20240229' => esc_html__('Claude 3 Opus (Complex Tasks)', 'mxchat'),5690 'claude-3-sonnet-20240229' => esc_html__('Claude 3 Sonnet (Balanced)', 'mxchat'),5691 'claude-3-haiku-20240307' => esc_html__('Claude 3 Haiku (Fastest)', 'mxchat'),5692 5704 ), 5693 5705 esc_html__('OpenAI Models', 'mxchat') => array( 5694 // GPT-5 family5695 5706 'gpt-5.2' => esc_html__('GPT-5.2 (Best General-Purpose & Agentic Model)', 'mxchat'), 5707 'gpt-5.1-chat-latest' => esc_html__('GPT-5.1 Chat Latest (Recommended)', 'mxchat'), 5696 5708 'gpt-5.1-2025-11-13' => esc_html__('GPT-5.1 (Flagship for Coding & Agentic Tasks)', 'mxchat'), 5697 5709 'gpt-5' => esc_html__('GPT-5 (Flagship for Coding, Reasoning & Agents)', 'mxchat'), 5698 'gpt-5-mini' => esc_html__('GPT-5 Mini (Fast er, Cost-Efficient for Precise Prompts)', 'mxchat'),5710 'gpt-5-mini' => esc_html__('GPT-5 Mini (Fast and Lightweight)', 'mxchat'), 5699 5711 'gpt-5-nano' => esc_html__('GPT-5 Nano (Fastest & Cheapest for Summarization/Classification)', 'mxchat'), 5700 5701 // Existing OpenAI models5702 'gpt-4.1-2025-04-14' => esc_html__('GPT-4.1 (Flagship for Complex Tasks)', 'mxchat'),5703 'gpt-4o' => esc_html__('GPT-4o (Recommended)', 'mxchat'),5704 'gpt-4o-mini' => esc_html__('GPT-4o Mini (Fast and Lightweight)', 'mxchat'),5705 'gpt-4-turbo' => esc_html__('GPT-4 Turbo (High-Performance)', 'mxchat'),5706 'gpt-4' => esc_html__('GPT-4 (High Intelligence)', 'mxchat'),5707 'gpt-3.5-turbo' => esc_html__('GPT-3.5 Turbo (Affordable and Fast)', 'mxchat'),5708 5712 ), 5709 5713 ); 5710 5714 5711 5715 // Retrieve the currently selected model from saved options 5712 $selected_model = isset($this->options['model']) ? esc_attr($this->options['model']) : 'gpt- 4o';5716 $selected_model = isset($this->options['model']) ? esc_attr($this->options['model']) : 'gpt-5.1-chat-latest'; 5713 5717 5714 5718 // Begin the select dropdown … … 5835 5839 5836 5840 // Get current model to determine if we should show/enable the toggle 5837 $current_model = isset($this->options['model']) ? $this->options['model'] : 'gpt- 4o';5841 $current_model = isset($this->options['model']) ? $this->options['model'] : 'gpt-5.1-chat-latest'; 5838 5842 5839 5843 // Models that DON'T support web search (per OpenAI docs) … … 5843 5847 // Check if current model is an OpenAI model that supports web search 5844 5848 $openai_models = array( 5845 'gpt-5.2', 'gpt-5.1-2025-11-13', 'gpt-5', 'gpt-5-mini', 'gpt-5-nano', 5846 'gpt-4.1-2025-04-14', 'gpt-4o', 'gpt-4o-mini', 'gpt-4-turbo', 'gpt-4', 'gpt-3.5-turbo' 5849 'gpt-5.2', 'gpt-5.1-chat-latest', 'gpt-5.1-2025-11-13', 'gpt-5', 'gpt-5-mini', 'gpt-5-nano' 5847 5850 ); 5848 5851 … … 6079 6082 ?> 6080 6083 <textarea id="intro_message" name="intro_message" rows="5" cols="50"><?php echo $saved_message; ?></textarea> 6084 <p class="description" style="margin-top: 8px;"> 6085 <?php esc_html_e('Use {visitor_name} to personalize greetings when lead capture is enabled.', 'mxchat'); ?><br> 6086 <code style="font-size: 12px;"><?php esc_html_e('Example: Hello {visitor_name}! How can I help you today?', 'mxchat'); ?></code> 6087 </p> 6081 6088 <?php 6082 6089 } … … 7241 7248 $options = get_option('mxchat_options', []); 7242 7249 7243 // Get value from options array with default of 807250 // Get value from options array with default of 35 7244 7251 $threshold = isset($options['similarity_threshold']) ? $options['similarity_threshold'] : 35; 7245 7252 … … 7261 7268 ); 7262 7269 echo '</div>'; 7263 echo '<p class="description">'; 7264 echo esc_html__('Adjust similarity threshold for optimal content matching. Too high may limit knowledge retrieval. We highly recommend using the MxChat Debugger found on the left side of your website when logged in as admin while testing the bot.', 'mxchat'); 7265 echo '</p>'; 7270 } 7271 7272 public function mxchat_rag_sources_limit_callback() { 7273 // Load from mxchat_options array 7274 $options = get_option('mxchat_options', []); 7275 7276 // Get value from options array with default of 6 7277 $rag_sources_limit = isset($options['rag_sources_limit']) ? intval($options['rag_sources_limit']) : 6; 7278 7279 echo '<div class="slider-container">'; 7280 echo sprintf( 7281 '<input type="range" 7282 id="rag_sources_limit" 7283 name="rag_sources_limit" 7284 min="3" 7285 max="10" 7286 step="1" 7287 value="%s" 7288 class="range-slider" />', 7289 esc_attr($rag_sources_limit) 7290 ); 7291 echo sprintf( 7292 '<span id="rag_sources_limit_value" class="range-value">%s</span>', 7293 esc_html($rag_sources_limit) 7294 ); 7295 echo '</div>'; 7266 7296 } 7267 7297 … … 7524 7554 } 7525 7555 7556 if (isset($input['rag_sources_limit'])) { 7557 $new_input['rag_sources_limit'] = absint($input['rag_sources_limit']); // Ensure it's an integer 7558 $new_input['rag_sources_limit'] = min(max($new_input['rag_sources_limit'], 3), 10); // Enforce range 3-10 7559 } 7560 7526 7561 if (isset($input['xai_api_key'])) { 7527 7562 $new_input['xai_api_key'] = sanitize_text_field($input['xai_api_key']); … … 7738 7773 'grok-2', 7739 7774 'deepseek-chat', 7775 'claude-opus-4-6', 7776 'claude-opus-4-5', 7740 7777 'claude-sonnet-4-5-20250929', 7741 7778 'claude-opus-4-1-20250805', … … 7743 7780 'claude-opus-4-20250514', 7744 7781 'claude-sonnet-4-20250514', 7745 'claude-3-7-sonnet-20250219',7746 // REMOVED: 'claude-3-5-sonnet-20241022',7747 'claude-3-opus-20240229',7748 'claude-3-sonnet-20240229',7749 'claude-3-haiku-20240307',7750 7782 'gpt-5.2', 7783 'gpt-5.1-chat-latest', 7751 7784 'gpt-5.1-2025-11-13', 7752 7785 'gpt-5', 7753 7786 'gpt-5-mini', 7754 7787 'gpt-5-nano', 7755 'gpt-4.1-2025-04-14',7756 'gpt-4o',7757 'gpt-4o-mini',7758 'gpt-4-turbo',7759 'gpt-4',7760 'gpt-3.5-turbo',7761 7788 ); 7762 7789 7763 7790 if (in_array($input['model'], $allowed_models)) { 7764 7791 $new_input['model'] = sanitize_text_field($input['model']); 7765 7792 } else { 7766 7793 // Fallback for any deprecated model 7767 $new_input['model'] = ' claude-3-7-sonnet-20250219';7794 $new_input['model'] = 'gpt-5.1-chat-latest'; 7768 7795 } 7769 7796 } -
mxchat-basic/trunk/includes/class-mxchat-integrator.php
r3446370 r3459102 185 185 wp_die(); 186 186 } 187 private function mxchat_fetch_conversation_history_for_ai($session_id ) {187 private function mxchat_fetch_conversation_history_for_ai($session_id, $session_start_timestamp = 0) { 188 188 $history = get_option("mxchat_history_{$session_id}", []); 189 190 // Check persistence setting - when OFF, only include messages from current page load 191 $options = get_option('mxchat_options', []); 192 $persistence_enabled = isset($options['chat_persistence_toggle']) && $options['chat_persistence_toggle'] === 'on'; 193 194 // Filter history when persistence is OFF to match what the user sees 195 if (!$persistence_enabled && $session_start_timestamp > 0) { 196 $history = array_filter($history, function($entry) use ($session_start_timestamp) { 197 // Include messages from this page load onwards 198 return isset($entry['timestamp']) && $entry['timestamp'] >= $session_start_timestamp; 199 }); 200 // Re-index array after filtering 201 $history = array_values($history); 202 } 203 189 204 $formatted_history = []; 190 205 … … 1577 1592 1578 1593 // If we get here, no intent matched OR the intent didn't provide a usable response 1579 1594 1580 1595 // Step 4: Generate AI response 1581 $conversation_history = $this->mxchat_fetch_conversation_history_for_ai($session_id); 1596 // Get session start timestamp - when persistence is OFF, only include messages from this page load 1597 $session_start_timestamp = isset($_POST['session_start_timestamp']) ? intval($_POST['session_start_timestamp']) : 0; 1598 $conversation_history = $this->mxchat_fetch_conversation_history_for_ai($session_id, $session_start_timestamp); 1582 1599 $this->mxchat_increment_chat_count(); 1583 1600 … … 1667 1684 $citation_links_enabled = isset($fresh_options['citation_links_toggle']) ? ($fresh_options['citation_links_toggle'] === 'on') : true; 1668 1685 1669 $system_instructions = $this->get_system_instructions($bot_id );1686 $system_instructions = $this->get_system_instructions($bot_id, $session_id); 1670 1687 if ($citation_links_enabled && !empty($system_instructions)) { 1671 1688 preg_match_all( … … 1753 1770 1754 1771 // Extract model from current options for bot-specific model support 1755 $selected_model = isset($current_options['model']) ? $current_options['model'] : 'gpt- 4o';1772 $selected_model = isset($current_options['model']) ? $current_options['model'] : 'gpt-5.1-chat-latest'; 1756 1773 1757 1774 $response = $this->mxchat_generate_response( … … 2535 2552 // Get options and determine the selected model 2536 2553 $options = $this->options ?? get_option('mxchat_options'); 2537 $selected_model = isset($options['model']) ? $options['model'] : 'gpt- 4o';2554 $selected_model = isset($options['model']) ? $options['model'] : 'gpt-5.1-chat-latest'; 2538 2555 2539 2556 // Extract model prefix to determine the provider … … 2585 2602 * Interpret query using OpenAI models 2586 2603 */ 2587 private function interpret_query_with_openai($user_query, $system_prompt, $api_key, $model = 'gpt- 4o') {2604 private function interpret_query_with_openai($user_query, $system_prompt, $api_key, $model = 'gpt-5.1-chat-latest') { 2588 2605 $url = 'https://api.openai.com/v1/chat/completions'; 2589 2606 $args = [ … … 4438 4455 $mxchat_options = get_option('mxchat_options', array()); 4439 4456 $current_options = !empty($bot_options) ? $bot_options : $mxchat_options; 4440 $selected_model = $current_options['model'] ?? 'gpt- 4o';4457 $selected_model = $current_options['model'] ?? 'gpt-5.1-chat-latest'; 4441 4458 4442 4459 if ($this->is_openai_chat_model($selected_model)) { … … 4653 4670 }); 4654 4671 4655 // Take top 3 unique URLs 4656 $top_urls = array_slice($url_groups, 0, 3, true); 4672 // Get RAG sources limit from options (default 6, min 3, max 10) 4673 $rag_sources_limit = isset($options['rag_sources_limit']) ? intval($options['rag_sources_limit']) : 6; 4674 if ($rag_sources_limit < 3) $rag_sources_limit = 3; 4675 if ($rag_sources_limit > 10) $rag_sources_limit = 10; 4676 4677 // Take top N unique URLs based on user setting 4678 $top_urls = array_slice($url_groups, 0, $rag_sources_limit, true); 4657 4679 4658 4680 // Track which document IDs are used for context … … 4680 4702 $content = ''; 4681 4703 $matches_used = 0; 4704 $total_chunks_used = 0; 4705 $max_total_chunks = 30; // Hard cap on total chunks to prevent excessive token usage 4682 4706 4683 4707 // Check if citation links are enabled (default to 'on' for backwards compatibility) … … 4688 4712 // Build content from top URLs 4689 4713 foreach ($top_urls as $source_url => $group) { 4714 // Stop if we've hit the total chunk limit 4715 if ($total_chunks_used >= $max_total_chunks) { 4716 break; 4717 } 4718 4690 4719 $full_text = ''; 4720 $chunks_in_this_source = 1; // Default for non-chunked content 4691 4721 4692 4722 if ($group['is_chunked']) { 4693 // Fetch all chunks for this URL and reassemble 4694 $full_text = $this->reassemble_chunks_from_wordpress($source_url); 4723 // Calculate how many chunks we can still use 4724 $chunks_remaining = $max_total_chunks - $total_chunks_used; 4725 4726 // Fetch chunks for this URL with limit 4727 $full_text = $this->reassemble_chunks_from_wordpress($source_url, $chunks_remaining, $chunks_in_this_source); 4695 4728 4696 4729 // If fetching all chunks fails, fall back to matched chunks … … 4702 4735 4703 4736 $chunk_texts = array(); 4737 $chunks_in_this_source = 0; 4704 4738 foreach ($group['chunks'] as $chunk) { 4739 if ($total_chunks_used + $chunks_in_this_source >= $max_total_chunks) { 4740 break; 4741 } 4705 4742 $chunk_texts[] = $chunk['text']; 4743 $chunks_in_this_source++; 4706 4744 } 4707 4745 $full_text = implode("\n\n", $chunk_texts); … … 4709 4747 } else { 4710 4748 $full_text = $group['single_text']; 4749 $chunks_in_this_source = 1; 4711 4750 } 4712 4751 … … 4740 4779 4741 4780 $matches_used++; 4781 $total_chunks_used += $chunks_in_this_source; 4742 4782 } 4743 4783 } … … 4772 4812 4773 4813 /** 4774 * Fetch and reassemble allchunks for a URL from WordPress database4814 * Fetch and reassemble chunks for a URL from WordPress database 4775 4815 * 4776 4816 * @param string $source_url The source URL to fetch chunks for 4777 * @return string Reassembled content from all chunks 4817 * @param int $max_chunks Maximum number of chunks to return (0 = unlimited) 4818 * @param int &$chunk_count Reference to store the actual number of chunks returned 4819 * @return string Reassembled content from chunks 4778 4820 */ 4779 private function reassemble_chunks_from_wordpress($source_url ) {4821 private function reassemble_chunks_from_wordpress($source_url, $max_chunks = 0, &$chunk_count = 0) { 4780 4822 global $wpdb; 4781 4823 $table = $wpdb->prefix . 'mxchat_system_prompt_content'; … … 4790 4832 4791 4833 if (empty($rows)) { 4834 $chunk_count = 0; 4792 4835 return ''; 4793 4836 } … … 4809 4852 // Sort by chunk index 4810 4853 ksort($chunks); 4854 4855 // Apply chunk limit if specified 4856 if ($max_chunks > 0 && count($chunks) > $max_chunks) { 4857 $chunks = array_slice($chunks, 0, $max_chunks, true); 4858 } 4859 4860 // Store actual chunk count 4861 $chunk_count = count($chunks); 4811 4862 4812 4863 // Reassemble content … … 4876 4927 $request_body = array( 4877 4928 'vector' => $user_embedding, 4878 'topK' => 50, // Increased for chunked content grouping - need more candidates to find top 3unique URLs4929 'topK' => 50, // Increased for chunked content grouping - need more candidates to find top N unique URLs 4879 4930 'includeMetadata' => true, 4880 4931 'includeValues' => true … … 4961 5012 $matches_used = 0; 4962 5013 $matches_used_for_context = []; 5014 $total_chunks_used = 0; 5015 $max_total_chunks = 30; // Hard cap on total chunks to prevent excessive token usage 4963 5016 4964 5017 // Check if citation links are enabled (default to 'on' for backwards compatibility) … … 5029 5082 }); 5030 5083 5031 // Take top 3 unique URLs 5032 $top_urls = array_slice($url_groups, 0, 3, true); 5033 5034 // Track which match IDs are actually used for context (only from top 3 URLs) 5084 // Get RAG sources limit from options (default 6, min 3, max 10) 5085 $rag_sources_limit = isset($current_options['rag_sources_limit']) ? intval($current_options['rag_sources_limit']) : 6; 5086 if ($rag_sources_limit < 3) $rag_sources_limit = 3; 5087 if ($rag_sources_limit > 10) $rag_sources_limit = 10; 5088 5089 // Take top N unique URLs based on user setting 5090 $top_urls = array_slice($url_groups, 0, $rag_sources_limit, true); 5091 5092 // Track which match IDs are actually used for context 5035 5093 foreach ($top_urls as $group) { 5036 5094 if ($group['is_chunked']) { … … 5045 5103 // Build content from top URLs 5046 5104 foreach ($top_urls as $source_url => $group) { 5105 // Stop if we've hit the total chunk limit 5106 if ($total_chunks_used >= $max_total_chunks) { 5107 break; 5108 } 5109 5047 5110 $full_text = ''; 5111 $chunks_in_this_source = 1; // Default for non-chunked content 5048 5112 5049 5113 if ($group['is_chunked']) { 5050 // Fetch all chunks for this URL and reassemble 5051 $full_text = $this->reassemble_chunks_from_pinecone($source_url, $bot_config); 5114 // Calculate how many chunks we can still use 5115 $chunks_remaining = $max_total_chunks - $total_chunks_used; 5116 5117 // Fetch chunks for this URL with limit 5118 $full_text = $this->reassemble_chunks_from_pinecone($source_url, $bot_config, $chunks_remaining, $chunks_in_this_source); 5052 5119 5053 5120 // If fetching all chunks fails, fall back to matched chunks … … 5059 5126 5060 5127 $chunk_texts = array(); 5128 $chunks_in_this_source = 0; 5061 5129 foreach ($group['chunks'] as $chunk) { 5130 if ($total_chunks_used + $chunks_in_this_source >= $max_total_chunks) { 5131 break; 5132 } 5062 5133 $chunk_texts[] = $chunk['text']; 5134 $chunks_in_this_source++; 5063 5135 } 5064 5136 $full_text = implode("\n\n", $chunk_texts); … … 5066 5138 } else { 5067 5139 $full_text = $group['single_text']; 5140 $chunks_in_this_source = 1; 5068 5141 } 5069 5142 … … 5097 5170 5098 5171 $matches_used++; 5172 $total_chunks_used += $chunks_in_this_source; 5099 5173 } 5100 5174 } … … 5230 5304 * @return string Reassembled content from all chunks 5231 5305 */ 5232 private function reassemble_chunks_from_pinecone($source_url, $bot_config ) {5306 private function reassemble_chunks_from_pinecone($source_url, $bot_config, $max_chunks = 0, &$chunk_count = 0) { 5233 5307 $api_key = $bot_config['api_key'] ?? ''; 5234 5308 $host = $bot_config['host'] ?? ''; … … 5236 5310 5237 5311 if (empty($host) || empty($api_key)) { 5312 $chunk_count = 0; 5238 5313 return ''; 5239 5314 } … … 5244 5319 $list_url = "https://{$host}/vectors/list"; 5245 5320 5321 // Limit to max_chunks if specified, otherwise fetch up to 100 5322 $fetch_limit = ($max_chunks > 0 && $max_chunks < 100) ? $max_chunks : 100; 5323 5246 5324 $list_body = array( 5247 5325 'prefix' => $base_hash . '_chunk_', 5248 'limit' => 1005326 'limit' => $fetch_limit 5249 5327 ); 5250 5328 … … 5332 5410 // Sort by chunk index 5333 5411 ksort($chunks); 5412 5413 // Apply chunk limit if specified 5414 if ($max_chunks > 0 && count($chunks) > $max_chunks) { 5415 $chunks = array_slice($chunks, 0, $max_chunks, true); 5416 } 5417 5418 // Store actual chunk count 5419 $chunk_count = count($chunks); 5334 5420 5335 5421 // Reassemble content … … 5396 5482 $bot_options = $this->get_bot_options($bot_id); 5397 5483 $current_options = !empty($bot_options) ? $bot_options : $mxchat_options; 5398 $selected_model = $current_options['model'] ?? 'gpt- 4o';5484 $selected_model = $current_options['model'] ?? 'gpt-5.1-chat-latest'; 5399 5485 5400 5486 // Verify it's an OpenAI model … … 5898 5984 * Checks for multi-bot add-on and uses bot-specific instructions if available 5899 5985 * Automatically strips URLs if citation links are disabled 5986 * Replaces {visitor_name} placeholder with actual visitor name if available 5900 5987 * 5901 5988 * @param string $bot_id The bot ID to get instructions for 5989 * @param string $session_id Optional session ID to lookup visitor name 5902 5990 */ 5903 private function get_system_instructions($bot_id = 'default' ) {5991 private function get_system_instructions($bot_id = 'default', $session_id = '') { 5904 5992 $instructions = ''; 5905 5993 … … 5927 6015 $instructions = preg_replace('#\bhttps?://[^\s<>"\']+#i', '', $instructions); 5928 6016 $instructions = preg_replace('/\s+/', ' ', trim($instructions)); // Clean up extra spaces 6017 } 6018 6019 // Replace {visitor_name} placeholder with actual visitor name if available 6020 if (!empty($instructions) && !empty($session_id) && stripos($instructions, '{visitor_name}') !== false) { 6021 $name_option_key = "mxchat_name_{$session_id}"; 6022 $visitor_name = get_option($name_option_key, ''); 6023 6024 if (!empty($visitor_name)) { 6025 $instructions = str_ireplace('{visitor_name}', sanitize_text_field($visitor_name), $instructions); 6026 } else { 6027 // Remove placeholder if no name is available 6028 $instructions = str_ireplace('{visitor_name}', '', $instructions); 6029 $instructions = preg_replace('/\s{2,}/', ' ', trim($instructions)); // Clean up extra spaces 6030 } 5929 6031 } 5930 6032 … … 5951 6053 return 'default'; 5952 6054 } 5953 private function mxchat_generate_response($relevant_content, $api_key, $xai_api_key, $claude_api_key, $deepseek_api_key, $gemini_api_key, $openrouter_api_key, $conversation_history, $streaming = false, $session_id = '', $testing_data = null, $selected_model = 'gpt- 4o') {6055 private function mxchat_generate_response($relevant_content, $api_key, $xai_api_key, $claude_api_key, $deepseek_api_key, $gemini_api_key, $openrouter_api_key, $conversation_history, $streaming = false, $session_id = '', $testing_data = null, $selected_model = 'gpt-5.1-chat-latest') { 5954 6056 try { 5955 6057 if (!$relevant_content) { … … 6262 6364 try { 6263 6365 $bot_id = $this->get_current_bot_id($session_id); 6264 $system_prompt_instructions = $this->get_system_instructions($bot_id );6366 $system_prompt_instructions = $this->get_system_instructions($bot_id, $session_id); 6265 6367 6266 6368 if (!is_array($conversation_history)) { … … 6472 6574 6473 6575 // Get system prompt instructions using centralized function 6474 $system_prompt_instructions = $this->get_system_instructions($bot_id );6576 $system_prompt_instructions = $this->get_system_instructions($bot_id, $session_id); 6475 6577 6476 6578 // Ensure conversation_history is an array … … 6757 6859 try { 6758 6860 $bot_id = $this->get_current_bot_id($session_id); 6759 $system_prompt_instructions = $this->get_system_instructions($bot_id );6861 $system_prompt_instructions = $this->get_system_instructions($bot_id, $session_id); 6760 6862 6761 6863 if (!is_array($conversation_history)) { … … 7087 7189 7088 7190 // Get system prompt instructions using centralized function 7089 $system_prompt_instructions = $this->get_system_instructions($bot_id );7191 $system_prompt_instructions = $this->get_system_instructions($bot_id, $session_id); 7090 7192 // Ensure conversation_history is an array 7091 7193 if (!is_array($conversation_history)) { … … 7382 7484 7383 7485 // Get system prompt instructions using centralized function 7384 $system_prompt_instructions = $this->get_system_instructions($bot_id );7486 $system_prompt_instructions = $this->get_system_instructions($bot_id, $session_id); 7385 7487 7386 7488 // Ensure conversation_history is an array … … 7619 7721 7620 7722 // Get system prompt instructions using centralized function 7621 $system_prompt_instructions = $this->get_system_instructions($bot_id );7723 $system_prompt_instructions = $this->get_system_instructions($bot_id, $session_id); 7622 7724 7623 7725 // Ensure conversation_history is an array … … 7883 7985 7884 7986 $bot_id = $this->get_current_bot_id(''); 7885 $system_prompt_instructions = $this->get_system_instructions($bot_id );7987 $system_prompt_instructions = $this->get_system_instructions($bot_id, $session_id); 7886 7988 7887 7989 $formatted_conversation = array(); … … 7985 8087 7986 8088 // Get system prompt instructions using centralized function 7987 $system_prompt_instructions = $this->get_system_instructions($bot_id );8089 $system_prompt_instructions = $this->get_system_instructions($bot_id, $session_id); 7988 8090 7989 8091 // Clean and validate conversation history … … 8094 8196 8095 8197 // Get system prompt instructions using centralized function 8096 $system_prompt_instructions = $this->get_system_instructions($bot_id );8198 $system_prompt_instructions = $this->get_system_instructions($bot_id, $session_id); 8097 8199 8098 8200 // Create a new array for the formatted conversation … … 8262 8364 8263 8365 // Get system prompt instructions using centralized function 8264 $system_prompt_instructions = $this->get_system_instructions($bot_id );8366 $system_prompt_instructions = $this->get_system_instructions($bot_id, $session_id); 8265 8367 8266 8368 // Add system prompt to relevant content … … 8461 8563 8462 8564 // Get system prompt instructions using centralized function 8463 $system_prompt_instructions = $this->get_system_instructions($bot_id );8565 $system_prompt_instructions = $this->get_system_instructions($bot_id, $session_id); 8464 8566 8465 8567 // Create a new array for the formatted conversation … … 8620 8722 8621 8723 // Get system prompt instructions using centralized function 8622 $system_prompt_instructions = $this->get_system_instructions($bot_id );8724 $system_prompt_instructions = $this->get_system_instructions($bot_id, $session_id); 8623 8725 8624 8726 // Add system prompt to relevant content … … 8764 8866 public function test_streaming_request() { 8765 8867 $options = get_option('mxchat_options', []); 8766 $model = $options['model'] ?? 'gpt- 4o';8868 $model = $options['model'] ?? 'gpt-5.1-chat-latest'; 8767 8869 8768 8870 // Detect provider from model prefix … … 8978 9080 'ajax_url' => admin_url('admin-ajax.php'), 8979 9081 'nonce' => wp_create_nonce('mxchat_chat_nonce'), 8980 'model' => isset($this->options['model']) ? $this->options['model'] : 'gpt- 4o',9082 'model' => isset($this->options['model']) ? $this->options['model'] : 'gpt-5.1-chat-latest', 8981 9083 'enable_streaming_toggle' => isset($this->options['enable_streaming_toggle']) ? $this->options['enable_streaming_toggle'] : 'on', 8982 9084 'contextual_awareness_toggle' => isset($this->options['contextual_awareness_toggle']) ? $this->options['contextual_awareness_toggle'] : 'off', … … 9574 9676 9575 9677 // Get selected model 9576 $selected_model = isset($this->options['model']) ? $this->options['model'] : 'gpt- 4o';9678 $selected_model = isset($this->options['model']) ? $this->options['model'] : 'gpt-5.1-chat-latest'; 9577 9679 9578 9680 // Check if OpenRouter is being used -
mxchat-basic/trunk/js/chat-script.js
r3446370 r3459102 12 12 init: function(botId) { 13 13 if (!this.instances[botId]) { 14 // When persistence is OFF, track when this session started 15 // so the AI only sees messages from this page load 16 var chatPersistenceEnabled = typeof mxchatChat !== 'undefined' && mxchatChat.chat_persistence_toggle === 'on'; 17 14 18 this.instances[botId] = { 15 19 botId: botId, … … 22 26 activeWordFile: null, 23 27 chatHistoryLoaded: false, 24 isStreaming: false 28 isStreaming: false, 29 // Fresh context timestamp - only used when persistence is OFF 30 sessionStartTimestamp: chatPersistenceEnabled ? 0 : Date.now() 25 31 }; 26 32 } … … 398 404 scrollToBottom(botId); 399 405 400 const currentModel = mxchatChat.model || 'gpt- 4o';406 const currentModel = mxchatChat.model || 'gpt-5.1-chat-latest'; 401 407 402 408 // Check if streaming is enabled AND supported for this model … … 433 439 scrollToBottom(botId); 434 440 435 const currentModel = mxchatChat.model || 'gpt- 4o';441 const currentModel = mxchatChat.model || 'gpt-5.1-chat-latest'; 436 442 437 443 // Check if streaming is enabled AND supported for this model … … 510 516 const pageContext = getPageContext(); 511 517 518 // Get instance for session start timestamp (used when persistence is OFF) 519 var instance = MxChatInstances.get(botId); 520 512 521 // Prepare AJAX data 513 522 const ajaxData = { … … 518 527 current_page_url: window.location.href, 519 528 current_page_title: document.title, 520 bot_id: botId 529 bot_id: botId, 530 // Pass session start timestamp so AI context matches what user sees 531 session_start_timestamp: instance.sessionStartTimestamp || 0 521 532 }; 522 533 … … 590 601 scrollToBottom(botId); 591 602 // Determine whether to use streaming 592 const currentModel = mxchatChat.model || 'gpt- 4o';603 const currentModel = mxchatChat.model || 'gpt-5.1-chat-latest'; 593 604 if (shouldUseStreaming(currentModel)) { 594 605 callMxChatStream(originalMessage, function(response) { … … 736 747 getElement(botId, 'mxchat-chatbot-wrapper').find('.mxchat-input-holder textarea').data('pending-message', message); 737 748 738 const currentModel = mxchatChat.model || 'gpt- 4o';749 const currentModel = mxchatChat.model || 'gpt-5.1-chat-latest'; 739 750 if (!isStreamingSupported(currentModel)) { 740 751 callMxChat(message, callback, botId); … … 744 755 // Get page context if contextual awareness is enabled 745 756 const pageContext = getPageContext(); 757 758 // Get instance for session start timestamp (used when persistence is OFF) 759 var instance = MxChatInstances.get(botId); 746 760 747 761 const formData = new FormData(); … … 753 767 formData.append('current_page_title', document.title); 754 768 formData.append('bot_id', botId); 755 769 // Pass session start timestamp so AI context matches what user sees 770 formData.append('session_start_timestamp', instance.sessionStartTimestamp || 0); 771 756 772 // Add page context if available 757 773 if (pageContext) { … … 1004 1020 scrollToBottom(botId); 1005 1021 // Determine whether to use streaming 1006 const currentModel = mxchatChat.model || 'gpt- 4o';1022 const currentModel = mxchatChat.model || 'gpt-5.1-chat-latest'; 1007 1023 if (shouldUseStreaming(currentModel)) { 1008 1024 callMxChatStream(originalMessage, callback, botId); … … 2702 2718 } 2703 2719 2720 /** 2721 * Replace {visitor_name} placeholder in intro message with actual visitor name 2722 * @param {string} botId - The bot instance ID 2723 * @param {string} visitorName - The visitor's name to insert 2724 */ 2725 function replaceVisitorNamePlaceholder(botId, visitorName) { 2726 var chatBox = getElementDOM(botId, 'chat-box'); 2727 if (!chatBox) return; 2728 2729 // Find the first bot message (intro message) 2730 var introMessage = chatBox.querySelector('.bot-message'); 2731 if (!introMessage) return; 2732 2733 var messageContent = introMessage.querySelector('div[dir="auto"]'); 2734 if (!messageContent) return; 2735 2736 var html = messageContent.innerHTML; 2737 2738 // Replace {visitor_name} placeholder (case-insensitive) 2739 if (visitorName && visitorName.trim()) { 2740 // Escape HTML to prevent XSS 2741 var safeName = $('<div>').text(visitorName.trim()).html(); 2742 html = html.replace(/\{visitor_name\}/gi, safeName); 2743 } else { 2744 // Remove placeholder and clean up spacing if no name provided 2745 html = html.replace(/\{visitor_name\}/gi, ''); 2746 // Clean up any double spaces that might result 2747 html = html.replace(/\s{2,}/g, ' ').trim(); 2748 } 2749 2750 messageContent.innerHTML = html; 2751 } 2752 2704 2753 function setEmailSubmissionState(botId, loading) { 2705 2754 var submitButton = getElementDOM(botId, 'email-submit-button'); … … 2887 2936 if (data.success) { 2888 2937 showChatContainerForBot(botId); 2938 2939 // Replace {visitor_name} placeholder in intro message with actual name 2940 if (userName) { 2941 replaceVisitorNamePlaceholder(botId, userName); 2942 } else { 2943 // Remove placeholder if no name provided 2944 replaceVisitorNamePlaceholder(botId, ''); 2945 } 2889 2946 2890 2947 if (data.message && typeof appendMessage === 'function') { -
mxchat-basic/trunk/js/mxchat-admin.js
r3448781 r3459102 410 410 $autosaveSections.find('input[type="range"]').on('input', function() { 411 411 const value = $(this).val(); 412 $('#threshold_value').text(value); 412 const $slider = $(this); 413 const sliderId = $slider.attr('id'); 414 // Find the corresponding value display span (convention: id_value) 415 const $valueSpan = $('#' + sliderId + '_value'); 416 if ($valueSpan.length) { 417 $valueSpan.text(value); 418 } else { 419 // Fallback for similarity_threshold which uses threshold_value 420 $('#threshold_value').text(value); 421 } 413 422 }); 414 423 … … 1008 1017 openai: [ 1009 1018 { value: 'gpt-5.2', label: 'GPT-5.2', description: 'Best general-purpose & agentic model with fast responses' }, 1019 { value: 'gpt-5.1-chat-latest', label: 'GPT-5.1 Chat Latest', description: 'Recommended for most use cases' }, 1010 1020 { value: 'gpt-5.1-2025-11-13', label: 'GPT-5.1', description: 'Flagship for coding & agentic tasks with low reasoning (400K context)' }, 1011 1021 { value: 'gpt-5', label: 'GPT-5', description: 'Flagship for coding, reasoning, and agentic tasks across domains' }, 1012 { value: 'gpt-5-mini', label: 'GPT-5 Mini', description: 'Fast er, more cost-efficient for well-defined tasks and precise prompts' },1022 { value: 'gpt-5-mini', label: 'GPT-5 Mini', description: 'Fast and lightweight' }, 1013 1023 { value: 'gpt-5-nano', label: 'GPT-5 Nano', description: 'Fastest and cheapest; ideal for summarization and classification' }, 1014 { value: 'gpt-4.1-2025-04-14', label: 'GPT-4.1', description: 'Flagship model for complex tasks' },1015 { value: 'gpt-4o', label: 'GPT-4o', description: 'Recommended for most use cases' },1016 { value: 'gpt-4o-mini', label: 'GPT-4o Mini', description: 'Fast and lightweight' },1017 { value: 'gpt-4-turbo', label: 'GPT-4 Turbo', description: 'High-performance model' },1018 { value: 'gpt-4', label: 'GPT-4', description: 'High intelligence model' },1019 { value: 'gpt-3.5-turbo', label: 'GPT-3.5 Turbo', description: 'Affordable and fast' },1020 1024 ], 1021 1025 claude: [ 1026 { value: 'claude-opus-4-6', label: 'Claude Opus 4.6', description: 'Most capable Claude model - recommended' }, 1027 { value: 'claude-opus-4-5', label: 'Claude Opus 4.5', description: 'Highly capable for complex tasks' }, 1022 1028 { value: 'claude-sonnet-4-5-20250929', label: 'Claude Sonnet 4.5', description: 'Best for complex agents and coding' }, 1023 1029 { value: 'claude-opus-4-1-20250805', label: 'Claude Opus 4.1', description: 'Exceptional for specialized complex tasks' }, 1024 1030 { value: 'claude-haiku-4-5-20251001', label: 'Claude Haiku 4.5', description: 'Fastest and most intelligent Haiku' }, 1025 { value: 'claude-opus-4-20250514', label: 'Claude 4 Opus', description: ' Most capable Claude model' },1031 { value: 'claude-opus-4-20250514', label: 'Claude 4 Opus', description: 'Complex tasks' }, 1026 1032 { value: 'claude-sonnet-4-20250514', label: 'Claude 4 Sonnet', description: 'High performance' }, 1027 { value: 'claude-3-7-sonnet-20250219', label: 'Claude 3.7 Sonnet', description: 'High intelligence' },1028 { value: 'claude-3-opus-20240229', label: 'Claude 3 Opus', description: 'Highly complex tasks' },1029 { value: 'claude-3-sonnet-20240229', label: 'Claude 3 Sonnet', description: 'Balanced performance' },1030 { value: 'claude-3-haiku-20240307', label: 'Claude 3 Haiku', description: 'Fastest Claude model' },1031 1033 ], 1032 1034 xai: [ -
mxchat-basic/trunk/mxchat-basic.php
r3448781 r3459102 4 4 * Plugin URI: https://mxchat.ai/ 5 5 * Description: AI chatbot for WordPress with OpenAI, Claude, xAI, DeepSeek, live agent, PDF uploads, WooCommerce, and training on website data. 6 * Version: 3.0. 56 * Version: 3.0.6 7 7 * Author: MxChat 8 8 * Author URI: https://mxchat.ai … … 479 479 * Migrate deprecated AI models to their replacements 480 480 * Version 2.5.1: Migrate Claude 3.5 Sonnet (deprecated) to Claude 3.7 Sonnet 481 * Version 3.0.55: Migrate GPT-4 series models (deprecated 2026-02-17) to GPT-5 series 481 482 */ 482 483 function mxchat_migrate_deprecated_models() { 483 484 $options = get_option('mxchat_options', array()); 484 485 // Check if model is set and is the deprecated Claude 3.5 Sonnet 486 if (isset($options['model']) && $options['model'] === 'claude-3-5-sonnet-20241022') { 487 // Update to Claude 3.7 Sonnet (the replacement model) 488 $options['model'] = 'claude-3-7-sonnet-20250219'; 485 $migrated = false; 486 $migration_message = ''; 487 488 if (!isset($options['model'])) { 489 return; 490 } 491 492 $current_model = $options['model']; 493 494 // Migrate deprecated Claude models to Claude Opus 4.6 (recommended replacement per Anthropic) 495 $deprecated_claude_models = array( 496 'claude-3-5-sonnet-20240620', // Retired Oct 28, 2025 497 'claude-3-5-sonnet-20241022', // Retired Oct 28, 2025 498 'claude-3-7-sonnet-20250219', // Retiring Feb 19, 2026 499 'claude-3-opus-20240229', // Retired Jan 5, 2026 500 'claude-3-sonnet-20240229', // Legacy 501 'claude-3-haiku-20240307', // Legacy 502 ); 503 if (in_array($current_model, $deprecated_claude_models, true)) { 504 $options['model'] = 'claude-opus-4-6'; 505 $migrated = true; 506 $migration_message = sprintf( 507 __('Your chatbot model has been automatically updated from %s to Claude Opus 4.6 due to Anthropic deprecating older Claude models.', 'mxchat'), 508 $current_model 509 ); 510 } 511 512 // Migrate deprecated Claude Haiku 3.5 to Claude Haiku 4.5 513 if ($current_model === 'claude-3-5-haiku-20241022') { 514 $options['model'] = 'claude-haiku-4-5-20251001'; 515 $migrated = true; 516 $migration_message = __('Your chatbot model has been automatically updated from Claude Haiku 3.5 to Claude Haiku 4.5 due to Anthropic deprecating the older model.', 'mxchat'); 517 } 518 519 // Migrate deprecated GPT-4 series and GPT-3.5 Turbo to GPT-5.1 Chat Latest 520 if (in_array($current_model, array('gpt-4o', 'gpt-4.1-2025-04-14', 'gpt-4-turbo', 'gpt-4', 'gpt-3.5-turbo'), true)) { 521 $options['model'] = 'gpt-5.1-chat-latest'; 522 $migrated = true; 523 $migration_message = sprintf( 524 __('Your chatbot model has been automatically updated from %s to GPT-5.1 Chat Latest due to OpenAI deprecating older models.', 'mxchat'), 525 $current_model 526 ); 527 } 528 529 // Migrate deprecated GPT-4o Mini and GPT-4.1 Mini to GPT-5 Mini 530 if (in_array($current_model, array('gpt-4o-mini', 'gpt-4.1-mini'), true)) { 531 $options['model'] = 'gpt-5-mini'; 532 $migrated = true; 533 $migration_message = sprintf( 534 __('Your chatbot model has been automatically updated from %s to GPT-5 Mini due to OpenAI deprecating GPT-4 series models.', 'mxchat'), 535 $current_model 536 ); 537 } 538 539 if ($migrated) { 489 540 update_option('mxchat_options', $options); 490 491 // Set a flag to show admin notice492 541 update_option('mxchat_model_migrated_notice', true); 493 494 //error_log('MxChat: Migrated deprecated Claude 3.5 Sonnet to Claude 3.7 Sonnet'); 542 update_option('mxchat_model_migration_message', $migration_message); 495 543 } 496 544 } … … 501 549 function mxchat_show_migration_notice() { 502 550 if (get_option('mxchat_model_migrated_notice')) { 551 $migration_message = get_option('mxchat_model_migration_message', __('Your chatbot model has been automatically updated due to a model deprecation.', 'mxchat')); 503 552 ?> 504 553 <div class="notice notice-info is-dismissible"> 505 554 <p> 506 555 <strong><?php esc_html_e('MxChat Model Updated', 'mxchat'); ?></strong><br> 507 <?php e sc_html_e('Your chatbot model has been automatically updated from Claude 3.5 Sonnet to Claude 3.7 Sonnet due to the deprecation of the previous model by Anthropic. Claude 3.7 Sonnet offers improved performance and capabilities.', 'mxchat'); ?>556 <?php echo esc_html($migration_message); ?> 508 557 </p> 509 558 </div> 510 559 <?php 511 560 delete_option('mxchat_model_migrated_notice'); 561 delete_option('mxchat_model_migration_message'); 512 562 } 513 563 } … … 773 823 } 774 824 825 // 3.0.6: Migrate deprecated OpenAI and Claude models 826 if (version_compare($current_version, '3.0.6', '<')) { 827 mxchat_migrate_deprecated_models(); 828 } 829 775 830 // Run full activation to ensure everything is up to date 776 831 mxchat_activate(); -
mxchat-basic/trunk/readme.txt
r3448781 r3459102 6 6 Tested up to: 6.9 7 7 Requires PHP: 7.2 8 Stable tag: 3.0. 58 Stable tag: 3.0.6 9 9 License: GPLv2 or later 10 10 License URI: https://www.gnu.org/licenses/gpl-2.0.html … … 38 38 👉 [Visit our website to view all add-ons](https://mxchat.ai) 39 39 40 ## 🔥 What's New in Version 3.0.5 41 42 🔧 **Gemini Embedding Model Update** 43 - Fixed: Updated Gemini embedding model from deprecated `gemini-embedding-exp-03-07` to stable `gemini-embedding-001` 44 45 🐛 **Bug Fixes** 46 - Fixed: Notification settings not saving on new installations 47 - Fixed: Save indicators not visible on settings fields (API keys, Slack, Telegram, Loops, Brave Search) 48 49 ✨ **Improvements** 50 - Added: Warning notice for WordPress database users recommending Pinecone for large knowledge bases (500+ entries) 51 - Improved: Minor admin UI updates for better user experience 40 ## 🔥 What's New in Version 3.0.6 41 42 - New: RAG Sources Limit slider - control how many knowledge base sources (3-10) are included in AI responses 43 - New: {visitor_name} placeholder support in Intro Message and AI Behavior settings for personalized greetings 44 - New: Added Claude Opus 4.6 and Claude Opus 4.5 models 45 - Fixed: Chat persistence OFF now correctly starts fresh AI context on page reload 46 - Deprecated: Removed all GPT-4 series, GPT-3.5 Turbo, and Claude 3.x models per provider deprecations 47 - Updated: Users on deprecated models auto-migrated to GPT-5.1/GPT-5 Mini or Claude Opus 4.6/Haiku 4.5 52 48 53 49 ## Core Features That Set MxChat Apart … … 69 65 70 66 **OpenRouter**: 100+ models from multiple providers with a single API key – including OpenAI, Anthropic, Google, Meta, Mistral, and more! 71 **OpenAI**: 72 GPT-5.2, GPT-5 , GPT-5-mini, GPT-5-nano, GPT-5.1, GPT-4.1, GPT-4o, GPT-4o-mini, GPT-4-turbo, GPT-4, GPT-3.5-turbo73 **Anthropic Claude**: 74 Claude Sonnet 4.5, Claude Opus 4.1, Claude Haiku 4.5, Claude 4 Sonnet, Claude 4 Opus, Claude 3.7 Sonnet, Claude 3.5 Sonnet (deprecated), Claude 3Opus67 **OpenAI**: 68 GPT-5.2, GPT-5.1 Chat Latest, GPT-5.1, GPT-5, GPT-5-mini, GPT-5-nano 69 **Anthropic Claude**: 70 Claude Opus 4.6, Claude Opus 4.5, Claude Sonnet 4.5, Claude Opus 4.1, Claude Haiku 4.5, Claude 4 Sonnet, Claude 4 Opus 75 71 **X.AI**: 76 72 Grok-4, Grok-3, Grok-3 Fast, Grok-3 Mini, Grok-3 Mini Fast, Grok-2, **Grok 4.1 Fast (Reasoning)**, **Grok 4.1 Fast (Non-Reasoning)** … … 164 160 = What AI models does MxChat support? = 165 161 166 MxChat supports 100+ AI models including OpenAI GPT-5 , GPT-5 Mini, GPT-4.1, GPT-4o, GPT-4 Turbo, Anthropic Claude Sonnet 4.5, Claude Opus 4, Claude Haiku, Google Gemini 2.0 Flash, Gemini 1.5 Pro, xAI Grok 4, Grok 3, DeepSeek Chat, and many more. With OpenRouter integration, you get access to models from OpenAI, Anthropic, Google, Meta, Mistral, and other providers with a single API key.162 MxChat supports 100+ AI models including OpenAI GPT-5.2, GPT-5.1, GPT-5, GPT-5 Mini, Anthropic Claude Opus 4.6, Claude Opus 4.5, Claude Sonnet 4.5, Claude Haiku 4.5, Google Gemini 2.0 Flash, Gemini 1.5 Pro, xAI Grok 4, Grok 3, DeepSeek Chat, and many more. With OpenRouter integration, you get access to models from OpenAI, Anthropic, Google, Meta, Mistral, and other providers with a single API key. 167 163 168 164 = How do I get API keys for the AI chatbot? = … … 266 262 267 263 == Changelog == 264 265 = 3.0.6 - February 11, 2026 = 266 - New: RAG Sources Limit slider - control how many knowledge base sources (3-10) are included in AI responses 267 - New: {visitor_name} placeholder support in Intro Message and AI Behavior settings for personalized greetings 268 - New: Added Claude Opus 4.6 and Claude Opus 4.5 models 269 - Fixed: Chat persistence OFF now correctly starts fresh AI context on page reload (previously AI retained full history) 270 - Deprecated: Removed all GPT-4 series and GPT-3.5 Turbo from model selection (OpenAI deprecation) 271 - Deprecated: Removed Claude 3.x series models (3.7 Sonnet, 3.5 Sonnet, 3 Opus, 3 Sonnet, 3 Haiku) per Anthropic deprecation 272 - Updated: Users on deprecated OpenAI models auto-migrated to GPT-5.1 Chat Latest (or GPT-5 Mini for mini models) 273 - Updated: Users on deprecated Claude models auto-migrated to Claude Opus 4.6 (or Claude Haiku 4.5 for Haiku users) 268 274 269 275 = 3.0.5 - January 28, 2026 = … … 790 796 == Upgrade Notice == 791 797 792 = 3.0. 5 - January 28, 2026 =793 Minor update: Updated Gemini embedding model to stable version, fixed notification settings on new installs, improved save indicators visibility, and added WordPress database warning for large knowledge bases.798 = 3.0.6 - February 11, 2026 = 799 New: RAG Sources Limit slider, Claude Opus 4.6/4.5 models, {visitor_name} placeholder support. Deprecated OpenAI & Claude models auto-migrated. 794 800 795 801 == License & Warranty ==
Note: See TracChangeset
for help on using the changeset viewer.