PluginProbe
MxChat – AI Chatbot & Content Generation for WordPress / 3.2.0
MxChat – AI Chatbot & Content Generation for WordPress v3.2.0
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/test-panel.js +3 -43 3.2.213.2.0 View file →
@@ -274,19 +274,8 @@
274 274 // NEW: Log approved URLs count
275 275 if (testingData.approved_urls && testingData.approved_urls.length > 0) {
276 276 this.log(`🔗 Approved URLs for citations: ${testingData.approved_urls.length}`);
277 277 }
278 -
279 - // 58f8b4: URL-guard outcome — stripping used to be completely silent,
280 - // which is why fabricated/stripped links were invisible from this panel.
281 - if (testingData.url_validation) {
282 - const uv = testingData.url_validation;
283 - if (uv.removed_count > 0) {
284 - this.log(`🚫 URL guard stripped ${uv.removed_count} unapproved link${uv.removed_count !== 1 ? 's' : ''}: ${(uv.removed_urls || []).join(', ')}`);
285 - } else if (uv.checked > 0) {
286 - this.log(`🔗 URL guard: all ${uv.checked} link${uv.checked !== 1 ? 's' : ''} in the answer approved (${uv.strict ? 'strict' : 'lenient'} mode)`);
287 - }
288 - }
289 278
290 279 // Show summary in debug console
291 280 if (testingData.top_matches && testingData.top_matches.length > 0) {
292 281 const aboveThreshold = testingData.top_matches.filter(match => match.above_threshold).length;
@@ -410,12 +399,8 @@
410 399 scoresEl.innerHTML = '<div class="no-data-message">No similarity data available</div>';
411 400 return;
412 401 }
413 402
414 - // Hybrid keyword boost (38ffa1): rows carry matched_via + fused_rank
415 - // when hybrid retrieval was on for this message.
416 - const hybridOn = topMatches.some(m => m.matched_via);
417 -
418 403 // Group matches by source URL
419 404 const groupedByUrl = {};
420 405 topMatches.forEach((match) => {
421 406 const url = match.source_display || 'Unknown';
@@ -426,11 +411,9 @@
426 411 bestScore: 0,
427 412 usedForContext: false,
428 413 totalChunks: match.total_chunks || 1,
429 414 matchedChunks: [],
430 - isChunked: match.is_chunk || false,
431 - bestFusedRank: Infinity,
432 - viaSet: {}
415 + isChunked: match.is_chunk || false
433 416 };
434 417 }
435 418
436 419 // Track best score
@@ -442,15 +425,8 @@
442 425 if (match.used_for_context) {
443 426 groupedByUrl[url].usedForContext = true;
444 427 }
445 428
446 - if (match.fused_rank && match.fused_rank < groupedByUrl[url].bestFusedRank) {
447 - groupedByUrl[url].bestFusedRank = match.fused_rank;
448 - }
449 - if (match.matched_via) {
450 - groupedByUrl[url].viaSet[match.matched_via] = true;
451 - }
452 -
453 429 // Add chunk info
454 430 groupedByUrl[url].matchedChunks.push({
455 431 chunkIndex: match.chunk_index,
456 432 score: match.similarity_percentage,
@@ -458,15 +434,10 @@
458 434 aboveThreshold: match.above_threshold
459 435 });
460 436 });
461 437
462 - // Convert to array: fused-rank order when hybrid is on, best cosine otherwise
463 - const urlGroups = Object.values(groupedByUrl).sort((a, b) => {
464 - if (hybridOn && a.bestFusedRank !== b.bestFusedRank) {
465 - return a.bestFusedRank - b.bestFusedRank;
466 - }
467 - return b.bestScore - a.bestScore;
468 - });
438 + // Convert to array and sort by best score
439 + const urlGroups = Object.values(groupedByUrl).sort((a, b) => b.bestScore - a.bestScore);
469 440
470 441 // Use backend counts if available, otherwise fall back to frontend calculation
471 442 const usedUrlCount = sourcesUsed > 0 ? sourcesUsed : urlGroups.filter(g => g.usedForContext).length;
472 443 const chunksInfo = totalChunksUsed > 0 ? `${totalChunksUsed} chunks sent to AI` : `${topMatches.length} chunk matches`;
@@ -493,18 +464,8 @@
493 464 const expandToggle = hasMultipleChunks
494 465 ? `<span class="chunk-expand-toggle" data-group="${groupIndex}">▶ Show chunks</span>`
495 466 : '';
496 467
497 - let viaChip = '';
498 - if (hybridOn) {
499 - const vias = Object.keys(group.viaSet);
500 - if (vias.length) {
501 - const viaLabel = (vias.length > 1 || vias[0] === 'both') ? 'Both'
502 - : (vias[0] === 'keyword' ? 'Keyword' : 'Vector');
503 - viaChip = `<span class="mxch-rag-via-chip mxch-rag-via-${viaLabel.toLowerCase()}">${viaLabel}</span>`;
504 - }
505 - }
506 -
507 468 html += `
508 469 <div class="match-card ${cardClass}">
509 470 <div class="match-header">
510 471 <div class="match-title">
@@ -509,9 +470,8 @@
509 470 <div class="match-header">
510 471 <div class="match-title">
511 472 <span class="status-icon">${statusIcon}</span>
512 473 <span class="similarity-score">${group.bestScore}%</span>
513 - ${viaChip}
514 474 ${chunkSummary}
515 475 </div>
516 476 <span class="context-label">${contextLabel}</span>
517 477 </div>