| @@ -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> |