PluginProbe
MxChat – AI Chatbot & Content Generation for WordPress / 3.1.1
MxChat – AI Chatbot & Content Generation for WordPress v3.1.1
3.2.21 3.2.20 3.2.19 3.2.18 3.2.17 3.2.16 3.2.15 3.2.14 3.2.12 3.2.13 3.2.11 3.2.10 3.2.9 3.2.8 3.2.7 3.2.6 3.2.5 3.2.4 3.2.3 3.2.2 3.2.1 2.0.3 2.0.4 2.0.5 2.0.6 All 152 releases
← All changes | js/mxchat-admin.js +28 -113 3.2.33.1.1 View file →
@@ -1027,12 +1027,8 @@
1027 1027 { value: 'gemini-1.5-pro', label: 'Gemini 1.5 Pro', description: 'Deprecated September 2025' },
1028 1028 { value: 'gemini-1.5-flash', label: 'Gemini 1.5 Flash', description: 'Deprecated September 2025' },
1029 1029 ],
1030 1030 openai: [
1031 - { value: 'gpt-5.4', label: 'GPT-5.4', description: 'Flagship reasoning and coding model' },
1032 - { value: 'gpt-5.4-mini', label: 'GPT-5.4 Mini', description: 'Fast and affordable with 400K context' },
1033 - { value: 'gpt-5.4-nano', label: 'GPT-5.4 Nano', description: 'Fastest and cheapest for lightweight tasks' },
1034 - { value: 'gpt-5.3-chat-latest', label: 'GPT-5.3 Chat', description: 'Optimized for natural conversations with reduced hallucinations' },
1035 1031 { value: 'gpt-5.2', label: 'GPT-5.2', description: 'Best general-purpose & agentic model with fast responses' },
1036 1032 { value: 'gpt-5.1-chat-latest', label: 'GPT-5.1 Chat Latest', description: 'Recommended for most use cases' },
1037 1033 { value: 'gpt-5.1-2025-11-13', label: 'GPT-5.1', description: 'Flagship for coding & agentic tasks with low reasoning (400K context)' },
1038 1034 { value: 'gpt-5', label: 'GPT-5', description: 'Flagship for coding, reasoning, and agentic tasks across domains' },
@@ -1617,71 +1613,8 @@
1617 1613 });
1618 1614
1619 1615 }
1620 1616
1621 -// 3.2.3: Confirmation dialog shown when the user attempts to switch embedding
1622 -// models after they've already embedded content with a different model. Mixing
1623 -// embeddings from two models silently breaks similarity matching.
1624 -function showEmbeddingSwitchWarning(data, newValue, onChoice) {
1625 - $('#mxchat_embedding_switch_warning').remove();
1626 -
1627 - const dimsBlock = data.dims_differ ? `
1628 - <div class="mxchat-embed-warn-dims">
1629 - <strong>Dimension mismatch:</strong>
1630 - Existing vectors are ${data.active_dims}-dimensional, but ${data.new_label}
1631 - produces ${data.new_dims}-dimensional vectors.
1632 - If you use Pinecone, your index will reject queries entirely until you re-embed.
1633 - </div>` : '';
1634 -
1635 - const $modal = $(`
1636 - <div id="mxchat_embedding_switch_warning" class="mxchat-embed-warn-overlay">
1637 - <div class="mxchat-embed-warn-dialog">
1638 - <div class="mxchat-embed-warn-header">
1639 - <span class="mxchat-embed-warn-icon">⚠️</span>
1640 - <h3>Switching embedding models will break similarity matching</h3>
1641 - </div>
1642 - <div class="mxchat-embed-warn-body">
1643 - <p>
1644 - Your knowledge base and actions are currently embedded with
1645 - <code>${data.active_label}</code>. Switching to
1646 - <code>${data.new_label}</code> means new queries are embedded with
1647 - a different model than the stored vectors — the chatbot will return
1648 - inaccurate results or fail to match anything.
1649 - </p>
1650 - ${dimsBlock}
1651 - <p><strong>To switch safely:</strong></p>
1652 - <ol>
1653 - <li>Go to <em>Knowledge Base</em> and delete all existing entries.</li>
1654 - <li>Go to <em>Actions</em> and delete all existing actions.</li>
1655 - <li>Come back here, switch the model, then re-import your content and re-add your actions.</li>
1656 - </ol>
1657 - </div>
1658 - <div class="mxchat-embed-warn-footer">
1659 - <button type="button" class="button button-secondary" id="mxchat_embed_warn_cancel">Cancel — keep ${data.active_label}</button>
1660 - <button type="button" class="button button-primary mxchat-embed-warn-danger" id="mxchat_embed_warn_continue">Switch anyway (I'll handle it)</button>
1661 - </div>
1662 - </div>
1663 - </div>
1664 - `);
1665 -
1666 - $('body').append($modal);
1667 -
1668 - let resolved = false;
1669 - function resolve(confirmed) {
1670 - if (resolved) return;
1671 - resolved = true;
1672 - $modal.remove();
1673 - if (typeof onChoice === 'function') onChoice(confirmed);
1674 - }
1675 -
1676 - // Click on the overlay background dismisses (cancel)
1677 - $modal.on('click', function(e) {
1678 - if (e.target === $modal[0]) resolve(false);
1679 - });
1680 - $modal.find('#mxchat_embed_warn_cancel').on('click', function() { resolve(false); });
1681 - $modal.find('#mxchat_embed_warn_continue').on('click', function() { resolve(true); });
1682 -}
1683 -
1684 1617 // Embedding model selector - completely separate from chat model selector
1685 1618 function setupMxChatEmbeddingModelSelector() {
1686 1619 const $embeddingModelSelect = $('#embedding_model');
1687 1620
@@ -1862,53 +1795,25 @@
1862 1795 const activeCategory = $('.mxchat-embedding-model-selector-categories .mxchat-embedding-model-category-btn.active').data('category');
1863 1796 populateEmbeddingModelsGrid(searchTerm, activeCategory);
1864 1797 });
1865 1798
1866 - // 3.2.3: Commit a model change — same as the original click handler, just
1867 - // factored out so it can be invoked from both the safe path and the
1868 - // post-confirmation path.
1869 - function commitEmbeddingModelChange(modelValue) {
1799 + // Use a direct selector to avoid conflicts with other card elements
1800 + $(document).on('click.embeddingModelSelector', '.mxchat-embedding-model-selector-grid .mxchat-embedding-model-selector-card', function(e) {
1801 + e.stopPropagation(); // Prevent event bubbling
1802 + const modelValue = $(this).data('value');
1803 +
1804 + // Important: Only update this specific select element
1870 1805 $embeddingModelSelect.val(modelValue);
1806 +
1807 + // Manually trigger change only on this element
1871 1808 const changeEvent = new Event('change', { bubbles: true });
1872 1809 $embeddingModelSelect[0].dispatchEvent(changeEvent);
1810 +
1811 + // Update button text
1873 1812 updateButtonText();
1813 +
1814 + // Hide modal
1874 1815 $('#' + embeddingModalId).hide();
1875 - }
1876 -
1877 - // Use a direct selector to avoid conflicts with other card elements
1878 - $(document).on('click.embeddingModelSelector', '.mxchat-embedding-model-selector-grid .mxchat-embedding-model-selector-card', function(e) {
1879 - e.stopPropagation(); // Prevent event bubbling
1880 - const modelValue = $(this).data('value');
1881 - const previousValue = $embeddingModelSelect.val();
1882 -
1883 - // No-op if the user clicked the already-selected card
1884 - if (modelValue === previousValue) {
1885 - $('#' + embeddingModalId).hide();
1886 - return;
1887 - }
1888 -
1889 - // 3.2.3: Preflight — if the user has content embedded with a different
1890 - // model, surface a confirmation dialog before committing the switch.
1891 - $.post(ajaxurl, {
1892 - action: 'mxchat_check_embedding_switch',
1893 - security: (typeof mxchatAdmin !== 'undefined' ? mxchatAdmin.nonce : ''),
1894 - new_model: modelValue
1895 - }).done(function(resp) {
1896 - if (resp && resp.success && resp.data && resp.data.is_mismatch) {
1897 - showEmbeddingSwitchWarning(resp.data, modelValue, function(confirmed) {
1898 - if (confirmed) {
1899 - commitEmbeddingModelChange(modelValue);
1900 - }
1901 - });
1902 - } else {
1903 - commitEmbeddingModelChange(modelValue);
1904 - }
1905 - }).fail(function() {
1906 - // If preflight fails, fall back to the original behavior so a network
1907 - // hiccup doesn't block legitimate model switches.
1908 - commitEmbeddingModelChange(modelValue);
1909 - });
1910 - return;
1911 1816 });
1912 1817
1913 1818 // Close modal when clicking outside - use namespaced events
1914 1819 $(window).on('click.embeddingModelSelector', function(event) {
@@ -2206,14 +2111,24 @@
2206 2111 const actionLabel = this.dataset.label;
2207 2112 const actionIcon = this.querySelector('.dashicons').getAttribute('class').replace('dashicons dashicons-', '');
2208 2113 const actionDescription = this.querySelector('p').textContent;
2209 2114
2210 - // Check if this is a promotional card (add-on not installed)
2211 - const isPromo = this.dataset.promo === 'true';
2212 -
2213 - if (isPromo || (addonName && !isInstalled)) {
2214 - // Add-on required but not installed — show informational notice
2215 - const addonDisplayName = this.querySelector('.mxchat-addon-info')?.textContent?.replace('Requires ', '').replace('— Get Add-on', '').trim() || addonName + ' Add-on';
2115 + // Pro check using the proper detection method
2116 + const proIsActivated = typeof mxchatAdmin !== 'undefined' &&
2117 + (mxchatAdmin.is_activated === '1' ||
2118 + mxchatAdmin.is_activated === 'true' ||
2119 + mxchatAdmin.is_activated === true);
2120 +
2121 + // Handle different states
2122 + if (isPro && !proIsActivated) {
2123 + // Pro feature but no Pro license
2124 + showProFeatureNotice();
2125 + return;
2126 + }
2127 +
2128 + if (addonName && !isInstalled) {
2129 + // Add-on required but not installed
2130 + const addonDisplayName = this.querySelector('.mxchat-addon-info')?.textContent?.replace('Requires ', '') || addonName + ' Add-on';
2216 2131 showAddonRequiredNotice(addonDisplayName);
2217 2132 return;
2218 2133 }
2219 2134