@absolutejs/absolute 0.19.0-beta.611 → 0.19.0-beta.613

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1714,6 +1714,10 @@ var buildRAGSectionRetrievalDiagnostics = (sources, trace) => {
1714
1714
  const vectorHits = channels.includes("vector") ? 1 : 0;
1715
1715
  const lexicalHits = channels.includes("lexical") ? 1 : 0;
1716
1716
  const hybridHits = isHybrid ? 1 : 0;
1717
+ const queryOrigin = source.metadata?.retrievalQueryOrigin;
1718
+ const primaryHits = queryOrigin === "primary" ? 1 : 0;
1719
+ const transformedHits = queryOrigin === "transformed" ? 1 : 0;
1720
+ const variantHits = queryOrigin === "variant" ? 1 : 0;
1717
1721
  if (!existing) {
1718
1722
  sections.set(key, {
1719
1723
  bestScore: source.score,
@@ -1724,10 +1728,13 @@ var buildRAGSectionRetrievalDiagnostics = (sources, trace) => {
1724
1728
  lexicalHits,
1725
1729
  parentLabel,
1726
1730
  path,
1731
+ primaryHits,
1727
1732
  sourceSet: new Set(source.source ? [source.source] : []),
1728
1733
  topChunkId: source.chunkId,
1729
1734
  topSource: source.source,
1730
1735
  totalScore: source.score,
1736
+ transformedHits,
1737
+ variantHits,
1731
1738
  vectorHits
1732
1739
  });
1733
1740
  continue;
@@ -1740,6 +1747,9 @@ var buildRAGSectionRetrievalDiagnostics = (sources, trace) => {
1740
1747
  existing.vectorHits += vectorHits;
1741
1748
  existing.lexicalHits += lexicalHits;
1742
1749
  existing.hybridHits += hybridHits;
1750
+ existing.primaryHits += primaryHits;
1751
+ existing.transformedHits += transformedHits;
1752
+ existing.variantHits += variantHits;
1743
1753
  if (source.score > existing.bestScore) {
1744
1754
  existing.bestScore = source.score;
1745
1755
  existing.topChunkId = source.chunkId;
@@ -1748,6 +1758,9 @@ var buildRAGSectionRetrievalDiagnostics = (sources, trace) => {
1748
1758
  }
1749
1759
  const diagnostics = [...sections.values()];
1750
1760
  const strongestBestHit = diagnostics.reduce((highest, section) => Math.max(highest, section.bestScore), 0);
1761
+ const parentLabelByKey = new Map(diagnostics.map((section) => [section.key, section.parentLabel]));
1762
+ const stageSectionCounts = new Map((trace?.steps ?? []).filter((step) => Array.isArray(step.sectionCounts) && step.sectionCounts.length > 0).map((step) => [step.stage, step.sectionCounts ?? []]));
1763
+ const stageSectionScores = new Map((trace?.steps ?? []).filter((step) => Array.isArray(step.sectionScores) && step.sectionScores.length > 0).map((step) => [step.stage, step.sectionScores ?? []]));
1751
1764
  return diagnostics.map((section) => {
1752
1765
  const siblingPool = diagnostics.filter((entry) => entry.parentLabel === section.parentLabel);
1753
1766
  const siblings = siblingPool.filter((entry) => entry.key !== section.key);
@@ -1768,8 +1781,103 @@ var buildRAGSectionRetrievalDiagnostics = (sources, trace) => {
1768
1781
  count: step.sectionCounts?.find((entry) => entry.key === section.key)?.count ?? 0,
1769
1782
  stage: step.stage
1770
1783
  })).filter((entry) => entry.count > 0) ?? [];
1784
+ const stageWeights = stageCounts.map((entry) => {
1785
+ const previousStageEntry = stageCounts[stageCounts.findIndex((candidate) => candidate.stage === entry.stage) - 1];
1786
+ const stageEntries = stageSectionCounts.get(entry.stage)?.filter((candidate) => candidate.count > 0) ?? [];
1787
+ const stageScoreEntries = stageSectionScores.get(entry.stage)?.filter((candidate) => candidate.totalScore > 0) ?? [];
1788
+ const stageTotal = stageEntries.reduce((sum, candidate) => sum + candidate.count, 0);
1789
+ const stageScoreTotal = stageScoreEntries.reduce((sum, candidate) => sum + candidate.totalScore, 0);
1790
+ const siblingStageEntries = stageEntries.filter((candidate) => candidate.key !== section.key && parentLabelByKey.get(candidate.key) === section.parentLabel);
1791
+ const parentStageEntries = stageEntries.filter((candidate) => parentLabelByKey.get(candidate.key) === section.parentLabel);
1792
+ const siblingStageScoreEntries = stageScoreEntries.filter((candidate) => candidate.key !== section.key && parentLabelByKey.get(candidate.key) === section.parentLabel);
1793
+ const parentStageScoreEntries = stageScoreEntries.filter((candidate) => parentLabelByKey.get(candidate.key) === section.parentLabel);
1794
+ const strongestStageSibling = siblingStageEntries.slice().sort((left, right) => right.count - left.count)[0];
1795
+ const parentStageTotal = parentStageEntries.reduce((sum, candidate) => sum + candidate.count, 0);
1796
+ const activeStageScore = stageScoreEntries.find((candidate) => candidate.key === section.key)?.totalScore;
1797
+ const strongestStageScoreSibling = siblingStageScoreEntries.slice().sort((left, right) => right.totalScore - left.totalScore)[0];
1798
+ const parentStageScoreTotal = parentStageScoreEntries.reduce((sum, candidate) => sum + candidate.totalScore, 0);
1799
+ const stageShare = stageTotal > 0 ? entry.count / stageTotal : 0;
1800
+ const retentionRate = typeof previousStageEntry?.count === "number" && previousStageEntry.count > 0 ? entry.count / previousStageEntry.count : undefined;
1801
+ const countDelta = typeof previousStageEntry?.count === "number" ? entry.count - previousStageEntry.count : undefined;
1802
+ const parentStageShare = parentStageTotal > 0 ? entry.count / parentStageTotal : undefined;
1803
+ const stageScoreShare = typeof activeStageScore === "number" && stageScoreTotal > 0 ? activeStageScore / stageScoreTotal : undefined;
1804
+ const parentStageScoreShare = typeof activeStageScore === "number" && parentStageScoreTotal > 0 ? activeStageScore / parentStageScoreTotal : undefined;
1805
+ const stageShareGap = stageTotal > 0 && strongestStageSibling ? entry.count / stageTotal - strongestStageSibling.count / stageTotal : undefined;
1806
+ const parentStageShareGap = parentStageTotal > 0 && strongestStageSibling ? entry.count / parentStageTotal - strongestStageSibling.count / parentStageTotal : undefined;
1807
+ const stageScoreShareGap = typeof activeStageScore === "number" && stageScoreTotal > 0 && strongestStageScoreSibling ? activeStageScore / stageScoreTotal - strongestStageScoreSibling.totalScore / stageScoreTotal : undefined;
1808
+ const parentStageScoreShareGap = typeof activeStageScore === "number" && parentStageScoreTotal > 0 && strongestStageScoreSibling ? activeStageScore / parentStageScoreTotal - strongestStageScoreSibling.totalScore / parentStageScoreTotal : undefined;
1809
+ const reasons2 = [];
1810
+ if (entry.stage === "rerank" && stageShare > 0.5 && (typeof stageShareGap !== "number" || stageShareGap > 0)) {
1811
+ reasons2.push("rerank_preserved_lead");
1812
+ }
1813
+ if (entry.stage === "finalize" && stageShare >= 0.5) {
1814
+ reasons2.push("final_stage_concentration");
1815
+ }
1816
+ if (entry.stage === "finalize" && typeof parentStageShare === "number" && parentStageShare >= 0.6 && (typeof parentStageShareGap !== "number" || parentStageShareGap > 0)) {
1817
+ reasons2.push("final_stage_dominant_within_parent");
1818
+ }
1819
+ if (strongestStageSibling && (typeof stageShareGap === "number" && stageShareGap <= 0.1 || typeof parentStageShareGap === "number" && parentStageShareGap <= 0.1)) {
1820
+ reasons2.push("stage_runner_up_pressure");
1821
+ }
1822
+ if (typeof countDelta === "number") {
1823
+ if (countDelta > 0) {
1824
+ reasons2.push("stage_expanded");
1825
+ } else if (countDelta < 0) {
1826
+ reasons2.push("stage_narrowed");
1827
+ } else {
1828
+ reasons2.push("stage_held");
1829
+ }
1830
+ }
1831
+ return {
1832
+ count: entry.count,
1833
+ countDelta,
1834
+ parentStageScoreShare,
1835
+ parentStageShare,
1836
+ parentStageShareGap,
1837
+ previousCount: previousStageEntry?.count,
1838
+ previousStage: previousStageEntry?.stage,
1839
+ reasons: reasons2,
1840
+ retentionRate,
1841
+ stage: entry.stage,
1842
+ stageScoreShare,
1843
+ stageScoreShareGap,
1844
+ stageShare,
1845
+ stageShareGap,
1846
+ totalScore: activeStageScore,
1847
+ strongestSiblingCount: strongestStageSibling?.count,
1848
+ strongestSiblingLabel: strongestStageSibling ? diagnostics.find((candidate) => candidate.key === strongestStageSibling.key)?.label ?? strongestStageSibling.key : undefined
1849
+ };
1850
+ });
1771
1851
  const firstSeenStage = stageCounts[0]?.stage;
1772
1852
  const lastSeenStage = stageCounts.at(-1)?.stage;
1853
+ const peakStageEntry = stageCounts.reduce((highest, entry) => !highest || entry.count > highest.count ? entry : highest, undefined);
1854
+ const finalStageEntry = stageCounts.at(-1);
1855
+ const peakCount = peakStageEntry?.count ?? section.count;
1856
+ const finalCount = finalStageEntry?.count;
1857
+ const finalRetentionRate = typeof finalCount === "number" && peakCount > 0 ? finalCount / peakCount : undefined;
1858
+ const dropFromPeak = typeof finalCount === "number" ? peakCount - finalCount : undefined;
1859
+ const queryAttributionReasons = [];
1860
+ const queryAttributionMode = section.primaryHits > 0 && section.transformedHits === 0 && section.variantHits === 0 ? "primary" : section.transformedHits > 0 && section.primaryHits === 0 && section.variantHits === 0 ? "transformed" : section.variantHits > 0 && section.primaryHits === 0 && section.transformedHits === 0 ? "variant" : "mixed";
1861
+ if (queryAttributionMode === "primary") {
1862
+ queryAttributionReasons.push("base_query_only");
1863
+ }
1864
+ if (queryAttributionMode === "transformed") {
1865
+ queryAttributionReasons.push("transformed_query_only");
1866
+ queryAttributionReasons.push("transform_introduced");
1867
+ }
1868
+ if (queryAttributionMode === "variant") {
1869
+ queryAttributionReasons.push("variant_only");
1870
+ queryAttributionReasons.push("variant_supported");
1871
+ }
1872
+ if (queryAttributionMode === "mixed") {
1873
+ queryAttributionReasons.push("mixed_query_sources");
1874
+ if (section.variantHits > 0) {
1875
+ queryAttributionReasons.push("variant_supported");
1876
+ }
1877
+ if (section.transformedHits > 0 && section.primaryHits === 0) {
1878
+ queryAttributionReasons.push("transform_introduced");
1879
+ }
1880
+ }
1773
1881
  if (section.bestScore >= strongestBestHit) {
1774
1882
  reasons.push("best_hit");
1775
1883
  }
@@ -1803,13 +1911,26 @@ var buildRAGSectionRetrievalDiagnostics = (sources, trace) => {
1803
1911
  parentShareGap: typeof parentShare === "number" && strongestSibling && parentTotal > 0 ? parentShare - strongestSibling.totalScore / parentTotal : undefined,
1804
1912
  path: section.path,
1805
1913
  firstSeenStage,
1914
+ finalCount,
1915
+ finalRetentionRate,
1806
1916
  lastSeenStage,
1917
+ dropFromPeak,
1918
+ peakCount,
1919
+ peakStage: peakStageEntry?.stage,
1920
+ queryAttribution: {
1921
+ mode: queryAttributionMode,
1922
+ primaryHits: section.primaryHits,
1923
+ reasons: queryAttributionReasons,
1924
+ transformedHits: section.transformedHits,
1925
+ variantHits: section.variantHits
1926
+ },
1807
1927
  retrievalMode: trace?.mode,
1808
1928
  reasons,
1809
1929
  rerankApplied: trace?.steps.some((step) => step.stage === "rerank" && step.metadata?.applied === true),
1810
1930
  scoreShare,
1811
1931
  scoreThresholdApplied: trace?.steps.some((step) => step.stage === "score_filter"),
1812
1932
  stageCounts,
1933
+ stageWeights,
1813
1934
  siblingCount: siblings.length,
1814
1935
  siblingScoreGap: strongestSibling ? section.totalScore - strongestSibling.totalScore : undefined,
1815
1936
  sourceCount: section.sourceSet.size,
@@ -1674,6 +1674,10 @@ var buildRAGSectionRetrievalDiagnostics = (sources, trace) => {
1674
1674
  const vectorHits = channels.includes("vector") ? 1 : 0;
1675
1675
  const lexicalHits = channels.includes("lexical") ? 1 : 0;
1676
1676
  const hybridHits = isHybrid ? 1 : 0;
1677
+ const queryOrigin = source.metadata?.retrievalQueryOrigin;
1678
+ const primaryHits = queryOrigin === "primary" ? 1 : 0;
1679
+ const transformedHits = queryOrigin === "transformed" ? 1 : 0;
1680
+ const variantHits = queryOrigin === "variant" ? 1 : 0;
1677
1681
  if (!existing) {
1678
1682
  sections.set(key, {
1679
1683
  bestScore: source.score,
@@ -1684,10 +1688,13 @@ var buildRAGSectionRetrievalDiagnostics = (sources, trace) => {
1684
1688
  lexicalHits,
1685
1689
  parentLabel,
1686
1690
  path,
1691
+ primaryHits,
1687
1692
  sourceSet: new Set(source.source ? [source.source] : []),
1688
1693
  topChunkId: source.chunkId,
1689
1694
  topSource: source.source,
1690
1695
  totalScore: source.score,
1696
+ transformedHits,
1697
+ variantHits,
1691
1698
  vectorHits
1692
1699
  });
1693
1700
  continue;
@@ -1700,6 +1707,9 @@ var buildRAGSectionRetrievalDiagnostics = (sources, trace) => {
1700
1707
  existing.vectorHits += vectorHits;
1701
1708
  existing.lexicalHits += lexicalHits;
1702
1709
  existing.hybridHits += hybridHits;
1710
+ existing.primaryHits += primaryHits;
1711
+ existing.transformedHits += transformedHits;
1712
+ existing.variantHits += variantHits;
1703
1713
  if (source.score > existing.bestScore) {
1704
1714
  existing.bestScore = source.score;
1705
1715
  existing.topChunkId = source.chunkId;
@@ -1708,6 +1718,9 @@ var buildRAGSectionRetrievalDiagnostics = (sources, trace) => {
1708
1718
  }
1709
1719
  const diagnostics = [...sections.values()];
1710
1720
  const strongestBestHit = diagnostics.reduce((highest, section) => Math.max(highest, section.bestScore), 0);
1721
+ const parentLabelByKey = new Map(diagnostics.map((section) => [section.key, section.parentLabel]));
1722
+ const stageSectionCounts = new Map((trace?.steps ?? []).filter((step) => Array.isArray(step.sectionCounts) && step.sectionCounts.length > 0).map((step) => [step.stage, step.sectionCounts ?? []]));
1723
+ const stageSectionScores = new Map((trace?.steps ?? []).filter((step) => Array.isArray(step.sectionScores) && step.sectionScores.length > 0).map((step) => [step.stage, step.sectionScores ?? []]));
1711
1724
  return diagnostics.map((section) => {
1712
1725
  const siblingPool = diagnostics.filter((entry) => entry.parentLabel === section.parentLabel);
1713
1726
  const siblings = siblingPool.filter((entry) => entry.key !== section.key);
@@ -1728,8 +1741,103 @@ var buildRAGSectionRetrievalDiagnostics = (sources, trace) => {
1728
1741
  count: step.sectionCounts?.find((entry) => entry.key === section.key)?.count ?? 0,
1729
1742
  stage: step.stage
1730
1743
  })).filter((entry) => entry.count > 0) ?? [];
1744
+ const stageWeights = stageCounts.map((entry) => {
1745
+ const previousStageEntry = stageCounts[stageCounts.findIndex((candidate) => candidate.stage === entry.stage) - 1];
1746
+ const stageEntries = stageSectionCounts.get(entry.stage)?.filter((candidate) => candidate.count > 0) ?? [];
1747
+ const stageScoreEntries = stageSectionScores.get(entry.stage)?.filter((candidate) => candidate.totalScore > 0) ?? [];
1748
+ const stageTotal = stageEntries.reduce((sum, candidate) => sum + candidate.count, 0);
1749
+ const stageScoreTotal = stageScoreEntries.reduce((sum, candidate) => sum + candidate.totalScore, 0);
1750
+ const siblingStageEntries = stageEntries.filter((candidate) => candidate.key !== section.key && parentLabelByKey.get(candidate.key) === section.parentLabel);
1751
+ const parentStageEntries = stageEntries.filter((candidate) => parentLabelByKey.get(candidate.key) === section.parentLabel);
1752
+ const siblingStageScoreEntries = stageScoreEntries.filter((candidate) => candidate.key !== section.key && parentLabelByKey.get(candidate.key) === section.parentLabel);
1753
+ const parentStageScoreEntries = stageScoreEntries.filter((candidate) => parentLabelByKey.get(candidate.key) === section.parentLabel);
1754
+ const strongestStageSibling = siblingStageEntries.slice().sort((left, right) => right.count - left.count)[0];
1755
+ const parentStageTotal = parentStageEntries.reduce((sum, candidate) => sum + candidate.count, 0);
1756
+ const activeStageScore = stageScoreEntries.find((candidate) => candidate.key === section.key)?.totalScore;
1757
+ const strongestStageScoreSibling = siblingStageScoreEntries.slice().sort((left, right) => right.totalScore - left.totalScore)[0];
1758
+ const parentStageScoreTotal = parentStageScoreEntries.reduce((sum, candidate) => sum + candidate.totalScore, 0);
1759
+ const stageShare = stageTotal > 0 ? entry.count / stageTotal : 0;
1760
+ const retentionRate = typeof previousStageEntry?.count === "number" && previousStageEntry.count > 0 ? entry.count / previousStageEntry.count : undefined;
1761
+ const countDelta = typeof previousStageEntry?.count === "number" ? entry.count - previousStageEntry.count : undefined;
1762
+ const parentStageShare = parentStageTotal > 0 ? entry.count / parentStageTotal : undefined;
1763
+ const stageScoreShare = typeof activeStageScore === "number" && stageScoreTotal > 0 ? activeStageScore / stageScoreTotal : undefined;
1764
+ const parentStageScoreShare = typeof activeStageScore === "number" && parentStageScoreTotal > 0 ? activeStageScore / parentStageScoreTotal : undefined;
1765
+ const stageShareGap = stageTotal > 0 && strongestStageSibling ? entry.count / stageTotal - strongestStageSibling.count / stageTotal : undefined;
1766
+ const parentStageShareGap = parentStageTotal > 0 && strongestStageSibling ? entry.count / parentStageTotal - strongestStageSibling.count / parentStageTotal : undefined;
1767
+ const stageScoreShareGap = typeof activeStageScore === "number" && stageScoreTotal > 0 && strongestStageScoreSibling ? activeStageScore / stageScoreTotal - strongestStageScoreSibling.totalScore / stageScoreTotal : undefined;
1768
+ const parentStageScoreShareGap = typeof activeStageScore === "number" && parentStageScoreTotal > 0 && strongestStageScoreSibling ? activeStageScore / parentStageScoreTotal - strongestStageScoreSibling.totalScore / parentStageScoreTotal : undefined;
1769
+ const reasons2 = [];
1770
+ if (entry.stage === "rerank" && stageShare > 0.5 && (typeof stageShareGap !== "number" || stageShareGap > 0)) {
1771
+ reasons2.push("rerank_preserved_lead");
1772
+ }
1773
+ if (entry.stage === "finalize" && stageShare >= 0.5) {
1774
+ reasons2.push("final_stage_concentration");
1775
+ }
1776
+ if (entry.stage === "finalize" && typeof parentStageShare === "number" && parentStageShare >= 0.6 && (typeof parentStageShareGap !== "number" || parentStageShareGap > 0)) {
1777
+ reasons2.push("final_stage_dominant_within_parent");
1778
+ }
1779
+ if (strongestStageSibling && (typeof stageShareGap === "number" && stageShareGap <= 0.1 || typeof parentStageShareGap === "number" && parentStageShareGap <= 0.1)) {
1780
+ reasons2.push("stage_runner_up_pressure");
1781
+ }
1782
+ if (typeof countDelta === "number") {
1783
+ if (countDelta > 0) {
1784
+ reasons2.push("stage_expanded");
1785
+ } else if (countDelta < 0) {
1786
+ reasons2.push("stage_narrowed");
1787
+ } else {
1788
+ reasons2.push("stage_held");
1789
+ }
1790
+ }
1791
+ return {
1792
+ count: entry.count,
1793
+ countDelta,
1794
+ parentStageScoreShare,
1795
+ parentStageShare,
1796
+ parentStageShareGap,
1797
+ previousCount: previousStageEntry?.count,
1798
+ previousStage: previousStageEntry?.stage,
1799
+ reasons: reasons2,
1800
+ retentionRate,
1801
+ stage: entry.stage,
1802
+ stageScoreShare,
1803
+ stageScoreShareGap,
1804
+ stageShare,
1805
+ stageShareGap,
1806
+ totalScore: activeStageScore,
1807
+ strongestSiblingCount: strongestStageSibling?.count,
1808
+ strongestSiblingLabel: strongestStageSibling ? diagnostics.find((candidate) => candidate.key === strongestStageSibling.key)?.label ?? strongestStageSibling.key : undefined
1809
+ };
1810
+ });
1731
1811
  const firstSeenStage = stageCounts[0]?.stage;
1732
1812
  const lastSeenStage = stageCounts.at(-1)?.stage;
1813
+ const peakStageEntry = stageCounts.reduce((highest, entry) => !highest || entry.count > highest.count ? entry : highest, undefined);
1814
+ const finalStageEntry = stageCounts.at(-1);
1815
+ const peakCount = peakStageEntry?.count ?? section.count;
1816
+ const finalCount = finalStageEntry?.count;
1817
+ const finalRetentionRate = typeof finalCount === "number" && peakCount > 0 ? finalCount / peakCount : undefined;
1818
+ const dropFromPeak = typeof finalCount === "number" ? peakCount - finalCount : undefined;
1819
+ const queryAttributionReasons = [];
1820
+ const queryAttributionMode = section.primaryHits > 0 && section.transformedHits === 0 && section.variantHits === 0 ? "primary" : section.transformedHits > 0 && section.primaryHits === 0 && section.variantHits === 0 ? "transformed" : section.variantHits > 0 && section.primaryHits === 0 && section.transformedHits === 0 ? "variant" : "mixed";
1821
+ if (queryAttributionMode === "primary") {
1822
+ queryAttributionReasons.push("base_query_only");
1823
+ }
1824
+ if (queryAttributionMode === "transformed") {
1825
+ queryAttributionReasons.push("transformed_query_only");
1826
+ queryAttributionReasons.push("transform_introduced");
1827
+ }
1828
+ if (queryAttributionMode === "variant") {
1829
+ queryAttributionReasons.push("variant_only");
1830
+ queryAttributionReasons.push("variant_supported");
1831
+ }
1832
+ if (queryAttributionMode === "mixed") {
1833
+ queryAttributionReasons.push("mixed_query_sources");
1834
+ if (section.variantHits > 0) {
1835
+ queryAttributionReasons.push("variant_supported");
1836
+ }
1837
+ if (section.transformedHits > 0 && section.primaryHits === 0) {
1838
+ queryAttributionReasons.push("transform_introduced");
1839
+ }
1840
+ }
1733
1841
  if (section.bestScore >= strongestBestHit) {
1734
1842
  reasons.push("best_hit");
1735
1843
  }
@@ -1763,13 +1871,26 @@ var buildRAGSectionRetrievalDiagnostics = (sources, trace) => {
1763
1871
  parentShareGap: typeof parentShare === "number" && strongestSibling && parentTotal > 0 ? parentShare - strongestSibling.totalScore / parentTotal : undefined,
1764
1872
  path: section.path,
1765
1873
  firstSeenStage,
1874
+ finalCount,
1875
+ finalRetentionRate,
1766
1876
  lastSeenStage,
1877
+ dropFromPeak,
1878
+ peakCount,
1879
+ peakStage: peakStageEntry?.stage,
1880
+ queryAttribution: {
1881
+ mode: queryAttributionMode,
1882
+ primaryHits: section.primaryHits,
1883
+ reasons: queryAttributionReasons,
1884
+ transformedHits: section.transformedHits,
1885
+ variantHits: section.variantHits
1886
+ },
1767
1887
  retrievalMode: trace?.mode,
1768
1888
  reasons,
1769
1889
  rerankApplied: trace?.steps.some((step) => step.stage === "rerank" && step.metadata?.applied === true),
1770
1890
  scoreShare,
1771
1891
  scoreThresholdApplied: trace?.steps.some((step) => step.stage === "score_filter"),
1772
1892
  stageCounts,
1893
+ stageWeights,
1773
1894
  siblingCount: siblings.length,
1774
1895
  siblingScoreGap: strongestSibling ? section.totalScore - strongestSibling.totalScore : undefined,
1775
1896
  sourceCount: section.sourceSet.size,
@@ -2717,6 +2717,10 @@ var buildRAGSectionRetrievalDiagnostics = (sources, trace) => {
2717
2717
  const vectorHits = channels.includes("vector") ? 1 : 0;
2718
2718
  const lexicalHits = channels.includes("lexical") ? 1 : 0;
2719
2719
  const hybridHits = isHybrid ? 1 : 0;
2720
+ const queryOrigin = source.metadata?.retrievalQueryOrigin;
2721
+ const primaryHits = queryOrigin === "primary" ? 1 : 0;
2722
+ const transformedHits = queryOrigin === "transformed" ? 1 : 0;
2723
+ const variantHits = queryOrigin === "variant" ? 1 : 0;
2720
2724
  if (!existing) {
2721
2725
  sections.set(key, {
2722
2726
  bestScore: source.score,
@@ -2727,10 +2731,13 @@ var buildRAGSectionRetrievalDiagnostics = (sources, trace) => {
2727
2731
  lexicalHits,
2728
2732
  parentLabel,
2729
2733
  path,
2734
+ primaryHits,
2730
2735
  sourceSet: new Set(source.source ? [source.source] : []),
2731
2736
  topChunkId: source.chunkId,
2732
2737
  topSource: source.source,
2733
2738
  totalScore: source.score,
2739
+ transformedHits,
2740
+ variantHits,
2734
2741
  vectorHits
2735
2742
  });
2736
2743
  continue;
@@ -2743,6 +2750,9 @@ var buildRAGSectionRetrievalDiagnostics = (sources, trace) => {
2743
2750
  existing.vectorHits += vectorHits;
2744
2751
  existing.lexicalHits += lexicalHits;
2745
2752
  existing.hybridHits += hybridHits;
2753
+ existing.primaryHits += primaryHits;
2754
+ existing.transformedHits += transformedHits;
2755
+ existing.variantHits += variantHits;
2746
2756
  if (source.score > existing.bestScore) {
2747
2757
  existing.bestScore = source.score;
2748
2758
  existing.topChunkId = source.chunkId;
@@ -2751,6 +2761,9 @@ var buildRAGSectionRetrievalDiagnostics = (sources, trace) => {
2751
2761
  }
2752
2762
  const diagnostics = [...sections.values()];
2753
2763
  const strongestBestHit = diagnostics.reduce((highest, section) => Math.max(highest, section.bestScore), 0);
2764
+ const parentLabelByKey = new Map(diagnostics.map((section) => [section.key, section.parentLabel]));
2765
+ const stageSectionCounts = new Map((trace?.steps ?? []).filter((step) => Array.isArray(step.sectionCounts) && step.sectionCounts.length > 0).map((step) => [step.stage, step.sectionCounts ?? []]));
2766
+ const stageSectionScores = new Map((trace?.steps ?? []).filter((step) => Array.isArray(step.sectionScores) && step.sectionScores.length > 0).map((step) => [step.stage, step.sectionScores ?? []]));
2754
2767
  return diagnostics.map((section) => {
2755
2768
  const siblingPool = diagnostics.filter((entry) => entry.parentLabel === section.parentLabel);
2756
2769
  const siblings = siblingPool.filter((entry) => entry.key !== section.key);
@@ -2771,8 +2784,103 @@ var buildRAGSectionRetrievalDiagnostics = (sources, trace) => {
2771
2784
  count: step.sectionCounts?.find((entry) => entry.key === section.key)?.count ?? 0,
2772
2785
  stage: step.stage
2773
2786
  })).filter((entry) => entry.count > 0) ?? [];
2787
+ const stageWeights = stageCounts.map((entry) => {
2788
+ const previousStageEntry = stageCounts[stageCounts.findIndex((candidate) => candidate.stage === entry.stage) - 1];
2789
+ const stageEntries = stageSectionCounts.get(entry.stage)?.filter((candidate) => candidate.count > 0) ?? [];
2790
+ const stageScoreEntries = stageSectionScores.get(entry.stage)?.filter((candidate) => candidate.totalScore > 0) ?? [];
2791
+ const stageTotal = stageEntries.reduce((sum, candidate) => sum + candidate.count, 0);
2792
+ const stageScoreTotal = stageScoreEntries.reduce((sum, candidate) => sum + candidate.totalScore, 0);
2793
+ const siblingStageEntries = stageEntries.filter((candidate) => candidate.key !== section.key && parentLabelByKey.get(candidate.key) === section.parentLabel);
2794
+ const parentStageEntries = stageEntries.filter((candidate) => parentLabelByKey.get(candidate.key) === section.parentLabel);
2795
+ const siblingStageScoreEntries = stageScoreEntries.filter((candidate) => candidate.key !== section.key && parentLabelByKey.get(candidate.key) === section.parentLabel);
2796
+ const parentStageScoreEntries = stageScoreEntries.filter((candidate) => parentLabelByKey.get(candidate.key) === section.parentLabel);
2797
+ const strongestStageSibling = siblingStageEntries.slice().sort((left, right) => right.count - left.count)[0];
2798
+ const parentStageTotal = parentStageEntries.reduce((sum, candidate) => sum + candidate.count, 0);
2799
+ const activeStageScore = stageScoreEntries.find((candidate) => candidate.key === section.key)?.totalScore;
2800
+ const strongestStageScoreSibling = siblingStageScoreEntries.slice().sort((left, right) => right.totalScore - left.totalScore)[0];
2801
+ const parentStageScoreTotal = parentStageScoreEntries.reduce((sum, candidate) => sum + candidate.totalScore, 0);
2802
+ const stageShare = stageTotal > 0 ? entry.count / stageTotal : 0;
2803
+ const retentionRate = typeof previousStageEntry?.count === "number" && previousStageEntry.count > 0 ? entry.count / previousStageEntry.count : undefined;
2804
+ const countDelta = typeof previousStageEntry?.count === "number" ? entry.count - previousStageEntry.count : undefined;
2805
+ const parentStageShare = parentStageTotal > 0 ? entry.count / parentStageTotal : undefined;
2806
+ const stageScoreShare = typeof activeStageScore === "number" && stageScoreTotal > 0 ? activeStageScore / stageScoreTotal : undefined;
2807
+ const parentStageScoreShare = typeof activeStageScore === "number" && parentStageScoreTotal > 0 ? activeStageScore / parentStageScoreTotal : undefined;
2808
+ const stageShareGap = stageTotal > 0 && strongestStageSibling ? entry.count / stageTotal - strongestStageSibling.count / stageTotal : undefined;
2809
+ const parentStageShareGap = parentStageTotal > 0 && strongestStageSibling ? entry.count / parentStageTotal - strongestStageSibling.count / parentStageTotal : undefined;
2810
+ const stageScoreShareGap = typeof activeStageScore === "number" && stageScoreTotal > 0 && strongestStageScoreSibling ? activeStageScore / stageScoreTotal - strongestStageScoreSibling.totalScore / stageScoreTotal : undefined;
2811
+ const parentStageScoreShareGap = typeof activeStageScore === "number" && parentStageScoreTotal > 0 && strongestStageScoreSibling ? activeStageScore / parentStageScoreTotal - strongestStageScoreSibling.totalScore / parentStageScoreTotal : undefined;
2812
+ const reasons2 = [];
2813
+ if (entry.stage === "rerank" && stageShare > 0.5 && (typeof stageShareGap !== "number" || stageShareGap > 0)) {
2814
+ reasons2.push("rerank_preserved_lead");
2815
+ }
2816
+ if (entry.stage === "finalize" && stageShare >= 0.5) {
2817
+ reasons2.push("final_stage_concentration");
2818
+ }
2819
+ if (entry.stage === "finalize" && typeof parentStageShare === "number" && parentStageShare >= 0.6 && (typeof parentStageShareGap !== "number" || parentStageShareGap > 0)) {
2820
+ reasons2.push("final_stage_dominant_within_parent");
2821
+ }
2822
+ if (strongestStageSibling && (typeof stageShareGap === "number" && stageShareGap <= 0.1 || typeof parentStageShareGap === "number" && parentStageShareGap <= 0.1)) {
2823
+ reasons2.push("stage_runner_up_pressure");
2824
+ }
2825
+ if (typeof countDelta === "number") {
2826
+ if (countDelta > 0) {
2827
+ reasons2.push("stage_expanded");
2828
+ } else if (countDelta < 0) {
2829
+ reasons2.push("stage_narrowed");
2830
+ } else {
2831
+ reasons2.push("stage_held");
2832
+ }
2833
+ }
2834
+ return {
2835
+ count: entry.count,
2836
+ countDelta,
2837
+ parentStageScoreShare,
2838
+ parentStageShare,
2839
+ parentStageShareGap,
2840
+ previousCount: previousStageEntry?.count,
2841
+ previousStage: previousStageEntry?.stage,
2842
+ reasons: reasons2,
2843
+ retentionRate,
2844
+ stage: entry.stage,
2845
+ stageScoreShare,
2846
+ stageScoreShareGap,
2847
+ stageShare,
2848
+ stageShareGap,
2849
+ totalScore: activeStageScore,
2850
+ strongestSiblingCount: strongestStageSibling?.count,
2851
+ strongestSiblingLabel: strongestStageSibling ? diagnostics.find((candidate) => candidate.key === strongestStageSibling.key)?.label ?? strongestStageSibling.key : undefined
2852
+ };
2853
+ });
2774
2854
  const firstSeenStage = stageCounts[0]?.stage;
2775
2855
  const lastSeenStage = stageCounts.at(-1)?.stage;
2856
+ const peakStageEntry = stageCounts.reduce((highest, entry) => !highest || entry.count > highest.count ? entry : highest, undefined);
2857
+ const finalStageEntry = stageCounts.at(-1);
2858
+ const peakCount = peakStageEntry?.count ?? section.count;
2859
+ const finalCount = finalStageEntry?.count;
2860
+ const finalRetentionRate = typeof finalCount === "number" && peakCount > 0 ? finalCount / peakCount : undefined;
2861
+ const dropFromPeak = typeof finalCount === "number" ? peakCount - finalCount : undefined;
2862
+ const queryAttributionReasons = [];
2863
+ const queryAttributionMode = section.primaryHits > 0 && section.transformedHits === 0 && section.variantHits === 0 ? "primary" : section.transformedHits > 0 && section.primaryHits === 0 && section.variantHits === 0 ? "transformed" : section.variantHits > 0 && section.primaryHits === 0 && section.transformedHits === 0 ? "variant" : "mixed";
2864
+ if (queryAttributionMode === "primary") {
2865
+ queryAttributionReasons.push("base_query_only");
2866
+ }
2867
+ if (queryAttributionMode === "transformed") {
2868
+ queryAttributionReasons.push("transformed_query_only");
2869
+ queryAttributionReasons.push("transform_introduced");
2870
+ }
2871
+ if (queryAttributionMode === "variant") {
2872
+ queryAttributionReasons.push("variant_only");
2873
+ queryAttributionReasons.push("variant_supported");
2874
+ }
2875
+ if (queryAttributionMode === "mixed") {
2876
+ queryAttributionReasons.push("mixed_query_sources");
2877
+ if (section.variantHits > 0) {
2878
+ queryAttributionReasons.push("variant_supported");
2879
+ }
2880
+ if (section.transformedHits > 0 && section.primaryHits === 0) {
2881
+ queryAttributionReasons.push("transform_introduced");
2882
+ }
2883
+ }
2776
2884
  if (section.bestScore >= strongestBestHit) {
2777
2885
  reasons.push("best_hit");
2778
2886
  }
@@ -2806,13 +2914,26 @@ var buildRAGSectionRetrievalDiagnostics = (sources, trace) => {
2806
2914
  parentShareGap: typeof parentShare === "number" && strongestSibling && parentTotal > 0 ? parentShare - strongestSibling.totalScore / parentTotal : undefined,
2807
2915
  path: section.path,
2808
2916
  firstSeenStage,
2917
+ finalCount,
2918
+ finalRetentionRate,
2809
2919
  lastSeenStage,
2920
+ dropFromPeak,
2921
+ peakCount,
2922
+ peakStage: peakStageEntry?.stage,
2923
+ queryAttribution: {
2924
+ mode: queryAttributionMode,
2925
+ primaryHits: section.primaryHits,
2926
+ reasons: queryAttributionReasons,
2927
+ transformedHits: section.transformedHits,
2928
+ variantHits: section.variantHits
2929
+ },
2810
2930
  retrievalMode: trace?.mode,
2811
2931
  reasons,
2812
2932
  rerankApplied: trace?.steps.some((step) => step.stage === "rerank" && step.metadata?.applied === true),
2813
2933
  scoreShare,
2814
2934
  scoreThresholdApplied: trace?.steps.some((step) => step.stage === "score_filter"),
2815
2935
  stageCounts,
2936
+ stageWeights,
2816
2937
  siblingCount: siblings.length,
2817
2938
  siblingScoreGap: strongestSibling ? section.totalScore - strongestSibling.totalScore : undefined,
2818
2939
  sourceCount: section.sourceSet.size,